Wikipedia:Reference desk/Archives/Computing/2012 December 1

{{#ifeq:{{PAGENAME}}|Special:Undelete| |{{#if:|

}} {{#ifeq:{{NAMESPACE}}|Wikipedia|{{#switch:{{NAMESPACE}}|= |
}}|{{error:not substituted|Archive header}}
}}}} {{#if:|
}}
width = "100%"
colspan="3" align="center" | Computing desk
width="20%" align="left" | < November 30

! width="25%" align="center"|<< Nov | December | Jan >>

! width="20%" align="right" |{{#ifexist:Wikipedia:Reference desk/Archives/Computing/2012 December 2|December 2|Current desk}} >

align=center width=95% style="background: #FFFFFF; border: 1px solid #003EBA;" cellpadding="8" cellspacing="0"
style="background: #5D7CBA; text-align: center; font-family:Arial; color:#FFFFFF;" | Welcome to the Wikipedia Computing Reference Desk Archives
The page you are currently viewing is {{#ifexist:Wikipedia:Reference desk/Archives/Computing/2012 December 11|an archive page|a transcluded archive page}}. While you can leave answers for any questions shown below, please ask new questions on one of the current reference desk pages.

__TOC__

= December 1 =

Python syntax error

I've recently started learning Python, and I'm trying to write a simple program to calculate the day of the week. However, the following code (designed to determine if a user-entered year is a leap year, in which case 1 must be subtracted from the total) does not appear to be valid:

if month == January or February and year % 4 == 0 and year % 100 != 0:

total = day + month_code + int((year_breaker[-2:]/4)) + int(year_breaker[-2:]) + century_code - 1

elif month == January or February and year % 400 == 0:

total = day + month_code + int((year_breaker[-2:]/4)) + int(year_breaker[-2:]) + century_code - 1

else total = day + month_code + int((year_breaker[-2:]/4)) + int(year_breaker[-2:]) + century_code

When I run the program, I receive the following error:

File "Weekday.py", line 53

else total = day + month_code + int((year_breaker[-2:]/4)) + int(year_breaker[-2:]) + century_code

^

SyntaxError: invalid syntax

What is invalid about the "l" of "total"? Pokajanje|Talk 00:06, 1 December 2012 (UTC)

: missing colon after else. -- Finlay McWalterTalk 00:15, 1 December 2012 (UTC)

::Yes, but also Python requires proper indentations, as a syntax element. Perhaps they were lost when the OP did the cut and paste, but, just in case, here it is corrected:

if month == January or February and year % 4 == 0 and year % 100 != 0:

total = day + month_code + int((year_breaker[-2:]/4)) + int(year_breaker[-2:]) + century_code - 1

elif month == January or February and year % 400 == 0:

total = day + month_code + int((year_breaker[-2:]/4)) + int(year_breaker[-2:]) + century_code - 1

else:

total = day + month_code + int((year_breaker[-2:]/4)) + int(year_breaker[-2:]) + century_code

::StuRat (talk) 00:20, 1 December 2012 (UTC)

:Note that error messages frequently point to the next thing after the error, rather than the error itself, as in this case. StuRat (talk) 00:23, 1 December 2012 (UTC)

Thanks for the quick responses and your patience. I am now receiving another, unrelated error. The formula requires that one of seven different numbers be added to the total, depending on the month (I have named this variable "month_code"). So early on in the program I have:

month = raw_input("Enter the month (the whole word). ")

And later I have an if statement beginning with:

if month == April or July:

month_code = 0

elif month == January or October:

month_code = 1

When the program runs, I can enter all the data, but then I receive:

NameError: name 'April' is not defined

Just as the previous error, I'm sure this is something obvious, but I don't know enough to see it. Pokajanje|Talk 00:34, 1 December 2012 (UTC)

  • {{ec}} Note that month == January or February will yield True as long as February is not False/None/0; use

month == January or month == February

or

month in (January, February)

Use parentheses to force the [http://docs.python.org/2/reference/expressions.html#summary operator precedence] you want, for example

if (month == January or month == February) and (year % 4 == 0) and (year % 100 != 0):

which also comes with the benefit of added readability. About the April symbol error, look up your code, make sure that April is being defined before execution reaches that point — Frankie (talk) 00:41, 1 December 2012 (UTC)

::I tried all three of your suggestions. None worked. I intend that if the user enters "April", thereby making "month" equal to it, "month_code" will be zero. So there's really nothing to define. Pokajanje|Talk 00:55, 1 December 2012 (UTC)

:::Ok, are you doing something like month = raw_input("Please enter the month: ")? If so you need to use quotes because it is a string: if month == "April". It's case sensitive, so if the user enters "april" it will yield False — Frankie (talk) 01:09, 1 December 2012 (UTC)

::::Yes, and I have since fixed that and several other errors. The program now runs fully, but it gives the wrong days (calling November 30, 2012 a Monday). I looked through it very carefully, and checked the math and the formula myself, but I still can't find my mistake. The full source code (thus far) can be found [http://pastebin.com/ztL5MLWj here]. The formula I am using can be found [http://www.mcs.csueastbay.edu/~malek/Mathlinks/Weekdays.html here]. Pokajanje|Talk 04:59, 1 December 2012 (UTC)

:::::Diagnosing these problems is called debugging and it's a very major component of programming at every level, so now you get to develop some skill at it. The amount of code you wrote without testing and debugging it was already maybe larger than ideal. You should write just a little bit of code (just a few lines when you're just getting started), test it, fix any problems, write a little more, etc. But this program is still pretty small and you should be able to find the problems and fix them.

Anyway what I'd suggest is working through the formula by hand with pencil and paper for a known date like November 30, 2012; write down all the intermediate results. Do you get the right answer? In this case, the program has errors. Add a series of print statements to the program to show the intermediate results during the calculation, and compare them to the steps in your hand calculation. Where you see a discrepancy, figure out what has happened, and that is probably a bug. Of course there may be multiple bugs, so keep testing and checking til you're confident that everything is fixed. Generally, don't try too hard to figure out in your head what the program is going to do at a given point, since it's easy to make errors. Add print statements to trace the program's activity so you can know for sure whether it's going wrong at a particular place.

One note: the integer division operator in Python is // (double slash) rather than / (single slash). Single slash works in Python 2 but will throw a warning is deprecated. In Python 3, it will give a floating point result and that can lead to wrong outputs. 66.127.54.40 (talk) 07:09, 1 December 2012 (UTC)

::::::I'm aware of debugging & its importance. I just don't know enough to see the bug yet. Pokajanje|Talk 17:15, 1 December 2012 (UTC)

:::::A few minor problems I see:

:::::1) When you give the error message "Error: this program cannot find dates before 1500 or after 2699", you don't do anything to prevent it from executing the rest of the code normally. Ideally you would loop back and ask for the year again.

:::::2) Asking for the first two digits of the year, then the last 2, is sloppy. You should just ask for the full year and parse it yourself.

:::::3) The prompts should end in a colon, not a period. This is how the user can easily distinguish between normal prints (ending in periods) and prompts.

:::::4) As pointed out above, you need to change the month name to either all uppercase or all lowercase, to make comparisons work despite their case. Python provides simple methods to do those conversions.

