Using Python 3 in Project 8 of Python For Kids For Dummies

In this post I talk about the changes that need to be made to the code of
Project 8 in order for it to work with Python 3. Happily, the code in Project 8 will work without changes.
However, in some places what Python outputs in Python 3 is different (usually just a little different) from the output in Python 2.7. The code below shows where the output is different.

Disclaimer

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.

Page 220

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

Page 222

All code syntax on page is the same, but some outputs are different in Python 3 – different output from type().

  
#Python 2.7
>>> "%s %s"%(1,2)
'1 2'
                              
"%s %s"%(1) #(two specifiers, one value)
"%s %s"%(1,2,3) #(two specifiers, three values)
                              
>>> values = (1,2)
>>> "%s %s"%values
'1 2'
>>> # Snuck in a tuple:
>>> type(values)
<type 'tuple'>
                              
                    
#Python 3 
>>> "%s %s"%(1,2)
'1 2'
                             
                             
"%s %s"%(1) #(two specifiers, one value)
"%s %s"%(1,2,3) #(two specifiers, three values)
                              

>>> values = (1,2)
>>> "%s %s"%values
'1 2'
>>> type(values)
<class 'tuple'>
>>> 
 

Page 223 – 224
All code on this page is the same, and all outputs from the code are the same in Python 3 as in Python 2.7.

Page 225
All code syntax on page is the same, but some outputs are different in Python 3 – different error messages.

  
#Python 2.7     
>>> def test_function():
        return (1,2,3) # returns a tuple with three elements
        
>>> a = test_function()
>>> a
(1, 2, 3)
>>> a,b,c = test_function()
>>> a
1
>>> b
2
>>> c
3
>>> a,b = test_function()

Traceback (most recent call last):
  File "<pyshell#59>", line 1, in <module>
    a,b = test_function()
ValueError: too many values to unpack
                            
                            
>>> a,b,c = (1,2,3) # unpack the tuple into a, b, c
>>> print("a: %s, b: %s, c: %s"%(a,b,c))
a: 1, b: 2, c: 3
>>> a,b = (1,2,3) # three values but only two variables.

Traceback (most recent call last):
  File "<pyshell#62>", line 1, in <module>
    a,b = (1,2,3)
ValueError: too many values to unpack

#Python 3
>>> def test_function():
        return (1,2,3) # returns a tuple with three elements
        
>>> a = test_function()
>>> a
(1, 2, 3)
>>> a,b,c = test_function()
>>> a
1
>>> b
2
>>> c
3
>>> a,b = test_function()
Traceback (most recent call last):
  File "<pyshell#27>", line 1, in <module>
    a,b = test_function()
ValueError: too many values to unpack (expected 2)
                            
                            
>>> a,b,c = (1,2,3) # unpack the tuple into a, b, c
>>> print("a: %s, b: %s, c: %s"%(a,b,c))
a: 1, b: 2, c: 3
>>> a,b = (1,2,3) # three values but only two variables.
Traceback (most recent call last):
  File "<pyshell#30>", line 1, in <module>
    a,b = (1,2,3) # three values but only two variables.
ValueError: too many values to unpack (expected 2)

Page 227-232

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

Python for Kids: Python 3 – Project 7

Using Python 3 in Project 7 of Python For Kids For Dummies

In this post I talk about the changes that need to be made to the code of
Project 7 in order for it to work with Python 3. Most of the code in project 7 will work without changes. However, in a lot of cases what Python outputs in Python 3 is different from the output in Python 2.7 and it’s those changes that I am mainly identifying below.

Disclaimer

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.

Page 178

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

Page 179-180
The code and syntax on these pages is the same, but the outputs are
different in Python 3. This is because, in Python 3,
the range builtin does not create a list as in Python 2.7 (see Python3/Project 5)

#Python 2.7 code: 

>>> test_string = '0123456789'
>>> test_string[0:1]
'0'
>>> test_string[1:3]
'12'
>>> # range(10) is a list of the numbers from 0 to 9 inclusive
>>> range(10)[0:1]
[0]
>>> range(10)[1:3]
[1, 2]
>>> test_string[:3]
'012'
>>> test_string[3:]
'3456789'
#Python 3 code:
>>> test_string = '0123456789'
>>> test_string[0:1]
'0'
>>> test_string[1:3]
'12'
>>> # range(10) is no longer a list. It's a.... errr... range 
>>> # so the [:] operator slices. You can use list()
>>> # to see what it corresponds to.
>>> range(10)[0:1]
range(0, 1)
>>> list(range(10)[0:1])
[0]
>>> # note same output as in Python 2.7 from range(10)[0:1]
>>> range(10)[1:3]
range(1, 3)
>>> list(range(10)[1:3])
[1, 2]
>>> test_string[:3]
'012'
>>> test_string[3:]
'3456789'
>>> 

Pages 180-196
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

Page 199

The code on this page uses raw_input, which has been renamed to input in Python 3.
Either change all occurrences or add a line

raw_input = input 

at the start of the relevant code.

#Python 2.7 code: 
#### Input and Output Section
message = raw_input("Type the message to process below:\n")
ciphertext = encrypt_msg(message, ENCRYPTION_DICT)
plaintext = decrypt_msg(message, DECRYPTION_DICT)
print("This message encrypts to")
print(ciphertext)
print # just a blank line for readability
print("This message decrypts to")
print(plaintext)

