Python for Kids: Python 3 – Project 3

Some people want to use my book Python for Kids for Dummies to learn Python 3. I am working through the code in the existing book, highlighting changes from Python 2 to Python 3 and providing code that will work in Python 3.

If you are using Python 2.7 you can ignore this post. This post is only for people who want to take the code in my book Python for Kids for Dummies and run it in Python 3.

Apologies also if you’re seeing

>

rather than

>

in this (or my other) posts. The way WordPress deals with the sourcecode tag is pretty much completely broken for the > character. I will do my best to fix – but WP often then breaks it after the fix.

Project 3 in the book is about getting information (input) from the user of your program. In it, the raw_input builtin from Python 2 is used. In Python 3 that builtin had its name changed to just input(). The bad news is that that means that none of the code using raw_input will work in Python 3. The good news is that you can replace raw_input by input wherever you see it and the code will work again. Alternatively, once you have completed Project 4 (it introduces the idea of putting your code in a file), you can place a single line at the start of your code that reads:

raw_input = input

Then you don’t need to change the rest of the code. This is equivalent to creating a variable called raw_input and assigning to it the built in function called input. Unfortunately, you’re still in Project 3, so that isn’t going to work. So here’s how you tackle Project 3 with Python 3.

Page 61

This code:

#Python 2.7 code:
>>> raw_input()
I am typing a response. Python won't see this until I press Enter.
"I am typing a response. Python won't see this until I press Enter."

will not work in Python 3. Watch what happens:

#Python 3 code:
>>> raw_input()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'raw_input' is not defined
>>> input()
I am typing a response. Python won't see this until I press Enter.
"I am typing a response. Python won't see this until I press Enter."
>>> 

Python 3 simply doesn’t recognise raw_input as a valid name for anything. As I mentioned above to get your Python 2.7 code working in Python 3, where you see raw_input, just write input instead:

#Python 2.7 code:
>>> raw_input("What is your guess?")
What is your guess?17
'17'

#Python 3 code:
>>> input("What is your guess?")
What is your guess?17
'17'

Page 62

All this code has problems because it uses raw_input. Replace with input instead throughout:

#Python 2.7 code:
>>> raw_input("What is your guess? ")
What is your guess? 17
'17'

>>> prompt = 'What is your guess? '
>>> raw_input(prompt)
What is your guess? 17
'17'

>>> prompt = 'What is your guess? '
>>> players_guess = raw_input(prompt)
What is your guess? 17
>>>
>>> players_guess
'17'

#Python 3 code:
>>> input("What is your guess?")
What is your guess?17
'17'

>>> input("What is your guess? ")
What is your guess? 17
'17'

>>> prompt = 'What is your guess? '
>>> input(prompt)
What is your guess? 17
'17'

>>> prompt = 'What is your guess? '
>>> players_guess = input(prompt)
What is your guess? 17
>>> players_guess
'17'

Page 63:

All code on this page is the same, and all outputs from the code is the same in Python 3 as in Python 2.7

Pages 64 and 65

With one exception, all code on these pages is the same, and all outputs from the code is the same in Python 3 as in Python 2.7. That exception relates to how division works.
Python 2.7 tries to be helpful for you when you divide. It does this by dividing integers differently to dividing floating point numbers:

#Python 2.7 code:
>>> 3/2
1
>>> -3/2
-2

Python 3 doesn’t worry. It will do the division as a floating point division whether you’re dividing integers or not.

#Python 3 code:
>>> 3/2
1.5
>>> -3/2
-1.5

If you are really desperate and want to do division Python 2.7 style, you can still do that, using the “floor” operator: // (two slashes together). Here is an example (it gives you the same results as the Python 2.7 code):

#Python 3 code:
>>> 3//2
1
>>> -3//2
-2

Page 67

All code on the first half of this page is the same, and all outputs from the code is the same in Python 3 as in Python 2.7. Page 67 gives you tips on how to work around the way Python 2.7 does division. These tips will not cause a problem in Python 3. Things will still work as you expect them, but the additional work is superfluous.

#Python 3 code:
>>> 3/2.
1.5

#Python 3 code:
>>> a=2
>>> 3/a
1
>>> 3/float(a)
1.5
>>>

In the second half of the page replace raw_input with input:

#Python 2.7 code:
>>> prompt = 'What is your guess? '
>>> raw_input(prompt)
What is your guess? 17
'17'