:::::5) "Enter the day" is ambiguous. Try "Enter the day of the month" (versus the day of the week).

:::::6) You have part of the last line repeated at the end, causing a syntax error.

:::::As for why you are getting wrong answers, if you can provide a text description of the logic you are attempting to implement, it would be easier to for us to help you debug. StuRat (talk) 07:41, 1 December 2012 (UTC)

:::::::Just to help the OP along: You program still has the (incorrect) if month == "April" or "July". This is not interpreted as if (month == "April") or (month == "July") as you intend. "July" on its own is the the second expression evaluated for the or. Since the truth value of a non-empty string in Python is True, this part is always true, and (anything or True) is also always true. Use the expanded version (something like that works in nearly every language), or use month in ("April", "July") - something similar works in many modern high-level languages (like Python), but not in other languages. --Stephan Schulz (talk) 07:56, 1 December 2012 (UTC)

:::::::What I would suggest (kind of a more specific debugging suggestion) is printing the values of month_code and century_code after they are computed. Are the results what you expected? If not, you have narrowed down the problem. 66.127.54.40 (talk) 08:33, 1 December 2012 (UTC)

The problem was with century_code as described by Stephan Schulz. The program now works perfectly (I have removed the error messages for simplicity) and it can be seen [http://pastebin.com/Nr1DjJrB here]. Thank you all for your patience. Pokajanje|Talk 19:23, 1 December 2012 (UTC)

:You haven't addressed my points #1 and #4, so it's not going to work in those cases. Also, you might want to change from "was" to "is" when you print the results, since the date might be in the past, present, or future. (You could also check against the current date and use "was", "is", or "will be", where appropriate, but that gets involved, as it depends on time zones, daylight savings time, etc.) StuRat (talk) 02:23, 2 December 2012 (UTC)

:The simplest way to fix issue #1 is to add an "else:" after the error message, and indent the rest of the program after it. This won't prompt them to re-enter the year, though, the program will just end. StuRat (talk) 02:34, 2 December 2012 (UTC)

:The simplest way to fix issue #4 is to add this line after they input the month:

month = month[0].upper() + month[1:].lower()

:This will make the first letter of the month uppercase and the rest lowercase. StuRat (talk) 02:51, 2 December 2012 (UTC)

:Also, I suggest you replace the last bit with this:

print "%s %s, %s is a" % (month, day, year),

if total % 7 == 0:

print "Saturday."

elif total % 7 == 1:

print "Sunday."

elif total % 7 == 2:

print "Monday."

elif total % 7 == 3:

print "Tuesday."

elif total % 7 == 4:

print "Wednesday."

elif total % 7 == 5:

print "Thursday."

elif total % 7 == 6 :

print "Friday."

:The advantage (along with being shorter), is that there's a single point of control. Thus, if you want to change the common part of the print, you need only change one line, instead of all 7. StuRat (talk) 03:24, 2 December 2012 (UTC)

::An even simpler and more compact idiom would be

weekdays = ("Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Friday")

print "%s %s, %s was a %s." % (month, day, year, weekdays[total % 7])

:: I.e. make it data-driven, not driven by control flow. --Stephan Schulz (talk) 08:16, 2 December 2012 (UTC)

:::...but don't forget to change "was" to "is", as I did, to avoid "January 1, 2200 was a Wednesday.". StuRat (talk) 08:38, 2 December 2012 (UTC)

::::Instead of month[0].upper() + month[1:].lower() you can write month.title(). StuRat, I know you just started learning Python and I don't think you should be instructing people in it quite yet.

::::The test century < 15 or century > 26 can be written not (15 <= century <= 26). This doesn't work in most other languages, though. (In C or C++ it will silently do the wrong thing).

::::For what it's worth there are standard library functions to do all of this stuff. You can replace everything after the raw_input statements with this:

import time

t = time.strptime("%d %s %d" % (century * 100 + year, month, day), "%Y %B %d")

print time.strftime("%B %d, %Y is a %A.", t)

::::See [http://docs.python.org/2/library/time.html the documentation]. Of course, it's fine to do everything yourself for practice, but once you're done practicing you should discard your code and use the library functions, since they're already debugged. I think no one has pointed out yet that your code tests century % 400 == 0 (it should be century % 4 == 0), and there may be other lingering bugs. -- BenRG (talk) 18:11, 2 December 2012 (UTC)

:::::Your method only shows them how to change a string to title form, while mine teaches how to change to uppercase and lowercase, and also how to slice and concatenate strings. Also, I doubt if you would have thought to show them any of it, had I not already brought up the issue. As for the 400 year check, I think that's right. The leap year rule is, every fourth year is a leap year, except for every hundredth year, except for every 400th year. So, 1600, 2000, and 2400 are still leap years, while 1700, 1800, 1900, 2100, 2200, and 2300 are not. StuRat (talk) 19:12, 2 December 2012 (UTC)

:::::Also, Ben, I did at least test my code. Your code doesn't work. First you need to define "century", perhaps with "century = year_breaker[:2]". Also, you are using "year" to mean just the last two digits of the year, while the OP is using it for the entire year. Finally, I get a string/integer incompatibility error when I try to run it. StuRat (talk) 19:30, 2 December 2012 (UTC)

JQuery works on Codecadamy but not on my machine

I'm working on this exercise: http://www.codecademy.com/courses/jquery-checkers-part-2/0#!/exercises/1

If you click "Result", you see a brown outline of a box and the words, "Checkers Moves: 0". Well, I get that far when saving the four files: Checkers.html, provided.js, script.js,style.css to a folder on my desktop.

However when I add the code that creates the 64 squares, it works on Codecadamy, but on my computer it doesn't register the changes (64 squares do not appear within the brown box, it looks just like it did before). I am positive I saved my work. Any ideas why it isn't showing the changes? 169.231.8.73 (talk) 09:16, 1 December 2012 (UTC)

:Are you linking to the JQuery library? The Codeacadamy frame includes a JQuery call that isn't listed in checkers.html (probably to simplify things, but it strikes me that it will confuse things). In the "" section of checkers.html, add