#Python 3 code: 
#### Input and Output Section
message = input("Type the message to process below:\n")
ciphertext = encrypt_msg(message, ENCRYPTION_DICT)
plaintext = decrypt_msg(message, DECRYPTION_DICT)
print("This message encrypts to")
print(ciphertext)
print # just a blank line for readability
print("This message decrypts to")
print(plaintext)


>>> ================================== RESTART ================================
>>>
Type the message you'd like to encrypt below:
I love learning Python. And my teacher is smelly. And I shouldn't start a sentence with and.
This message encrypts to
F|ilsb|ib7okfkd|Mvqelk+|xka|jv|qb79ebo|fp|pjbiiv+||xka|F|pelriak$q|pq7oq|7|pbkqbk9b|tfqe|7ka+
This message decrypts to
L2oryh2ohduqlqj2SBwkrq;2Dqg2pB2whdfkhu2lv2vphooB;22Dqg2L2vkrxogq*w2vwduw2d2vhqwhqfh2zlwk2dqg;

                             
>>> ================================== RESTART ================================
>>>
Type the message you'd like to encrypt below:
F|ilsb|ib7okfkd|Mvqelk+|xka|jv|qb79ebo|fp|pjbiiv+||xka|F|pelriak$q|pq7oq|7|pbkqbk9b|tfqe|7ka+
This message encrypts to
C_fip8_f84lhcha_Jsnbih(_uh7_gs_n846b8l_cm_mg8ffs(__uh7_C_mbiof7h!n_mn4ln_4_m8hn8h68_qcnb_4h7(
This message decrypts to
I love learning Python. And my teacher is smelly.  And I shouldn't start a sentence with and.

Page 200

This code works as is in both Python 2.7 and Python 3. However, the way the open() builtin works has changed in Python 3 and this will cause some issues in later projects. In Python 3 open() has the same syntax as in Python 2.7, but uses a different way to get data out of the file and into your hands. As a practical matter this means that some Python 2.7 code will sometimes cause problems when run in Python 3. If you run into such a problem (open code that works in Python 2.7 but fails in Python 3), the first thing to try is to add the binary modifier. So,
instead of ‘r’ or ‘w’ for read and write use ‘rb’ or ‘wb’. This code doesn’t need it, but a later project will.

Page 201

The code on this page is the same, but the outputs are different in Python 3. Python 3 returns how much data has
been written (in this case, 36)

#Python 2.7 code: 
>>> file_object = open('p4k_test.py','w')
>>> text = "print('Hello from within the file')\n" # watch the " and '
>>> file_object.write(text) # writes it to the file
>>> file_object.write(text) # writes it to the file again!
>>> file_object.close() # finished with file, so close it
#Python 3 code:
>>> file_object = open('p4k_test.py','w')
>>> text = "print('Hello from within the file')\n" # watch the " and '
>>> file_object.write(text) # writes it to the file
36
>>> file_object.write(text) # writes it to the file again!
36
>>> file_object.close() # finished with file, so close it

Pages 202 and 203

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

Page 204

All code on this page is the same in Python 3 as in Python 2.7, but some of the outputs are different
A line has been added in the Python 3 code below to shown that the file_object has been closed after leaving the
with clause – this was explicit in the print out in Python 2.7.

>>> #Python 2.7
>>> with open('p4k_test.py','r') as file_object:
        print(file_object.read())
        
        
print('Hello from within the file')
print('Hello from within the file')

>>> file_object
<closed file 'p4k_test.py', mode 'r' at 0xf7fed0>
       
       
>>> #Python 3
>>> with open('p4k_test.py','r') as file_object:
        print(file_object.read())

        
print('Hello from within the file')
print('Hello from within the file')

>>> file_object  # output different from 2.7
<_io.TextIOWrapper name='p4k_test.py' mode='r' encoding='UTF-8'>

>>> file_object.closed # but the file is still closed
True

Page 205

All code on this page is the same in Python 3 as in Python 2.7, but some of the outputs are different
A line has been added in the Python 3 code below to shown that the file_object has been closed after leaving the
with clause – this was explicit in the print out in Python 2.7. Also, because Python 3 uses a different way
of getting information from a file it is identified differently. In Python 2.7 it’s call a file – pretty straight
forward. in Python 3 it’s called a _io.TextIOWrapper. Not as enlightening, but a student doesn’t need to worry about
this difference in detail.

>>> #Python 2.7
>>> with open('testfile2','w') as a:
        a.write('stuff')
        
>>> with open('testfile2','r') as a,
         open('p4k_test.py','r') as b:
        print(a.read())
        print(b.read())
        
stuff
print('Hello from within the file')
print('Hello from within the file')

>>> a
<closed file 'testfile2', mode 'r' at 0xf6e540>
>>> b
<closed file 'p4k_test.py', mode 'r' at 0xef4ed0>


       
>>> #Python 3
>>> with open('testfile2','r') as a, open('p4k_test.py','r') as b:
	print(a.read())
	print(b.read())

	
stuff
print('Hello from within the file')
print('Hello from within the file')

>>> a
<_io.TextIOWrapper name='testfile2' mode='r' encoding='UTF-8'>
>>> a.closed
True
>>> b
<_io.TextIOWrapper name='p4k_test.py' mode='r' encoding='UTF-8'>
>>> b.closed
True                                  

Page 207

All code on this page is the same in Python 3 as in Python 2.7, but some of the outputs are different
(the write method returns the amount of data written and this is output in the console in Python 3)

>>> #Python 2.7
>>> INPUT_FILE_NAME = "cryptopy_input.txt"
>>> with open(INPUT_FILE_NAME,'w') as input_file:
        input_file.write('This is some test text')

       
>>> #Python 3
>>> INPUT_FILE_NAME = "cryptopy_input.txt"
>>> with open(INPUT_FILE_NAME,'w') as input_file:
	input_file.write('This is some test text')

	
22

# this code is the same in Python 2.7 and Python 3:

INPUT_FILE_NAME = “cryptopy_input.txt”
OUTPUT_FILE_NAME = “cryptopy_output.txt”

Page 208-218
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

Python for Kids: Python 3 – Project 6

Using Python 3 in Project 6 of Python For Kids For Dummies

In this post I talk about the changes that need to be made to the code of Project 6 in order for it to work with Python 3.  Most of the code in project 6 will work without changes. However, in a lot of cases what Python outputs in Python 3 is different from the output in Python 2.7.

Disclaimer

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.

Page 144:

Code and outputs are the same.

Page 145: code same, outputs different:

# Python 2.7 output

>>> dir(my_message)
['__add__', '__class__', '__contains__', '__delattr__',
'__doc__', '__eq__', '__format__', '__ge__',
'__getattribute__', '__getitem__', '__getnewargs__',
'__getslice__', '__gt__', '__hash__', '__init__', '__le__',
'__len__', '__lt__', '__mod__', '__mul__', '__ne__',
'__new__', '__reduce__', '__reduce_ex__', '__repr__',
'__rmod__', '__rmul__', '__setattr__', '__sizeof__',
'__str__', '__subclasshook__', '_formatter_field_name_split',
'_formatter_parser', 'capitalize', 'center', 'count',
'decode', 'encode', 'endswith', 'expandtabs', 'find',
'format', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower',
'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower',
'lstrip', 'partition', 'replace', 'rfind', 'rindex', 'rjust',
'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines',
'startswith', 'strip', 'swapcase', 'title', 'translate',
'upper', 'zfill']

# Python 3 output

>>> dir(my_message)
['__add__', '__class__', '__contains__', '__delattr__', 
'__dir__', '__doc__', '__eq__', '__format__', '__ge__', 
'__getattribute__', '__getitem__', '__getnewargs__', 
'__gt__', '__hash__', '__init__', '__iter__', '__le__', 
'__len__', '__lt__', '__mod__', '__mul__', '__ne__', 
'__new__', '__reduce__', '__reduce_ex__', '__repr__', 
'__rmod__', '__rmul__', '__setattr__', '__sizeof__', 
'__str__', '__subclasshook__', 'capitalize', 'casefold', 
'center', 'count', 'encode', 'endswith', 'expandtabs', 
'find', 'format', 'format_map', 'index', 'isalnum', 
'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 
'islower', 'isnumeric', 'isprintable', 'isspace', 
'istitle', 'isupper', 'join', 'ljust', 'lower', 
'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 
'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 
'split', 'splitlines', 'startswith', 'strip', 'swapcase', 
'title', 'translate', 'upper', 'zfill']

Page 146 – code same, outputs different:

# Python 2.7 output
>>> type('a string object')
<type 'str'>
>>> type([]) # that is, an empty list
<type 'list'>

# Python 3 output
>>> type('a string object')
<class 'str'>
>>> type([]) # that is, an empty list
<class 'list'>

# output for id() for both Python 2.7 and Python 3 is an integer

>>> id('a string object')
139900104204840

Page 147 – code same, outputs different

# Python 2.7 output

>>> help(my_message.upper) # spot the dot?
Help on built-in function upper:
upper(...)
    S.upper() -> string
    Return a copy of the string S converted to uppercase.
          

# Python 3 output          
>>> help(my_message.upper) # spot the dot?
Help on built-in function upper:

upper(...)
    S.upper() -> str
    
    Return a copy of S converted to uppercase.

Page 148 – code and outputs the same

Page 149 – Code the same, outputs different.
In Python 2.7 the range builtin creates a list. In Python 3 it creates a generator. The end result in this code is the same, but the way it is achieved is different.

# Python 2.7 
>>> range(3)
[0, 1, 2]
>>> for i in range(3):
        print(i)
0
1
2


# Python 3 output   
>>> range(3)
range(0, 3)
>>> for i in range(3):
        print(i)

        
0
1
2

Page 150 – Style error in the first code block on the page. Should have been print(i), otherwise code and outputs the same:

#Python 2.7
>>> for i in dir(my_message):
          print i
__add__
__class__
__contains__
[...]
# Python 3
>>> for i in dir(my_message):
          print(i)
__add__
__class__
__contains__
[...]          

Page 150 – balance of code – code same, outputs different

# Python 2.7

>>> string_object_attributes = dir(my_message)
>>> string_object_attributes
['__add__', '__class__', '__contains__', '__delattr__',
'__doc__', '__eq__', '__format__', '__ge__',
'__getattribute__', '__getitem__', '__getnewargs__',
'__getslice__', '__gt__', '__hash__', '__init__', '__le__',
'__len__', '__lt__', '__mod__', '__mul__', '__ne__',
'__new__', '__reduce__', '__reduce_ex__', '__repr__',
'__rmod__', '__rmul__', '__setattr__', '__sizeof__',
'__str__', '__subclasshook__', '_formatter_field_name_split',
'_formatter_parser', 'capitalize', 'center', 'count',
'decode', 'encode', 'endswith', 'expandtabs', 'find',
'format', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower',
'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower',
'lstrip', 'partition', 'replace', 'rfind', 'rindex', 'rjust',
'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines',
'startswith', 'strip', 'swapcase', 'title', 'translate',
'upper', 'zfill']


>>> dir(string_object_attributes)
['__add__', '__class__', '__contains__', '__delattr__',
'__delitem__', '__delslice__', '__doc__', '__eq__',
'__format__', '__ge__', '__getattribute__', '__getitem__',
'__getslice__', '__gt__', '__hash__', '__iadd__', '__imul__',
'__init__', '__iter__', '__le__', '__len__', '__lt__',
'__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__',
'__repr__', '__reversed__', '__rmul__', '__setattr__',
'__setitem__', '__setslice__', '__sizeof__', '__str__',
'__subclasshook__', 'append', 'count', 'extend', 'index',
'insert', 'pop', 'remove', 'reverse', 'sort']
   
# Python 3
>>> string_object_attributes = dir(my_message)
>>> string_object_attributes
['__add__', '__class__', '__contains__', '__delattr__', 
'__dir__', '__doc__', '__eq__', '__format__', '__ge__', 
'__getattribute__', '__getitem__', '__getnewargs__', 
'__gt__', '__hash__', '__init__', '__iter__', '__le__', 
'__len__', '__lt__', '__mod__', '__mul__', '__ne__', 
'__new__', '__reduce__', '__reduce_ex__', '__repr__', 
'__rmod__', '__rmul__', '__setattr__', '__sizeof__', 
'__str__', '__subclasshook__', 'capitalize', 'casefold', 
'center', 'count', 'encode', 'endswith', 'expandtabs', 
'find', 'format', 'format_map', 'index', 'isalnum', 
'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 
'islower', 'isnumeric', 'isprintable', 'isspace', 
'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 
'maketrans', 'partition', 'replace', 'rfind', 'rindex', 
'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 
'splitlines', 'startswith', 'strip', 'swapcase', 'title', 
'translate', 'upper', 'zfill']


>>> dir(string_object_attributes)
['__add__', '__class__', '__contains__', '__delattr__', 
'__delitem__', '__dir__', '__doc__', '__eq__', '__format__', 
'__ge__', '__getattribute__', '__getitem__', '__gt__', 
'__hash__', '__iadd__', '__imul__', '__init__', '__iter__', 
'__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', 
'__reduce__', '__reduce_ex__', '__repr__', '__reversed__', 
'__rmul__', '__setattr__', '__setitem__', '__sizeof__', 
'__str__', '__subclasshook__', 'append', 'clear', 'copy', 
'count', 'extend', 'index', 'insert', 'pop', 'remove', 
'reverse', 'sort']
   

Page 152-154 – code and outputs are the same

Page 155 – up to the warning box the code and outputs are the same

Page 155 Warning box:
The warning box on page 155 relies on the fact that in Python 2.7 the range() builtin returns a list. However, in Python 3 it returns a generator, so it doesn’t have a reverse method. You can get the same behavior [sic] if you force it to be a list using the list() builtin:

## Python 3 code:
>>> a_list = list(range(10))
>>> a_list
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> reversed_list = a_list.reverse()
>>> # reverse doesn't return a value!
>>> print(reversed_list)
None
>>> a_list
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

Page 157-161 code and outputs the same

Page 162 – Code different
Change raw_input to input as explained in the Python 3 post for Project 5.

# Python 2.7
""" 1337.py
Given a message, convert it into 1337 sp34k
Brendan Scott
January 2015 """

TEST_MESSAGE = "Hello World!"
TEST_SUBSTITUTIONS = [['e','3']]
#### Function Section
def encode_message(message, substitutions):
    for s in substitutions:
        """Take a string message and apply each of the substitutions
        provided. Substitutions should be a list, the elements of
        substitutions need to be lists of length 2 of the form
        (old_string, new_string) """
        old = s[0]
        new = s[1]
        converted = message.replace(old,new)
    return converted
    
    
#### Testing Section
message = raw_input("Type the message to be encoded here: ")
converted_text = encode_message(message, TEST_SUBSTITUTIONS)
print(message)
print(converted_text)


# Python 3
""" 1337.py
Given a message, convert it into 1337 sp34k
Brendan Scott
January 2015 """

raw_input = input # this fixes raw_input!

TEST_MESSAGE = "Hello World!"
TEST_SUBSTITUTIONS = [['e','3']]
#### Function Section
def encode_message(message, substitutions):
    for s in substitutions:
        """Take a string message and apply each of the substitutions
        provided. Substitutions should be a list, the elements of
        substitutions need to be lists of length 2 of the form
        (old_string, new_string) """
        old = s[0]
        new = s[1]
        converted = message.replace(old,new)
    return converted
    
    
#### Testing Section
message = raw_input("Type the message to be encoded here: ")
converted_text = encode_message(message, TEST_SUBSTITUTIONS)
print(message)
print(converted_text)

Page 164 – Style error – should be print(s) not print s. With print(s) the code is the same in Python 2.7 and Python 3.

#Python 2.7 code: 
>>> substitutions = [['a','4'], ['e','3'], ['l','1'], ['o','0'], 
                     ['t','7']]
>>> for s in substitutions:
          print s
          
['a',  '4']
['e',  '3']
['l',  '1']
['o',  '0']
['t',  '7']
#Python 3 code:
>>> substitutions = [['a','4'], ['e','3'], ['l','1'], ['o','0'], 
                     ['t','7']]
>>> for s in substitutions:
          print(s)

          
['a', '4']
['e', '3']
['l', '1']
['o', '0']
['t', '7']

Page 166 Code different
Use input instead of raw_input as explained in the Python 3 post for Project 5. In this case, i have added raw_input = input after the docstring.

     
#Python 3 code:
""" 1337.py
Given a message, convert it into 1337 sp34k
Brendan Scott
January 2015 """

raw_input = input # this fixes raw_input!

TEST_MESSAGE = "Hello World!"
##TEST_SUBSTITUTIONS = [['e','3']]
SUBSTITUTIONS = [['a', '4'], ['e', '3'], ['l', '1'], ['o', '0'], 
                 ['t', '7']]
                 
#### Function Section
def encode_message(message, substitutions):
    """Take a string message and apply each of the substitutions
    provided. Substitutions should be a list, the elements of
    substitutions need to be lists of length 2 of the form
    (old_string, new_string) """
    for s in substitutions:
        old = s[0]
        new = s[1]
        converted = message.replace(old,new)
    return converted
    
#### Testing Section
message = raw_input("Type the message to be encoded here: ")
converted_text = encode_message(message, SUBSTITUTIONS)
print(message)
print(converted_text)

Page 168-169 Code different
Use input instead of raw_input as explained in the Python 3 post for Project 5. In this case, i have added raw_input = input after the docstring.


#Python 3 code:
""" 1337.py
Given a message, convert it into 1337 sp34k
Brendan Scott
January 2015 """

raw_input = input # this fixes raw_input!

TEST_MESSAGE = "Hello World!"
##TEST_SUBSTITUTIONS = [['e','3']]
SUBSTITUTIONS = [['a', '4'], ['e', '3'], ['l', '1'], ['o', '0'],
                 ['t', '7']]
                
#### Function Section
def encode_message(message, substitutions):
    """Take a string message and apply each of the substitutions
    provided. Substitutions should be a list, the elements of
    substitutions need to be lists of length 2 of the form
    (old_string, new_string) """
    for s in substitutions:
        old = s[0]
        new = s[1]
        converted = message.replace(old,new)
        print("converted text = "+converted) # Added
    print("Leaving encode_message") # Added
    
    return converted

#### Testing Section
message = raw_input("Type the message to be encoded here: ")
converted_text = encode_message(message, SUBSTITUTIONS)
print("started with "+message) # Changed
print("Converted to "+converted_text) # Changed

Page 170 Code different
Use input instead of raw_input as explained in the Python 3 post for Project 5. In this case, i have added raw_input = input after the docstring.


#Python 3 code:
""" 1337.py
Given a message, convert it into 1337 sp34k
Brendan Scott
January 2015 """

raw_input = input # this fixes raw_input!

TEST_MESSAGE = "Hello World!"
##TEST_SUBSTITUTIONS = [['e','3']]
SUBSTITUTIONS = [['a','4'], ['e','3'], ['l','1'], ['o','0'],
                 ['t','7']]
              
#### Function Section
def encode_message(message, substitutions):
    """Take a string message and apply each of the substitutions provided.
    Substitutions should be a list, the elements of substitutions need to
    be lists of length 2 of the form (old_string, new_string) """
    
    for s in substitutions:
        old = s[0]
        new = s[1]
        message = message.replace(old,new) # Changed
        print("converted text = "+message)
    print("Leaving encode_message") # Changed
    return message # Changed
    
#### Testing Section
message = raw_input("Type the message to be encoded here: ")
converted_text = encode_message(message, SUBSTITUTIONS)
print("started with "+message)
print("Converted to "+converted_text)


Python for Kids: Python 3 – Project 5

Disclaimer

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.

 

Using Python3 in Project 5 of Python For Kids For Dummies

Project 5 introduces the concept of using functions for performing repetitive work when you’re programming.  All of the keywords introduced in this Project are the same and have the same syntax in Python 3, so you really shouldn’t have any trouble with this code – except for the fact that some of the code has raw_input in it and that caused problems in earlier chapters.  As I mentioned in my earlier post you can either:

  • replace every reference to raw_input by plain old input; or
  • at the top of your file add the line raw_input = input.

If you’re cutting and pasting  from the code on the website this is probably the easiest thing to do.

Basically, everything in this project will work if you use one of the two strategies above. However, some of the code will give a different output when run under Python3 compared to Python2.7. There is also one place where the code in the book is redundant.  This is the use of the float() builtin – Python3 automatically calculates its results using decimals.

Page 105 – 110:

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

Page 111-112

This code has raw_input. Add a line raw_input = input # this fixes raw_input! at the top of the file to get it working.

#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')

#Python 3 code:
import random
raw_input = input # this fixes raw_input!

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')

Page 113

This code has raw_input. Add a line raw_input = input # this fixes raw_input! at the top of the file to get it working.

#Python 2.7 code:
"""guess_game_fun
Guess Game with a Function
In this project the guess game is recast using a function"""

import random

computers_number = random.randint(1,100)
PROMPT = 'What is your guess? '

def do_guess_round():
    """Choose a random number, ask the user for a guess
    check whether the guess is true
    and repeat until the user is correct"""
    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')

do_guess_round()
#Python 3 code:
"""guess_game_fun
Guess Game with a Function
In this project the guess game is recast using a function"""

import random
raw_input = input # this fixes raw_input!

computers_number = random.randint(1,100)
PROMPT = 'What is your guess? '

def do_guess_round():
    """Choose a random number, ask the user for a guess
    check whether the guess is true
    and repeat until the user is correct"""
    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')

do_guess_round()

Pages 114 – 116:

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

Page 117

This code has raw_input. Add a line raw_input = input # this fixes raw_input! at the top of the file to get it working.

#Python 2.7 code:
"""guess_game_fun
Guess Game with a Function
In this project the guess game is recast using a function"""

import random

computers_number = random.randint(1,100)
PROMPT = 'What is your guess? '

def do_guess_round():
    """Choose a random number, ask the user for a guess
    check whether the guess is true
    and repeat until the user is correct"""
    computers_number = random.randint(1,100) # Added
    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')

while True:
    # Print statements added:
    print("Starting a new Round!")
    print("The computer's number should be "+str(computers_number))
    print("Let the guessing begin!!!")
    do_guess_round()
    print("") # blank line

#Python 3 code:
"""guess_game_fun
Guess Game with a Function
In this project the guess game is recast using a function"""

import random
raw_input = input # this fixes raw_input!

computers_number = random.randint(1,100)
PROMPT = 'What is your guess? '

def do_guess_round():
    """Choose a random number, ask the user for a guess
    check whether the guess is true
    and repeat until the user is correct"""
    computers_number = random.randint(1,100) # Added
    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')

while True:
    # Print statements added:
    print("Starting a new Round!")
    print("The computer's number should be "+str(computers_number))
    print("Let the guessing begin!!!")
    do_guess_round()
    print("") # blank line

Pages 118 – 129:

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 130-131:

This code has raw_input. Add a line raw_input = input # this fixes raw_input! at the top of the file to get it working.

#Python 2.7 code:
"""guess_game_fun
Guess Game with a Function
In this project the guess game is recast using a function"""
import random

PROMPT = 'What is your guess? '

def do_guess_round():
    """Choose a random number, ask the user for a guess
    check whether the guess is true
    and repeat until the user is correct"""
    computers_number = random.randint(1, 100)
    number_of_guesses = 0 # Added

    while True:
        players_guess = raw_input(PROMPT)
        number_of_guesses = number_of_guesses+1 # Added
        if computers_number == int(players_guess):
            print('Correct!')
            return number_of_guesses # Changed
        elif computers_number > int(players_guess):
            print('Too low')
        else:
            print('Too high')

total_rounds = 0 # Added
total_guesses = 0 # Added

while True:
    total_rounds = total_rounds+1 # Added
    print("Starting round number: "+str(total_rounds)) # Changed
    print("Let the guessing begin!!!")
    this_round = do_guess_round() # Changed
    total_guesses = total_guesses+this_round # Added
    print("You took "+str(this_round)+" guesses") # Added
    avg = str(total_guesses/float(total_rounds)) # Added
    print("Your guessing average = "+avg) # Added
    print("") # blank line
#Python 3 code:
"""guess_game_fun
Guess Game with a Function
In this project the guess game is recast using a function"""
import random
raw_input = input # this fixes raw_input!

PROMPT = 'What is your guess? '

def do_guess_round():
    """Choose a random number, ask the user for a guess
    check whether the guess is true
    and repeat until the user is correct"""
    computers_number = random.randint(1, 100)
    number_of_guesses = 0 # Added

    while True:
        players_guess = raw_input(PROMPT)
        number_of_guesses = number_of_guesses+1 # Added
        if computers_number == int(players_guess):
            print('Correct!')
            return number_of_guesses # Changed
        elif computers_number > int(players_guess):
            print('Too low')
        else:
            print('Too high')

total_rounds = 0 # Added
total_guesses = 0 # Added

while True:
    total_rounds = total_rounds+1 # Added
    print("Starting round number: "+str(total_rounds)) # Changed
    print("Let the guessing begin!!!")
    this_round = do_guess_round() # Changed
    total_guesses = total_guesses+this_round # Added
    print("You took "+str(this_round)+" guesses") # Added
    avg = str(total_guesses/float(total_rounds)) # Added
    print("Your guessing average = "+avg) # Added
    print("") # blank line

Page 132:

This code has raw_input. Add a line raw_input = input # this fixes raw_input! at the top of the file to get it working. The code here is only a single side function. If you have the raw_input = input line earlier in the file you don’t need to add it again. I’m showing it here just for completeness.

#Python 2.7 code:
CONFIRM_QUIT_MESSAGE = 'Are you sure you want to quit (Y/n)? '

def confirm_quit():
    """Ask user to confirm that they want to quit
    default to yes
    Return True (yes, quit) or False (no, don't quit) """
    spam = raw_input(CONFIRM_QUIT_MESSAGE)
    if spam == 'n':
        return False
    else:
        return True

#Python 3 code:
CONFIRM_QUIT_MESSAGE = 'Are you sure you want to quit (Y/n)? '

def confirm_quit():
    """Ask user to confirm that they want to quit
    default to yes
    Return True (yes, quit) or False (no, don't quit) """
    spam = input(CONFIRM_QUIT_MESSAGE)
    if spam == 'n':
        return False
    else:
        return True        

Pages 133-134:

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

Page 135:

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:

  • see the errata on Project 5. The line avg = str(total_guesses/float(total_rounds)) needs to be moved; and
  • the use of float() is unnecessary. We did this because Python 2.7 thinks if you divide a whole number by a whole number you want a whole number as an answer. If you want a decimal you need to use float().  Python3 calculates using decimals by default so float() is unnecessary.

Here is the corrected code (works in both Python 2.7 and Python 3):


    # new if condition (and code block) to test against quit
    if this_round == QUIT:
        total_rounds = total_rounds - 1
        # removed line from here
        if total_rounds == 0:
            stats_message = 'You completed no rounds. '+\
                              'Please try again later.'
        else:
            avg = str(total_guesses/float(total_rounds)) # to here
            stats_message = 'You played ' + str(total_rounds) +\
                              ' rounds, with an average of '+\
                              str(avg)
        break

Page 136:

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.

Page 137:

This code has raw_input. Add a line raw_input = input # this fixes raw_input! at the top of the file to get it working. You also need to incorporate the fixes mentioned in relation to the code on page 135.

Here is the corrected code in Python 3:

#Working Python 3 code:
"""guess_game_fun
Guess Game with a Function
In this project the guess game is recast using a function"""

import random
raw_input = input # this fixes raw_input!
PROMPT = 'What is your guess? '

# New constants
QUIT = -1
QUIT_TEXT = 'q'
QUIT_MESSAGE = 'Thank you for playing'
CONFIRM_QUIT_MESSAGE = 'Are you sure you want to quit (Y/n)? '

# New confirm_quit function
def confirm_quit():
    """Ask user to confirm that they want to quit
    default to yes
    Return True (yes, quit) or False (no, don't quit) """
    spam = raw_input(CONFIRM_QUIT_MESSAGE)
    if spam == 'n':
        return False
    else:
        return True

def do_guess_round():
    """Choose a random number, ask the user for a guess
    check whether the guess is true
    and repeat until the user is correct"""
    computers_number = random.randint(1, 100)
    number_of_guesses = 0

    while True:
        players_guess = raw_input(PROMPT)
        # new if clause to test against quit
        if players_guess == QUIT_TEXT:
            if confirm_quit():
                  return QUIT
            else:
                  continue # that is, do next round of loop
        number_of_guesses = number_of_guesses+1
        if computers_number == int(players_guess):
            print('Correct!')
            return number_of_guesses
        elif computers_number > int(players_guess):
            print('Too low')
        else:
            print('Too high')

total_rounds = 0
total_guesses = 0

while True:
    total_rounds = total_rounds+1
    print("Starting round number: "+str(total_rounds))
    print("Let the guessing begin!!!")
    this_round = do_guess_round()

    # new if condition (and code block) to test against quit
    if this_round == QUIT:
        total_rounds = total_rounds - 1
        if total_rounds == 0:
            stats_message = 'You completed no rounds. '+\
                              'Please try again later.'
        else:
            avg = str(total_guesses/float(total_rounds))
            stats_message = 'You played ' + str(total_rounds) +\
                              ' rounds, with an average of '+\
                              str(avg)
        break
    total_guesses = total_guesses+this_round
    avg = str(total_guesses/float(total_rounds))
    print("You took "+str(this_round)+" guesses")
    print("Your guessing average = "+str(avg))
    print("")
# Added exit messages
print(stats_message)

Python for Kids: Python 3 – Project 4

Disclaimer

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.

Using Python3 in Project 4 of Python For Kids For Dummies

Project 4 introduces the IDLE integrated development environment. When you download and install a version of Python 3 for Windows (I tested version 3.4.4)  you should get a folder called Python 3.4 (or whatever version you installed) in your Start Menu.  In that folder should be an entry called IDLE (Python 3.4 GUI – 32 bit).  If you run that you will be launched into the Python 3.4 equivalent of the IDLE mentioned in the book.

The good news is that pretty much everything in this project is the same for Python 3. That’s partly because the project is mainly concerned with introducing the IDLE environment and the concept of storing code in a file.  IDLE in Python 3 has all of the features listed in Project 4 as for Python 2.7:

Syntax highlighting (page 87)

Tab Completion (page 88/89)

Command history (page 90/91)

The IDLE Editor Window (page 92-95)

Comments (page 95-98)

Saving files (page 98)

Commenting out code (page 98-100) (the same commenting format -> # or triple quotes for docstrings “”” are the same in Python 3)

Indenting and dedenting code (page 101-102)

You should be able to breeze through Project 4 using Python 3.

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

&amp;gt;

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.

Python for Kids: Python 3 – Project 2

Some people want to use my book Python for Kids for Dummies to learn Python 3. Choosing Python 2.7 over Python 3 was a difficult decision and I have given reasons why in the book.* Nevertheless, if I write a new edition of the book, it definitely will be in Python 3, so I plan to work through the code in the existing book, highlighting changes from Python 2 to Python 3 and providing code that will work in Python 3.

I am working from the downloadable code samples (they are cross referenced to page numbers in the book), so it might be an idea to get a copy, although working from the hard copy should also be fine. Get a copy from the link in the right hand sidebar.

For Project 2, most of the code works exactly the same in Python 2.7 and Python 3. There are some changes though later in the Project (from page 50). Those changes are set out below (page numbers from the 2015 printing).

Code on Pages 36 to Page 50

All of the code on these pages works in Python 3 and gives the same output.

Code on Page 50

#Python 2.7 code:
>>> my_message = 'Hello World!'
>>> while True:
...       print(my_message),
...

Comment

In Python 2.7 you use the comma -> , to tell print to NOT include a new line at the end of what is printed.
In Python 3 print has become a function. Functions are not discussed till Project 5! Implementing this in Python 3 needs a lot of extra concepts, that I’m not going to explain here. Instead, I’m just going to give you working code. You will need to come back to this after you’ve done Project 5. Hopefully then it will make more sense.

#Python 3
>>> while True:
...       print(my_message, end=&amp;quot; &amp;quot;)
...

Code on Page 51

#Python 2.7 code:
>>> range(3)
[0, 1, 2]

Comment

In Python 2.7 range() creates a list. In Python 3 it makes something like a generator** – and generators are not even covered in the book!😦 The main difference is that, with a list, all the items that you need are created ahead of time. However, with a generator, you only create the next item when you need it. Practically, the code will work in the same manner and you won’t be able to notice any difference (see the examples on the next page). For example, the numbers produced by range in Python 3 will start at 0 and run up to the number one less than the number you give to range. The good news though is that you can ignore my warning (on page 52) about using range() if you’re running Python 3. In Python 3 range doesn’t blow out your memory, so feel free to use it for numbers as big as you like.

#Python 3 code:
>>> range(3)
range(0, 3)

Code on Page 52

#Python 2.7 code:
>>> range(3,10)
[3, 4, 5, 6, 7, 8, 9]

>>> range(3,10,2)
[3, 5, 7, 9]

Comment

See comments on generators above. You won’t be able to see the practical difference until you cover for loops (see below).

#Python 3 code:
>>> range(3,10)
range(3, 10)

>>> range(3,10,2)
range(3, 10, 2)

Code on Page 53

#Python 2.7 code:
>>> range(13,10,-1)
[13, 12, 11]

Comment

Same comments on generators. See below.

#Python 3 code:
>>> range(13,10,-1)
range(13, 10, -1)

#Python 2.7 code:
>>> for i in range(3):
...        print(i)
...
0
1
2

#Python 3 code:
>>> for i in range(3):
...        print(i)
...
0
1
2

Comment

In this example both the code and the output from the Python 2.7 and Python 3 code was the same. However, the code created the output in different ways (the Python 2.7 code created a list, while the Python 3 code created a generator). Anywhere you use range in the book, you can use it when using Python 3.

Also, using this for loop structure you can test to see whether the earlier ranges are practically the same in Python 2.7 and Python 3.
For example (from page 52):

#Python 2.7 code:
>>> range(3,10)
[3, 4, 5, 6, 7, 8, 9]

>>> range(3,10,2)
[3, 5, 7, 9]

#Python 3 code:
>>> for i in range(3,10):
...        print(i)
...
3
4
5
6
7
8
9

# note same numbers as in [3, 4, 5, 6, 7, 8, 9]

>>> for i in range(3,10,2):
...        print(i)
...
3
5
7
9

# note: odd numbers from 3 to 10

Code on Page 54

#Python 2.7 code:
>>> my_message = &amp;quot;Hello World!&amp;quot;
>>> for i in range(300):
...          print(my_message),
...

Comment

See comments on print above.

#Python 3 code:

>>> my_message = &amp;quot;Hello World!&amp;quot;
>>> for i in range(300):
...          print(my_message, end=&amp;quot; &amp;quot;)
...

Note that, in Python 2.7 when the print run had finished the >>> prompt started on a new line. However, in Python 3 the prompt >>> starts immediately after the last Hello World! on the same line.

Note:
* I had dreams of extending the book for parents to include, for example, loading applications to the cloud. Right now (March 2016, a year after I finished writing the book) Google App Engine, perhaps the easiest way to get an app live on the internet, still does not support Python 3 (although it is available through a separate service – GAE Managed VM hosting).

** It creates an “immutable sequence type” according to the docs. See Terry’s comment.

Follow

Get every new post delivered to your Inbox.

Join 86 other followers