#Python 3 code:
>>> prompt = 'What is your guess? '
>>> input(prompt)
What is your guess? 17
'17'

Page 68

Replace raw_input with input:

#Python 2.7
>>> players_guess = raw_input(prompt)
What is your guess? 17
>>> players_guess+1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: cannot concatenate 'str' and 'int' objects

>>> players_guess
'17'

#Python 3 code:
>>> players_guess = input(prompt)
What is your guess? 17
>>> players_guess+1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Can't convert 'int' object to str implicitly

>>> players_guess
'17'

Note that the text of the TypeError changes a little from Python 2.7 to Python 3. The comments about raw_input always returning a string apply to input.

Pages 69-74

All code on these pages is the same, and all outputs from the code is the same in Python 3 as in Python 2.7.

Pages 75-76

Replace raw_input with input:

#Python 2.7 code:
>>> computers_number = 17
>>> prompt = 'What is your guess? '
>>> while True:
...        players_guess = raw_input(prompt)
...        if computers_number == int(players_guess):
...             print('Correct!')
...             break
...        elif computers_number > int(players_guess):
...             print('Too low')
...        else:
...             print('Too high')
...
What is your guess? 3
Too low
What is your guess? 93
Too high
What is your guess? 50
Too high
What is your guess? 30
Too high
What is your guess? 20
Too high
What is your guess? 10
Too low
What is your guess? 19
Too high
What is your guess? 16
Too low
What is your guess? 18
Too high
What is your guess? 17
Correct!

#Python 3 code:
>>> computers_number = 17
>>> prompt = 'What is your guess? '
>>> while True:
...        players_guess = input(prompt)
...        if computers_number == int(players_guess):
...             print('Correct!')
...             break
...        elif computers_number > int(players_guess):
...             print('Too low')
...        else:
...             print('Too high')
...
What is your guess? 3
Too low
What is your guess? 93
Too high
What is your guess? 50
Too high
What is your guess? 30
Too high
What is your guess? 20
Too high
What is your guess? 10
Too low
What is your guess? 19
Too high
What is your guess? 16
Too low
What is your guess? 18
Too high
What is your guess? 17
Correct!

Page 76 (still)

The break keyword is the same for both Python versions.

Page 77-81

All code on these pages is the same, and all outputs from the code is the same in Python 3 as in Python 2.7. However, behind the scenes the code is working differently in the two Python versions because of the issue with range discussed in my previous post. In short, Python 2.7 works out the members of a list before it uses them, while Python 3 will work them out “on the fly”.

Obviously, at the bottom of page 79, the heading in the readout identifies whatever version of Python 3 you’re using (in this case Python 3.3.5):

#Python 2.7 code:
Python 2.7.3 (default, Apr 14 2012, 08:58:41) [GCC] on
            linux2
Type "help", "copyright", "credits" or "license" for more
            information.
>>> random.randint(1,100)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'random' is not defined

#Python 3 code:
Python 3.3.5 (default, Mar 27 2014, 17:16:46) [GCC] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> random.randint(1,100)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'random' is not defined

Page 82

Replace raw_input with input:

#Python 2.7 code:
>>> import random
>>>
>>> computers_number = random.randint(1,100)
>>> prompt = 'What is your guess? '
>>> while True:
...     players_guess = raw_input(prompt)
...     if computers_number == int(players_guess):
...         print('Correct!')
...         break
...     elif computers_number > int(players_guess):
...         print('Too low')
...     else:
...         print('Too high')
...
What is your guess? 24
Too low
What is your guess? 86
Too low
What is your guess? 94
Too low
What is your guess? 98
Too high
What is your guess? 96
Too high
What is your guess? 95
Correct!

#Python 3 code:
>>> import random
>>>
>>> computers_number = random.randint(1,100)
>>> prompt = 'What is your guess? '
>>> while True:
...     players_guess = input(prompt)
...     if computers_number == int(players_guess):
...         print('Correct!')
...         break
...     elif computers_number > int(players_guess):
...         print('Too low')
...     else:
...         print('Too high')
...
What is your guess? 24
Too low
What is your guess? 86
Too low
What is your guess? 94
Too low
What is your guess? 98
Too low
What is your guess? 99
Correct!

The code in the Zen of Python section works the same in Python 2.7 and Python 3.