========
UPDATE 23-Jun-2013: After approving comments yesterday and tweaking my doctests, this exercise certainly must have been on my mind! I woke up this morning with a “why didn’t I do it this way before?!” thought. My 2nd revision to this exercise is posted as a reply below.
========
UPDATE 10-Mar-2013: OUCH! Mongo apologies for all the kind people who have commented!!!! Just received another one today. I’m just a budding blogger (ha – more like blogger-wannabe; i don’t deserve the “blogger” title by any stretch — yet!) as well as a terrifically overworked employee, so there’s little time to play these days. I will be getting back into it with a small diversion toward into some HTML parsing.
Thank you, thank you, thank you to the commenters! It’s really delightful you happened to discover my little post. Cheers to all.
— Original 20-Jan-2013 post below —
Over the weekend, I was at the MIT Press bookstore in Cambridge MA for “The CSound Book” and of course I had to ask if they had any Python books. I picked up a copy of John V. Guttag’s “Introduction to Computation and Programming Using Python“, Spring 2013 Edition.
Starting reading it, and will likely reveal various things from it as this blog continues. For today, however, here’s the “finger exercise” from section 2.2:
“Write a program that examines three variables–x, y, and z–and prints the largest odd number among them. If none of them are odd, it should print a message to that effect.”
Here’s my solution. It sure looks ugly to me, but I think it works.
I also added in the doctest module with verbose, as a kind of unit test, to validate against some outputs recorded in an IDLE session. According to the documention, “The doctest module searches for pieces of text that look like interactive Python sessions, and then executes those sessions to verify that they work exactly as shown.”
Self-documenting AND testable — cool, yes?
POSTSCRIPT: One can google and find an approach like this, but I took the path of a person who hasn’t yet learned anything other than simple comparison operators, compound Boolean operations, and int, print, and the modulo operator %.
OH, and to be clear. because I wanted to have the doctest module, the solution is also implemented with a function definition. Output from running is below the source code.
# largestodd.py # # Example 2.2 taken from "Introduction to Computation and # Programming Using Python", Spring 2013 Edition, p.16 # Exercise author: John V. Guttag # # Code author: mgh from "My Pythonic Year" blog at pythonicyear.com def largestodd(x,y,z): """Compare three numbers and print largest odd, or none is odd, a message to that effect. >>> largestodd(1,3,5) z is largest odd >>> largestodd(1,5,3) y is largest odd >>> largestodd(7,5,3) x is largest odd >>> largestodd(2,5,3) y is largest odd >>> largestodd(2,5,7) z is largest odd >>> largestodd(5,2,7) z is largest odd >>> largestodd(7,2,5) x is largest odd >>> largestodd(7,9,2) y is largest odd >>> largestodd(11,9,2) x is largest odd >>> largestodd(11,2,2) x is largest odd >>> largestodd(2,3,2) y is largest odd >>> largestodd(2,2,23) z is largest odd >>> largestodd(2,2,2) NONE of x y z are odd """ if x%2 != 0 : if y%2 != 0 : if z%2 !=0 : # all three are odd if x > y and x > z : print 'x is largest odd' elif y > z: print 'y is largest odd' else: print 'z is largest odd' else: # only x and y are odd if x > y : print 'x is largest odd' else: print 'y is largest odd' elif z%2 != 0: # both x and z are odd if x > z : print 'x is largest odd' else: print 'z is largest odd' else: #x odd, but neither y nor z print 'x is largest odd' else: #x not odd, test y and z if y%2 != 0: # y is odd if z%2 != 0: # y and z are odd if y > z: print 'y is largest odd' else: print 'z is largest odd' else: print 'y is largest odd' else: #y not odd if z%2 != 0: print 'z is largest odd' else: print 'NONE of x y z are odd' return if __name__ == "__main__": import doctest doctest.testmod()
Output when run:
>>> Trying: largestodd(1,3,5) Expecting: z is largest odd ok Trying: largestodd(1,5,3) Expecting: y is largest odd ok Trying: largestodd(7,5,3) Expecting: x is largest odd ok Trying: largestodd(2,5,3) Expecting: y is largest odd ok Trying: largestodd(2,5,7) Expecting: z is largest odd ok Trying: largestodd(5,2,7) Expecting: z is largest odd ok Trying: largestodd(7,2,5) Expecting: x is largest odd ok Trying: largestodd(7,9,2) Expecting: y is largest odd ok Trying: largestodd(11,9,2) Expecting: x is largest odd ok Trying: largestodd(11,2,2) Expecting: x is largest odd ok Trying: largestodd(2,3,2) Expecting: y is largest odd ok Trying: largestodd(2,2,23) Expecting: z is largest odd ok Trying: largestodd(2,2,2) Expecting: NONE of x y z are odd ok 1 items had no tests: __main__ 1 items passed all tests: 13 tests in __main__.largestodd 13 tests in 2 items. 13 passed and 0 failed. Test passed. >>>
Hey, thanks for posting this, it helped me sense check what I was doing.
I did it the way you mentioned it above but also tried to make it a little simpler:
cool – i did not think of the case where multiple items could be both odd, and equal; however, of the set “2, 3, 3”, if asked what the largest odd number is, would you NOT say “3”?
Hah – which only just hits me now, the exercise doesn’t ask WHICH is the largest, “x”, “y” or “z”, but wants the largest odd NUMBER to be printed out. Whoops, my bad.
Also, it doesn’t say they have to be positive numbers! Your “a,b,c” approach breaks down if things are negative, no? Try “-1, -10, -3” and see what happens.
I should add some negative (and equals) cases into my test code!
Hey man I came across your blog while looking for simpler solution on the web. Unfortunately couldn’t fine anything and the mind boggling began. At first I wrote it with an amount of code similar to yours, but was sure that could be simplified and after spending couple of days trying different variations I came up with one solid and simple solution so here it is:
Let me know what you think and will be happy to keep contact with you, as it looks like we are on the same road, and could be of value to each-other.
yay! very nice… and small!
if you want the # to appear also instead of the letter you have to separate it and turn it into a string
x=3
y=2
z=5
if (x > y and x > z) and (x % 2 !=0):
print str(x) + ‘ is the biggest odd’
elif (y > x and y > z) and (y % 2 !=0):
print str(y) + ‘ is the biggest odd’
elif (z > x and z > y) and (z % 2 !=0):
print str(z) + ‘ is the biggest odd’
else:
print ‘None are odd’
This fails if there is one odd number and two larger even numbers
Ouch! Indeed, you are right. I should tweak my doctest for such a condition, and try again.
Did you happen to notice that when all items are odd, this solution also fails that case as well. Oops!
I just began learning the python language and came across this question. This is great, didn’t think of doing it this way.
I made some changes so I could run my test code against your solution and it failed a few conditions. Try with the following:
x=5
y=2
z=7
Should print out “Z is largest odd”, right?
See if you can find the error!
I’m just a beginner so I think the code looks kind of crappy but at least is does the job!
x = 9
y = 13
z = 6
a = x
b = y
c = z
if x%2 !=0:
x = a
if x%2 == 0:
x = 0
if y%2 !=0:
y = b
if y%2 == 0:
y = 0
if z%2 !=0:
z = c
if z%2 == 0:
z = 0
if a > b and a > c:
print “x is the biggest odd”
if b > a and b > c:
print “y is the biggest odd”
if c > a and c > b:
print “z is the biggest odd”
if x + y + z == 0:
print “none is odd”
Hmm. See a recent comment asking what happens if one odd, and the other two are larger even numbers!
Also, what if all numbers are the same (odd) number?!
And… what if some of your odd numbers are negative?
Here’s an update to my doctest code.
NOTE I have changed the output message to display the value of the number!
This is with the syntax:
print 'x (%d) is largest odd'%x
Here is the new doctest code. Please! Give this a try before posting your solution.
Note, too, one quirk with the doctest code when all are the same, it assumes the final number, i.e. “z”, is the one to report. Of course, they’re all the same in this case — so if your test fails on the letter, but is correct with the number, you’ve got it.
"""Compare three numbers and print largest odd, or none if none odd
>>> largestodd(1,1,1)
z (1) is largest odd
>>> largestodd(1,3,5)
z (5) is largest odd
>>> largestodd(1,5,3)
y (5) is largest odd
>>> largestodd(7,5,3)
x (7) is largest odd
>>> largestodd(2,5,3)
y (5) is largest odd
>>> largestodd(2,5,7)
z (7) is largest odd
>>> largestodd(5,2,7)
z (7) is largest odd
>>> largestodd(7,2,5)
x (7) is largest odd
>>> largestodd(7,9,2)
y (9) is largest odd
>>> largestodd(11,9,2)
x (11) is largest odd
>>> largestodd(11,2,2)
x (11) is largest odd
>>> largestodd(11,12,12)
x (11) is largest odd
>>> largestodd(2,3,2)
y (3) is largest odd
>>> largestodd(4,3,4)
y (3) is largest odd
>>> largestodd(2,2,23)
z (23) is largest odd
>>> largestodd(42,42,23)
z (23) is largest odd
>>> largestodd(2,2,2)
NONE of x y z are odd
>>> largestodd(-1,2,2)
x (-1) is largest odd
>>> largestodd(-1,2,10)
x (-1) is largest odd
>>> largestodd(-1,-3,10)
x (-1) is largest odd
>>> largestodd(-1,-4,-4)
x (-1) is largest odd
>>> largestodd(-1,2,2)
x (-1) is largest odd
>>> largestodd(-1,-3,-7)
x (-1) is largest odd
"""
CORRECTION.
Only a day later and I see that I should probably have used the “.format” ability which seems to be the pythonic way used in v3, and also introduced in 2.6.
That is, instead of this:
Try this:
Wow, there’s a LOT of flexibility here… see: Python 2 Format Examples
After approving comments yesterday and tweaking my doctests, this exercise certainly must have been on my mind! I woke up this morning with a “why didn’t I do it this way before?!” thought. This is my second revision to this exercise.
I believe I was originally trying to do the exercise with the self-imposed limitation of only using the Python elements revealed in the book up to that point, i.e. no functions. And thus no globals.
However, here’s a revision that uses both (just to make it a little cleaner). One could have in-lined this approach of “test, and update-if-needed” for each parameter, one after the other. I just separated that part out into the “update_odd()” function:
This seemed less buggy. Didn’t try with negative numbers though. This class is my first attempt @ coding so please let me know if I can improve on this.
x, y, z = 5, 4, 7
if (x > y and x > z) and (x%2 == 1):
print “x is the biggest odd”
elif (y > x and y > z) and (y%2 == 1):
print “y is the biggest odd”
elif (z > x and z > y) and (z%2 == 1):
print “z is the biggest odd”
elif x%2 == 1:
print “x is the biggest odd”
else:
print “none is odd”
Why the last elif?
What if x, y, z are 8,5,6 ?
(Answer should be “5” i.e. “y”, right?)
Or 4,7,7 ?
(Answer should be “7” is greatest odd number, yes?)
What does your code do in such cases…? Think (or walk) it through.
It’s an annoying exercise, yah? 🙂
For page 20 problem:
[Ed. note: wrapped code with “pre” tags]
I know I am a little late to this discussion but after thinking of a solution nonstop for about two day I may have found a solution. I am a beginner and am barely about to start chapter 3 of introduction to computation and programming using python by John V. Guttag. I am also going over the edx course. Well, here is my solution (could probably use some more testing so, please, have at it.
[ed. note: added “pre” tags to surround above commment]
Excellent!
Moved a few things around to be able to run my old doctest on your code, and we have the following success. I’ll post the runnable code as the next reply.
Derrick’s code altered with my doctest examples:
Coming to this discussion a bit late, but I was wondering if there was any reason not to do it this way…
(edited by webmaster to preserved original indenting)
So I too am a little late to this discussion, and quite frankly I am only about two days into this programming business and I have no idea what a doctest is, but I figured I’d post my solution too and see if anyone has any feedback. I’m pretty sure it works, though it may have the potential for slimming down a bit.
Thanks for any feedback I can get!
(edited by webmaster to preserved original indenting)
Hey admin why not try out this. its quite shorter and works fine. Let me know what you think
$
$
(edited by webmaster to preserved original indenting)
at this stage of the book, we haven’t been introduced to functions so I guessed this could be achieved without using functions
so I was reviewing my earlier code and found out it does not accommodate for numbers that aren’t odd. So I came up with a slight modification, I also used the ‘input’ so that you can input number right into the shell prompt. so:
(edited by webmaster to preserved original indenting)
my bad, didn’t debug properly. this is best;
(edited by webmaster to preserved original indenting)
I’ve just found out that course and I’m really enjoying the material. Today I read ch. 2 and decided to give it a try:
(edited by webmaster to preserve original indents)
y’all just being lazy.
Booleans are necessary for this:
(edited by webmaster to preserve original indenting)
it doesnot work for 156,25,160. it said no odd.
I wrote this solution, hope it helps:
(edited by webmaster to preserved original indenting)
my solution i think it is simple
[edited by webmaster to preserve original indenting]
Anyone else spot a possible problem with this solution?
(hint below…)
scroll down…
Hint: think “sign” ! (and reply if you need more info)
Here is my solution 🙂
Nice! Passed all my doctest tests. If you want to see the slightly modified code, check out: largestodd-germancitomartinez-377.txt
(it’s a .txt file, so you’ll need to change to .py if you want to run it yourself.)
Here is output using the “-v” at the end:
I was reading the same book and came up with the following code, I believe it’s the shortest 😉
Hmmm… not sure about this one; what if x and z are even and y is odd?