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)