learn python 3 the hard way: a very simple introduction to ... a... · the fourth edition of learn...

345

Upload: others

Post on 13-Mar-2020

33 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of
Page 2: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

ContentsPreface

Improvements in the Fourth Edition

Acknowledgements

The Hard Way Is Easier

Reading and Writing

Attention to Detail

Spotting Differences

Ask, Don’t Stare

Do Not Copy-Paste

Using the Included Videos

A Note on Practice and Persistence

Exercise 0. The Setup

macOS

Windows

Linux

Finding Things on the Internet

Warnings for Beginners

Alternative Text Editors

Page 3: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 1. A Good First Program

What You Should See

Study Drills

Common Student Questions

Exercise 2. Comments and Pound Characters

What You Should See

Study Drills

Common Student Questions

Exercise 3. Numbers and Math

What You Should See

Study Drills

Common Student Questions

Exercise 4. Variables and Names

What You Should See

Study Drills

Common Student Questions

Exercise 5. More Variables and Printing

What You Should See

Study Drills

Common Student Questions

Page 4: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 6. Strings and Text

What You Should See

Study Drills

Break It

Common Student Questions

Exercise 7. More Printing

What You Should See

Study Drills

Break It

Common Student Questions

Exercise 8. Printing, Printing

What You Should See

Study Drills

Common Student Questions

Exercise 9. Printing, Printing, Printing

What You Should See

Study Drills

Common Student Questions

Exercise 10. What Was That?

What You Should See

Page 5: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Escape Sequences

Study Drills

Common Student Questions

Exercise 11. Asking Questions

What You Should See

Study Drills

Common Student Questions

Exercise 12. Prompting People

What You Should See

Study Drills

Common Student Questions

Exercise 13. Parameters, Unpacking, Variables

Hold Up! Features Have Another Name

What You Should See

Study Drills

Common Student Questions

Exercise 14. Prompting and Passing

What You Should See

Study Drills

Common Student Questions

Page 6: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 15. Reading Files

What You Should See

Study Drills

Common Student Questions

Exercise 16. Reading and Writing Files

What You Should See

Study Drills

Common Student Questions

Exercise 17. More Files

What You Should See

Study Drills

Common Student Questions

Exercise 18. Names, Variables, Code, Functions

What You Should See

Study Drills

Common Student Questions

Exercise 19. Functions and Variables

What You Should See

Study Drills

Common Student Questions

Page 7: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 20. Functions and Files

What You Should See

Study Drills

Common Student Questions

Exercise 21. Functions Can Return Something

What You Should See

Study Drills

Common Student Questions

Exercise 22. What Do You Know So Far?

What You Are Learning

Exercise 23. Strings, Bytes, and Character Encodings

Initial Research

Switches, Conventions, and Encodings

Disecting the Output

Disecting the Code

Encodings Deep Dive

Breaking It

Exercise 24. More Practice

What You Should See

Study Drills

Page 8: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Common Student Questions

Exercise 25. Even More Practice

What You Should See

Study Drills

Common Student Questions

Exercise 26. Congratulations, Take a Test!

Common Student Questions

Exercise 27. Memorizing Logic

The Truth Terms

The Truth Tables

Common Student Questions

Exercise 28. Boolean Practice

What You Should See

Study Drills

Common Student Questions

Exercise 29. What If

What You Should See

Study Drills

Common Student Questions

Exercise 30. Else and If

Page 9: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

What You Should See

Study Drills

Common Student Questions

Exercise 31. Making Decisions

What You Should See

Study Drills

Common Student Questions

Exercise 32. Loops and Lists

What You Should See

Study Drills

Common Student Questions

Exercise 33. While Loops

What You Should See

Study Drills

Common Student Questions

Exercise 34. Accessing Elements of Lists

Study Drills

Exercise 35. Branches and Functions

What You Should See

Study Drills

Page 10: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Common Student Questions

Exercise 36. Designing and Debugging

Rules for If-Statements

Rules for Loops

Tips for Debugging

Homework

Exercise 37. Symbol Review

Keywords

Data Types

String Escape Sequences

Old Style String Formats

Operators

Reading Code

Study Drills

Common Student Questions

Exercise 38. Doing Things to Lists

What You Should See

What Lists Can Do

When to Use Lists

Study Drills

Page 11: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Common Student Questions

Exercise 39. Dictionaries, Oh Lovely Dictionaries

A Dictionary Example

What You Should See

What Dictionaries Can Do

Study Drills

Common Student Questions

Exercise 40. Modules, Classes, and Objects

Modules Are Like Dictionaries

What You Should See

Study Drills

Common Student Questions

Exercise 41. Learning to Speak Object-Oriented

Word Drills

Phrase Drills

Combined Drills

A Reading Test

Practice English to Code

Reading More Code

Common Student Questions

Page 12: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 42. Is-A, Has-A, Objects, and Classes

How This Looks in Code

About class Name(object)

Study Drills

Common Student Questions

Exercise 43. Basic Object-Oriented Analysis and Design

The Analysis of a Simple Game Engine

Top Down versus Bottom Up

The Code for “Gothons from Planet Percal #25“

What You Should See

Study Drills

Common Student Questions

Exercise 44. Inheritance Versus Composition

What Is Inheritance?

The Reason for super()

Composition

When to Use Inheritance or Composition

Study Drills

Common Student Questions

Exercise 45. You Make a Game

Page 13: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Evaluating Your Game

Function Style

Class Style

Code Style

Good Comments

Evaluate Your Game

Exercise 46. A Project Skeleton

macOS/Linux Setup

Windows 10 Setup

Creating the Skeleton Project Directory

Testing Your Setup

Using the Skeleton

Required Quiz

Common Student Questions

Exercise 47. Automated Testing

Writing a Test Case

Testing Guidelines

What You Should See

Study Drills

Common Student Questions

Page 14: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 48. Advanced User Input

Our Game Lexicon

A Test First Challenge

What You Should Test

Study Drills

Common Student Questions

Exercise 49. Making Sentences

Match and Peek

The Sentence Grammar

A Word On Exceptions

The Parser Code

Playing With The Parser

What You Should Test

Study Drills

Common Student Questions

Exercise 50. Your First Website

Installing Flask

Make a Simple “Hello World” Project

What’s Going On?

Fixing Errors

Page 15: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Create Basic Templates

Study Drills

Common Student Questions

Exercise 51. Getting Input from a Browser

How the Web Works

How Forms Work

Creating HTML Forms

Creating a Layout Template

Writing Automated Tests for Forms

Study Drills

Breaking It

Exercise 52. The Start of Your Web Game

Refactoring the Exercise 43 Game

Creating an Engine

Your Final Exam

Common Student Questions

Exercise 53. Next Steps

How to Learn Any Programming Language

Exercise 54. Advice from an Old Programmer

Appendix A: Command Line Crash Course

Page 16: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Introduction: Shut Up and Shell

The Setup

Paths, Folders, Directories (pwd)

If You Get Lost

Make a Directory (mkdir)

Change Directory (cd)

List Directory (ls)

Remove Directory (rmdir)

Moving Around (pushd, popd)

Making Empty Files (Touch, New-Item)

Copy a File (cp)

Moving a File (mv)

View a File (less, MORE)

Stream a File (cat)

Removing a File (rm)

Exiting Your Terminal (exit)

Command Line Next Steps

Page 17: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

PrefaceThis simple book is meant to get you started in programming. The title saysit’s the hard way to learn to write code, but it’s actually not. It’s only the“hard” way because it uses a technique called instruction. Instruction iswhere I tell you to do a sequence of controlled exercises designed to build askill through repetition. This technique works very well with beginners whoknow nothing and need to acquire basic skills before they can understandmore complex topics. It’s used in everything from martial arts to music toeven basic math and reading skills.

This book instructs you in Python by slowly building and establishing skillsthrough techniques such as practice and memorization, then applying them toincreasingly difficult problems. By the end of the book you will have thetools needed to begin learning more complex programming topics. I like totell people that my book gives you your “programming black belt.” What thismeans is that you know the basics well enough to now start learningprogramming.

If you work hard, take your time, and build these skills, you will learn tocode.

Improvements in the Fourth Edition

The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’vestandardized on this version of Python because it has a new improved stringformatting system that is easier to use than the previous 4 (or 3, I forget, therewere many). There are a few problems with Python 3.6 for beginners, but I’llbe helping you navigate these issues in the book. A particularly hairyproblem is Python 3.6 has very poor error messages in some key areas thatI’ll be helping you understand.

I have also improved the videos based on my experiences over the last fiveyears teaching people Python. In the past the videos simply let you watch medo the exercise. The fourth edition videos also show you how to break—and

Page 18: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

then fix—every exercise. This skill is called “debugging.” It will teach youhow to fix problems you run into but also how Python runs the programsyou’re creating. The goal of this new methodology is to build a mental modelof how Python runs your code so you can more easily figure out why it’sbroken. You’ll also learn many useful tricks for debugging broken software.

Lastly, the fourth edition fully supports Microsoft Windows 10 frombeginning to end. The previous edition focused mostly on the Unix stylesystems such as macOS and Linux, with Windows being more of anafterthought. At the time I started writing the fourth edition Microsoft hadstarted to take open source tools and developers seriously, and it was difficultto ignore them as a serious Python development platform. The videos willfeature Microsoft windows using Python in various scenarios and will alsoshow macOS and Linux for full compatibility. I’ll tell you about any gotchason each platform, cover installation instructions, and provide any other tips Ican give you.

Acknowledgements

I would like to thank Angela for helping me with the first two versions of thisbook. Without her I probably wouldn’t have bothered to finish it at all. Shedid the copy-editing of the first draft and supported me immensely while Iwrote it.

I’d also like to thank Greg Newman for doing the original cover art, BrianShumate for early website designs, and all of the people who read this bookand took the time to send me feedback and corrections.

Thank you.

Page 19: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

The Hard Way Is EasierWith the help of this book, you will do the incredibly simple things that allprogrammers do to learn a programming language:

1. Go through each exercise.

2. Type in each file exactly.

3. Make it run.

That’s it. This will be very difficult at first, but stick with it. If you go throughthis book and do each exercise for one or two hours a night, you will have agood foundation for moving on to another book about Python to continueyour studies. This book won’t turn you into a programmer overnight, but itwill get you started on the path to learning how to code.

This book’s job is to teach you the three most essential skills that a beginningprogrammer needs to know: reading and writing, attention to detail, andspotting differences.

Reading and Writing

If you have a problem typing, you will have a problem learning to code, andespecially if you have a problem typing the fairly odd characters in sourcecode. Without this simple skill you will be unable to learn even the mostbasic things about how software works.

Typing the code samples and getting them to run will help you learn thenames of the symbols, get familiar with typing them, and get you reading thelanguage.

Attention to Detail

The one skill that separates bad programmers from good programmers is

Page 20: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

attention to detail. In fact, it’s what separates the good from the bad in anyprofession. You must pay attention to the tiniest details of your work or youwill miss important elements of what you create. In programming, this is howyou end up with bugs and difficult-to-use systems.

By going through this book, and copying each example exactly, you will betraining your brain to focus on the details of what you are doing, as you aredoing it.

Spotting Differences

A very important skill (that most programmers develop over time) is theability to visually notice differences between things. An experiencedprogrammer can take two pieces of code that are slightly different andimmediately start pointing out the differences. Programmers have inventedtools to make this even easier, but we won’t be using any of these. You firsthave to train your brain the hard way, then use the tools.

While you do these exercises, typing each one in, you will be makingmistakes. It’s inevitable; even seasoned programmers would make a few.Your job is to compare what you have written to what’s required and fix allthe differences. By doing so, you will train yourself to notice mistakes, bugs,and other problems.

Ask, Don’t Stare

If you write code, you will write bugs. A “bug” means a defect, error, orproblem with the code you’ve written. The legends say that this comes froman actual moth that flew into one of the first computers causing it tomalfunction. Fixing it required “de-bugging” the computer. In the world ofsoftware, there are a lot of bugs. So many.

Like that first moth, your bugs will be hidden somewhere in the code, andyou have to go find them. You can’t just sit at your computer screen staringat the words you’ve written hoping that the answer jumps out at you. There isno more additional information you can get doing that, and you need

Page 21: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

additional information. You need to get up and go find the moth.

To do that you have to interrogate your code and ask it what is going on orlook at the problem from a different view. In this book I’ll frequently tell youto “stop staring and ask”. I’ll show you how to make your code tell youeverything it can about what’s going on and how to turn this into possiblesolutions. I’ll also give you ways to see your code in different ways, so youcan get more information and insight.

Do Not Copy-Paste

You must type each of these exercises in, manually. If you copy and paste,you might as well not even do them. The point of these exercises is to trainyour hands, your brain, and your mind in how to read, write, and see code. Ifyou copy-paste, you are cheating yourself out of the effectiveness of thelessons.

Using the Included Videos

The Python 3 edition of Learn Python The Hard Way has an extensive set ofvideos demonstrating how the code works and, most importantly, how tobreak it. The videos are the perfect place to demonstrate many commonerrors by breaking the Python code on purpose and showing you how to fix it.I’ll also be walking through the code using debugging and interrogation tricksand techniques. The videos are where I show you how to “stop staring andask” the code what’s wrong.

A Note on Practice and Persistence

While you are studying programming, I’m studying how to play guitar. Ipractice it every day for at least two hours a day. I play scales, chords, andarpeggios for an hour and then learn music theory, ear training, songs, andanything else I can. Some days I study guitar and music for eight hoursbecause I feel like it and it’s fun. To me repetitive practice is natural and justhow to learn something. I know that to get good at anything you have to

Page 22: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

practice every day, even if I suck that day (which is often) or it’s difficult.Keep trying, and eventually it’ll be easier and fun.

Between the time that I wrote Learn Python The Hard Way and Learn RubyThe Hard Way I discovered drawing and painting. I fell in love with makingvisual art at the age of 39 and have been spending every day studying it inmuch the same way that I studied guitar, music, and programming. I collectedbooks of instructional material, did what the books said, painted every day,and focused on enjoying the process of learning. I am by no means an“artist,” or even that good, but I can now say that I can draw and paint. Thesame method I’m teaching you in this book applied to my adventures in art. Ifyou break the problem down into small exercises and lessons, and do themevery day, you can learn to do almost anything. If you focus on slowlyimproving and enjoying the learning process, then you will benefit no matterhow good you are at it.

As you study this book, and continue with programming, remember thatanything worth doing is difficult at first. Maybe you are the kind of personwho is afraid of failure, so you give up at the first sign of difficulty. Maybeyou never learned self-discipline, so you can’t do anything that’s “boring.”Maybe you were told that you are “gifted,” so you never attempt anythingthat might make you seem stupid or not a prodigy. Maybe you arecompetitive and unfairly compare yourself to someone like me who’s beenprogramming for more than 20 years.

Whatever your reason for wanting to quit, keep at it. Force yourself. If yourun into a Study Drill you can’t do, or a lesson you just do not understand,then skip it and come back to it later. Just keep going because withprogramming there’s this very odd thing that happens. At first, you will notunderstand anything. It’ll be weird, just like with learning any humanlanguage. You will struggle with words and not know what symbols arewhat, and it’ll all be very confusing. Then one day BANG—your brain willsnap and you will suddenly “get it.” If you keep doing the exercises and keeptrying to understand them, you will get it. You might not be a master coder,but you will at least understand how programming works.

If you give up, you won’t ever reach this point. You will hit the firstconfusing thing (which is everything at first) and then stop. If you keep

Page 23: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

trying, keep typing it in, keep trying to understand it and reading about it, youwill eventually get it. If you go through this whole book, and you still do notunderstand how to code, at least you gave it a shot. You can say you triedyour best and a little more, and it didn’t work out, but at least you tried. Youcan be proud of that.

Page 24: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 0. The SetupThis exercise has no code. It is simply the exercise you complete to get yourcomputer to run Python. You should follow these instructions as exactly aspossible. If you have problems following the written instructions, then watchthe included videos for your platform.

Warning!

If you do not know how to use PowerShell on Windows, Terminal onmacOS or bash on Linux then you need to go learn that first. You should dothe exercises in Appendix A first before continuing with these exercises.

macOS

Do the following tasks to complete this exercise:

1. Go to https://www.python.org/downloads/release/python-360/ anddownload the “macOS 64-bit/32-bit installer”. Install it like you would anyother software.

2. Go to https://atom.io/ with your browser, get the Atom text editor, andinstall it. If Atom does not suite you, then see Alternative Text Editors at theend of this exercise.

3. Put Atom (your text editor) in your dock, so you can reach it easily.

4. Find your Terminal program. Search for it. You will find it.

5. Put your Terminal in your dock as well.

6. Run your Terminal program. It won’t look like much.

Page 25: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

7. In your Terminal program, run python3.6. You run things in Terminal byjust typing the name and hitting RETURN.

8. Type quit(), Enter, and get out of python3.6.

9. You should be back at a prompt similar to what you had before you typedpython. If not, find out why.

10. Learn how to make a directory in the Terminal.

11. Learn how to change into a directory in the Terminal.

12. Use your editor to create a file in this directory. You will make the file,“Save” or “Save As...,” and pick this directory.

13. Go back to Terminal using just the keyboard to switch windows.

14. Back in Terminal, list the directory with ls to see your newly created file.

0.1.1 macOS: What You Should See

Here’s me doing this on my macOS computer in Terminal. Your computermight be different but should be similar to this.

$ python3.6Python 3.6.0 (default, Feb 2 2017, 12:48:29)[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang -700.1.81)] on darwinType "help", "copyright", "credits" or "license" for more information.>>>~ $ mkdir lpthw~ $ cd lpthwlpthw $ l s# ... Use your text editor here to edit test.txt....lpthw $ lstest.txtlpthw $

Windows

1. Go to https://atom.io with your browser, get the Atom text editor, and

Page 26: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

install it. You do not need to be the administrator to do this.

2. Make sure you can get to Atom easily by putting it on your desktop and/orin Quick Launch. Both options are available during setup.

(a) If you cannot run Atom because your computer is not fast enough, then seeAlternative Text Editors at the end of this exercise.

3. Run PowerShell from the Start menu. Search for it, and you can just pressEnter to run it.

4. Make a shortcut to it on your desktop and/or Quick Launch for yourconvenience.

5. Run your PowerShell program (which I will call Terminal later). It won’tlook like much.

6. Download Python 3.6 fromhttps://www.python.org/downloads/release/python-360/ and install it. Be sureto check the box that says to add Python 3.6 to your path.

7. In your PowerShell (Terminal) program, run python. You run things inTerminal by just typing the name and pressing Enter.

(a) If you type python and it does not run, then you have to reinstall Pythonand make sure you check the box for “Add python to the PATH.” It’s verysmall so look carefully.

8. Type quit(), and press Enter to exit python.

9. You should be back at a prompt similar to what you had before you typedpython. If not, find out why.

10. Learn how to make a directory in the PowerShell (Terminal).

11. Learn how to change into a directory in the PowerShell (Terminal).

12. Use your editor to create a file in this directory. Make the file, Save orSave As..., and pick this directory.

Page 27: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

13. Go back to PowerShell (Terminal) using just the keyboard to switchwindows. Look it up if you can’t figure it out.

14. Back in PowerShell (Terminal), list the directory to see your newlycreated file.

From now on, when I say “Terminal” or “shell” I mean PowerShell, andthat’s what you should use. When I run python3.6 you can just type python.

0.2.1 Windows: What You Should See

> python>>> quit()> mkdir lpthw> cd lpthw... Here you would use your text editor to make test.txt in lpthw ...>> dir Volume in drive C is Volume Serial Number is 085C—7E02

Directory of C:\Documents and Settings\you\lpthw

04.05.2010 23:32 <DIR> .04.05.2010 23:32 <DIR> ..04.05.201 0 23:32 6 test.txt 1 File(s) 6 bytes 2 Dir(s) 14 804 623 360 bytes free

>

It is still correct if you see different information than mine, but yours shouldbe similar.

Linux

Linux is a varied operating system with many different ways to installsoftware. I’m assuming if you are running Linux then you know how toinstall packages, so here are your instructions:

1. Use your package manager to install Python 3.6, and if you can’t, then

Page 28: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

download source from https://www.python.org/downloads/release/python-360/ and build from source.

2. Use your Linux package manager, and install the Atom text editor. If Atomdoes not suite you, then see Alternative Text Editors at the end of thisexercise.

3. Make sure you can get to Atom easily by putting it in your windowmanager’s menu.

4. Find your Terminal program. It could be called GNOME Terminal, Konsole,or xterm.

5. Put your Terminal in your dock as well.

6. Run your Terminal program. It won’t look like much.

7. In your Terminal program, run python3.6. You run things in Terminal byjust typing the command name and pressing Enter. If you can’t runpython3.6, try running just python.

8. Type quit() and press Enter to exit python.

9. You should be back at a prompt similar to what you had before you typedpython. If not, find out why.

10. Learn how to make a directory in Terminal.

11. Learn how to change into a directory in Terminal.

12. Use your editor to create a file in this directory. Typically, you will makethe file, Save or Save As..., and pick this directory.

13. Go back to Terminal using just the keyboard to switch windows. Look itup if you can’t figure it out.

14. Back in Terminal, list the directory to see your newly created file.

0.3.1 Linux: What You Should See

Page 29: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

$ python>>> quit()$ mkdir lpthw$ cd lpthw# ... Use your text editor here to edit test.txt ...$ lstest.txt$

It is still correct if you see different information than mine, but yours shouldbe similar.

Finding Things on the Internet

A major part of this book is learning to research programming topics online.I’ll tell you to “search for this on the internet,” and your job is to use a searchengine to find the answer. The reason I have you search instead of just givingyou the answer is because I want you to be an independent learner who doesnot need my book when you’re done with it. If you can find the answers toyour questions online, then you are one step closer to not needing me, andthat is my goal.

Thanks to search engines such as Google you can easily find anything I tellyou to find. If I say, “search online for the python list functions,” then yousimply do this:

1. Go to http://google.com/.

2. Type: python3 list functions.

3. Read the websites listed to find the best answer.

Warnings for Beginners

You are done with this exercise. This exercise might be hard for youdepending on your familiarity with your computer. If it is difficult, take thetime to read and study and get through it, because until you can do these verybasic things you will find it difficult to get much programming done.

Page 30: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

If someone tells you to stop at a specific exercise in this book or to skipcertain ones, you should ignore that person. Anyone trying to hide knowledgefrom you, or worse, make you get it from them instead of through your ownefforts, is trying to make you depend on them for your skills. Don’t listen tothem, and do the exercises anyway so that you learn how to educate yourself.

A programmer will eventually tell you to use macOS or Linux. If theprogrammer likes fonts and typography, they’ll tell you to get a macOScomputer. If he likes control and has a huge beard, he will (or ze will if youprefer non-gendered pronouns of humans with beards) tell you to installLinux. Again, use whatever computer you have right now that works. All youneed is an editor, a terminal, and Python.

Finally, the purpose of this setup helps you do three things very reliablywhile you work on the exercises:

1. Write exercises using the text editor.

2. Run the exercises you wrote.

3. Fix them when they are broken.

4. Repeat.

Anything else will only confuse you, so stick to the plan.

Alternative Text Editors

Text editors are very important to a programmer, but as a beginner you onlyneed a simple programmer’s text editor. These are different from software forwriting stories and books because they work with the unique needs ofcomputer code. I recommend Atom in this book because it is free and worksnearly everywhere. However, Atom may not run well on your computer, sohere are some alternatives to try:

Page 31: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

These are ranked in order of most likely to work. Keep in mind that theseprojects may be abandoned, dead, or not work anymore on your computer. Ifyou try one and it doesn’t work, try another one. I’ve also listed the “WorksOn” in order of most likely to work, so if you’re on Windows then look at theeditors where Windows is listed first in the “Works On” column.

If you already know how to use Vim or Emacs then feel free to use them. Ifyou have never used Vim or Emacs then avoid them. Programmers may try toconvince you to use Vim or Emacs, but this will only derail you. Your focusis learning Python, not learning Vim or Emacs. If you try to use Vim anddon’t know how to quit, then type :q! or ZZ. If someone told you to use Vim,and they didn’t even tell you this, then now you know why you shouldn’tlisten to them.

Page 32: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 1. A Good First Program

Warning!

If you skipped Exercise 0, then you are not doing this book right. Are youtrying to use IDLE or an IDE? I said not to use one in Exercise 0, so youshould not use one. If you skipped Exercise 0 please go back to it and read it.

You should have spent a good amount of time in Exercise 0 learning how toinstall a text editor, run the text editor, run the terminal, and work with bothof them. If you haven’t done that, then do not go on. You will not have agood time. This is the only time I’ll start an exercise with a warning that youshould not skip or get ahead of yourself.

Type the following text into a single file named ex1.py. Python works bestwith files ending in .py.

ex1.py

1 print("Hello World!")

2 print("Hello Again")

3 print("I like typing this.")

4 print("This is fun.")

5 print('Yay! Printing.')

6 print("I'd much rather you 'not'.")

7 print('I "said" do not touch this.')

Your Atom text editor should look something like this on all platforms:

Page 33: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Don’t worry if your editor doesn’t look exactly the same; it should be closethough. You may have a slightly different window header, maybe slightlydifferent colors, and the left side of your Atom window won’t say “zedshaw”but will instead show the directory you used for saving your files. All ofthose differences are fine.

When you create this file, keep in mind these points:

1. I did not type the line numbers on the left. Those are printed in the book soI can talk about specific lines by saying, “See line 5...” You do not type linenumbers into Python scripts.

Page 34: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

2. I have the print at the beginning of the line, and it looks exactly the sameas what I have in ex1.py. Exactly means exactly, not kind of sort of the same.Every single character has to match for it to work. Color doesn’t matter, onlythe characters you type.

In Terminal run the file by typing:

python3.6 ex1.py

If you did it right then you should see the same output as I in the What YouShould See section of this exercise. If not, you have done something wrong.No, the computer is not wrong.

What You Should See

On macOS in the Terminal you should see this:

Page 35: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

On Windows in PowerShell you should see this:

Page 36: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

You may see different names, before the python3.6 ex1.py command, butthe important part is that you type the command and see the output is thesame as mine.

If you have an error it will look like this:

$ python3.6 python/ex1.py File "python/ex1.py" , line 3 print (" I like typing this. ^SyntaxError : EOL while scanning string literal

It’s important that you can read these error messages because you will bemaking many of these mistakes. Even I make many of these mistakes. Let’slook at this line by line.

1. We ran our command in the Terminal to run the ex1.py script.

2. Python tells us that the file ex1.py has an error on line 3 of ex1.py.

3. It prints this line of code for us to see it.

Page 37: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

4. Then it puts a ^ (caret) character to point at where the problem is. Noticethe missing " (double-quote) character?

5. Finally, it prints out a “SyntaxError” and tells us something about whatmight be the error. Usually these are very cryptic, but if you copy that textinto a search engine, you will find someone else who’s had that error, andyou can probably figure out how to fix it.

Study Drills

The Study Drills contain things you should try to do. If you can’t, skip it andcome back later.

For this exercise, try these things:

1. Make your script print another line.

2. Make your script print only one of the lines.

3. Put a # (octothorpe) character at the beginning of a line. What did it do?Try to find out what this character does.

From now on, I won’t explain how each exercise works unless an exercise isdifferent.

Warning!

An “octothorpe” is also called a “pound”, “hash”, “mesh”, or any number ofnames. Pick the one that makes you chill out.

Common Student Questions

These are actual questions that real students have asked when doing thisexercise.

Page 38: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Can I use IDLE? No, you should use Terminal on macOS and PowerShellon Windows, just like I have here. If you don’t know how to use those, thenyou can go read the “Command Line Crash Course” in Appendix A.

How do you get colors in your editor? Save your file first as a .py file, suchas ex1.py. Then you’ll have color when you type.

I get SyntaxError: invalid syntax when I run ex1.py. You are probablytrying to run Python, then trying to type Python again. Close your Terminal,start it again, and right away type only python3.6 ex1.py.

I get can't open file 'ex1.py': [Errno 2] No such file ordirectory. You need to be in the same directory as the file you created.Make sure you use the cd command to go there first. For example, if yousaved your file in lpthw/ex1.py, then you would do cd lpthw/ before tryingto run python3.6 ex1.py. If you don’t know what any of that means, then gothrough Appendix A.

My file doesn’t run; I just get the prompt back with no output. You mostlikely took the code in my ex1.py file literally and thought thatprint("Hello World!") meant to type only "Hello World!" into the file,without the print. Your file has to be exactly like mine.

Page 39: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 2. Comments and PoundCharactersComments are very important in your programs. They are used to tell youwhat something does in English, and they are used to disable parts of yourprogram if you need to remove them temporarily. Here’s how you usecomments in Python:

ex2.py

1 # A comment, this is so you can read your program later.2 # Anything after the # is ignored by python.34 print("I could have code like this.") # and the comment after is ignored56 # You can also use a comment to "disable" or comment out code:7 # print("This won't run.")89 print("This will run.")

From now on, I’m going to write code like this. It is important for you tounderstand that everything does not have to be literal. Your screen andprogram may visually look different, but what’s important is the text you typeinto the file you’re writing in your text editor. In fact, I could work with anytext editor and the results would be the same.

What You Should See

Exercise 2 Session

$ python3.6 ex2.pyI could have code like this.This will run.

Again, I’m not going to show you screenshots of all the terminals possible.You should understand that the preceding is not a literal translation of what

Page 40: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

your output should look like visually, but the text between the first $python3.6 ... and last $ lines will be what you focus on.

Study Drills

1. Find out if you were right about what the # character does and make sureyou know what it’s called (octothorpe or pound character).

2. Take your ex2.py file and review each line going backward. Start at thelast line, and check each word in reverse against what you should have typed.

3. Did you find more mistakes? Fix them.

4. Read what you typed above out loud, including saying each character byits name. Did you find more mistakes? Fix them.

Common Student Questions

Are you sure # is called the pound character? I call it the octothorpebecause that is the only name that no one country uses and that works inevery country. Every country thinks its name for this one character is both themost important way to do it and the only way it’s done. To me this is simplyarrogance and, really, y’all should just chill out and focus on more importantthings like learning to code.

Why does the # in print("Hi # there.") not get ignored? The # in thatcode is inside a string, so it will be put into the string until the ending "character is hit. Pound characters in string are just considered characters, notcomments.

How do I comment out multiple lines? Put a # in front of each one.

I can’t figure out how to type a # character on my country’s keyboard.How do I do that? Some countries use the Alt key and combinations of otherkeys to print characters foreign to their language. You’ll have to look onlinein a search engine to see how to type it.

Page 41: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Why do I have to read code backward? It’s a trick to make your brain notattach meaning to each part of the code, and doing that makes you processeach piece exactly. This catches errors and is a handy error-checkingtechnique.

Page 42: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 3. Numbers and MathEvery programming language has some kind of way of doing numbers andmath. Do not worry: programmers frequently lie about being math geniuseswhen they really aren’t. If they were math geniuses, they would be doingmath, not writing buggy web frameworks so they can drive race cars.

This exercise has lots of math symbols. Let’s name them right away so youknow what they are called. As you type this one in, say the name. Whensaying them feels boring you can stop saying them. Here are the names:

• + plus

• - minus

• / slash

• * asterisk

• % percent

• < less-than

• > greater-than

• <= less-than-equal

• >= greater-than-equal

Notice how the operations are missing? After you type in the code for thisexercise, go back and figure out what each of these does and complete thetable. For example, + does addition.

ex3.py

1 print("I will now count my chickens:")

Page 43: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

2 3 print("Hens", 25 + 30 / 6) 4 print("Roosters", 100 - 25 * 3 % 4) 5 6 print("Now I will count the eggs:") 7 8 print(3 + 2 + 1 - 5 + 4 % 2 - 1 / 4 + 6) 910 print("Is it true that 3 + 2 < 5 - 7?")1112 print(3 + 2 < 5 - 7)1314 print("What is 3 + 2?", 3 + 2)15 print("What is 5 - 7?", 5 - 7)1617 print("Oh, that's why it's False.")1819 print("How about some more.")2021 print("Is it greater?", 5 > -2)22 print("Is it greater or equal?", 5 >= -2)23 print("Is it less or equal?", 5 <= -2)

Make sure you type this exactly before you run it. Compare each line of yourfile to my file.

What You Should See

Exercise 3 Session

$ python3.6 ex3.pyI will now count my chickens:Hens 30.0Roosters 97Now I will count the eggs:6.75Is it true that 3 + 2 < 5 - 7?FalseWhat is 3 + 2? 5What is 5 - 7? -2Oh, that's why it's False.How about some more.Is it greater? TrueIs it greater or equal? True

Page 44: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Is it less or equal? False

Study Drills

1. Above each line, use the # to write a comment to yourself explaining whatthe line does.

2. Remember in Exercise 0 when you started python3.6? Start python3.6this way again and, using the math operators, use Python as a calculator.

3. Find something you need to calculate and write a new .py file that does it.

4. Rewrite ex3.py to use floating point numbers so it’s more accurate. 20.0 isfloating point.

Common Student Questions

Why is the % character a “modulus” and not a “percent“? Mostly that’sjust how the designers chose to use that symbol. In normal writing you arecorrect to read it as a “percent.” In programming this calculation is typicallydone with simple division and the / operator. The % modulus is a differentoperation that just happens to use the % symbol.

How does % work? Another way to say it is, “X divided by Y with Jremaining.” For example, “100 divided by 16 with 4 remaining.” The resultof % is the J part, or the remaining part.

What is the order of operations? In the United States we use an acronymcalled PEMDAS which stands for Parentheses Exponents MultiplicationDivision Addition Subtraction. That’s the order Python follows as well. Themistake people make with PEMDAS is to think this is a strict order, as in “Do P,then E, then M, then D, then A, then S.” The actual order is you do themultiplication and division (M&D) in one step, from left to right, then you dothe addition and subtraction in one step from left to right. So, you couldrewrite PEMDAS as PE(M&D)(A&S).

Page 45: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 4. Variables and NamesNow you can print things with print and you can do math. The next step isto learn about variables. In programming, a variable is nothing more than aname for something, similar to how my name “Zed” is a name for, “Thehuman who wrote this book.” Programmers use these variable names to maketheir code read more like English and because they have lousy memories. Ifthey didn’t use good names for things in their software, they’d get lost whenthey tried to read their code again.

If you get stuck with this exercise, remember the tricks you have been taughtso far of finding differences and focusing on details:

1. Write a comment above each line explaining to yourself what it does inEnglish.

2. Read your .py file backward.

3. Read your .py file out loud, saying even the characters.

ex4.py

1 cars = 100 2 space_in_a_car = 4.0 3 drivers = 30 4 passengers = 90 5 cars_not_driven = cars - drivers 6 cars_driven = drivers 7 carpool_capacity = cars_driven * space_in_a_car 8 average_passengers_per_car = passengers / cars_driven 91011 print("There are", cars, "cars available.")12 print("There are only", drivers, "drivers available.")13 print("There will be", cars_not_driven, "empty cars today.")14 print("We can transport", carpool_capacity, "people today.")15 print("We have", passengers, "to carpool today.")16 print("We need to put about", average_passengers_per_car,17 "in each car.")

Page 46: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Warning!

The _ in space_in_a_car is called an underscore character. Find out howto type it if you do not already know. We use this character a lot to put animaginary space between words in variable names.

What You Should See

Exercise 4 Session

$ python3.6 ex4.pyThere are 100 cars available.There are only 30 drivers available.There will be 70 empty cars today.We can transport 120.0 people today.We have 90 to carpool today.We need to put about 3.0 in each car.

Study Drills

When I wrote this program the first time I had a mistake, and Python told meabout it like this:

Traceback ( most recent call last ): File "ex4.py" , line 8 , in <module> average_passengers_per_car = car_pool_capacity / passengerNameError : name ' car_pool_capacity ' is not defined

Explain this error in your own words. Make sure you use line numbers andexplain why.

Here are more study drills:

1. I used 4.0 for space_in_a_car, but is that necessary? What happens if it’sjust 4?

Page 47: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

2. Remember that 4.0 is a floating point number. It’s just a number with adecimal point, and you need 4.0 instead of just 4 so that it is floating point.

3. Write comments above each of the variable assignments.

4. Make sure you know what = is called (equals) and that its purpose is togive data (numbers, strings, etc.) names (cars_driven, passengers).

5. Remember that _ is an underscore character.

6. Try running python3.6 from the Terminal as a calculator like you didbefore, and use variable names to do your calculations. Popular variablenames are also i, x, and j.

Common Student Questions

What is the difference between = (single-equal) and == (double-equal)?The = (single-equal) assigns the value on the right to a variable on the left.The == (double-equal) tests whether two things have the same value. You’lllearn about this in Exercise 27.

Can we write x=100 instead of x = 100? You can, but it’s bad form. Youshould add space around operators like this so that it’s easier to read.

What do you mean by “read the file backward”? Very simple. Imagineyou have a file with 16 lines of code in it. Start at line 16, and compare it tomy file at line 16. Then do it again for 15, and so on until you’ve read thewhole file backward.

Why did you use 4.0 for space_in_a_car? It is mostly so you can then findout what a floating point number is and ask this question. See the StudyDrills.

Page 48: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 5. More Variables and PrintingNow we’ll do even more typing of variables and printing them out. This timewe’ll use something called a “format string.” Every time you put " (double-quotes) around a piece of text you have been making a string. A string is howyou make something that your program might give to a human. You printstrings, save strings to files, send strings to web servers, and many otherthings.

Strings are really handy, so in this exercise you will learn how to makestrings that have variables embedded in them. You embed variables inside astring by using a special {} sequence and then put the variable you wantinside the {} characters. You also must start the string with the letter f for“format”, as in f"Hello {somevar}". This little f before the " (double-quote)and the {} characters tell Python 3, “Hey, this string needs to be formatted.Put these variables in there.”

As usual, just type this in even if you do not understand it, and make itexactly the same.

ex5.py

1 my_name = 'Zed A. Shaw' 2 my_age = 35 # not a lie 3 my_height = 74 # inches 4 my_weight = 180 # lbs 5 my_eyes = 'Blue' 6 my_teeth = 'White' 7 my_hair = 'Brown' 8 9 print(f"Let's talk about {my_name}.")10 print(f"He's {my_height} inches tall.")11 print(f"He's {my_weight} pounds heavy.")12 print("Actually that's not too heavy.")13 print(f"He's got {my_eyes} eyes and {my_hair} hair.")14 print(f"His teeth are usually {my_teeth} depending on the coffee."1516 # this line is tricky, try to get it exactly right17 total = my_age + my_height + my_weight

Page 49: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

18 print(f"If I add {my_age}, {my_height}, and {my_weight} I get {total}."

What You Should See

Exercise 5 Session

$ python3.6 ex5.pyLet's talk about Zed A. Shaw.He's 74 inches tall.He's 180 pounds heavy.Actually that's not too heavy.He's got Blue eyes and Brown hair.His teeth are usually White depending on the coffee.If I add 35, 74, and 180 I get 289.

Study Drills

1. Change all the variables so there is no my_ in front of each one. Make sureyou change the name everywhere, not just where you used = to set them.

2. Try to write some variables that convert the inches and pounds tocentimeters and kilograms. Do not just type in the measurements. Work outthe math in Python.

Common Student Questions

Can I make a variable like this: 1 = 'Zed Shaw'? No, 1 is not a validvariable name. They need to start with a character, so a1 would work, but 1will not.

How can I round a floating point number? You can use the round()function like this: round(1.7333).

Why does this not make sense to me? Try making the numbers in this scriptyour measurements. It’s weird, but talking about yourself will make it seemmore real. Also, you’re just starting out so it won’t make too much sense.Keep going and more exercises will explain it more.

Page 50: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 6. Strings and TextWhile you have been writing strings, you still do not know what they do. Inthis exercise we create a bunch of variables with complex strings so you cansee what they are for. First an explanation of strings.

A string is usually a bit of text you want to display to someone or “export”out of the program you are writing. Python knows you want something to bea string when you put either " (double-quotes) or ' (single-quotes) around thetext. You saw this many times with your use of print when you put the textyou want to go inside the string inside " or ' after the print to print thestring.

Strings can contain any number of variables that are in your Python script.Remember that a variable is any line of code where you set a name = (equal)to a value. In the code for this exercise, types_of_people = 10 creates avariable named types_of_people and sets it = (equal) to 10. You can put thatin any string with {types_of_people}. You also see that I have to use aspecial type of string to “format“; it’s called an “f-string” and looks like this:

f"some stuff here { avariable }"f"some other stuff { anothervar }"

Python also has another kind of formatting using the .format() syntax whichyou see on line 17. You’ll see me use that sometimes when I want to apply aformat to an already created string, such as in a loop. We’ll cover that morelater.

We will now type in a whole bunch of strings, variables, and formats, andprint them. You will also practice using short abbreviated variable names.Programmers love saving time at your expense by using annoyingly short andcryptic variable names, so let’s get you started reading and writing them earlyon.

ex6.py

Page 51: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

1 types_of_people = 10 2 x = f"There are {types_of_people} types of people." 3 4 binary = "binary" 5 do_not = "don't" 6 y = f"Those who know {binary} and those who {do_not}." 7 8 print(x) 9 print(y)1011 print(f"I said: {x}")12 print(f"I also said: '{y}'")1314 hilarious = False15 joke_evaluation = "Isn't that joke so funny?! {}"1617 print(joke_evaluation.format(hilarious))1819 w = "This is the left side of..."20 e = "a string with a right side."2122 print(w + e)

What You Should See

Exercise 6 Session

$ python3.6 ex6.pyThere are 10 types of people.Those who know binary and those who don't.I said: There are 10 types of people.I also said: 'Those who know binary and those who don't.'Isn't that joke so funny?! FalseThis is the left side of...a string with a right side.

Study Drills

1. Go through this program and write a comment above each line explainingit.

2. Find all the places where a string is put inside a string. There are fourplaces.

Page 52: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

3. Are you sure there are only four places? How do you know? Maybe I likelying.

4. Explain why adding the two strings w and e with + makes a longer string.

Break It

You are now at a point where you can try to break your code to see whathappens. Think of this as a game to devise the most clever way to break thecode. You can also find the simplest way to break it. Once you break thecode, you then need to fix it. If you have a friend, then the two of you can tryto break each other’s code and fix it. Give your friend your ex6.py file sothey can break something. Then you try to find their error and fix it. Have funwith this, and remember that if you wrote this code once you can do it again.If you take your damage too far, you can always type it in again for extrapractice.

Common Student Questions

Why do you put ' (single-quotes) around some strings and not others?Mostly it’s because of style, but I’ll use a single-quote inside a string that hasdouble-quotes. Look at lines 6 and 15 to see how I’m doing that.

If you thought the joke was funny could you write hilarious = True?Yes, and you’ll learn more about these boolean values in Exercise 27.

Page 53: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 7. More PrintingNow we are going to do a bunch of exercises where you just type code in andmake it run. I won’t be explaining this exercise because it is more of thesame. The purpose is to build up your chops. See you in a few exercises, anddo not skip! Do not paste!

ex7.py

1 print("Mary had a little lamb.") 2 print("Its fleece was white as {}.".format('snow')) 3 print("And everywhere that Mary went.") 4 print("." * 10) # what'd that do? 5 6 end1 = "C" 7 end2 = "h" 8 end3 = "e" 9 end4 = "e"10 end5 = "s"11 end6 = "e"12 end7 = "B"13 end8 = "u"14 end9 = "r"15 end10 = "g"16 end11 = "e"17 end12 = "r"1819 # watch that comma at the end. try removing it to see what happens20 print(end1 + end2 + end3 + end4 + end5 + end6, end=' ')21 print(end7 + end8 + end9 + end10 + end11 + end12)

What You Should See

Exercise 7 Session

$ python3.6 ex7.pyMary had a little lamb.Its fleece was white as snow.And everywhere that Mary went.

Page 54: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

..........Cheese Burger

Study Drills

For these next few exercises, you will have the exact same Study Drills.

1. Go back through and write a comment on what each line does.

2. Read each one backward or out loud to find your errors.

3. From now on, when you make mistakes, write down on a piece of paperwhat kind of mistake you made.

4. When you go to the next exercise, look at the mistakes you have made andtry not to make them in this new one.

5. Remember that everyone makes mistakes. Programmers are like magicianswho fool everyone into thinking they are perfect and never wrong, but it’s allan act. They make mistakes all the time.

Break It

Did you have fun breaking the code in Exercise 6? From now on you’regoing to break all the code you write or a friend’s code. I won’t have a BreakIt section explicitly in every exercise, but I will do this in almost everyvideo. Your goal is to find as many different ways to break your code untilyou get tired or exhaust all possibilities. In some exercises I might point out aspecific common way people break that exercise’s code, but otherwiseconsider this a standing order to always break it.

Common Student Questions

Why are you using the variable named ’snow’? That’s actually not avariable: it is just a string with the word snow in it. A variable wouldn’t havethe single-quotes around it.

Page 55: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Is it normal to write an English comment for every line of code like yousay to do in Study Drill 1? No, you write comments only to explain difficultto understand code or why you did something. Why is usually much moreimportant, and then you try to write the code so that it explains howsomething is being done on its own. However, sometimes you have to writesuch nasty code to solve a problem that it does need a comment on every line.In this case it’s strictly for you to practice translating code to English.

Can I use single-quotes or double-quotes to make a string or do they dodifferent things? In Python either way to make a string is acceptable,although typically you’ll use single-quotes for any short strings like 'a' or'snow'.

Page 56: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 8. Printing, PrintingWe will now see how to do a more complicated formatting of a string. Thiscode looks complex, but if you do your comments above each line and breakeach thing down to its parts, you’ll understand it.

ex8.py

1 formatter = "{} {} {} {}" 2 3 print(formatter.format(1, 2, 3, 4)) 4 print(formatter.format("one", "two", "three", "four")) 5 print(formatter.format(True, False, False, True)) 6 print(formatter.format(formatter, formatter, formatter, formatter)) 7 print(formatter.format( 8 "Try your", 9 "Own text here",10 "Maybe a poem",11 "Or a song about fear"12 ))

What You Should See

Exercise 8 Session

$ python3.6 ex8.py1 2 3 4one two three fourTrue False False True{} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}Try your Own text here Maybe a poem Or a song about fear

In this exercise I’m using something called a “function” to turn theformatter variable into other strings. When you see me writeformatter.format(...) I’m telling python to do the following:

1. Take the formatter string defined on line 1.

2. Call its format function, which is similar to telling it to do a command line

Page 57: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

command named format.

3. Pass to format four arguments, which match up with the four {} in theformatter variable. This is like passing arguments to the command linecommand format.

4. The result of calling format on formatter is a new string that has the {}replaced with the four variables. This is what print is now printing out.

That’s a lot for the eighth exercise, so what I want you to do is consider this abrain teaser. It’s alright if you don’t really understand what’s going onbecause the rest of the book will slowly make this clear. At this point, try tostudy this and see what’s going on, then move on to the next exercise.

Study Drills

1. Do your checks, write down your mistakes, and try not to make the samemistakes on the next exercise.

Common Student Questions

Why do I have to put quotes around “one” but not around True orFalse? Python recognizes True and False as keywords representing theconcept of true and false. If you put quotes around them then they are turnedinto strings and won’t work. You’ll learn more about how these work inExercise 27.

Can I use IDLE to run this? No, you should learn to use the command line.It is essential to learning programming and is a good place to start if you wantto learn about programming. IDLE will fail for you when you get further inthe book.

Page 58: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 9. Printing, Printing, PrintingBy now you should realize the pattern for this book is to use more than oneexercise to teach you something new. I start with code that you might notunderstand, then more exercises explain the concept. If you don’t understandsomething now, you will later as you complete more exercises. Write downwhat you don’t understand, and keep going.

ex9.py

1 # Here's some new strange stuff, remember type it exactly. 2 3 days = "Mon Tue Wed Thu Fri Sat Sun" 4 months = "Jan\nFeb\nMar\nApr\nMay\nJun\nJul\nAug" 5 6 print("Here are the days: ", days) 7 print("Here are the months: ", months) 8 9 print("""10 There's something going on here.11 With the three double-quotes.12 We'll be able to type as much as we like.13 Even 4 lines if we want, or 5, or 6.14 """)

What You Should See

Exercise 9 Session

$ python3.6 ex9.pyHere are the days: Mon Tue Wed Thu Fri Sat SunHere are the months: JanFebMarAprMayJunJulAug

Page 59: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

There's something going on here.With the three double-quotes.We'll be able to type as much as we like.Even 4 lines if we want, or 5, or 6.

Study Drills

1. Check your work, write down your mistakes, try not to make them on thenext exercise.

2. Are you breaking your code and then fixing it?

Common Student Questions

Why do I get an error when I put spaces between the three double-quotes? You have to type them like """ and not " " ", meaning with nospaces between each one.

What if I wanted to start the months on a new line? You simply start thestring with \n like this: ” \ nJan \ nFeb \ nMar \ nApr \ nMay \ nJun \ nJul \nAug”

Is it bad that my errors are always spelling mistakes? Most programmingerrors in the beginning (and even later) are simple spelling mistakes, typos, orgetting simple things out of order.

Page 60: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 10. What Was That?In Exercise 9 I threw you some new stuff, just to keep you on your toes. Ishowed you two ways to make a string that goes across multiple lines. In thefirst way, I put the characters \n (backslash n) between the names of themonths. These two characters put a new line character into the string atthat point.

This \ (backslash) character encodes difficult-to-type characters into a string.There are various “escape sequences” available for different characters youmight want to use. We’ll try a few of these sequences so you can see what Imean.

An important escape sequence is to escape a single-quote ' or double-quote". Imagine you have a string that uses double-quotes and you want to put adouble-quote inside the string. If you write "I "understand" joe." thenPython will get confused because it will think the " around "understand"actually ends the string. You need a way to tell Python that the " inside thestring isn’t a real double-quote.

To solve this problem you escape double-quotes and single-quotes so Pythonknows to include them in the string. Here’s an example:

"I am 6'2\" tall." # escape double—quote inside string'I am 6\'2" tall.' # escape single—quote inside string

The second way is by using triple-quotes, which is just """ and works like astring, but you also can put as many lines of text as you want until you type""" again. We’ll also play with these.

ex10.py

1 tabby_cat = "\tI'm tabbed in." 2 persian_cat = "I'm split\non a line." 3 backslash_cat = "I'm \\ a \\ cat." 4 5 fat_cat = """

Page 61: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

6 I'll do a list: 7 \t* Cat food 8 \t* Fishies 9 \t* Catnip\n\t* Grass10 """1112 print(tabby_cat)13 print(persian_cat)14 print(backslash_cat)15 print(fat_cat)

What You Should See

Look for the tab characters that you made. In this exercise the spacing isimportant to get right.

$ python ex10 . py I'm tabbed in.I'm spliton a line.I'm \ a \ cat .

I'll do a list: * Cat food * Fishies * Catnip * Grass

Escape Sequences

This is all of the escape sequences Python supports. You may not use manyof these, but memorize their format and what they do anyway. Try them outin some strings to see if you can make them work.

Page 62: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Study Drills

1. Memorize all the escape sequences by putting them on flash cards.

2. Use ''' (triple-single-quote) instead. Can you see why you might use thatinstead of """?

3. Combine escape sequences and format strings to create a more complexformat.

Common Student Questions

I still haven’t completely figured out the last exercise. Should I continue?Yes, keep going. Instead of stopping, take notes listing things you don’tunderstand for each exercise. Periodically go through your notes and see ifyou can figure these things out after you’ve completed more exercises.Sometimes, though, you may need to go back a few exercises and do themagain.

What makes \\ special compared to the other ones? It’s simply the way

Page 63: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

you would write out one backslash (\) character. Think about why you wouldneed this.

When I write // or /n it doesn’t work. That’s because you are using aforward-slash / and not a backslash \. They are different characters that dovery different things.

I don’t get Study Drill 3. What do you mean by “combine” escapesequences and formats? One concept I need you to understand is that eachof these exercises can be combined to solve problems. Take what you knowabout format strings and write some new code that uses format strings andthe escape sequences from this exercise.

What’s better, ''' or """? It’s entirely based on style. Go with the '''(triple-single-quote) style for now, but be ready to use either depending onwhat feels best or what everyone else is doing.

Page 64: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 11. Asking QuestionsNow it is time to pick up the pace. You are doing a lot of printing to get youfamiliar with typing simple things, but those simple things are fairly boring.What we want to do now is get data into your programs. This is a little trickybecause you have to learn to do two things that may not make sense rightaway, but trust me and do it anyway. It will make sense in a few exercises.

Most of what software does is the following:

1. Take some kind of input from a person.

2. Change it.

3. Print out something to show how it changed.

So far you have been printing strings, but you haven’t been able to get anyinput from a person. You may not even know what “input” means, but typethis code in anyway and make it exactly the same. In the next exercise we’lldo more to explain input.

ex11.py

1 print("How old are you?", end=' ')2 age = input()3 print("How tall are you?", end=' ')4 height = input()5 print("How much do you weigh?", end=' ')6 weight = input()78 print(f"So, you're {age} old, {height} tall and {weight} heavy."

Warning!

We put a end=' ' at the end of each print line. This tells print to not endthe line with a newline character and go to the next line.

Page 65: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

What You Should See

Exercise 11 Session

$ python3.6 ex11.pyHow old are you? 38How tall are you? 6'2"How much do you weigh? 180lbsSo, you're 38 old, 6'2" tall and 180lbs heavy.

Study Drills

1. Go online and find out what Python’s input does.

2. Can you find other ways to use it? Try some of the samples you find.

3. Write another “form” like this to ask some other questions.

Common Student Questions

How do I get a number from someone so I can do math? That’s a littleadvanced, but try x = int(input()), which gets the number as a string frominput() then converts it to an integer using int().

I put my height into raw input like this input("6'2") but it doesn’t work.You don’t put your height in there, you type it directly into your terminal.First thing is, go back and make the code exactly like mine. Next, run thescript, and when it pauses, type your height in at your keyboard. That’s allthere is to it.

Page 66: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 12. Prompting PeopleWhen you typed input() you were typing the ( and ) characters, which areparenthesis characters. This is similar to when you used them to do aformat with extra variables, as in f"{x} {y}". For input you can also put ina prompt to show to a person so he knows what to type. Put a string that youwant for the prompt inside the () so that it looks like this:

y = input("Name?")

This prompts the user with “Name?” and puts the result into the variable y.This is how you ask someone a question and get the answer.

This means we can completely rewrite our previous exercise using just inputto do all the prompting.

ex12.py

1 age = input("How old are you? ")2 height = input("How tall are you? ")3 weight = input("How much do you weigh? ")45 print(f"So, you're {age} old, {height} tall and {weight} heavy."

What You Should See

Exercise 12 Session

$ python3.6 ex12.pyHow old are you? 38How tall are you? 6'2"How much do you weigh? 180lbsSo, you're 38 old, 6'2" tall and 180lbs heavy.

Study Drills

Page 67: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

1. In Terminal, where you normally run python3.6 to run your scripts, typepydoc input. Read what it says. If you’re on Windows try python3.6 -mpydoc input instead.

2. Get out of pydoc by typing q to quit.

3. Look online for what the pydoc command does.

4. Use pydoc to also read about open, file, os, and sys. It’s alright if you donot understand those; just read through and take notes about interestingthings.

Common Student Questions

How come I get SyntaxError: invalid syntax whenever I run pydoc?You aren’t running pydoc from the command line; you’re probably running itfrom inside python3.6. Exit out of python3.6 first.

Why does my pydoc not pause like yours does? Sometimes if the helpdocument is short enough to fit on one screen then pydoc will just print it.

When I run pydoc I get more is not recognized as an internal. Someversions of Windows do not have that command, which means pydoc isbroken for you. You can skip this Study Drill and just search online forPython documentation when you need it.

Why can’t I do print("How old are you?", input())? You can, but thenthe result of calling input() is never saved to a variable, and it’ll work in astrange way. Try this, and then try to print out what you type. See if you candebug why this isn’t working.

Page 68: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 13. Parameters, Unpacking,VariablesIn this exercise we will cover one more input method you can use to passvariables to a script (script being another name for your .py files). You knowhow you type python3.6 ex13.py to run the ex13.py file? Well the ex13.pypart of the command is called an “argument.” What we’ll do now is write ascript that also accepts arguments.

Type this program and I’ll explain it in detail:

ex13.py

1 from sys import argv2 # read the WYSS section for how to run this3 script, first, second, third = argv45 print("The script is called:", script)6 print("Your first variable is:", first)7 print("Your second variable is:", second)8 print("Your third variable is:", third)

On line 1 we have what’s called an “import.” This is how you add features toyour script from the Python feature set. Rather than give you all the featuresat once, Python asks you to say what you plan to use. This keeps yourprograms small, but it also acts as documentation for other programmers whoread your code later.

The argv is the “argument variable,” a very standard name in programmingthat you will find used in many other languages. This variable holds thearguments you pass to your Python script when you run it. In the exercisesyou will get to play with this more and see what happens.

Line 3 “unpacks” argv so that, rather than holding all the arguments, it getsassigned to four variables you can work with: script, first, second, andthird. This may look strange, but “unpack” is probably the best word to

Page 69: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

describe what it does. It just says, “Take whatever is in argv, unpack it, andassign it to all of these variables on the left in order.”

After that we just print them out like normal.

Hold Up! Features Have Another Name

I call them “features” here (these little things you import to make yourPython program do more) but nobody else calls them features. I just used thatname because I needed to trick you into learning what they are withoutjargon. Before you can continue, you need to learn their real name: modules.

From now on we will be calling these “features” that we import modules. I’llsay things like, “You want to import the sys module.” They are also called“libraries” by other programmers, but let’s just stick with modules.

What You Should See

Warning!

Pay attention! You have been running python scripts without command linearguments. If you type only python3.6 ex13.py you are doing it wrong! Payclose attention to how I run it. This applies any time you see argv being used.

Run the program like this (and you must pass three command linearguments):

Exercise 13 Session

$ python3.6 ex13.py first 2nd 3rdThe script is called: ex13.pyYour first variable is: firstYour second variable is: 2ndYour third variable is: 3rd

Page 70: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

This is what you should see when you do a few different runs with differentarguments:

Exercise 13 Session

$ python3.6 ex13.py stuff things thatThe script is called: ex13.pyYour first variable is: stuffYour second variable is: thingsYour third variable is: that$$ python3.6 ex13.py apple orange grapefruitThe script is called: ex13.pyYour first variable is: appleYour second variable is: orangeYour third variable is: grapefruit

You can actually replace first, 2nd, and 3rd with any three things you want.

If you do not run it correctly, then you will get an error like this:

Exercise 13 Session

$ python3.6 ex13.py first 2ndTraceback (most recent call last): File "ex13.py", line 3, in <module> script, first, second, third = argvValueError: not enough values to unpack (expected 4, got 3)

This happens when you do not put enough arguments on the command whenyou run it (in this case just first 2nd). Notice that when I run it I give itfirst 2nd, which caused it to give an error about “need more than 3 valuesto unpack” telling you that you didn’t give it enough parameters.

Study Drills

1. Try giving fewer than three arguments to your script. See that error youget? See if you can explain it.

2. Write a script that has fewer arguments and one that has more. Make sure

Page 71: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

you give the unpacked variables good names.

3. Combine input with argv to make a script that gets more input from auser. Don’t overthink it. Just use argv to get something, and input to getsomething else from the user.

4. Remember that modules give you features. Modules. Modules. Rememberthis because we’ll need it later.

Common Student Questions

When I run it I get ValueError: need more than 1 value to unpack.Remember that an important skill is paying attention to details. If you look atthe What You Should See section you see that I run the script with parameterson the command line. You should replicate how I ran it exactly.

What’s the difference between argv and input()? The difference has to dowith where the user is required to give input. If they give your script inputson the command line, then you use argv. If you want them to input using thekeyboard while the script is running, then use input().

Are the command line arguments strings? Yes, they come in as strings,even if you typed numbers on the command line. Use int() to convert themjust like with int(input()).

How do you use the command line? You should have learned to use it veryquickly and fluently by now, but if you need to learn it at this stage, then readthe Command Line Crash Course I wrote for this book in Appendix A.

I can’t combine argv with input(). Don’t overthink it. Just slap two lines atthe end of this script that uses input() to get something and then print it.From that, start playing with more ways to use both in the same script.

Why can’t I do this input('? ') = x? Because that’s backward to how itshould work. Do it the way I do it and it’ll work.

Page 72: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 14. Prompting and PassingLet’s do one exercise that uses argv and input together to ask the usersomething specific. You will need this for the next exercise where you learnto read and write files. In this exercise we’ll use input slightly differently byhaving it print a simple > prompt. This is similar to a game like Zork orAdventure.

ex14.py

1 from sys import argv 2 3 script, user_name = argv 4 prompt = '> ' 5 6 print(f"Hi {user_name}, I'm the {script} script.") 7 print("I'd like to ask you a few questions.") 8 print(f"Do you like me {user_name}?") 9 likes = input(prompt)1011 print(f"Where do you live {user_name}?")12 lives = input(prompt)1314 print("What kind of computer do you have?")15 computer = input(prompt)1617 print(f"""18 Alright, so you said {likes} about liking me.19 You live in {lives}. Not sure where that is.20 And you have a {computer} computer. Nice.21 """)

We make a variable prompt that is set to the prompt we want, and we givethat to input instead of typing it over and over. Now if we want to make theprompt something else, we just change it in this one spot and rerun the script.Very handy.

What You Should See

Page 73: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

When you run this, remember that you have to give the script your name forthe argv arguments.

Exercise 14 Session

$ python3.6 ex14.py zedHi zed, I'm the ex14.py script.I'd like to ask you a few questions.Do you like me zed?> YesWhere do you live zed?> San FranciscoWhat kind of computer do you have?> Tandy 1000

Alright, so you said Yes about liking me.You live in San Francisco. Not sure where that is.And you have a Tandy 1000 computer. Nice.

Study Drills

1. Find out what the games Zork and Adventure were. Try to find a copy andplay it.

2. Change the prompt variable to something else entirely.

3. Add another argument and use it in your script, the same way you did inthe previous exercise with first, second = ARGV.

4. Make sure you understand how I combined a """ style multiline stringwith the {} format activator as the last print.

Common Student Questions

I get SyntaxError: invalid syntax when I run this script. Again, youhave to run it right on the command line, not inside Python. If you typepython3.6, and then try to type python3.6 ex14.py Zed it will fail becauseyou are running Python inside Python. Close your window and then just typepython3.6 ex14.py Zed.

Page 74: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

I don’t understand what you mean by changing the prompt? See thevariable prompt = '> '. Change that to have a different value. You knowthis; it’s just a string and you’ve done 13 exercises making them, so take thetime to figure it out.

I get the error ValueError: need more than 1 value to unpack.Remember when I said you need to look at the What You Should See (WYSS)section and replicate what I did? You need to do the same thing here, andfocus on how I type the command in and why I have a command lineargument.

How can I run this from IDLE? Don’t use IDLE.

Can I use double-quotes for the prompt variable? You totally can. Goahead and try that.

You have a Tandy computer? I did when I was little.

I get NameError: name 'prompt' is not defined when I run it. Youeither spelled the name of the prompt variable wrong or forgot that line. Goback and compare each line of code to mine, from at the bottom of the scriptto the top. Any time you see this error, it means you spelled something wrongor forgot to create the variable.

Page 75: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 15. Reading FilesYou know how to get input from a user with input or argv. Now you willlearn about reading from a file. You may have to play with this exercise themost to understand what’s going on, so do the exercise carefully andremember your checks. Working with files is an easy way to erase your workif you are not careful.

This exercise involves writing two files. One is the usual ex15.py file thatyou will run, but the other is named ex15_sample.txt. This second file isn’ta script but a plain text file we’ll be reading in our script. Here are thecontents of that file:

This is stuff I typed into a file.It is really cool stuff.Lots and lots of fun to have in here.

What we want to do is “open” that file in our script and print it out. However,we do not want to just “hard code” the name ex15_sample.txt into ourscript. “Hard coding” means putting some bit of information that shouldcome from the user as a string directly in our source code. That’s bad becausewe want it to load other files later. The solution is to use argv or input to askthe user what file to open instead of “hard coding” the file’s name.

ex15.py

1 from sys import argv 2 3 script, filename = argv 4 5 txt = open(filename) 6 7 print(f"Here's your file {filename}:") 8 print(txt.read()) 910 print("Type the filename again:")11 file_again = input("> ")12

Page 76: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

13 txt_again = open(file_again)1415 print(txt_again.read())

A few fancy things are going on in this file, so let’s break it down realquickly:

Lines 1-3 uses argv to get a filename. Next we have line 5, where we use anew command open. Right now, run pydoc open and read the instructions.Notice how, like your own scripts and input, it takes a parameter and returnsa value you can set to your own variable. You just opened a file.

Line 7 prints a little message, but on line 8 we have something very new andexciting. We call a function on txt named read. What you get back fromopen is a file, and it also has commands you can give it. You give a file acommand by using the . (dot or period), the name of the command, andparameters, just like with open and input. The difference is that txt.read()says, “Hey txt! Do your read command with no parameters!”

The remainder of the file is more of the same, but we’ll leave the analysis toyou in the Study Drills.

What You Should See

Warning!

Pay attention! I said pay attention! You have been running scripts with justthe name of the script, but now that you are using argv you have to addarguments. Look at the very first line of the example below and you will see Ido python ex15.py ex15_sample.txt to run it. See the extra argumentex15_sample.txt after the ex15.py script name. If you do not type that youwill get an error so pay attention!

I made a file called ex15_sample.txt and ran my script.

Exercise 15 Session

Page 77: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

$ python3.6 ex15.py ex15_sample.txtHere's your file ex15_sample.txt:This is stuff I typed into a file.It is really cool stuff.Lots and lots of fun to have in here.

Type the filename again:> ex15_sample.txtThis is stuff I typed into a file.It is really cool stuff.Lots and lots of fun to have in here.

Study Drills

This is a big jump, so be sure you do this Study Drill as best you can beforemoving on.

1. Above each line, write out in English what that line does.

2. If you are not sure, ask someone for help or search online. Many timessearching for “python3.6 THING” will find answers to what that THINGdoes in Python. Try searching for “python3.6 open.”

3. I used the word “commands” here, but commands are also called“functions” and “methods.” You will learn about functions and methods laterin the book.

4. Get rid of the lines 10-15 where you use input and run the script again.

5. Use only input and try the script that way. Why is one way of getting thefilename better than another?

6. Start python3.6 to start the python3.6 shell, and use open from the promptjust like in this program. Notice how you can open files and run read on themfrom within python3.6?

7. Have your script also call close() on the txt and txt_again variables. It’simportant to close files when you are done with them.

Page 78: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Common Student Questions

Does txt = open(filename) return the contents of the file? No, it doesn’t.It actually makes something called a “file object.” You can think of a file likean old tape drive that you saw on mainframe computers in the 1950s or evenlike a DVD player from today. You can move around inside them and then“read” them, but the DVD player is not the DVD the same way the file objectis not the file’s contents.

I can’t type code into Terminal/PowerShell like you say in Study Drill 7.First thing, from the command line just type python3.6 and press Enter. Nowyou are in python3.6 as we’ve done a few other times. Then you can type incode and Python will run it in little pieces. Play with that. To get out of ittype quit() and hit Enter.

Why is there no error when we open the file twice? Python will not restrictyou from opening a file more than once, and sometimes this is necessary.

What does from sys import argv mean? For now just understand that sysis a package, and this phrase just says to get the argv feature from thatpackage. You’ll learn more about these later.

I put the name of the file in as script, ex15_sample.txt = argv, but itdoesn’t work. No, that’s not how you do it. Make the code exactly like mine,then run it from the command line the exact same way I do. You don’t put thenames of files in, you let Python put the name in.

Page 79: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 16. Reading and Writing FilesIf you did the Study Drills from the last exercise, you should have seen allsorts of commands (methods/functions) you can give to files. Here’s the listof commands I want you to remember:

• close – Closes the file. Like File->Save.. in your editor.

• read – Reads the contents of the file. You can assign the result to a variable.

• readline – Reads just one line of a text file.

• truncate – Empties the file. Watch out if you care about the file.

• write('stuff') – Writes “stuff” to the file.

• seek(0) – Move the read/write location to the beginning of the file.

One way to remember what each of these does is to think of a vinyl record,cassette tape, VHS tape, DVD, or CD player. In the early days of computersdata was stored on each of these kinds of media, so many of the fileoperations still resemble a storage system that is linear. Tape and DVD drivesneed to “seek” a specific spot, and then you can read or write at that spot.Today we have operating systems and storage media that blur the linesbetween random access memory and disk drives, but we still use the olderidea of a linear tape with a read/write head that must be moved.

For now, these are the important commands you need to know. Some of themtake parameters, but we do not really care about that. You only need toremember that write takes a parameter of a string you want to write to thefile.

Let’s use some of this to make a simple little text editor:

ex16.py

Page 80: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

1 from sys import argv 2 3 script, filename = argv 4 5 print(f"We're going to erase {filename}.") 6 print("If you don't want that, hit CTRL-C (^C).") 7 print("If you do want that, hit RETURN.") 8 9 input("?")1011 print("Opening the file...")12 target = open(filename, 'w')1314 print("Truncating the file. Goodbye!")15 target.truncate()1617 print("Now I'm going to ask you for three lines.")1819 line1 = input("line 1: ")20 line2 = input("line 2: ")21 line3 = input("line 3: ")2223 print("I'm going to write these to the file.")2425 target.write(line1)26 target.write("\n")27 target.write(line2)28 target.write("\n")29 target.write(line3)30 target.write("\n")3132 print("And finally, we close it.")33 target.close()

That’s a large file, probably the largest you have typed in. So go slow, doyour checks, and make it run. One trick is to get bits of it running at a time.Get lines 1-8 running, then five more, then a few more, until it’s all done andrunning.

What You Should See

There are actually two things you will see. First the output of your new script:

Exercise 16 Session

Page 81: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

$ python3.6 ex16.py test.txtWe're going to erase test.txt.If you don't want that, hit CTRL-C (^C).If you do want that, hit RETURN.?Opening the file...Truncating the file. Goodbye!Now I'm going to ask you for three lines.line 1: Mary had a little lambline 2: Its fleece was white as snowline 3: It was also tastyI'm going to write these to the file.And finally, we close it.

Now, open up the file you made (in my case test.txt) in your editor andcheck it out. Neat, right?

Study Drills

1. If you do not understand this, go back through and use the comment trickto get it squared away in your mind. One simple English comment aboveeach line will help you understand or at least let you know what you need toresearch more.

2. Write a script similar to the last exercise that uses read and argv to readthe file you just created.

3. There’s too much repetition in this file. Use strings, formats, and escapesto print out line1, line2, and line3 with just one target.write() commandinstead of six.

4. Find out why we had to pass a 'w' as an extra parameter to open. Hint:open tries to be safe by making you explicitly say you want to write a file.

5. If you open the file with 'w' mode, then do you really need thetarget.truncate()? Read the documentation for Python’s open functionand see if that’s true.

Common Student Questions

Page 82: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Is the truncate() necessary with the 'w' parameter? See Study Drills 5.

What does 'w' mean? It’s really just a string with a character in it for thekind of mode for the file. If you use 'w' then you’re saying “open this file in’write’ mode,” thus the 'w' character. There’s also 'r' for “read,” 'a' forappend, and modifiers on these.

What modifiers to the file modes can I use? The most important one toknow for now is the + modifier, so you can do 'w+', 'r+', and 'a+'. Thiswill open the file in both read and write mode and, depending on thecharacter use, position the file in different ways.

Does just doing open(filename) open it in 'r' (read) mode? Yes, that’sthe default for the open() function.

Page 83: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 17. More FilesNow let’s do a few more things with files. We’ll write a Python script to copyone file to another. It’ll be very short but will give you ideas about otherthings you can do with files.

ex17.py

1 from sys import argv 2 from os.path import exists 3 4 script, from_file, to_file = argv 5 6 print(f"Copying from {from_file} to {to_file}") 7 8 # we could do these two on one line, how? 9 in_file = open(from_file)10 indata = in_file.read()1112 print(f"The input file is {len(indata)} bytes long")1314 print(f"Does the output file exist? {exists(to_file)}")15 print("Ready, hit RETURN to continue, CTRL-C to abort.")16 input()1718 out_file = open(to_file, 'w')19 out_file.write(indata)2021 print("Alright, all done.")2223 out_file.close()24 in_file.close()

You should immediately notice that we import another handy commandnamed exists. This returns True if a file exists, based on its name in a stringas an argument. It returns False if not. We’ll be using this function in thesecond half of this book to do lots of things, but right now you should seehow you can import it.

Using import is a way to get tons of free code other better (well, usually)

Page 84: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

programmers have written so you do not have to write it.

What You Should See

Just like your other scripts, run this one with two arguments: the file to copyfrom and the file to copy it to. I’m going to use a simple test file namedtest.txt:

Exercise 17 Session

$ # first make a sample file $echo "This is a test file." > test.txt$ # then look at it$ cat test.txtThis is a test file.$ # now run our script on it$ python3.6 ex17.py test.txt new_file.txtCopying from test.txt to new_file.txtThe input file is 21 bytes longDoes the output file exist? FalseReady, hit RETURN to continue, CTRL-C to abort.

Alright, all done.

It should work with any file. Try a bunch more and see what happens. Just becareful you do not blast an important file.

Warning!

Did you see the trick I did with echo to make a file and cat to show the file?You can learn how to do that in Appendix A, “Command Line CrashCourse.”

Study Drills

1. This script is really annoying. There’s no need to ask you before doing thecopy, and it prints too much out to the screen. Try to make the script more

Page 85: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

friendly to use by removing features.

2. See how short you can make the script. I could make this one line long.

3. Notice at the end of the What You Should See I used something called cat?It’s an old command that “con*cat*enates” files together, but mostly it’s justan easy way to print a file to the screen. Type man cat to read about it.

4. Find out why you had to write out_file.close() in the code.

5. Go read up on Python’s import statement, and start python3.6 to try it out.Try importing some things and see if you can get it right. It’s alright if you donot.

Common Student Questions

Why is the 'w' in quotes? That’s a string. You’ve been using strings for awhile now. Make sure you know what a string is.

No way you can make this one line! That ; depends ; on ; how ; you ; define; one ; line ; of ; code.

Is it normal to feel like this exercise was really hard? Yes, it is totallynormal. Programming may not “click” for you until maybe even Exercise 36,or it might not until you finish the book and then make something withPython. Everyone is different, so just keep going and keep reviewingexercises that you had trouble with until it clicks. Be patient.

What does the len() function do? It gets the length of the string that youpass to it then returns that as a number. Play with it.

When I try to make this script shorter I get an error when I close thefiles at the end. You probably did something like this, indata =open(from_file).read(), which means you don’t need to then doin_file.close() when you reach the end of the script. It should already beclosed by Python once that one line runs.

I get a Syntax:EOL while scanning string literal error. You forgot to

Page 86: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

end a string properly with a quote. Go look at that line again.

Page 87: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 18. Names, Variables, Code,FunctionsBig title, right? I am about to introduce you to the function! Dum dum dah!Every programmer will go on and on about functions and all the differentideas about how they work and what they do, but I will give you the simplestexplanation you can use right now.

Functions do three things:

1. They name pieces of code the way variables name strings and numbers.

2. They take arguments the way your scripts take argv.

3. Using 1 and 2, they let you make your own "mini-scripts" or "tinycommands."

You can create a function by using the word def in Python. I'm going to haveyou make four different functions that work like your scripts, and I'll thenshow you how each one is related.

ex18.py

1 # this one is like your scripts with argv 2 def print_two(*args): 3 arg1, arg2 = args 4 print(f"arg1: {arg1}, arg2: {arg2}") 5 6 # ok, that *args is actually pointless, we can just do this 7 def print_two_again(arg1, arg2): 8 print(f"arg1: {arg1}, arg2: {arg2}") 910 # this just takes one argument11 def print_one(arg1):12 print(f"arg1: {arg1}")1314 # this one takes no arguments15 def print_none():

Page 88: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

16 print("I got nothin'.")171819 print_two("Zed","Shaw")20 print_two_again("Zed","Shaw")21 print_one("First!")22 print_none()

Let's break down the first function, print_two, which is the most similar towhat you already know from making scripts:

1. First we tell Python we want to make a function using def for "define".

2. On the same line as def we give the function a name. In this case we justcalled it "print_two," but it could also be "peanuts." It doesn't matter, exceptthat your function should have a short name that says what it does.

3. Then we tell it we want *args (asterisk args), which is a lot like your argvparameter but for functions. This has to go inside () parentheses to work.

4. Then we end this line with a : (colon) and start indenting.

5. After the colon all the lines that are indented four spaces will becomeattached to this name, print_two. Our first indented line is one that unpacksthe arguments, the same as with your scripts.

6. To demonstrate how it works we print these arguments out, just like wewould in a script.

The problem with print_two is that it's not the easiest way to make afunction. In Python we can skip the whole unpacking arguments and just usethe names we want right inside (). That's what print_two_again does.

After that you have an example of how you make a function that takes oneargument in print_one.

Finally you have a function that has no arguments in print_none.

Warning!

Page 89: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

This is very important. Do not get discouraged right now if this doesn't quitemake sense. We're going to do a few exercises linking functions to yourscripts and show you how to make more. For now, just keep thinking "mini-script" when I say "function" and keep playing with them.

What You Should See

If you run ex18.py you should see:

Exercise 18 Session

$ python3.6 ex18.pyarg1: Zed, arg2: Shawarg1: Zed, arg2: Shawarg1: First!I got nothin'.

Right away you can see how a function works. Notice that you used yourfunctions the way you use things like exists, open, and other "commands."In fact, I've been tricking you because in Python those "commands" are justfunctions. This means you can make your own commands and use them inyour scripts too.

Study Drills

Create a function checklist for later exercises. Write these checks on an indexcard and keep it by you while you complete the rest of these exercises or untilyou feel you do not need the index card anymore:

1. Did you start your function definition with def?

2. Does your function name have only characters and _ (underscore)characters?

3. Did you put an open parenthesis ( right after the function name?

Page 90: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

4. Did you put your arguments after the parenthesis ( separated by commas?

5. Did you make each argument unique (meaning no duplicated names)?

6. Did you put a close parenthesis and a colon ): after the arguments?

7. Did you indent all lines of code you want in the function four spaces? Nomore, no less.

8. Did you "end" your function by going back to writing with no indent(dedenting we call it)?

When you run ("use" or "call") a function, check these things:

1. Did you call/use/run this function by typing its name?

2. Did you put the ( character after the name to run it?

3. Did you put the values you want into the parenthesis separated bycommas?

4. Did you end the function call with a ) character?

Use these two checklists on the remaining lessons until you do not need themanymore.

Finally, repeat this a few times to yourself:

"To 'run, ' 'call, ' or 'use' a function all mean the same thing."

Common Student Questions

What's allowed for a function name? The same as variable names.Anything that doesn't start with a number and is letters, numbers, andunderscores will work.

What does the * in *args do? That tells Python to take all the arguments tothe function and then put them in args as a list. It's like argv that you've been

Page 91: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

using but for functions. It's not normally used too often unless specificallyneeded.

This feels really boring and monotonous. That's good. It means you'restarting to get better at typing in the code and understanding what it does. Tomake it less boring, take everything I tell you to type in, and then break it onpurpose.

Page 92: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 19. Functions and VariablesFunctions may have been a mind-blowing amount of information, but do notworry. Just keep doing these exercises and going through your checklist fromthe last exercise and you will eventually get it.

There is one tiny point that you might not have realized, which we’llreinforce right now. The variables in your function are not connected to thevariables in your script. Here’s an exercise to get you thinking about this:

ex19.py

1 def cheese_and_crackers(cheese_count, boxes_of_crackers): 2 print(f"You have {cheese_count} cheeses!") 3 print(f"You have {boxes_of_crackers} boxes of crackers!") 4 print("Man that's enough for a party!") 5 print("Get a blanket.\n") 6 7 8 print("We can just give the function numbers directly:") 9 cheese_and_crackers(20, 30)101112 print("OR, we can use variables from our script:")13 amount_of_cheese = 1014 amount_of_crackers = 501516 cheese_and_crackers(amount_of_cheese, amount_of_crackers)171819 print("We can even do math inside too:")20 cheese_and_crackers(10 + 20, 5 + 6)212223 print("And we can combine the two, variables and math:")24 cheese_and_crackers(amount_of_cheese + 100, amount_of_crackers

This shows all the different ways we’re able to give our functioncheese_and_crackers the values it needs to print them. We can give itstraight numbers. We can give it variables. We can give it math. We can even

Page 93: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

combine math and variables.

In a way, the arguments to a function are kind of like our = character whenwe make a variable. In fact, if you can use = to name something, you canusually pass it to a function as an argument.

What You Should See

You should study the output of this script and compare it with what you thinkyou should get for each of the examples in the script.

Exercise 19 Session

$ python3.6 ex19.pyWe can just give the function numbers directly:You have 20 cheeses!You have 30 boxes of crackers!Man that's enough for a party!Get a blanket.

OR, we can use variables from our script:You have 10 cheeses!You have 50 boxes of crackers!Man that's enough for a party!Get a blanket.

We can even do math inside too:You have 30 cheeses!You have 11 boxes of crackers!Man that's enough for a party!Get a blanket.

And we can combine the two, variables and math:You have 110 cheeses!You have 1050 boxes of crackers!Man that's enough for a party!Get a blanket.

Study Drills

1. Go back through the script and type a comment above each line explaining

Page 94: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

in English what it does.

2. Start at the bottom and read each line backward, saying all the importantcharacters.

3. Write at least one more function of your own design, and run it 10 differentways.

Common Student Questions

How can there possibly be 10 different ways to run a function? Believe itor not, there’s a theoretically infinite number of ways to call any function.See how creative you can get with functions, variables, and input from a user.

Is there a way to analyze what this function is doing so I can understandit better? There are many different ways, but try putting an English commentabove each line describing what the line does. Another trick is to read thecode out loud. Yet another is to print the code out and draw on the paper withpictures and comments showing what’s going on.

What if I want to ask the user for the numbers of cheese and crackers?You need to use int() to convert what you get from input().

Does making the variable amount_of_cheese change the variablecheese_count in the function? No, those variables are separate and liveoutside the function. They are then passed to the function, and temporaryversions are made just for the function’s run. When the function exits thesetemporary variables go away and everything keeps working. Keep going inthe book, and this should become clearer.

Is it bad to have global variables (like amount_of_cheese) with the samename as function variables? Yes, since then you’re not quite sure which oneyou’re talking about. But sometimes necessity means you have to use thesame name, or you might do it on accident. Just avoid it whenever you can.

Is there a limit to the number of arguments a function can have? Itdepends on the version of Python and the computer you’re on, but it is fairly

Page 95: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

large. The practical limit though is about five arguments before the functionbecomes annoying to use.

Can you call a function within a function? Yes, you’ll make a game thatdoes this later in the book.

Page 96: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 20. Functions and FilesRemember your checklist for functions, then do this exercise paying closeattention to how functions and files can work together to make useful stuff.

ex20.py

1 from sys import argv 2 3 script, input_file = argv 4 5 def print_all(f): 6 print(f.read()) 7 8 def rewind(f): 9 f.seek(0)1011 def print_a_line(line_count, f):12 print(line_count, f.readline())1314 current_file = open(input_file)1516 print("First let's print the whole file:\n")1718 print_all(current_file)1920 print("Now let's rewind, kind of like a tape.")2122 rewind(current_file)2324 print("Let's print three lines:")2526 current_line = 127 print_a_line(current_line, current_file)2829 current_line = current_line + 130 print_a_line(current_line, current_file)3132 current_line = current_line + 133 print_a_line(current_line, current_file)

Pay close attention to how we pass in the current line number each time we

Page 97: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

run print_a_line.

What You Should See

Exercise 20 Session

$ python3.6 ex20.py test.txtFirst let's print the whole file:

This is line 1This is line 2This is line 3

Now let's rewind, kind of like a tape.Let's print three lines:1 This is line 1

2 This is line 2

3 This is line 3

Study Drills

1. Write English comments for each line to understand what that line does.

2. Each time print_a_line is run, you are passing in a variablecurrent_line. Write out what current_line is equal to on each functioncall, and trace how it becomes line_count in print_a_line.

3. Find each place a function is used, and check its def to make sure that youare giving it the right arguments.

4. Research online what the seek function for file does. Try pydoc file,and see if you can figure it out from there. Then try pydoc file.seek to seewhat seek does.

5. Research the shorthand notation +=, and rewrite the script to use += instead.

Page 98: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Common Student Questions

What is f in the print_all and other functions? The f is a variable justlike you had in other functions in Exercise 18, except this time it’s a file. Afile in Python is kind of like an old tape drive on a mainframe or maybe aDVD player. It has a “read head,” and you can “seek” this read head aroundthe file to positions, then work with it there. Each time you do f.seek(0)you’re moving to the start of the file. Each time you do f.readline() you’rereading a line from the file and moving the read head to right after the \n thatends that line. This will be explained more as you go on.

Why does seek(0) not set the current_line to 0? First, the seek()function is dealing in bytes, not lines. The code seek(0) moves the file to the0 byte (first byte) in the file. Second, current_line is just a variable and hasno real connection to the file at all. We are manually incrementing it.

What is +=? You know how in English I can rewrite “it is” as “it’s”? Or I canrewrite “you are” as “you’re”? In English this is called a contraction, and thisis kind of like a contraction for the two operations = and +. That means x = x+ y is the same as x += y.

How does readline() know where each line is? Inside readline() is codethat scans each byte of the file until it finds a \n character, then stops readingthe file to return what it found so far. The file f is responsible for maintainingthe current position in the file after each readline() call, so that it will keepreading each line.

Why are there empty lines between the lines in the file? The readline()function returns the \n that’s in the file at the end of that line. Add a end ="" at the end of your print function calls to avoid adding double \n to everyline.

Page 99: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 21. Functions Can ReturnSomethingYou have been using the = character to name variables and set them tonumbers or strings. We’re now going to blow your mind again by showingyou how to use = and a new Python word return to set variables to be avalue from a function. There will be one thing to pay close attention to, butfirst type this in:

ex21.py

1 def add(a, b): 2 print(f"ADDING {a} + {b}") 3 return a + b 4 5 def subtract(a, b): 6 print(f"SUBTRACTING {a} - {b}") 7 return a - b 8 9 def multiply(a, b):10 print(f"MULTIPLYING {a} * {b}")11 return a * b1213 def divide(a, b):14 print(f"DIVIDING {a} / {b}")15 return a / b161718 print("Let's do some math with just functions!")1920 age = add(30, 5)21 height = subtract(78, 4)22 weight = multiply(90, 2)23 iq = divide(100, 2)2425 print(f"Age: {age}, Height: {height}, Weight: {weight}, IQ: {iq}"262728 # A puzzle for the extra credit, type it in anyway.29 print("Here is a puzzle.")

Page 100: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

3031 what = add(age, subtract(height, multiply(weight, divide(iq, 3233 print("That becomes: ", what, "Can you do it by hand?")

We are now doing our own math functions for add, subtract, multiply, anddivide. The important thing to notice is the last line where we say return a+ b (in add). What this does is the following:

1. Our function is called with two arguments: a and b.

2. We print out what our function is doing, in this case “ADDING.”

3. Then we tell Python to do something kind of backward: we return theaddition of a + b. You might say this as, “I add a and b, then return them.”

4. Python adds the two numbers. Then when the function ends, any line thatruns it will be able to assign this a + b result to a variable.

As with many other things in this book, you should take this real slow, breakit down, and try to trace what’s going on. To help there is extra credit to solvea puzzle and learn something cool.

What You Should See

Exercise 21 Session

$ python3.6 ex21.pyLet's do some math with just functions!ADDING 30 + 5SUBTRACTING 78 - 4MULTIPLYING 90 * 2DIVIDING 100 / 2Age: 35, Height: 74, Weight: 180, IQ: 50.0Here is a puzzle.DIVIDING 50.0 / 2MULTIPLYING 180 * 25.0SUBTRACTING 74 - 4500.0ADDING 35 + -4426.0That becomes: -4391.0 Can you do it by hand?

Page 101: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Study Drills

1. If you aren’t really sure what return does, try writing a few of your ownfunctions and have them return some values. You can return anything thatyou can put to the right of an =.

2. At the end of the script is a puzzle. I’m taking the return value of onefunction and using it as the argument of another function. I’m doing this in achain so that I’m kind of creating a formula using the functions. It looksreally weird, but if you run the script, you can see the results. What youshould do is try to figure out the normal formula that would recreate thissame set of operations.

3. Once you have the formula worked out for the puzzle, get in there and seewhat happens when you modify the parts of the functions. Try to change it onpurpose to make another value.

4. Do the inverse. Write a simple formula and use the functions in the sameway to calculate it.

This exercise might really whack your brain out, but take it slow and easyand treat it like a little game. Figuring out puzzles like this is what makesprogramming fun, so I’ll be giving you more little problems like this as wego.

Common Student Questions

Why does Python print the formula or the functions “backward“? It’snot really backward, it’s “inside out.” When you start breaking down thefunction into separate formulas and function calls you’ll see how it works.Try to understand what I mean by “inside out” rather than “backward.”

How can I use input() to enter my own values? Rememberint(input())? The problem with that is then you can’t enter floating point,so also try using float(input()) instead.

What do you mean by “write out a formula“? Try 24 + 34 / 100 - 1023

Page 102: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

as a start. Convert that to use the functions. Now come up with your ownsimilar math equation, and use variables so it’s more like a formula.

Page 103: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 22. What Do You Know So Far?There won’t be any code in this exercise or the next one, so there’s no WhatYou Should See or Study Drills either. In fact, this exercise is like one giantStudy Drills. I’m going to have you do a review of what you have learned sofar.

First, go back through every exercise you have done so far and write downevery word and symbol (another name for “character“) that you have used.Make sure your list of symbols is complete.

Next to each word or symbol, write its name and what it does. If you can’tfind a name for a symbol in this book, then look for it online. If you do notknow what a word or symbol does, then read about it again and try using it insome code.

You may run into a few things you can’t find out or know, so just keep thoseon the list and be ready to look them up when you find them.

Once you have your list, spend a few days rewriting the list and double-checking that it’s correct. This may get boring, but push through and reallynail it down.

Once you have memorized the list and what they do, then step it up bywriting out tables of symbols, their names, and what they do from memory. Ifyou hit some you can’t recall from memory, go back and memorize themagain.

Warning!

The most important thing when doing this exercise is: “There is no failure,only trying.”

Page 104: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

What You Are Learning

It’s important when you are doing a boring, mindless memorization exerciselike this to know why. It helps you focus on a goal and know the purpose ofall your efforts.

In this exercise you are learning the names of symbols so that you can readsource code more easily. It’s similar to learning the alphabet and basic wordsof English, except this Python alphabet has extra symbols you might notknow.

Just take it slow and do not hurt your brain. It’s best to take 15 minutes at atime with your list and then take a break. Giving your brain a rest will helpyou learn faster with less frustration.

Page 105: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 23. Strings, Bytes, and CharacterEncodingsTo do this exercise you’ll need to download a text file that I’ve writtennamed languages.txt This file was created with a list of human languagesto demonstrate a few interesting concepts:

1. How modern computers store human languages for display and processingand how Python 3 calls this strings.

2. How you must “encode” and “decode” Python’s strings into a type calledbytes.

3. How to handle errors in your string and byte handling.

4. How to read code and find out what it means even if you’ve never seen itbefore.

In addition to that you’ll also get a brief glimpse of the Python 3 if-statement and lists for processing a list of things. You don’t have tomaster this code or understand these concepts right away. You’ll get plenty ofpractice in later exercises. For now your job is to get a taste of the future andlearn the four topics in the preceding list.

Warning!

This exercise is hard! There’s a lot of information in it that you need tounderstand, and it’s information that goes deep into computers. This exerciseis complex because Python’s strings are complex and difficult to use. Irecommend you take this exercise painfully slow. Write down every wordyou don’t understand, and look it up or research it. Take a paragraph at a timeif you must. You can continue with other exercises while you study this one,so don’t get stuck here. Just chip away at it for as long as it takes.

Page 106: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Initial Research

I’m going to teach you how to research a piece of code to expose its secrets.You’ll need the languages.txt file for this code to work, so make sure youdownload it first. The languages.txt file simply contains a list of humanlanguage names that are encoded in UTF-8.

ex23.py

1 import sys 2 script, encoding, error = sys.argv 3 4 5 def main(language_file, encoding, errors): 6 line = language_file.readline() 7 8 if line: 9 print_line(line, encoding, errors)10 return main(language_file, encoding, errors)111213 def print_line(line, encoding, errors):14 next_lang = line.strip()15 raw_bytes = next_lang.encode(encoding, errors=errors)16 cooked_string = raw_bytes.decode(encoding, errors=errors)1718 print(raw_bytes, "<===>", cooked_string)192021 languages = open("languages.txt", encoding="utf-8")2223 main(languages, encoding, error)

Simply write down a list of each thing you’ve never seen before. There maybe quite a few things that are new, so scan the file a few times.

Once you have that you’ll want to run this Python script to play with it. Hereare some example commands I used to test it:

Page 107: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Warning!

You’ll notice I’m using images here to show you what you should see. Afterextensive testing it turns out that so many people have their computersconfigured to not display utf-8 that I had to use images so you’ll know whatto expect. Even my own typesetting system (LaTeX) couldn’t handle theseencodings, forcing me to use images instead. If you don’t see this then yourterminal is most likely not able to display utf-8 and you should try to fix that.

These examples use the utf-8, utf-16, and big5 encodings to demonstratethe conversion and the types of errors you can get. Each of these names arecalled a “codec” in Python 3, but you use the parameter “encoding”. At theend of this exercise there’s a list of the available encodings if you want to trymore. I’ll cover what all of this output means shortly. You’re only trying toget an idea of how this works so we can talk about it.

After you’ve run it a few times, go through your list of symbols and make aguess as to what they do. When you’ve written down your guesses trylooking the symbols up online to see if you can confirm your hypothesis.Don’t worry if you have no idea how to search for them. Just give it a try.

Switches, Conventions, and Encodings

Before I can get into what this code means, you need to learn some basicsabout how data is stored in a computer. Modern computers are incredibly

Page 108: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

complex, but at their core they are like a huge array of light switches.Computers use electricity to flip switches on or off. These switches canrepresent 1 for on, or 0 for off. In the old days there were all kinds of weirdcomputers that did more than just 1 or 0, but these days it’s just 1s and 0s.One represents energy, electricity, on, power, substance. Zero represents off,done, gone, power down, the lack of energy. We call these 1s and 0s “bits.”

Now, a computer that only let you work with 1 and 0 would be both horriblyinefficient and incredibly annoying. Computers take these 1s and 0s and usethem to encode larger numbers. At the small end a computer will use 8 ofthese 1s and 0s to encode 256 numbers (0-255). What does “encode” meanthough? It’s nothing more than an agreed upon standard for how a sequenceof bits should represent a number. It’s a convention humans picked orstumbled on that says that 00000000 would be 0, 11111111 would be 255, and00001111 would be 15. There were even huge wars in the early history ofcomputers on nothing more than the order of these bits because they weresimply conventions we all had to agree on.

Today we call a “byte” a sequence of 8 bits (1s and 0s). In the old dayseveryone had their own convention for a byte, so you’ll still run into peoplewho think that this term should be flexible and handle sequences of 9 bits, 7bits, 6 bits, but now we just say it’s 8 bits. That’s our convention, and thatconvention defines our encoding for a byte. There are futher conventions forencoding large numbers using 16, 32, 64, and even more bits if you get intoreally big math. There’s entire standards groups who do nothing but argueabout these conventions, then implement them as encodings that eventuallyturn switches on and off.

Once you have bytes you can start to store and display text by deciding onanother convention for how a number maps to a letter. In the early days ofcomputing there were many conventions that mapped 8 or 7 bits (or less ormore) onto lists of characters kept inside a computer. The most popularconvention ended up being American Standard Code for InformationInterchange or ASCII. This standard maps a number to a letter. The number90 is Z, which in bits is 1011010, which gets mapped to the ASCII tableinside the computer.

You can try this out in Python right now:

Page 109: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

>>> 0b101101090>>> ord ( ' Z ' )90>>> chr ( 90 )' Z '>>>

First, I write the number 90 in binary, then I get the number based on theletter ’Z’, then I convert the number to the letter ’Z’. Don’t worry aboutneeding to remember this though. I think I’ve had to do it twice the entiretime I’ve used Python.

Once we have the ASCII convention for encoding a character using 8 bits (abyte), we can then “string” them together to make a word. If I want to writemy name “Zed A. Shaw,” I just use a sequence of bytes that are [90, 101,100, 32, 65, 46, 32, 83, 104, 97, 119]. Most of the early text incomputers was nothing more than sequences of bytes, stored in memory, thata computer used to display text to a person. Again, this is just a sequence ofconventions that turned switches on and off.

The problem with ASCII is that it only encodes English and maybe a fewother similar languages. Remember that a byte can hold 256 numbers (0-255,or 00000000-11111111). Turns out, there’s a lot more characters than 256used throughout the world’s languages. Different countries created their ownencoding conventions for their languages, and that mostly worked, but manyencodings could only handle one language. That meant if you want to put thetitle of an American English book in the middle of a Thai sentence you werekind of in trouble. You’d need one encoding for Thai and for English.

To solve this problem a group of people created Unicode. It sounds like“encode,” and it is meant to be a “universal encoding” of all humanlanguages. The solution Unicode provides is like the ASCII table, but it’shuge by comparison. You can use 32 bits to encode a Unicode character, andthat is more characters than we could possibly find. A 32-bit number meanswe can store 4,294,967,295 characters (2^32), which is enough space forevery possible human language and probably a lot of alien ones too. Rightnow we use the extra space for important things like poop and smile emojis.

Page 110: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

We now have a convention for encoding any characters we want, but 32 bitsis 4 bytes (32/8 == 4) which means there is so much wasted space in mosttext we want to encode. We can also use 16 bits (2 bytes), but still there’sgoing to be wasted space in most text. The solution is to use a cleverconvention to encode most common characters using 8 bits, and then“escape” into larger numbers when we need to encode more characters. Thatmeans we have one more convention that is nothing more than a compressionencoding, making it possible for most common characters to use 8 bits andthen escape out into 16 or 32 bits as needed.

The convention for encoding text in Python is called “utf-8”, which means“Unicode Transformation Format 8 Bits.” It is a convention for encodingUnicode characters into sequences of bytes (which are sequences of bits(which turn sequences of switches on and off)). You can also use otherconventions (encodings), but utf-8 is the current standard.

Disecting the Output

We can now look at the output of the commands above. Let’s take just thatfirst command and the first few lines of output:

The ex23.py script is taking bytes written inside the b'' (byte string) and

Page 111: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

converting them to the UTF-8 (or other) encoding you specified. On the leftis the numbers for each byte of the utf-8 (shown in hexadecimal), and theright has the character output as actual utf-8. The way to think of this is theleft side of <===> is the Python numerical bytes, or the “raw” bytes Pythonuses to store the string. You specify this with b'' to tell Python this is“bytes”. These raw bytes are then displayed “cooked” on the right so you cansee the real characters in your terminal.

Disecting the Code

We have an understanding of strings and byte sequences. In Python a stringis a UTF-8 encoded sequence of characters for displaying or working withtext. The bytes are then the “raw” sequence of bytes that Python uses to storethis UTF-8 string and start with a b' to tell Python you are working withraw bytes. This is all based on conventions for how Python wants to workwith text. Here’s a Python session showing me encoding strings and decodingbytes.

All you need to remember is if you have raw bytes, then you must use.decode() to get the string. Raw bytes have no convention to them. Theyare just sequences of bytes with no meaning other than numbers, so you musttell Python to “decode this into a utf string”. If you have a string and want

Page 112: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

to send it, store it, share it, or do some other operation, then usually it’llwork, but sometimes Python will throw up an error saying it doesn’t knowhow to “encode” it. Again, Python knows its internal convention, but it hasno idea what convention you need. In that case, you must use .encode() toget the bytes you need.

The way to remember this (even though I look it up almost every time) is toremember the mnemonic “DBES” which stands for “Decode Bytes EncodeStrings”. I say “dee bess” in my head when I have to convert bytes andstrings. When you have bytes and need a string, “Decode Bytes”. Whenyou have a string and need bytes, “Encode Strings”.

With that in mind, let’s break down the code in ex23.py line-by-line:

1-2 I start with your usual command line argument handling that you already know.

5 I start the main meat of this code in a function conveniently called main.This will be called at the end of this script to get things going.

6 The first thing this function does is read one line from the languages file itis given. You have done this before so nothing new here. Just readline asbefore when dealing with text files.

8 Now I use something new. You will learn about this in the second half ofthe book, so consider this a teaser of interesting things to come. This is anif-statement, and it lets you make decisions in your Python code. You can“test” the truth of a variable and, based on that truth, run a piece of code ornot run it. In this case I’m testing whether line has something in it. Thereadline function will return an empty string when it reaches the end of thefile and if line simply tests for this empty string. As long as readline givesus something, this will be true, and the code under (indented in, lines 9-10)will run. When this is false, Python will skip lines 9-10.

9 I then call a separate function to do the actual printing of this line. Thissimplifies my code and makes it easier for me to understand it. If I want tolearn what this function does, I can jump to it and study. Once I know whatprint_line does I can attach my memory to the name print_line and forget

Page 113: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

about the details.

10 I have written a tiny yet powerful piece of magic here. I am calling mainagain inside main. Actually it’s not magic since nothing really is magical inprogramming. All the information you need is there. This looks like I amcalling the function inside itself, which seems like it should be illegal to do.Ask yourself, why should that be illegal? There’s no technical reason why Ican’t call any function I want right there, even this main function. If afunction is simply a jump to the top where I’ve named it main, then callingthis function at the end of itself would...jump back to the top and run it again.That would make it loop. Now look back at line 8, and you’ll see the if-statement keeps this function from looping forever. Carefully study thisbecause it is a significant concept, but don’t worry if you can’t grasp it rightaway.

11 I now start the definition for the print_line function, which does theactual encoding of each line from the languages.txt file.

12 This is a simple stripping of the trailing \n on the line string.

13 Now I finally take the language I’ve received from the languages.txt fileand “encode” it into the raw bytes. Remember the “DBES” mnemonic.“Decode Bytes, Encode Strings”. The next_lang variable is a string, so to getthe raw bytes I must call .encode() on it to “Encode Strings”. I pass toencode() the encoding I want and how to handle errors.

14 I then do the extra step of showing the inverse of line 15 by creating acooked_string variable from the raw_bytes. Remember, “DBES” says I“Decode Bytes”, and raw_bytes is bytes, so I call .decode() on it to get aPython string. This string should be the same as the next_lang variable.

15 I’m done defining functions, so now I want to open the languages.txtfile.

16 The end of the script simply runs the main function with all the correctparameters to get everything going and kick start the loop. Remember thatthis then jumps to where the main function is defined on line 5, and on line 10main is called again, causing this to keep looping. The if line: on line 8

Page 114: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

will prevent our loop from going forever.

Encodings Deep Dive

We can now use our little script to explore other encodings. Here’s meplaying with different encodings and seeing how to break them:

First, I’m doing a simple UTF-16 encoding so you can see how it changescompared to UTF-8. You can also use “utf-32” to see how that’s even biggerand get an idea of the space saved with UTF-8. After that I try Big5, andyou’ll see that Python does not like that at all. It throws up an error that’big6’ can’t encode some of the characters at position 0 (which is superhelpful). One solution is to tell python to “replace” any bad characters for theBig5 encoding. That’s the next example, and you’ll see it puts a ? characterwherever it finds a character that doesn’t match the Big5 encoding system.

Breaking It

Rough ideas include the following:

1. Find strings of text encoded in other encodings and place them in theex23.py file to see how it breaks.

Page 115: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

2. Find out what happens when you give an encoding that doesn’t exist.

3. Extra challenging: Rewrite this using the b'' bytes instead of the UTF-8strings, effectively reversing the script.

4. If you can do that, then you can also break these bytes by removing someto see what happens. How much do you need to remove to cause Python tobreak? How much can you remove to damage the string output but passPython’s decoding system.

5. Use what you learned from #4 to see if you can mangle the files. Whaterrors do you get? How much damage can you cause and get the file pastPython’s decoding system?

Page 116: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 24. More PracticeYou are getting to the end of this section. You should have enough Python“under your fingers” to move on to learning about how programming reallyworks, but you should do some more practice. This exercise is longer and allabout building up stamina. The next exercise will be similar. Do them, getthem exactly right, and do your checks.

ex24.py

1 print("Let's practice everything.") 2 print('You\'d need to know \'bout escapes with \\ that do:') 3 print('\n newlines and \t tabs.') 4 5 poem = """ 6 \tThe lovely world 7 with logic so firmly planted 8 cannot discern \n the needs of love 9 nor comprehend passion from intuition10 and requires an explanation11 \n\t\twhere there is none.12 """1314 print("--------------")15 print(poem)16 print("--------------")171819 five = 10 - 2 + 3 - 620 print(f"This should be five: {five}")2122 def secret_formula(started):23 jelly_beans = started * 50024 jars = jelly_beans / 100025 crates = jars / 10026 return jelly_beans, jars, crates272829 start_point = 1000030 beans, jars, crates = secret_formula(start_point)3132 # remember that this is another way to format a string

Page 117: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

33 print("With a starting point of: {}".format(start_point))34 # it's just like with an f"" string35 print(f"We'd have {beans} beans, {jars} jars, and {crates} crates."3637 start_point = start_point / 103839 print("We can also do that this way:")40 formula = secret_formula(start_point)41 # this is an easy way to apply a list to a format string42 print("We'd have {} beans, {} jars, and {} crates.".format(*formula))

What You Should See

Exercise 24 Session

$ python3.6 ex24.pyLet's practice everything.You'd need to know 'bout escapes with \ that do:

newlines and tabs.--------------

The lovely worldwith logic so firmly plantedcannot discern the needs of lovenor comprehend passion from intuitionand requires an explanation

where there is none.

--------------This should be five: 5With a starting point of: 10000We'd have 5000000 beans, 5000.0 jars, and 50.0 crates.We can also do that this way:We'd have 500000.0 beans, 500.0 jars, and 5.0 crates.

Study Drills

1. Make sure to do your checks: read it backward, read it out loud, and putcomments above confusing parts.

Page 118: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

2. Break the file on purpose, then run it to see what kinds of errors you get.Make sure you can fix it.

Common Student Questions

Why do you call the variable jelly_beans but the name beans later?That’s part of how a function works. Remember that inside the function thevariable is temporary. When you return it then it can be assigned to a variablefor later. I’m just making a new variable named beans to hold the returnvalue.

What do you mean by reading the code backward? Start at the last line.Compare that line in your file to the same line in mine. Once it’s exactly thesame, move up to the next line. Do this until you get to the first line of thefile.

Who wrote that poem? I did. Not all of my poems suck.

Page 119: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 25. Even More PracticeWe’re going to do some more practice involving functions and variables tomake sure you know them well. This exercise should be straightforward foryou to type in, break down, and understand.

However, this exercise is a little different. You won’t be running it. Insteadyou will import it into Python and run the functions yourself.

ex25.py

1 def break_words(stuff): 2 """This function will break up words for us.""" 3 words = stuff.split(' ') 4 return words 5 6 def sort_words(words): 7 """Sorts the words.""" 8 return sorted(words) 910 def print_first_word(words):11 """Prints the first word after popping it off."""12 word = words.pop(0)13 print(word)1415 def print_last_word(words):16 """Prints the last word after popping it off."""17 word = words.pop(-1)18 print(word)1920 def sort_sentence(sentence):21 """Takes in a full sentence and returns the sorted words."""22 words = break_words(sentence)23 return sort_words(words)2425 def print_first_and_last(sentence):26 """Prints the first and last words of the sentence."""27 words = break_words(sentence)28 print_first_word(words)29 print_last_word(words)30

Page 120: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

31 def print_first_and_last_sorted(sentence):32 """Sorts the words then prints the first and last one."""33 words = sort_sentence(sentence)34 print_first_word(words)35 print_last_word(words)

First, run this with python3.6 ex25.py to find any errors you have made.Once you have found all of the errors you can and fixed them, you will thenwant to follow the What You Should See section to complete the exercise.

What You Should See

In this exercise we’re going to interact with your ex25.py file inside thepython3.6 interpreter you used periodically to do calculations. You runpython3.6 from the terminal like this:

$ python3.6Python 3.6.0rc2 (v3.6.0rc2:800a67f7806d, Dec 16 2016, 14:12:21)[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwinType "help " , "copyright" , "credits" or "license" for more information.>>>

Your output should look like mine, and after the > character (called theprompt) you can type Python code in, and it will run immediately. Using thisI want you to type each of these lines of Python code into python3.6 and seewhat it does:

Exercise 25 Python Session

1 import ex25 2 sentence = "All good things come to those who wait." 3 words = ex25.break_words(sentence) 4 words 5 sorted_words = ex25.sort_words(words) 6 sorted_words 7 ex25.print_first_word(words) 8 ex25.print_last_word(words) 9 words10 ex25.print_first_word(sorted_words)11 ex25.print_last_word(sorted_words)12 sorted_words

Page 121: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

13 sorted_words = ex25.sort_sentence(sentence)14 sorted_words15 ex25.print_first_and_last(sentence)16 ex25.print_first_and_last_sorted(sentence)

Here’s what it looks like when I work with the ex25.py module inpython3.6:

Exercise 25 Python Session

Python 3.6.0 (default, Feb 2 2017, 12:48:29)[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwinType "help", "copyright", "credits" or "license" for more information.>>> import ex25>>> sentence = "All good things come to those who wait.">>> words = ex25.break_words(sentence)>>> words['All', 'good', 'things', 'come', 'to', 'those', 'who', 'wait.']>>> sorted_words = ex25.sort_words(words)>>> sorted_words['All', 'come', 'good', 'things', 'those', 'to', 'wait.', 'who']>>> ex25.print_first_word(words)All>>> ex25.print_last_word(words)wait.>>> words['good', 'things', 'come', 'to', 'those', 'who']>>> ex25.print_first_word(sorted_words)All>>> ex25.print_last_word(sorted_words)who>>> sorted_words['come', 'good', 'things', 'those', 'to', 'wait.']>>> sorted_words = ex25.sort_sentence(sentence)>>> sorted_words['All', 'come', 'good', 'things', 'those', 'to', 'wait.', 'who']>>> ex25.print_first_and_last(sentence)Allwait.>>> ex25.print_first_and_last_sorted(sentence)Allwho

As you go through each of these lines, make sure you can find the functionthat’s being run in ex25.py and you understand how each one works. If you

Page 122: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

get different results or error, you’ll have to go fix your code, exit python3.6,and start over.

Study Drills

1. Take the remaining lines of the What You Should See output and figure outwhat they are doing. Make sure you understand how you are running yourfunctions in the ex25 module.

2. Try doing this: help(ex25) and also help(ex25.break_words). Noticehow you get help for your module and how the help is those odd """ stringsyou put after each function in ex25? Those special strings are calleddocumentation comments, and we’ll be seeing more of them.

3. Typing ex25. is annoying. A shortcut is to do your import like this: fromex25 import * which is like saying, “Import everything from ex25.”Programmers like saying things backward. Start a new session and see howall your functions are right there.

4. Try breaking your file and see what it looks like in python when you use it.You will have to quit python with quit() to be able to reload it.

Common Student Questions

I get None printed out for some of the functions. You probably have afunction that is missing the return at the end. Go backward through the fileand confirm that every line is right.

I get -bash: import: command not found when I type import ex25. Payattention to what I’m doing in the What You Should See section. I’m doingthis in Python, not in the Terminal. That means you first run Python.

I get ImportError: No module named ex25.py when I type importex25.py. Don’t add the .py to the end. Python knows the file ends in .py, soyou just type import ex25.

I get SyntaxError: invalid syntax when I run this. That means you have

Page 123: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

something like a missing ( or " or similar syntax error on that line or above it.Any time you get that error, start at the line it mentions and check that it’sright, then go backward checking each line above that.

How can the words.pop function change the words variable? That’s acomplicated question, but in this case words is a list, and because of that youcan give it commands, and it’ll retain the results of those commands. This issimilar to how files and many other things worked when you were workingwith them.

When should I print instead of return in a function? The return from afunction gives the line of code that called the function a result. You can thinkof a function as taking input through its arguments and returning outputthrough return. The print is completely unrelated to this and only deals withprinting output to the terminal.

Page 124: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 26. Congratulations, Take a Test!You are almost done with the first half of the book. The second half is wherethings get interesting. You will learn logic and be able to do useful things likemake decisions.

Before you continue, I have a quiz for you. This quiz will be very hardbecause it requires you to fix someone else’s code. When you are aprogrammer you often have to deal with other programmers’ code—and alsowith their arrogance. Programmers will very frequently claim that their codeis perfect.

These programmers are stupid people who care little for others. A goodprogrammer assumes, like a good scientist, that there’s always someprobability their code is wrong. Good programmers start from the premisethat their software is broken and then work to rule out all possible ways itcould be wrong before finally admitting that maybe it really is the other guy’scode.

In this exercise, you will practice dealing with a bad programmer by fixing abad programmer’s code. I have poorly copied Exercises 24 and 25 into a fileand removed random characters and added flaws. Most of the errors arethings Python will tell you, while some of them are math errors you shouldfind. Others are formatting errors or spelling mistakes in the strings.

All of these errors are very common mistakes all programmers make. Evenexperienced ones.

Your job in this exercise is to correct this file. Use all of your skills to makethis file better. Analyze it first, maybe printing it out to edit it like you woulda school term paper. Fix each flaw and keep running it and fixing it until thescript runs perfectly. Try not to get help. If you get stuck take a break andcome back to it later.

Even if this takes days to do, bust through it and make it right.

Page 125: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

The point of this exercise isn’t to type it in but to fix an existing file. To dothat, you must go to this site:

• http://learnpythonthehardway.org/python3/exercise26.txt

Copy-paste the code into a file named ex26.py. This is the only time you areallowed to copy-paste.

Common Student Questions

Do I have to import ex25.py, or can I just remove the references to it?You can do either. This file has the functions from ex25 though, so first gowith removing references to it.

Can I run the code while I’m fixing it? You most certainly may. Thecomputer is there to help, so use it as much as possible.

Page 126: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 27. Memorizing LogicToday is the day you start learning about logic. Up to this point you havedone everything you possibly can reading and writing files, to the Terminal,and have learned quite a lot of the math capabilities of Python.

From now on, you will be learning logic. You won’t learn complex theoriesthat academics love to study but just the simple basic logic that makes realprograms work and that real programmers need every day.

Learning logic has to come after you do some memorization. I want you to dothis exercise for an entire week. Do not falter. Even if you are bored out ofyour mind, keep doing it. This exercise has a set of logic tables you mustmemorize to make it easier for you to do the later exercises.

I’m warning you this won’t be fun at first. It will be downright boring andtedious, but this teaches you a very important skill you will need as aprogrammer. You will need to be able to memorize important concepts inyour life. Most of these concepts will be exciting once you get them. Youwill struggle with them, like wrestling a squid, then one day you willunderstand it. All that work memorizing the basics pays off big later.

Here’s a tip on how to memorize something without going insane: Do a tinybit at a time throughout the day and mark down what you need to work onmost. Do not try to sit down for two hours straight and memorize thesetables. This won’t work. Your brain will only retain whatever you studied inthe first 15 or 30 minutes anyway. Instead, create a bunch of index cards witheach column on the left (True or False) on the front, and the column on theright on the back. You should then take them out, see the “True or False” andimmediately say “True!” Keep practicing until you can do this.

Once you can do that, start writing out your own truth tables each night into anotebook. Do not just copy them. Try to do them from memory. When youget stuck, glance quickly at the ones I have here to refresh your memory.Doing this will train your brain to remember the whole table.

Page 127: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Do not spend more than one week on this, because you will be applying it asyou go.

The Truth Terms

In Python we have the following terms (characters and phrases) fordetermining if something is “True” or “False.” Logic on a computer is allabout seeing if some combination of these characters and some variables isTrue at that point in the program.

• and

• or

• not

• != (not equal)

• == (equal)

• >= (greater-than-equal)

• <= (less-than-equal)

• True

• False

You actually have run into these characters before but maybe not the terms.The terms (and, or, not) actually work the way you expect them to, just likein English.

The Truth Tables

We will now use these characters to make the truth tables you need tomemorize.

Page 128: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of
Page 129: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Now use these tables to write up your own cards and spend the weekmemorizing them. Remember though, there is no failing in this book, justtrying as hard as you can each day, and then a little bit more.

Common Student Questions

Can’t I just learn the concepts behind boolean algebra and not memorizethis? Sure, you can do that, but then you’ll have to constantly go through therules for Boolean algebra while you code. If you memorize these first, it notonly builds your memorization skills, but it also makes these operations

Page 130: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

natural. After that, the concept of Boolean algebra is easy. But do whateverworks for you.

Page 131: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 28. Boolean PracticeThe logic combinations you learned from the last exercise are called“Boolean” logic expressions. Boolean logic is used everywhere inprogramming. It is a fundamental part of computation, and knowing themvery well is akin to knowing your scales in music.

In this exercise you will take the logic exercises you memorized and starttrying them out in Python. Take each of these logic problems and write whatyou think the answer will be. In each case it will be either True or False.Once you have the answers written down, you will start Python in yourterminal and type each logic problem in to confirm your answers.

1. True and True 2. False and True 3. 1 == 1 and 2 == 1 4. "test" == "test" 5. 1 == 1 or 2 != 1 6. True and 1 == 1 7. False and 0 != 0 8. True or 1 == 1 9. "test" == "testing"10. 1 != 0 and 2 == 111. "test" != "testing"12. "test" == 113. not (True and False)14. not (1 == 1 and 0 != 1)15. not (10 == 1 or 1000 == 1000)16. not (1 != 10 or 3 == 4)17. not ("testing" == "testing" and "Zed" == "Cool Guy")18. 1 == 1 and (not ("testing" == 1 or 1 == 0))19. "chunky" == "bacon" and (not (3 == 4 or 3 == 3))20. 3 == 3 and (not ("testing" == "testing" or "Python" == "Fun"))

I will also give you a trick to help you figure out the more complicated onestoward the end.

Whenever you see these Boolean logic statements, you can solve them easilyby this simple process:

Page 132: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

1. Find an equality test (== or !=) and replace it with its truth.

2. Find each and/or inside parentheses and solve those first.

3. Find each not and invert it.

4. Find any remaining and/or and solve it.

5. When you are done you should have True or False.

I will demonstrate with a variation on #20:

3 != 4 and not ("testing" != "test" or "Python" == "Python")

Here’s me going through each of the steps and showing you the translationuntil I’ve boiled it down to a single result:

1. Solve each equality test:

3 != 4 is True: True and not ("testing" != "test" or "Python" == "Python")"testing" != "test" is True: True and not (True or "Python" == "Python")"Python" == "Python": True and not (True or True)

2. Find each and/or in parentheses ():

(True or True) is True: True and not (True)

3. Find each not and invert it:

not (True) is False: True and False

4. Find any remaining and/or and solve them:

True and False is False

With that we’re done and know the result is False.

Warning!

Page 133: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

The more complicated ones may seem very hard at first. You should be ableto take a good first stab at solving them, but do not get discouraged. I’m justgetting you primed for more of these “logic gymnastics” so that later coolstuff is much easier. Just stick with it, and keep track of what you get wrong,but do not worry that it’s not getting in your head quite yet. It’ll come.

What You Should See

After you have tried to guess at these, this is what your session with Pythonmight look like:

$ python3.6Python 2.5.1 (r251:54863, Feb 6 2009, 19:02:12)[GCC 4.0.1 ( Apple Inc . build 5465)] on darwinType "help" , "copyright" , "credits" or "license" for more information.>>> True and TrueTrue>>> 1 == 1 and 2 == 2True

Study Drills

1. There are a lot of operators in Python similar to != and ==. Try to find asmany “equality operators” as you can. They should be like < or <=.

2. Write out the names of each of these equality operators. For example, I call!= “not equal.”

3. Play with Python by typing out new Boolean operators, and before youpress Enter try to shout out what it is. Do not think about it. Shout the firstthing that comes to mind. Write it down, then press Enter, and keep track ofhow many you get right and wrong.

4. Throw away the piece of paper from 3 so you do not accidentally try to useit later.

Common Student Questions

Page 134: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Why does "test" and "test" return "test" or 1 and 1 return 1 insteadof True? Python and many languages like to return one of the operands totheir Boolean expressions rather than just True or False. This means that ifyou did False and 1 you get the first operand (False), but if you do Trueand 1 you get the second (1). Play with this a bit.

Is there any difference between != and <>? Python has deprecated <> infavor of !=, so use !=. Other than that there should be no difference.

Isn’t there a shortcut? Yes. Any and expression that has a False isimmediately False, so you can stop there. Any or expression that has a Trueis immediately True, so you can stop there. But make sure that you canprocess the whole expression because later it becomes helpful.

Page 135: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 29. What IfHere is the next script of Python you will enter, which introduces you to theif-statement. Type this in, make it run exactly right, and then we’ll see ifyour practice has paid off.

ex29.py

1 people = 20 2 cats = 30 3 dogs = 15 4 5 6 if people < cats: 7 print("Too many cats! The world is doomed!") 8 9 if people > cats:10 print("Not many cats! The world is saved!")1112 if people < dogs:13 print("The world is drooled on!")1415 if people > dogs:16 print("The world is dry!")171819 dogs += 52021 if people >= dogs:22 print("People are greater than or equal to dogs.")2324 if people <= dogs:25 print("People are less than or equal to dogs.")262728 if people == dogs:29 print("People are dogs.")

What You Should See

Exercise 29 Session

Page 136: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

$ python3.6 ex29.pyToo many cats! The world is doomed!The world is dry!People are greater than or equal to dogs.People are less than or equal to dogs.People are dogs.

Study Drills

In this Study Drill, try to guess what you think the if-statement is and whatit does. Try to answer these questions in your own words before moving on tothe next exercise:

1. What do you think the if does to the code under it?

2. Why does the code under the if need to be indented four spaces?

3. What happens if it isn’t indented?

4. Can you put other boolean expressions from Exercise 27 in the if-statement? Try it.

5. What happens if you change the initial values for people, cats, and dogs?

Common Student Questions

What does += mean? The code x += 1 is the same as doing x = x + 1 butinvolves less typing. You can call this the “increment by” operator. The samegoes for -= and many other expressions you’ll learn later.

Page 137: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 30. Else and IfIn the last exercise you worked out some if-statements and then tried toguess what they are and how they work. Before you learn more I’ll explainwhat everything is by answering the questions you had from Study Drills.You did the Study Drills right?

1. What do you think the if does to the code under it? An if-statementcreates what is called a “branch” in the code. It’s kind of like those chooseyour own adventure books where you are asked to turn to one page if youmake one choice and another if you go a different direction. The if-statement tells your script, “If this Boolean expression is True, then run thecode under it, otherwise skip it.”

2. Why does the code under the if need to be indented four spaces? A colonat the end of a line is how you tell Python you are going to create a new“block” of code, and then indenting four spaces tells Python what lines ofcode are in that block. This is exactly the same thing you did when you madefunctions in the first half of the book.

3. What happens if it isn’t indented? If it isn’t indented, you will most likelycreate a Python error. Python expects you to indent something after you end aline with a : (colon).

4. Can you put other boolean expressions from Exercise 27 in the if-statement? Try it. Yes you can, and they can be as complex as you like,although really complex things generally are bad style.

5. What happens if you change the initial values for people, cats, and dogs?Because you are comparing numbers, if you change the numbers, differentif-statements will evaluate to True and the blocks of code under them willrun. Go back and put different numbers in and see if you can figure out inyour head which blocks of code will run.

Compare my answers to your answers, and make sure you really understandthe concept of a “block” of code. This is important for when you do the next

Page 138: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

exercise where you write all the parts of if-statements that you can use.

Type this one in and make it work too.

ex30.py

1 people = 30 2 cars = 40 3 trucks = 15 4 5 6 if cars > people: 7 print("We should take the cars.") 8 elif cars < people: 9 print("We should not take the cars.")10 else:11 print("We can't decide.")1213 if trucks > cars:14 print("That's too many trucks.")15 elif trucks < cars:16 print("Maybe we could take the trucks.")17 else:18 print("We still can't decide.")1920 if people > trucks:21 print("Alright, let's just take the trucks.")22 else:23 print("Fine, let's stay home then.")

What You Should See

Exercise 30 Session

$ python3.6 ex30.pyWe should take the cars.Maybe we could take the trucks.Alright, let's just take the trucks.

Study Drills

Page 139: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

1. Try to guess what elif and else are doing.

2. Change the numbers of cars, people, and trucks, and then trace througheach if-statement to see what will be printed.

3. Try some more complex boolean expressions like cars > people ortrucks < cars.

4. Above each line write an English description of what the line does.

Common Student Questions

What happens if multiple elif blocks are True? Python starts at the topand runs the first block that is True, so it will run only the first one.

Page 140: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 31. Making DecisionsIn the first half of this book you mostly just printed out things calledfunctions, but everything was basically in a straight line. Your scripts ranstarting at the top and went to the bottom where they ended. If you made afunction, you could run that function later, but it still didn’t have the kind ofbranching you need to really make decisions. Now that you have if, else,and elif you can start to make scripts that decide things.

In the last script you wrote out a simple set of tests asking some questions. Inthis script you will ask the user questions and make decisions based on theiranswers. Write this script, and then play with it quite a lot to figure it out.

ex31.py

1 print("""You enter a dark room with two doors. 2 Do you go through door #1 or door #2?""") 3 4 door = input("> ") 5 6 if door == "1": 7 print("There's a giant bear here eating a cheese cake.") 8 print("What do you do?") 9 print("1. Take the cake.")10 print("2. Scream at the bear.")1112 bear = input("> ")1314 if bear == "1":15 print("The bear eats your face off. Good job!")16 elif bear == "2":17 print("The bear eats your legs off. Good job!")18 else:19 print(f"Well, doing {bear} is probably better.")20 print("Bear runs away.")2122 elif door == "2":23 print("You stare into the endless abyss at Cthulhu's retina."24 print("1. Blueberries.")25 print("2. Yellow jacket clothespins.")

Page 141: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

26 print("3. Understanding revolvers yelling melodies.")2728 insanity = input("> ")2930 if insanity == "1" or insanity == "2":31 print("Your body survives powered by a mind of jello."32 print("Good job!")33 else:34 print("The insanity rots your eyes into a pool of muck."35 print("Good job!")3637 else:38 print("You stumble around and fall on a knife and die. Good job!"

A key point here is that you are now putting the if-statements inside if-statements as code that can run. This is very powerful and can be used tocreate “nested” decisions, where one branch leads to another and another.

Make sure you understand this concept of if-statements inside if-statements.In fact, do the Study Drills to really nail it.

What You Should See

Here is me playing this little adventure game. I do not do so well.

Exercise 31 Session

$ python3.6 ex31.pyYou enter a dark room with two doors.Do you go through door #1 or door #2?> 1There's a giant bear here eating a cheese cake.What do you do?1. Take the cake.2. Scream at the bear.> 2The bear eats your legs off. Good job!

Study Drills

1. Make new parts of the game and change what decisions people can make.

Page 142: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Expand the game out as much as you can before it gets ridiculous.

2. Write a completely new game. Maybe you don’t like this one, so makeyour own. This is your computer; do what you want.

Common Student Questions

Can you replace elif with a sequence of if-else combinations? You canin some situations, but it depends on how each if/else is written. It alsomeans that Python will check every if-else combination, rather than just thefirst false ones like it would with if-elif-else. Try to make some of theseto figure out the differences.

How do I tell whether a number is between a range of numbers? Youhave two options: Use 0 < x < 10 or 1 <= x < 10, which is classic notation,or use x in range(1, 10).

What if I wanted more options in the if-elif-else blocks? Add moreelif blocks for each possible choice.

Page 143: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 32. Loops and ListsYou should now be able to do some programs that are much more interesting.If you have been keeping up, you should realize that now you can combineall the other things you have learned with if-statements and booleanexpressions to make your programs do smart things.

However, programs also need to do repetitive things very quickly. We aregoing to use a for-loop in this exercise to build and print various lists. Whenyou do the exercise, you will start to figure out what they are. I won’t tell youright now. You have to figure it out.

Before you can use a for-loop, you need a way to store the results of loopssomewhere. The best way to do this is with lists. Lists are exactly whattheir name says: a container of things that are organized in order from first tolast. It’s not complicated; you just have to learn a new syntax. First, there’show you make lists:

hairs = ['brown', 'blond', 'red']eyes = ['brown', 'blue', 'green']weights = [1, 2, 3, 4]

You start the list with the [ (left bracket) which “opens” the list. Then youput each item you want in the list separated by commas, similar to functionarguments. Lastly, end the list with a ] (right bracket) to indicate that it’sover. Python then takes this list and all its contents and assigns them to thevariable.

Warning!

This is where things get tricky for people who can’t code. Your brain hasbeen taught that the world is flat. Remember in the last exercise where youput if-statements inside if-statements? That probably made your brainhurt because most people do not ponder how to “nest” things inside things. Inprogramming nested structures are all over the place. You will find functions

Page 144: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

that call other functions that have if-statements that have lists with listsinside lists. If you see a structure like this that you can’t figure out, take out apencil and paper and break it down manually bit by bit until you understandit.

We now will build some lists using some for-loops and print them out:

ex32.py

1 the_count = [1, 2, 3, 4, 5] 2 fruits = ['apples', 'oranges', 'pears', 'apricots'] 3 change = [1, 'pennies', 2, 'dimes', 3, 'quarters'] 4 5 # this first kind of for-loop goes through a list 6 for number in the_count: 7 print(f"This is count {number}") 8 9 # same as above10 for fruit in fruits:11 print(f"A fruit of type: {fruit}")1213 # also we can go through mixed lists too14 # notice we have to use {} since we don't know what's in it15 for i in change:16 print(f"I got {i}")1718 # we can also build lists, first start with an empty one19 elements = []2021 # then use the range function to do 0 to 5 counts22 for i in range(0, 6):23 print(f"Adding {i} to the list.")24 # append is a function that lists understand25 elements.append(i)2627 # now we can print them out too28 for i in elements:29 print(f"Element was: {i}")

What You Should See

Exercise 32 Session

Page 145: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

$ python3.6 ex32.pyThis is count 1This is count 2This is count 3This is count 4This is count 5A fruit of type: applesA fruit of type: orangesA fruit of type: pearsA fruit of type: apricotsI got 1I got penniesI got 2I got dimesI got 3I got quartersAdding 0 to the list.Adding 1 to the list.Adding 2 to the list.Adding 3 to the list.Adding 4 to the list.Adding 5 to the list.Element was: 0Element was: 1Element was: 2Element was: 3Element was: 4Element was: 5

Study Drills

1. Take a look at how you used range. Look up the range function tounderstand it.

2. Could you have avoided that for-loop entirely on line 22 and justassigned range(0,6) directly to elements?

3. Find the Python documentation on lists and read about them. What otheroperations can you do to lists besides append?

Common Student Questions

Page 146: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

How do you make a 2-dimensional (2D) list? That’s a list in a list like this:[[1,2,3],[4,5,6]]

Aren’t lists and arrays the same thing? Depends on the language and theimplementation. In classic terms a list is very different from an array becauseof how they’re implemented. In Ruby though they call these arrays. InPython they call them lists. Just call these lists for now since that’s whatPython calls them.

Why is a for-loop able to use a variable that isn’t defined yet? Thevariable is defined by the for-loop when it starts, initializing it to the currentelement of the loop iteration each time through.

Why does for i in range(1, 3): only loop two times instead of threetimes? The range() function only does numbers from the first to the last, notincluding the last. So it stops at two, not three in the preceding. This turns outto be the most common way to do this kind of loop.

What does elements.append() do? It simply appends to the end of the list.Open up the Python shell and try a few examples with a list you make. Anytime you run into things like this, always try to play with them interactivelyin the Python shell.

Page 147: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 33. While LoopsNow to totally blow your mind with a new loop, the while-loop. A while-loop will keep executing the code block under it as long as a booleanexpression is True.

Wait, you have been keeping up with the terminology, right? That if we writea line and end it with a : (colon) then that tells Python to start a new block ofcode? Then we indent and that’s the new code. This is all about structuringyour programs so that Python knows what you mean. If you do not get thatidea then go back and do some more work with if-statements, functions,and the for-loop until you get it.

Later on we’ll have some exercises that will train your brain to read thesestructures, similar to how we burned boolean expressions into your brain.

Back to while-loops. What they do is simply do a test like an if-statement,but instead of running the code block once, they jump back to the “top”where the while is, and repeat. A while-loop runs until the expression isFalse.

Here’s the problem with while-loops: Sometimes they do not stop. This isgreat if your intention is to just keep looping until the end of the universe.Otherwise you almost always want your loops to end eventually.

To avoid these problems, there are some rules to follow:

1. Make sure that you use while-loops sparingly. Usually a for-loop isbetter.

2. Review your while statements and make sure that the boolean test willbecome False at some point.

3. When in doubt, print out your test variable at the top and bottom of thewhile-loop to see what it’s doing.

Page 148: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

In this exercise, you will learn the while-loop while doing these threechecks:

ex33.py

1 i = 0 2 numbers = [] 3 4 while i < 6: 5 print(f"At the top i is {i}") 6 numbers.append(i) 7 8 i = i + 1 9 print("Numbers now: ", numbers)10 print(f"At the bottom i is {i}")111213 print("The numbers: ")1415 for num in numbers:16 print(num)

What You Should See

Exercise 33 Session

$ python3.6 ex33.pyAt the top i is 0Numbers now: [0]At the bottom i is 1At the top i is 1Numbers now: [0, 1]At the bottom i is 2At the top i is 2Numbers now: [0, 1, 2]At the bottom i is 3At the top i is 3Numbers now: [0, 1, 2, 3]At the bottom i is 4At the top i is 4Numbers now: [0, 1, 2, 3, 4]At the bottom i is 5At the top i is 5

Page 149: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Numbers now: [0, 1, 2, 3, 4, 5]At the bottom i is 6The numbers:012345

Study Drills

1. Convert this while-loop to a function that you can call, and replace 6 inthe test (i < 6) with a variable.

2. Use this function to rewrite the script to try different numbers.

3. Add another variable to the function arguments that you can pass in thatlets you change the + 1 on line 8 so you can change how much it incrementsby.

4. Rewrite the script again to use this function to see what effect that has.

5. Write it to use for-loops and range. Do you need the incrementor in themiddle anymore? What happens if you do not get rid of it?

If at any time that you are doing this it goes crazy (it probably will), just holddown CTRL and press c (CTRL-c) and the program will abort.

Common Student Questions

What’s the difference between a for-loop and a while-loop? A for-loopcan only iterate (loop) “over” collections of things. A while-loop can do anykind of iteration (looping) you want. However, while-loops are harder to getright, and you normally can get many things done with for-loops.

Loops are hard. How do I figure them out? The main reason people don’tunderstand loops is because they can’t follow the “jumping” that the codedoes. When a loop runs, it goes through its block of code, and at the end it

Page 150: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

jumps back to the top. To visualize this, put print statements all over the loopprinting out where in the loop Python is running and what the variables areset to at those points. Write print lines before the loop, at the top of the loop,in the middle, and at the bottom. Study the output and try to understand thejumping that’s going on.

Page 151: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 34. Accessing Elements of ListsLists are pretty useful, but unless you can get at the things in them they aren’tall that good. You can already go through the elements of a list in order, butwhat if you want say, the fifth element? You need to know how to access theelements of a list. Here’s how you would access the first element of a list:

animals = ['bear', 'tiger', 'penguin', 'zebra']bear = animals[0]

You take a list of animals, and then you get the first (1st) one using 0?! Howdoes that work? Because of the way math works, Python starts its lists at 0rather than 1. It seems weird, but there are many advantages to this, eventhough it is mostly arbitrary.

The best way to explain why is by showing you the difference between howyou use numbers and how programmers use numbers.

Imagine you are watching the four animals in our list (['bear', 'tiger','penguin', 'zebra']) run in a race. They cross the finish line in the orderwe have them in this list. The race was really exciting because the animalsdidn’t eat each other and somehow managed to run a race. Your friend showsup late and wants to know who won. Does your friend say, “Hey, who camein zeroth?” No, he says, “Hey, who came in first?”

This is because the order of the animals is important. You can’t have thesecond animal without the first (1st) animal, and you can’t have the thirdwithout the second. It’s also impossible to have a “zeroth” animal since zeromeans nothing. How can you have a nothing win a race? It just doesn’t makesense. We call these kinds of numbers “ordinal” numbers, because theyindicate an ordering of things.

Programmers, however, can’t think this way because they can pick anyelement out of a list at any point. To programmers, the list of animals is morelike a deck of cards. If they want the tiger, they grab it. If they want the zebra,they can take it too. This need to pull elements out of lists at random means

Page 152: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

that they need a way to indicate elements consistently by an address, or an“index,” and the best way to do that is to start the indices at 0. Trust me onthis: the math is way easier for these kinds of accesses. This kind of numberis a “cardinal” number and means you can pick at random, so there needs tobe a 0 element.

How does this help you work with lists? Simple, every time you say toyourself, “I want the third animal,” you translate this “ordinal” number to a“cardinal” number by subtracting 1. The “third” animal is at index 2 and isthe penguin. You have to do this because you have spent your whole lifeusing ordinal numbers, and now you have to think in cardinal. Just subtract 1and you will be good.

Remember: ordinal == ordered, 1st; cardinal == cards at random, 0.

Let’s practice this. Take this list of animals, and follow the exercises where Itell you to write down what animal you get for that ordinal or cardinalnumber. Remember, if I say “first,” “second,” then I’m using ordinal, sosubtract 1. If I give you cardinal (like “The animal at 1”), then use it directly.

animals = ['bear', 'python3.6', 'peacock', 'kangaroo', 'whale', 'platypus']

1. The animal at 1.

2. The third (3rd) animal.

3. The first (1st) animal.

4. The animal at 3.

5. The fifth (5th) animal.

6. The animal at 2.

7. The sixth (6th) animal.

8. The animal at 4.

For each of these, write out a full sentence of the form: “The first (1st) animal

Page 153: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

is at 0 and is a bear.” Then say it backwards: “The animal at 0 is the 1stanimal and is a bear.”

Use your Python to check your answers.

Study Drills

1. With what you know of the difference between these types of numbers, canyou explain why the year 2010 in “January 1, 2010,” really is 2010 and not2009? (Hint: you can’t pick years at random.)

2. Write some more lists and work out similar indexes until you can translatethem.

3. Use Python to check your answers.

Warning!

Programmers will tell you to read this guy named “Dijkstra” on this subject. Irecommend you avoid his writings on this unless you enjoy being yelled at bysomeone who stopped programming at the same time programming started.

Page 154: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 35. Branches and FunctionsYou have learned if-statements, functions, and lists. Now it’s time to bendyour mind. Type this in, and see if you can figure out what it’s doing.

ex35.py

1 from sys import exit 2 3 def gold_room(): 4 print("This room is full of gold. How much do you take?") 5 6 choice = input("> ") 7 if "0" in choice or "1" in choice: 8 how_much = int(choice) 9 else:10 dead("Man, learn to type a number.")1112 if how_much < 50:13 print("Nice, you're not greedy, you win!")14 exit(0)15 else:16 dead("You greedy bastard!")171819 def bear_room():20 print("There is a bear here.")21 print("The bear has a bunch of honey.")22 print("The fat bear is in front of another door.")23 print("How are you going to move the bear?")24 bear_moved = False2526 while True:27 choice = input("> ")2829 if choice == "take honey":30 dead("The bear looks at you then slaps your face off."31 elif choice == "taunt bear" and not bear_moved:32 print("The bear has moved from the door.")33 print("You can go through it now.")34 bear_moved = True35 elif choice == "taunt bear" and bear_moved:

Page 155: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

36 dead("The bear gets pissed off and chews your leg off."37 elif choice == "open door" and bear_moved:38 gold_room()39 else:40 print("I got no idea what that means.")414243 def cthulhu_room():44 print("Here you see the great evil Cthulhu.")45 print("He, it, whatever stares at you and you go insane."46 print("Do you flee for your life or eat your head?")4748 choice = input("> ")4950 if "flee" in choice:51 start()52 elif "head" in choice:53 dead("Well that was tasty!")54 else:55 cthulhu_room()565758 def dead(why):59 print(why, "Good job!")60 exit(0)6162 def start():63 print("You are in a dark room.")64 print("There is a door to your right and left.")65 print("Which one do you take?")6667 choice = input("> ")6869 if choice == "left":70 bear_room()71 elif choice == "right":72 cthulhu_room()73 else:74 dead("You stumble around the room until you starve.")757677 start()

What You Should See

Here’s me playing the game:

Page 156: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 35 Session

$ python3.6 ex35.pyYou are in a dark room.There is a door to your right and left.Which one do you take?> leftThere is a bear here.The bear has a bunch of honey.The fat bear is in front of another door.How are you going to move the bear?> taunt bearThe bear has moved from the door.You can go through it now.> open doorThis room is full of gold. How much do you take?> 1000You greedy bastard! Good job!

Study Drills

1. Draw a map of the game and how you flow through it.

2. Fix all of your mistakes, including spelling mistakes.

3. Write comments for the functions you do not understand.

4. Add more to the game. What can you do to both simplify and expand it?

5. The gold_room has a weird way of getting you to type a number. What areall the bugs in this way of doing it? Can you make it better than what I’vewritten? Look at how int() works for clues.

Common Student Questions

Help! How does this program work!? When you get stuck understanding apiece of code, simply write an English comment above every line explainingwhat that line does. Keep your comments short and similar to the code. Theneither diagram how the code works or write a paragraph describing it. If you

Page 157: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

do that you’ll get it.

Why did you write while True? That makes an infinite loop.

What does exit(0) do? On many operating systems a program can abortwith exit(0), and the number passed in will indicate an error or not. If youdo exit(1) then it will be an error, but exit(0) will be a good exit. Thereason it’s backward from normal Boolean logic (with 0==False) is that youcan use different numbers to indicate different error results. You can doexit(100) for a different error result than exit(2) or exit(1).

Why is input() sometimes written as input('> ')? The parameter toinput is a string that it should print as a prompt before getting the user’sinput.

Page 158: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 36. Designing and DebuggingNow that you know if-statements, I’m going to give you some rules forfor-loops and while-loops that will keep you out of trouble. I’m also goingto give you some tips on debugging so that you can figure out problems withyour program. Finally, you will design a little game similar to the lastexercise but with a slight twist.

Rules for If-Statements

1. Every if-statement must have an else.

2. If this else should never run because it doesn’t make sense, then you mustuse a die function in the else that prints out an error message and dies, justlike we did in the last exercise. This will find many errors.

3. Never nest if-statements more than two deep and always try to do themone deep.

4. Treat if-statements like paragraphs, where each if-elif-else groupingis like a set of sentences. Put blank lines before and after.

5. Your Boolean tests should be simple. If they are complex, move theircalculations to variables earlier in your function and use a good name for thevariable.

If you follow these simple rules, you will start writing better code than mostprogrammers. Go back to the last exercise and see if I followed all of theserules. If not, fix my mistakes.

Warning!

Never be a slave to the rules in real life. For training purposes you need tofollow these rules to make your mind strong, but in real life sometimes these

Page 159: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

rules are just stupid. If you think a rule is stupid, try not using it.

Rules for Loops

1. Use a while-loop only to loop forever, and that means probably never.This only applies to Python; other languages are different.

2. Use a for-loop for all other kinds of looping, especially if there is a fixedor limited number of things to loop over.

Tips for Debugging

1. Do not use a “debugger.” A debugger is like doing a full-body scan on asick person. You do not get any specific useful information, and you find awhole lot of information that doesn’t help and is just confusing.

2. The best way to debug a program is to use print to print out the values ofvariables at points in the program to see where they go wrong.

3. Make sure parts of your programs work as you work on them. Do not writemassive files of code before you try to run them. Code a little, run a little, fixa little.

Homework

Now write a game similar to the one that I created in the last exercise. It canbe any kind of game you want in the same flavor. Spend a week on it makingit as interesting as possible. For Study Drills, use lists, functions, andmodules (remember those from Exercise 13?) as much as possible, and findas many new pieces of Python as you can to make the game work.

Before you start coding you must draw a map for your game. Create therooms, monsters, and traps that the player must go through on paper beforeyou code.

Page 160: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Once you have your map, try to code it up. If you find problems with the mapthen adjust it and make the code match.

The best way to work on a piece of software is in small chunks like this:

1. On a sheet of paper or an index card, write a list of tasks you need tocomplete to finish the software. This is your to do list.

2. Pick the easiest thing you can do from your list.

3. Write out English comments in your source file as a guide for how youwould accomplish this task in your code.

4. Write some of the code under the English comments.

5. Quickly run your script so see if that code worked.

6. Keep working in a cycle of writing some code, running it to test it, andfixing it until it works.

7. Cross this task off your list, then pick your next easiest task and repeat.

This process will help you work on software in a methodical and consistentmanner. As you work, update your list by removing tasks you don’t reallyneed and adding ones you do.

Page 161: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 37. Symbol ReviewIt’s time to review the symbols and Python words you know and to try to pickup a few more for the next few lessons. I have written out all the Pythonsymbols and keywords that are important to know.

In this lesson take each keyword and first try to write out what it does frommemory. Next, search online for it and see what it really does. This may bedifficult because some of these are difficult to search for, but try anyway.

If you get one of these wrong from memory, make an index card with thecorrect definition and try to “correct” your memory.

Finally, use each of these in a small Python program, or as many as you canget done. The goal is to find out what the symbol does, make sure you got itright, correct it if you did not, then use it to lock it in.

Keywords

Page 162: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Data Types

For data types, write out what makes up each one. For example, with strings,write out how you create a string. For numbers, write out a few numbers.

Page 163: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

String Escape Sequences

For string escape sequences, use them in strings to make sure they do whatyou think they do.

Old Style String Formats

Same thing for string formats: use them in some strings to know what theydo.

Page 164: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Older Python 2 code uses these formatting characters to do what f-strings do.Try them out as an alternative.

Operators

Some of these may be unfamiliar to you, but look them up anyway. Find outwhat they do, and if you still can’t figure it out, save it for later.

Page 165: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Spend about a week on this, but if you finish faster that’s great. The point isto try to get coverage on all these symbols and make sure they are locked inyour head. What’s also important is to find out what you do not know so youcan fix it later.

Reading Code

Now find some Python code to read. You should be reading any Python code

Page 166: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

you can and trying to steal ideas that you find. You actually should haveenough knowledge to be able to read but maybe not understand what the codedoes. What this lesson teaches is how to apply things you have learned tounderstand other people’s code.

First, print out the code you want to understand. Yes, print it out, becauseyour eyes and brain are more used to reading paper than computer screens.Make sure you print a few pages at a time.

Second, go through your printout and take notes on the following:

1. Functions and what they do.

2. Where each variable is first given a value.

3. Any variables with the same names in different parts of the program. Thesemay be trouble later.

4. Any if-statements without else clauses. Are they right?

5. Any while-loops that might not end.

6. Any parts of code that you can’t understand for whatever reason.

Third, once you have all of this marked up, try to explain it to yourself bywriting comments as you go. Explain the functions, how they are used, whatvariables are involved and anything you can to figure this code out.

Lastly, on all of the difficult parts, trace the values of each variable line byline, function by function. In fact, do another printout, and write in themargin the value of each variable that you need to “trace.”

Once you have a good idea of what the code does, go back to the computerand read it again to see if you find new things. Keep finding more code anddoing this until you do not need the printouts anymore.

Study Drills

Page 167: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

1. Find out what a “flow chart” is and draw a few.

2. If you find errors in code you are reading, try to fix them, and send theauthor your changes.

3. Another technique for when you are not using paper is to put # commentswith your notes in the code. Sometimes, these could become the actualcomments to help the next person.

Common Student Questions

How would I search for these things online? Simply put “python3.6”before anything you want to find. For example, to find yield search forpython3.6 yield.

Page 168: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 38. Doing Things to ListsYou have learned about lists. When you learned about while-loops you“appended” numbers to the end of a list and printed them out. There werealso Study Drills where you were supposed to find all the other things youcan do to lists in the Python documentation. That was a while back, so reviewthose topics if you do not know what I’m talking about.

Found it? Remember it? Good. When you did this you had a list, and you“called” the function append on it. However, you may not really understandwhat’s going on so let’s see what we can do to lists.

When you write mystuff.append('hello') you are actually setting off achain of events inside Python to cause something to happen to the mystufflist. Here’s how it works:

1. Python sees you mentioned mystuff and looks up that variable. It mighthave to look backward to see if you created it with =, if it is a functionargument, or if it’s a global variable. Either way it has to find the mystufffirst.

2. Once it finds mystuff it reads the . (period) operator and starts to look atvariables that are a part of mystuff. Since mystuff is a list, it knows thatmystuff has a bunch of functions.

3. It then hits append and compares the name to all the names that mystuffsays it owns. If append is in there (it is), then Python grabs that to use.

4. Next Python sees the ( (parenthesis) and realizes, “Oh hey, this should be afunction.” At this point it calls (runs, executes) the function just likenormally, but instead it calls the function with an extra argument.

5. That extra argument is ... mystuff! I know, weird, right? But that’s howPython works, so it’s best to just remember it and assume that’s the result.What happens, at the end of all this, is a function call that looks like:append(mystuff, 'hello') instead of what you read, which is

Page 169: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

mystuff.append('hello').

For the most part you do not have to know that this is going on, but it helpswhen you get error messages from Python like this:

$ python3.6>>> class Thing(object):... def test(message):... print(message)...>>> a = Thing()>>> a.test ("hello")Traceback (most recent call last): File "<stdin>", line 1 , in <module>TypeError : test() takes exactly 1 argument (2 given)>>>

What was all that? Well, this is me typing into the Python shell and showingyou some magic. You haven’t seen class yet, but we’ll get into that later. Fornow you see how Python said test() takes exactly 1 argument (2given). If you see this, it means that Python changed a.test("hello") totest(a, "hello") and that somewhere someone messed up and didn’t addthe argument for a.

This might be a lot to take in, but we’re going to spend a few exercisesgetting this concept firm in your brain. To kick things off, here’s an exercisethat mixes strings and lists for all kinds of fun.

ex38.py

1 ten_things = "Apples Oranges Crows Telephone Light Sugar" 2 3 print("Wait there are not 10 things in that list. Let's fix that." 4 5 stuff = ten_things.split(' ') 6 more_stuff = ["Day", "Night", "Song", "Frisbee", 7 "Corn", "Banana", "Girl", "Boy"] 8 9 while len(stuff) != 10:10 next_one = more_stuff.pop()11 print("Adding: ", next_one)12 stuff.append(next_one)

Page 170: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

13 print(f"There are {len(stuff)} items now.")1415 print("There we go: ", stuff)1617 print("Let's do some things with stuff.")1819 print(stuff[1])20 print(stuff[-1]) # whoa! fancy21 print(stuff.pop())22 print(' '.join(stuff)) # what? cool!23 print('#'.join(stuff[3:5])) # super stellar!

What You Should See

Wait there are not 10 things in that list. Let's fix that.Adding: BoyThere are 7 items now.Adding: GirlThere are 8 items now.Adding: BananaThere are 9 items now.Adding: CornThere are 10 items now.There we go: ['Apples', 'Oranges', 'Crows', 'Telephone', 'Light', 'Sugar', 'Boy', 'Girl', 'Banana', 'Corn']Let's do some things with stuff.OrangesCornCornApples Oranges Crows Telephone Light Sugar Boy Girl BananaTelephone#Light

What Lists Can Do

Let’s say you want to create a computer game based on Go Fish. If you don’tknow what Go Fish is, take the time now to go read up on it on the internet.To do this you would need to have some way of taking the concept of a “deckof cards” and put it into your Python program. You then have to write Pythoncode that knows how to work this imaginary version of a deck of cards sothat a person playing your game thinks that it’s real, even if it isn’t. What youneed is a “deck of cards” structure, and programmers call this kind of thing a“data structure”.

Page 171: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

What’s a data structure? If you think about it, a “data structure” is just aformal way to structure (organize) some data (facts). It really is that simple.Even though some data structures can get insanely complex, all they are isjust a way to store facts inside a program so you can access them in differentways. They structure data.

I’ll be getting into this more in the next exercise, but lists are one of the mostcommon data structures programmers use. They are simply ordered lists offacts you want to store and access randomly or linearly by an index. What?!Remember what I said though, just because a programmer said “list is a list”doesn’t mean that it’s any more complex than what a list already is in the realworld. Let’s look at the deck of cards as an example of a list:

1. You have a bunch of cards with values.

2. Those cards are in a stack, list, or list from the top card to the bottom card.

3. You can take cards off the top, the bottom, the middle at random.

4. If you want to find a specific card, you have to grab the deck and gothrough it one at a time.

Let’s look at what I said:

“An ordered list” Yes, deck of cards is in order with a first, and a last.

“of things you want to store” Yes, cards are things I want to store.

“and access randomly” Yes, I can grab a card from anywhere in the deck.

“or linearly” Yes, if I want to find a specific card I can start at the beginningand go in order.

“by an index” Almost, since with a deck of cards if I told you to get the cardat index 19 you’d have to count until you found that one. In our Python liststhe computer can just jump right to any index you give it.

That is all a list does, and this should give you a way to figure out concepts inprogramming. Every concept in programming usually has some relationship

Page 172: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

to the real world. At least the useful ones do. If you can figure out what theanalog in the real world is, then you can use that to figure out what the datastructure should be able to do.

When to Use Lists

You use a list whenever you have something that matches the list datastructure’s useful features:

1. If you need to maintain order. Remember, this is listed order, not sortedorder. Lists do not sort for you.

2. If you need to access the contents randomly by a number. Remember, thisis using cardinal numbers starting at 0.

3. If you need to go through the contents linearly (first to last). Remember,that’s what for-loops are for.

Then that’s when you use a list.

Study Drills

1. Take each function that is called, and go through the steps for functioncalls to translate them to what Python does. For example, more_stuff.pop()is pop(more_stuff).

2. Translate these two ways to view the function calls in English. Forexample, more_stuff.pop() reads as, “Call pop on more_stuff.”Meanwhile, pop(more_stuff) means, “Call pop with argument more_stuff.”Understand how they are really the same thing.

3. Go read about “object-oriented programming” online. Confused? I wastoo. Do not worry. You will learn enough to be dangerous, and you canslowly learn more later.

4. Read up on what a “class” is in Python. Do not read about how otherlanguages use the word “class.“ That will only mess you up.

Page 173: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

5. Do not worry If you do not have any idea what I’m talking about.Programmers like to feel smart, so they invented object-orientedprogramming, named it OOP, and then used it way too much. If you thinkthat’s hard, you should try to use “functional programming.”

6. Find 10 examples of things in the real world that would fit in a list. Trywriting some scripts to work with them.

Common Student Questions

Didn’t you say to not use while-loops? Yes, so just remember sometimesyou can break the rules if you have a good reason. Only idiots are slaves torules all the time.

Why does join(' ', stuff) not work? The way the documentation forjoin is written doesn’t make sense. It does not work like that and is instead amethod you call on the inserted string to put between the list to be joined.Rewrite it like ' '.join(stuff).

Why did you use a while-loop? Try rewriting it with a for-loop and see ifthat’s easier.

What does stuff[3:5] do? That extracts a “slice” from the stuff list that isfrom element 3 to element 4, meaning it does not include element 5. It’ssimilar to how range(3,5) would work.

Page 174: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 39. Dictionaries, Oh LovelyDictionariesYou are now going to learn about the Dictionary data structure in Python. ADictionary (or “dict“) is a way to store data just like a list, but instead ofusing only numbers to get the data, you can use almost anything. This letsyou treat a dict like it’s a database for storing and organizing data.

Let’s compare what dicts can do to what lists can do. You see, a list lets youdo this:

Exercise 39 Python Session

>>> things = ['a', 'b', 'c', 'd']>>> print(things[1])b>>> things[1] = 'z'>>> print(things[1])z>>> things['a', 'z', 'c', 'd']

You can use numbers to “index” into a list, meaning you can use numbers tofind out what’s in lists. You should know this about lists by now, but makesure you understand that you can only use numbers to get items out of a list.

What a dict does is let you use anything, not just numbers. Yes, a dictassociates one thing to another, no matter what it is. Take a look:

Exercise 39 Python Session

>>> stuff = {'name': 'Zed', 'age': 39, 'height': 6 * 12 + 2}>>> print(stuff['name'])Zed>>> print(stuff['age'])39>>> print(stuff['height'])

Page 175: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

74>>> stuff['city'] = "SF">>> print(stuff['city'])SF

You will see that instead of just numbers we’re using strings to say what wewant from the stuff dictionary. We can also put new things into thedictionary with strings. It doesn’t have to be strings though. We can also dothis:

Exercise 39 Python Session

>>> stuff[1] = "Wow">>> stuff[2] = "Neato">>> print(stuff[1])Wow>>> print(stuff[2])Neato

In this code I used numbers, and then you can see there are numbers andstrings as keys in the dict when I print it. I could use anything. Well almost,but just pretend you can use anything for now.

Of course, a dictionary that you can only put things in is pretty stupid, sohere’s how you delete things, with the del keyword:

Exercise 39 Python Session

>>> del stuff['city']>>> del stuff[1]>>> del stuff[2]>>> stuff{'name': 'Zed', 'age': 39, 'height': 74}

A Dictionary Example

We’ll now do an exercise that you must study very carefully. I want you totype this code in and try to understand what’s going on. Take note of whenyou put things in a dict, get them from a hash, and all the operations you use.

Page 176: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Notice how this example is mapping states to their abbreviations and then theabbreviations to cities in the states. Remember, “mapping” or “associating” isthe key concept in a dictionary.

ex39.py

1 # create a mapping of state to abbreviation 2 states = { 3 'Oregon': 'OR', 4 'Florida': 'FL', 5 'California': 'CA', 6 'New York': 'NY', 7 'Michigan': 'MI' 8 } 910 # create a basic set of states and some cities in them11 cities = {12 'CA': 'San Francisco',13 'MI': 'Detroit',14 'FL': 'Jacksonville'15 }1617 # add some more cities18 cities['NY'] = 'New York'19 cities['OR'] = 'Portland'2021 # print out some cities22 print('-' * 10)23 print("NY State has: ", cities['NY'])24 print("OR State has: ", cities['OR'])2526 # print some states27 print('-' * 10)28 print("Michigan's abbreviation is: ", states['Michigan'])29 print("Florida's abbreviation is: ", states['Florida'])3031 # do it by using the state then cities dict32 print('-' * 10)33 print("Michigan has: ", cities[states['Michigan']])34 print("Florida has: ", cities[states['Florida']])3536 # print every state abbreviation37 print('-' * 10)38 for state, abbrev in list(states.items()):39 print(f"{state} is abbreviated {abbrev}")

Page 177: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

4041 # print every city in state42 print('-' * 10)43 for abbrev, city in list(cities.items()):44 print(f"{abbrev} has the city {city}")4546 # now do both at the same time47 print('-' * 10)48 for state, abbrev in list(states.items()):49 print(f"{state} state is abbreviated {abbrev}")50 print(f"and has city {cities[abbrev]}")5152 print('-' * 10)53 # safely get a abbreviation by state that might not be there54 state = states.get('Texas')5556 if not state:57 print("Sorry, no Texas.")5859 # get a city with a default value60 city = cities.get('TX', 'Does Not Exist')61 print(f"The city for the state 'TX' is: {city}")

What You Should See

Exercise 39 Session

$ python3.6 ex39.py----------NY State has: New YorkOR State has: Portland----------Michigan's abbreviation is: MIFlorida's abbreviation is: FL----------Michigan has: DetroitFlorida has: Jacksonville----------Oregon is abbreviated ORFlorida is abbreviated FLCalifornia is abbreviated CANew York is abbreviated NYMichigan is abbreviated MI----------CA has the city San Francisco

Page 178: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

MI has the city DetroitFL has the city JacksonvilleNY has the city New YorkOR has the city Portland----------Oregon state is abbreviated ORand has city PortlandFlorida state is abbreviated FLand has city JacksonvilleCalifornia state is abbreviated CAand has city San FranciscoNew York state is abbreviated NYand has city New YorkMichigan state is abbreviated MIand has city Detroit----------Sorry, no Texas.The city for the state 'TX' is: Does Not Exist

What Dictionaries Can Do

Dictionaries are another example of a data structure, and, like lists, they areone of the most commonly used data structures in programming. A dictionaryis used to map or associate things you want to store to keys you need to getthem. Again, programmers don’t use a term like “dictionary” for somethingthat doesn’t work like an actual dictionary full of words, so let’s use that asour real world example.

Let’s say you want to find out what the word “Honorificabilitudinitatibus”means. Today you would simply copy-paste that word into a search engineand then find out the answer, and we could say a search engine is like a reallyhuge super complex version of the Oxford English Dictionary (OED). Beforesearch engines what you would do is this:

1. Go to your library and get “the dictionary”. Let’s say it’s the OED.

2. You know “honorificabilitudinitatibus” starts with the letter ’H’ so youlook on the side of the book for the little tab that has ’H’ on it.

3. Then you’d skim the pages until you are close to where “hon” started.

Page 179: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

4. Then you’d skim a few more pages until you found“honorificabilitudinitatibus” or hit the beginning of the “hp” words andrealize this word isn’t in the OED.

5. Once you found the entry, you’d read the definition to figure out what itmeans.

This process is nearly exactly the way a dict works, and you are basically“mapping” the word “honorificabilitudinitatibus” to its definition. A dict inPython is just like a dictionary in the real world such as the OED.

Study Drills

1. Do this same kind of mapping with cities and states/regions in yourcountry or some other country.

2. Find the Python documentation for dictionaries and try to do even morethings to them.

3. Find out what you can’t do with dictionaries. A big one is that they do nothave order, so try playing with that.

Common Student Questions

What is the difference between a list and a dictionary? A list is for anordered list of items. A dictionary (or dict) is for matching some items(called “keys“) to other items (called “values“).

What would I use a dictionary for? When you have to take one value and“look up” another value. In fact, you could call dictionaries “look up tables.”

What would I use a list for? Use a list for any sequence of things that needto be in order, and you only need to look them up by a numeric index.

What if I need a dictionary, but I need it to be in order? Take a look at thecollections.OrderedDict data structure in Python. Search for it online tofind the documentation.

Page 180: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 40. Modules, Classes, and ObjectsPython is called an "object-oriented programming language." This meansthere is a construct in Python called a class that lets you structure yoursoftware in a particular way. Using classes, you can add consistency to yourprograms so that they can be used in a cleaner way. At least that's the theory.

I am now going to teach you the beginnings of object-oriented programming,classes, and objects using what you already know about dictionaries andmodules. My problem is that object-oriented programming (OOP) is justplain weird. You have to struggle with this, try to understand what I say here,type in the code, and in the next exercise I'll hammer it in.

Here we go.

Modules Are Like Dictionaries

You know how a dictionary is created and used and that it is a way to mapone thing to another. That means if you have a dictionary with a key "apple"and you want to get it then you do this:

ex40a.py

1 mystuff = {'apple': "I AM APPLES!"}2 print(mystuff['apple'])

Keep this idea of "get X from Y" in your head, and now think about modules.You've made a few so far, and you should know they are:

1. A Python file with some functions or variables in it ..

2. You import that file.

3. And you can access the functions or variables in that module with the .(dot) operator.

Page 181: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Imagine I have a module that I decide to name mystuff.py and I put afunction in it called apple. Here's the module mystuff.py:

ex40a.py

1 # this goes in mystuff.py2 def apple():3 print("I AM APPLES!")

Once I have this code, I can use the module MyStuff with import and thenaccess the apple function:

ex40a.py

1 import mystuff2 mystuff.apple()

I could also put a variable in it named tangerine:

ex40a.py

1 def apple():2 print("I AM APPLES!")34 # this is just a variable5 tangerine = "Living reflection of a dream"

I can access that the same way:

ex40a.py

1 import mystuff23 mystuff.apple()4 print(mystuff.tangerine)

Refer back to the dictionary, and you should start to see how this is similar tousing a dictionary, but the syntax is different. Let's compare:

Page 182: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

ex40a.py

1 mystuff['apple'] # get apple from dict2 mystuff.apple() # get apple from the module3 mystuff.tangerine # same thing, it's just a variable

This means we have a very common pattern in Python:

1. Take a key=value style container.

2. Get something out of it by the key's name.

In the case of the dictionary, the key is a string and the syntax is [key]. In thecase of the module, the key is an identifier, and the syntax is .key. Other thanthat they are nearly the same thing.

40.1.1 Classes Are Like Modules

You can think about a module as a specialized dictionary that can storePython code so you can access it with the . operator. Python also has anotherconstruct that serves a similar purpose called a class. A class is a way to takea grouping of functions and data and place them inside a container so you canaccess them with the . (dot) operator.

If I were to create a class just like the mystuff module, I'd do something likethis:

ex40a.py

1 class MyStuff(object):23 def __init__(self):4 self.tangerine = "And now a thousand years between"56 def apple(self):7 print("I AM CLASSY APPLES!")

That looks complicated compared to modules, and there is definitely a lotgoing on by comparison, but you should be able to make out how this is like

Page 183: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

a "mini-module" with MyStuff having an apple() function in it. What isprobably confusing is the __init__() function and use of self.tangerinefor setting the tangerine instance variable.

Here's why classes are used instead of modules: You can take this MyStuffclass and use it to craft many of them, millions at a time if you want, andeach one won't interfere with each other. When you import a module there isonly one for the entire program unless you do some monster hacks.

Before you can understand this though, you need to know what an "object" isand how to work with MyStuff just like you do with the mystuff.py module.

40.1.2 Objects Are Like Import

If a class is like a "mini-module," then there has to be a concept similar toimport but for classes. That concept is called "instantiate", which is just afancy, obnoxious, overly smart way to say "create." When you instantiate aclass what you get is called an object.

You instantiate (create) a class by calling the class like it's a function, likethis:

ex40a.py

1 thing = MyStuff()2 thing.apple()3 print(thing.tangerine)

The first line is the "instantiate" operation, and it's a lot like calling afunction. However, Python coordinates a sequence of events for you behindthe scenes. I'll go through these steps using the preceding code for MyStuff:

1. Python looks for MyStuff() and sees that it is a class you've defined.

2. Python crafts an empty object with all the functions you've specified in theclass using def.

3. Python then looks to see if you made a "magic" __init__ function, and if

Page 184: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

you have it calls that function to initialize your newly created empty object.

4. In the MyStuff function __init__ I then get this extra variable self, whichis that empty object Python made for me, and I can set variables on it just likeyou would with a module, dictionary, or other object.

5. In this case, I set self.tangerine to a song lyric and then I've initializedthis object.

6. Now Python can take this newly minted object and assign it to the thingvariable for me to work with.

That's the basics of how Python does this "mini-import" when you call a classlike a function. Remember that this is not giving you the class but instead isusing the class as a blueprint for building a copy of that type of thing.

Keep in mind that I'm giving you a slightly inaccurate idea of how these workso that you can start to build up an understanding of classes based on whatyou know about modules. The truth is, classes and objects suddenly divergefrom modules at this point. If I were being totally honest, I'd say somethingmore like this:

• Classes are like blueprints or definitions for creating new mini-modules.

• Instantiation is how you make one of these mini-modules and import it atthe same time. "Instantiate" just means to create an object from the class.

• The resulting created mini-module is called an object, and you then assign itto a variable to work with it.

At this point objects behave differently from modules, and this should onlyserve as a way for you to bridge over to understanding classes and objects.

40.1.3 Getting Things from Things

I now have three ways to get things from things:

ex40a.py

Page 185: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

1 # dict style 2 mystuff['apples'] 3 4 # module style 5 mystuff.apples() 6 print(mystuff.tangerine) 7 8 # class style 9 thing = MyStuff()10 thing.apples()11 print(thing.tangerine)

40.1.4 A First Class Example

You should start seeing the similarities in these three key=value containertypes and probably have a bunch of questions. Hang on with the questions, asthe next exercise will hammer home your "object-oriented vocabulary." Inthis exercise, I just want you to type in this code and get it working so thatyou have some experience before moving on.

ex40.py

1 class Song(object): 2 3 def __init__(self, lyrics): 4 self.lyrics = lyrics 5 6 def sing_me_a_song(self): 7 for line in self.lyrics: 8 print(line) 910 happy_bday = Song(["Happy birthday to you",11 "I don't want to get sued",12 "So I'll stop right there"])1314 bulls_on_parade = Song(["They rally around tha family",15 "With pockets full of shells"])1617 happy_bday.sing_me_a_song()1819 bulls_on_parade.sing_me_a_song()

Page 186: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

What You Should See

Exercise 40 Session

$ python3.6 ex40.pyHappy birthday to youI don't want to get suedSo I'll stop right thereThey rally around tha familyWith pockets full of shells

Study Drills

1. Write some more songs using this and make sure you understand thatyou're passing a list of strings as the lyrics.

2. Put the lyrics in a separate variable, then pass that variable to the class touse instead.

3. See if you can hack on this and make it do more things. Don't worry if youhave no idea how, just give it a try, see what happens. Break it, trash it, thrashit, you can't hurt it.

4. Search online for "object-oriented programming" and try to overflow yourbrain with what you read. Don't worry if it makes absolutely no sense to you.Half of that stuff makes no sense to me too.

Common Student Questions

Why do I need self when I make __init__ or other functions forclasses? If you don't have self, then code like cheese = 'Frank' isambiguous. That code isn't clear about whether you mean the instance'scheese attribute or a local variable named cheese. With self.cheese ='Frank' it's very clear you mean the instance attribute self.cheese.

Page 187: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 41. Learning to Speak Object-OrientedIn this exercise I’m going to teach you how to speak “object oriented.” WhatI’ll do is give you a small set of words with definitions you need to know.Then I’ll give you a set of sentences with holes in them that you’ll have tounderstand. Finally, I’m going to give you a large set of exercises that youhave to complete to make these sentences solid in your vocabulary.

Word Drills

class Tell Python to make a new type of thing.

object Two meanings: the most basic type of thing, and any instance of something.

instance What you get when you tell Python to create a class.

def How you define a function inside a class.

self Inside the functions in a class, self is a variable for the instance/objectbeing accessed.

inheritance The concept that one class can inherit traits from another class,much like you and your parents.

composition The concept that a class can be composed of other classes asparts, much like how a car has wheels.

attribute A property classes have that are from composition and are usuallyvariables.

is-a A phrase to say that something inherits from another, as in a “salmon” is-a “fish.”

Page 188: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

has-a A phrase to say that something is composed of other things or has atrait, as in “a salmon has-a mouth.”

Take some time to make flash cards for these terms and memorize them. Asusual this won’t make too much sense until after you are finished with thisexercise, but you need to know the base words first.

Phrase Drills

Next I have a list of Python code snippets on the left, and the Englishsentences for them:

class X(Y) “Make a class named X that is-a Y.”

class X(object): def __init__(self, J) “class X has-a __init__ that takes selfand J parameters.”

class X(object): def M(self, J) “class X has-a function named M that takesself and J parameters.”

foo = X() “Set foo to an instance of class X.”

foo.M(J) “From foo, get the M function, and call it with parameters self, J.”

foo.K = Q “From foo, get the K attribute, and set it to Q.”

In each of these, where you see X, Y, M, J, K, Q, and foo, you can treat thoselike blank spots. For example, I can also write these sentences as follows:

1. “Make a class named ??? that is-a Y.”

2. “class ??? has-a __init__ that takes self and ??? parameters.”

3. “class ??? has-a function named ??? that takes self and ??? parameters.”

4. “Set foo to an instance of class ???.”

5. “From foo, get the ??? function, and call it with self=??? and parameters

Page 189: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

???.”

6. “From foo, get the ??? attribute, and set it to ???.”

Again, write these on some flash cards and drill them. Put the Python codesnippet on the front and the sentence on the back. You have to be able to saythe sentence exactly the same every time whenever you see that form. Notsort of the same, but exactly the same.

Combined Drills

The final preparation for you is to combine the words drills with the phrasedrills. What I want you to do for this drill is this:

1. Take a phrase card and drill it.

2. Flip it over and read the sentence, and for each word in the sentence that isin your words drills, get that card.

3. Drill those words for that sentence.

4. Keep going until you are bored, then take a break and do it again.

A Reading Test

I now have a little Python hack script that will drill you on these words youknow in an infinite manner. This is a simple script you should be able tofigure out, and the only thing it does is use a library called urllib todownload a list of words I have. Here’s the script, which you should enterinto oop_test.py to work with it:

ex41.py

1 import random 2 from urllib.request import urlopen 3 import sys 4

Page 190: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

5 WORD_URL = "http://learncodethehardway.org/words.txt" 6 WORDS = [] 7 8 PHRASES = { 9 "class %%%(%%%):":10 "Make a class named %%% that is-a %%%.",11 "class %%%(object):\n\tdef __init__(self, ***)" :12 "class %%% has-a __init__ that takes self and *** params."13 "class %%%(object):\n\tdef ***(self, @@@)":14 "class %%% has-a function *** that takes self and @@@ params."15 "*** = %%%()":16 "Set *** to an instance of class %%%.",17 "***.***(@@@)":18 "From *** get the *** function, call it with params self, @@@."19 "***.*** = '***'":20 "From *** get the *** attribute and set it to '***'."21 }2223 # do they want to drill phrases first24 if len(sys.argv) == 2 and sys.argv[1] == "english":25 PHRASE_FIRST = True26 else:27 PHRASE_FIRST = False2829 # load up the words from the website30 for word in urlopen(WORD_URL).readlines():31 WORDS.append(str(word.strip(), encoding="utf-8"))323334 def convert(snippet, phrase):35 class_names = [w.capitalize() for w in36 random.sample(WORDS, snippet.count("%%%"))]37 other_names = random.sample(WORDS, snippet.count("***"))38 results = []39 param_names = []4041 for i in range(0, snippet.count("@@@")):42 param_count = random.randint(1,3)43 param_names.append(', ' .join(44 random.sample(WORDS, param_count)))4546 for sentence in snippet, phrase:47 result = sentence[:]4849 # fake class names50 for word in class_names:51 result = result.replace("%%%", word, 1)

Page 191: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

5253 # fake other names54 for word in other_names:55 result = result.replace("***", word, 1)5657 # fake parameter lists58 for word in param_names:59 result = result.replace("@@@", word, 1)6061 results.append(result)6263 return results646566 # keep going until they hit CTRL-D67 try:68 while True:69 snippets = list(PHRASES.keys())70 random.shuffle(snippets)7172 for snippet in snippets:73 phrase = PHRASES[snippet]74 question, answer = convert(snippet, phrase)75 if PHRASE_FIRST:76 question, answer = answer, question7778 print(question)7980 input("> ")81 print(f"ANSWER: {answer}\n\n")82 except EOFError:83 print("\nBye")

Run this script and try to translate the “object-oriented phrases” into Englishtranslations. You should see that the PHRASES dict has both forms and thatyou just have to enter the correct one.

Practice English to Code

Next you should run the script with the “english” option so that you drill theinverse operation:

$ python oop_test . py english

Page 192: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Remember that these phrases are using nonsense words. Part of learning toread code well is to stop placing so much meaning on the names used forvariables and classes. Too often people will read a word like “Cork” andsuddenly get derailed because that word will confuse them about themeaning. In the above example, “Cork” is just an arbitrary name chosen for aclass. Don’t place any other meaning on it, and instead treat it like thepatterns I’ve given you.

Reading More Code

You are now to go on a new quest to read even more code, to read thephrases you just learned in the code you read. You will look for all the fileswith classes and then do the following:

1. For each class give its name and what other classes it inherits from.

2. Under that, list every function it has and the parameters they take.

3. List all of the attributes it uses on its self.

4. For each attribute, give the class this attribute is.

The goal is to go through real code and start learning to “pattern match” thephrases you just learned against how they’re used. If you drill this enoughyou should start to see these patterns shout at you in the code whereas beforethey just seemed like vague blank spots you didn’t know.

Common Student Questions

What does result = sentence[:] do? That’s a Python way of copying alist. You’re using the list slice syntax [:] to effectively make a slice from thevery first element to the very last one.

This script is hard to get running! By this point you should be able to typethis in and get it working. It does have a few little tricks here and there, butthere’s nothing complex about it. Just do all the things you’ve learned so farto debug scripts. Type each line in, confirm that it’s exactly like mine, and

Page 193: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

research anything you don’t know online.

It’s still too hard! You can do this. Take it very slow, character by characterif you have to, but type it in exactly and figure out what it does.

Page 194: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 42. Is-A, Has-A, Objects, andClassesAn important concept that you have to understand is the difference between aclass and an object. The problem is, there is no real “difference” between aclass and an object. They are actually the same thing at different points intime. I will demonstrate by a Zen koan:

What i s the difference between a f i s h and a salmon?

Did that question sort of confuse you? Really sit down and think about it for aminute. I mean, a fish and a salmon are different but, wait, they are the samething, right? A salmon is a kind of fish, so I mean it’s not different. But at thesame time, a salmon is a particular type of fish so it’s actually different fromall other fish. That’s what makes it a salmon and not a halibut. So a salmonand a fish are the same but different. Weird.

This question is confusing because most people do not think about real thingsthis way, but they intuitively understand them. You do not need to thinkabout the difference between a fish and a salmon because you know how theyare related. You know a salmon is a kind of fish and that there are other kindsof fish without having to understand that.

Let’s take it one step further. Let’s say you have a bucket full of three salmonand because you are a nice person, you have decided to name them Frank,Joe, and Mary. Now, think about this question:

What i s the difference between Mary and a salmon?

Again this is a weird question, but it’s a bit easier than the fish versus salmonquestion. You know that Mary is a salmon, so she’s not really different. She’sjust a specific “instance” of a salmon. Joe and Frank are also instances ofsalmon. What do I mean when I say instance? I mean they were created fromsome other salmon and now represent a real thing that has salmon-likeattributes.

Page 195: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Now for the mind-bending idea: Fish is a class, and Salmon is a class, andMary is an object. Think about that for a second. Let’s break it down slowlyand see if you get it.

A fish is a class, meaning it’s not a real thing, but rather a word we attach toinstances of things with similar attributes. Got fins? Got gills? Lives inwater? Alright it’s probably a fish.

Someone with a Ph.D. then comes along and says, “No, my young friend, thisfish is actually Salmo salar, affectionately known as a salmon.” Thisprofessor has just clarified the fish further, and made a new class called“Salmon” that has more specific attributes. Longer nose, reddish flesh, big,lives in the ocean or fresh water, tasty? Probably a salmon.

Finally, a cook comes along and tells the Ph.D., “No, you see this Salmonright here, I’ll call her Mary, and I’m going to make a tasty fillet out of herwith a nice sauce.” Now you have this instance of a salmon (which also is aninstance of a fish) named Mary turned into something real that is filling yourbelly. It has become an object.

There you have it: Mary is a kind of salmon that is a kind of fish—object is aclass is a class.

How This Looks in Code

This is a weird concept, but to be very honest you only have to worry about itwhen you make new classes and when you use a class. I will show you twotricks to help you figure out whether something is a class or an object.

First, you need to learn two catch phrases “is-a” and “has-a.” You use thephrase is-a when you talk about objects and classes being related to eachother by a class relationship. You use has-a when you talk about objects andclasses that are related only because they reference each other.

Now, go through this piece of code and replace each ##?? comment with acomment that says whether the next line represents an is-a or a has-arelationship and what that relationship is. In the beginning of the code, I’ve

Page 196: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

laid out a few examples, so you just have to write the remaining ones.

Remember, is-a is the relationship between fish and salmon, while has-a isthe relationship between salmon and gills.

ex42.py

1 ## Animal is-a object (yes, sort of confusing) look at the extra credit 2 class Animal(object): 3 pass 4 5 ## ?? 6 class Dog(Animal): 7 8 def __init__(self, name): 9 ## ??10 self.name = name1112 ## ??13 class Cat(Animal):1415 def __init__(self, name):16 ## ??17 self.name = name1819 ## ??20 class Person(object):2122 def __init__(self, name):23 ## ??24 self.name = name2526 ## Person has-a pet of some kind27 self.pet = None2829 ## ??30 class Employee(Person):3132 def __init__(self, name, salary):33 ## ?? hmm what is this strange magic?34 super(Employee, self).__init__(name)35 ## ??36 self.salary = salary3738 ## ??

Page 197: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

39 class Fish(object):40 pass4142 ## ??43 class Salmon(Fish):44 pass4546 ## ??47 class Halibut(Fish):48 pass495051 ## rover is-a Dog52 rover = Dog("Rover")5354 ## ??55 satan = Cat("Satan")5657 ## ??58 mary = Person("Mary")5960 ## ??61 mary.pet = satan6263 ## ??64 frank = Employee("Frank", 120000)6566 ## ??67 frank.pet = rover6869 ## ??70 flipper = Fish()7172 ## ??73 crouse = Salmon()7475 ## ??76 harry = Halibut()

About class Name(object)

Remember how I was yelling at you to always use class Name(object), andI couldn’t tell you why? Now I can tell you, because you just learned aboutthe difference between a class and an object. I couldn’t tell you until nowbecause you would have just been confused and couldn’t learn to use the

Page 198: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

technology.

What happened is Python’s original rendition of class was broken in manyserious ways. By the time they admitted the fault it was too late, and they hadto support it. In order to fix the problem, they needed some “new class” styleso that the “old classes” would keep working, but you could use the newmore correct version.

This is where “class is-a object” comes in. They decided that they woulduse the word “object,” lowercased, to be the “class” that you inherit from tomake a class. Confusing, right? A class inherits from the class named objectto make a class but it’s not an object really it’s a class, but do not forget toinherit from object.

Exactly. The choice of one single word meant that I couldn’t teach you aboutthis until now. Now you can try to understand the concept of a class that is anobject if you like.

However, I would suggest you do not. Just completely ignore the idea of oldstyle versus new style classes and assume that Python always requires(object) when you make a class. Save your brain power for somethingimportant.

Study Drills

1. Research why Python added this strange object class and what that means.

2. Is it possible to use a class like it’s an object?

3. Fill out the animals, fish, and people in this exercise with functions thatmake them do things. See what happens when functions are in a “base class”like Animal versus in, say, Dog.

4. Find other people’s code and work out all the is-a and has-a relationships.

5. Make some new relationships that are lists and dictionaries so you can alsohave “has-many” relationships.

Page 199: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

6. Do you think there’s such thing as an “is-many” relationship? Read about“multiple inheritance,” then avoid it if you can.

Common Student Questions

What are these ## ?? comments for? Those are “fill-in-the-blank”comments that you are supposed to fill in with the right “is-a,” “has-a”concepts. Read this exercise again and look at the other comments to seewhat I mean.

What is the point of self.pet = None? That makes sure that the self.petattribute of that class is set to a default of None.

What does super(Employee, self).__init__(name) do? That’s how youcan run the __init__ method of a parent class reliably. Search for “python3.6super” and read the various advice on it being evil and good for you.

Page 200: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 43. Basic Object-Oriented Analysisand DesignI’m going to describe a process to use when you want to build somethingusing Python, specifically with object-oriented programming (OOP). What Imean by a “process” is that I’ll give you a set of steps that you do in order butthat you aren’t meant to be a slave to or that will totally always work forevery problem. They are just a good starting point for many programmingproblems and shouldn’t be considered the only way to solve these types ofproblems. This process is just one way to do it that you can follow.

The process is as follows:

1. Write or draw about the problem.

2. Extract key concepts from 1 and research them.

3. Create a class hierarchy and object map for the concepts.

4. Code the classes and a test to run them.

5. Repeat and refine.

The way to look at this process is that it is “top down,” meaning it starts fromthe very abstract loose idea and then slowly refines it until the idea is solidand something you can code.

I start by just writing about the problem and trying to think up anything I canabout it. Maybe I’ll even draw a diagram or two, maybe a map of some kind,or even write myself a series of emails describing the problem. This gives mea way to express the key concepts in the problem and also explore what Imight already know about it.

Then I go through these notes, drawings, and descriptions, and I pull out thekey concepts. There’s a simple trick to doing this: Simply make a list of all

Page 201: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

the nouns and verbs in your writing and drawings, then write out how they’rerelated. This gives me a good list of names for classes, objects, and functionsin the next step. I take this list of concepts and then research any that I don’tunderstand so I can refine them further if needed.

Once I have my list of concepts I create a simple outline/tree of the conceptsand how they are related as classes. You can usually take your list of nounsand start asking “Is this one like other concept nouns? That means they havea common parent class, so what is it called?” Keep doing this until you havea class hierarchy that’s just a simple tree list or a diagram. Then take theverbs you have and see if those are function names for each class and putthem in your tree.

With this class hierarchy figured out, I sit down and write some basicskeleton code that has just the classes, their functions, and nothing more. Ithen write a test that runs this code and makes sure the classes I’ve mademake sense and work right. Sometimes I may write the test first though, andother times I might write a little test, a little code, a little test, etc. until I havethe whole thing built.

Finally, I keep cycling over this process repeating it and refining as I go andmaking it as clear as I can before doing more implementation. If I get stuck atany particular part because of a concept or problem I haven’t anticipated,then I sit down and start the process over on just that part to figure it out morebefore continuing.

I will now go through this process while coming up with a game engine and agame for this exercise.

The Analysis of a Simple Game Engine

The game I want to make is called “Gothons from Planet Percal #25,” and itwill be a small space adventure game. With nothing more than that concept inmy mind, I can explore the idea and figure out how to make the game cometo life.

43.1.1 Write or Draw About the Problem

Page 202: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

I’m going to write a little paragraph for the game:

“Aliens have invaded a space ship and our hero has to go through a maze ofrooms defeating them so he can escape into an escape pod to the planetbelow. The game will be more like a Zork or Adventure type game with textoutputs and funny ways to die. The game will involve an engine that runs amap full of rooms or scenes. Each room will print its own description whenthe player enters it and then tell the engine what room to run next out of themap.”

At this point I have a good idea for the game and how it would run, so now Iwant to describe each scene:

Death This is when the player dies and should be something funny.

Central Corridor This is the starting point and has a Gothon alreadystanding there that the players have to defeat with a joke before continuing.

Laser Weapon Armory This is where the hero gets a neutron bomb to blowup the ship before getting to the escape pod. It has a keypad the hero has toguess the number for.

The Bridge Another battle scene with a Gothon where the hero places thebomb.

Escape Pod Where the hero escapes but only after guessing the right escapepod.

At this point I might draw out a map of these, maybe write more descriptionsof each room—whatever comes to mind as I explore the problem.

43.1.2 Extract Key Concepts and Research Them

I now have enough information to extract some of the nouns and analyzetheir class hierarchy. First I make a list of all the nouns:

• Alien

Page 203: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

• Player

• Ship

• Maze

• Room

• Scene

• Gothon

• Escape Pod

• Planet

• Map

• Engine

• Death

• Central Corridor

• Laser Weapon Armory

• The Bridge

I would also possibly go through all the verbs and see if they are anythingthat might be good function names, but I’ll skip that for now.

At this point you might also research each of these concepts and anything youdon’t know right now. For example, I might play a few of these types ofgames and make sure I know how they work. I might research how ships aredesigned or how bombs work. Maybe I’ll research some technical issue likehow to store the game’s state in a database. After I’ve done this research Imight start over at step 1 based on new information I have and rewrite mydescription and extract new concepts.

Page 204: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

43.1.3 Create a Class Hierarchy and Object Map for the Concepts

Once I have that I turn it into a class hierarchy by asking “What is similar toother things?” I also ask “What is basically just another word for anotherthing?”

Right away I see that “Room” and “Scene” are basically the same thingdepending on how I want to do things. I’m going to pick “Scene” for thisgame. Then I see that all the specific rooms like “Central Corridor” arebasically just Scenes. I see also that Death is basically a Scene, whichconfirms my choice of “Scene” over “Room” since you can have a deathscene, but a death room is kind of odd. “Maze” and “Map” are basically thesame so I’m going to go with “Map” since I used it more often. I don’t wantto do a battle system, so I’m going to ignore “Alien” and “Player” and savethat for later. The “Planet” could also just be another scene instead ofsomething specific.

After all of that thought process I start to make a class hierarchy that lookslike this in my text editor:

* Map* Engine* Scene * Death * Central Corridor * Laser Weapon Armory * The Bridge * Escape Pod

I would then go through and figure out what actions are needed on each thingbased on verbs in the description. For example, I know from the descriptionI’m going to need a way to “run” the engine, “get the next scene” from themap, get the “opening scene,” and “enter” a scene. I’ll add those like this:

* Map – next_scene – opening_scene* Engine – play* Scene – enter

Page 205: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

* Death * Central Corridor * Laser Weapon Armory * The Bridge * Escape Pod

Notice how I just put -enter under Scene since I know that all the scenesunder it will inherit it and have to override it later.

43.1.4 Code the Classes and a Test to Run Them

Once I have this tree of classes and some of the functions I open up a sourcefile in my editor and try to write the code for it. Usually I’ll just copy-pastethe tree into the source file and then edit it into classes. Here’s a smallexample of how this might look at first, with a simple little test at the end ofthe file.

ex43_classes.py

1 class Scene(object): 2 3 def enter(self): 4 pass 5 6 7 class Engine(object): 8 9 def __init__(self, scene_map):10 pass1112 def play(self):13 pass1415 class Death(Scene):1617 def enter(self):18 pass1920 class CentralCorridor(Scene):2122 def enter(self):23 pass24

Page 206: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

25 class LaserWeaponArmory(Scene):2627 def enter(self):28 pass2930 class TheBridge(Scene):3132 def enter(self):33 pass3435 class EscapePod(Scene):3637 def enter(self):38 pass394041 class Map(object):4243 def __init__(self, start_scene):44 pass4546 def next_scene(self, scene_name):47 pass4849 def opening_scene(self):50 pass515253 a_map = Map('central_corridor')54 a_game = Engine(a_map)55 a_game.play()

In this file you can see that I simply replicated the hierarchy I wanted andthen added a little bit of code at the end to run it and see if it all works in thisbasic structure. In the later sections of this exercise you’ll fill in the rest ofthis code and make it work to match the description of the game.

43.1.5 Repeat and Refine

The last step in my little process isn’t so much a step as it is a while-loop.You don’t ever do this as a one-pass operation. Instead you go back over thewhole process again and refine it based on information you’ve learned fromlater steps. Sometimes I’ll get to step 3 and realize that I need to work on 1and 2 more, so I’ll stop and go back and work on those. Sometimes I’ll get a

Page 207: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

flash of inspiration and jump to the end to code up the solution in my headwhile I have it there, but then I’ll go back and do the previous steps to makesure I cover all the possibilities I have.

The other idea in this process is that it’s not just something you do at onesingle level but something that you can do at every level when you run into aparticular problem. Let’s say I don’t know how to write the Engine.playmethod yet. I can stop and do this whole process on just that one function tofigure out how to write it.

Top Down versus Bottom Up

The process is typically labeled “top down” since it starts at the most abstractconcepts (the top) and works its way down to actual implementation. I wantyou to use this process I just described when analyzing problems in the bookfrom now on, but you should know that there’s another way to solveproblems in programming that starts with code and goes “up” to the abstractconcepts. This other way is labeled “bottom up.” Here are the general stepsyou follow to do this:

1. Take a small piece of the problem; hack on some code and get it to runbarely.

2. Refine the code into something more formal with classes and automatedtests.

3. Extract the key concepts you’re using and try to find research for them.

4. Write a description of what’s really going on.

5. Go back and refine the code, possibly throwing it out and starting over.

6. Repeat, moving on to some other piece of the problem.

I find this process is better once you’re more solid at programming and arenaturally thinking in code about problems. This process is very good whenyou know small pieces of the overall puzzle, but maybe don’t have enoughinformation yet about the overall concept. Breaking it down in little pieces

Page 208: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

and exploring with code then helps you slowly grind away at the problemuntil you’ve solved it. However, remember that your solution will probablybe meandering and weird, so that’s why my version of this process involvesgoing back and finding research, then cleaning things up based on whatyou’ve learned.

The Code for “Gothons from Planet Percal #25“

Stop! I’m going to show you my final solution to the preceding problem, butI don’t want you to just jump in and type this up. I want you to take the roughskeleton code I did and try to make it work based on the description. Onceyou have your solution then you can come back and see how I did it.

I’m going to break this final file ex43.py down into sections and explain eachone rather than dump all the code at once.

ex43.py

1 from sys import exit2 from random import randint3 from textwrap import dedent

This is just our basic imports for the game. The only new thing is the importof the dedent function from the textwrap module. This little function willhelp us write our room descriptions using """ (triple-quote) strings. It simplystrips leading white-space from the beginning of lines in a string. Withoutthis function using """ style strings fails because they are indented on thescreen the same level as in the Python code.

ex43.py

1 class Scene(object):23 def enter(self):4 print("This scene is not yet configured.")5 print("Subclass it and implement enter().")6 exit(1)

Page 209: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

As you saw in the skeleton code, I have a base class for Scene that will havethe common things that all scenes do. In this simple program they don’t domuch, so this is more a demonstration of what you would do to make a baseclass.

ex43.py

1 class Engine(object): 2 3 def __init__(self, scene_map): 4 self.scene_map = scene_map 5 6 def play(self): 7 current_scene = self.scene_map.opening_scene() 8 last_scene = self.scene_map.next_scene('finished') 910 while current_scene != last_scene:11 next_scene_name = current_scene.enter()12 current_scene = self.scene_map.next_scene(next_scene_name)1314 # be sure to print out the last scene15 current_scene.enter()

I also have my Engine class, and you can see how I’m already using themethods for Map.opening_scene and Map.next_scene. Because I’ve done abit of planning I can just assume I’ll write those and then use them beforeI’ve written the Map class.

ex43.py

1 class Death(Scene): 2 3 quips = [ 4 "You died. You kinda suck at this.", 5 "Your Mom would be proud...if she were smarter.", 6 "Such a luser.", 7 "I have a small puppy that's better at this.", 8 "You're worse than your Dad's jokes." 910 ]1112 def enter(self):13 print(Death.quips[randint(0, len(self.quips)-1)])

Page 210: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

14 exit(1)

My first scene is the odd scene named Death, which shows you the simplestkind of scene you can write.

ex43.py

1 class CentralCorridor(Scene): 2 3 def enter(self): 4 print(dedent(""" 5 The Gothons of Planet Percal #25 have invaded your ship and 6 destroyed your entire crew. You are the last surviving 7 member and your last mission is to get the neutron destruct 8 bomb from the Weapons Armory, put it in the bridge, and 9 blow the ship up after getting into an escape pod.1011 You're running down the central corridor to the Weapons12 Armory when a Gothon jumps out, red scaly skin, dark grimy13 teeth, and evil clown costume flowing around his hate14 filled body. He's blocking the door to the Armory and15 about to pull a weapon to blast you.16 """))1718 action = input("> ")1920 if action == "shoot!":21 print(dedent("""22 Quick on the draw you yank out your blaster and fire23 it at the Gothon. His clown costume is flowing and24 moving around his body, which throws off your aim.25 Your laser hits his costume but misses him entirely.26 This completely ruins his brand new costume his mother27 bought him, which makes him fly into an insane rage28 and blast you repeatedly in the face until you are29 dead. Then he eats you.30 """))31 return 'death'3233 elif action == "dodge!":34 print(dedent("""35 Like a world class boxer you dodge, weave, slip and36 slide right as the Gothon's blaster cranks a laser37 past your head. In the middle of your artful dodge38 your foot slips and you bang your head on the metal39 wall and pass out. You wake up shortly after only to

Page 211: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

40 die as the Gothon stomps on your head and eats you.41 """))42 return 'death'4344 elif action == "tell a joke":45 print(dedent("""46 Lucky for you they made you learn Gothon insults in47 the academy. You tell the one Gothon joke you know:48 Lbhe zbgure vf fb sng, jura fur fvgf nebhaq gur ubhfr,49 fur fvgf nebhaq gur ubhfr. The Gothon stops, tries50 not to laugh, then busts out laughing and can't move.51 While he's laughing you run up and shoot him square in52 the head putting him down, then jump through the53 Weapon Armory door.54 """))55 return 'laser_weapon_armory'5657 else:58 print("DOES NOT COMPUTE!")59 return 'central_corridor'

After that I’ve created the CentralCorridor, which is the start of the game.I’m doing the scenes for the game before the Map because I need to referencethem later. You should also see how I use the dedent function on line 4. Tryremoving it later to see what it does.

ex43.py

1 class LaserWeaponArmory(Scene): 2 3 def enter(self): 4 print(dedent(""" 5 You do a dive roll into the Weapon Armory, crouch and scan 6 the room for more Gothons that might be hiding. It's dead 7 quiet, too quiet. You stand up and run to the far side of 8 the room and find the neutron bomb in its container. 9 There's a keypad lock on the box and you need the code to 10 get the bomb out. If you get the code wrong 10 times then 11 the lock closes forever and you can't get the bomb. The 12 code is 3 digits. 13 """)) 14 15 code = f"{randint(1,9)}{randint(1,9)}{randint(1,9)}" 16 guess = input("[keypad]> ") 17 guesses = 0

Page 212: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

18 19 while guess != code and guesses < 10: 20 print("BZZZZEDDD!") 21 guesses += 1 22 guess = input("[keypad]> ") 23 24 if guess == code: 25 print(dedent(""" 26 The container clicks open and the seal breaks, letting 27 gas out. You grab the neutron bomb and run as fast as 28 you can to the bridge where you must place it in the 29 right spot. 30 """)) 31 return 'the_bridge' 32 else: 33 print(dedent(""" 34 The lock buzzes one last time and then you hear a 35 sickening melting sound as the mechanism is fused 36 together. You decide to sit there, and finally the 37 Gothons blow up the ship from their ship and you die. 38 """)) 39 return 'death' 40 41 42 43 class TheBridge(Scene): 44 45 def enter(self): 46 print(dedent(""" 47 You burst onto the Bridge with the netron destruct bomb 48 under your arm and surprise 5 Gothons who are trying to 49 take control of the ship. Each of them has an even uglier 50 clown costume than the last. They haven't pulled their 51 weapons out yet, as they see the active bomb under your 52 arm and don't want to set it off. 53 """)) 54 55 action = input("> ") 56 57 if action == "throw the bomb": 58 print(dedent(""" 59 In a panic you throw the bomb at the group of Gothons 60 and make a leap for the door. Right as you drop it a 61 Gothon shoots you right in the back killing you. As 62 you die you see another Gothon frantically try to 63 disarm the bomb. You die knowing they will probably 64 blow up when it goes off. 65 """))

Page 213: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

66 return 'death' 67 68 elif action == "slowly place the bomb": 69 print(dedent(""" 70 You point your blaster at the bomb under your arm and 71 the Gothons put their hands up and start to sweat. 72 You inch backward to the door, open it, and then 73 carefully place the bomb on the floor, pointing your 74 blaster at it. You then jump back through the door, 75 punch the close button and blast the lock so the 76 Gothons can't get out. Now that the bomb is placed 77 you run to the escape pod to get off this tin can. 78 """)) 79 80 return 'escape_pod' 81 else: 82 print("DOES NOT COMPUTE!") 83 return "the_bridge" 84 85 86 class EscapePod(Scene): 87 88 def enter(self): 89 print(dedent(""" 90 You rush through the ship desperately trying to make it to 91 the escape pod before the whole ship explodes. It seems 92 like hardly any Gothons are on the ship, so your run is 93 clear of interference. You get to the chamber with the 94 escape pods, and now need to pick one to take. Some of 95 them could be damaged but you don't have time to look. 96 There's 5 pods, which one do you take? 97 """)) 98 99 good_pod = randint(1,5)100 guess = input("[pod #]> ")101102103 if int(guess) != good_pod:104 print(dedent("""105 You jump into pod {guess} and hit the eject button.106 The pod escapes out into the void of space, then107 implodes as the hull ruptures, crushing your body into108 jam jelly.109 """))110 return 'death'111 else:112 print(dedent("""113 You jump into pod {guess} and hit the eject button.

Page 214: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

114 The pod easily slides out into space heading to the115 planet below. As it flies to the planet, you look116 back and see your ship implode then explode like a117 bright star, taking out the Gothon ship at the same118 time. You won!119 """))120121 return 'finished'122123 class Finished(Scene):124125 def enter(self):126 print("You won! Good job.")127 return 'finished'

This is the rest of the game’s scenes, and since I know I need them and havethought about how they’ll flow together I’m able to code them up directly.

Incidentally, I wouldn’t just type all this code in. Remember I said to try andbuild this incrementally, one little bit at a time. I’m just showing you the finalresult.

ex43.py

1 class Map(object): 2 3 scenes = { 4 'central_corridor': CentralCorridor(), 5 'laser_weapon_armory': LaserWeaponArmory(), 6 'the_bridge': TheBridge(), 7 'escape_pod': EscapePod(), 8 'death': Death(), 9 'finished': Finished(),10 }1112 def __init__(self, start_scene):13 self.start_scene = start_scene1415 def next_scene(self, scene_name):16 val = Map.scenes.get(scene_name)17 return val1819 def opening_scene(self):20 return self.next_scene(self.start_scene)

Page 215: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

After that I have my Map class, and you can see it is storing each scene byname in a dictionary, and then I refer to that dict with Map.scenes. This isalso why the map comes after the scenes because the dictionary has to refer tothe scenes, so they have to exist.

ex43.py

1 a_map = Map('central_corridor')2 a_game = Engine(a_map)3 a_game.play()

Finally I’ve got my code that runs the game by making a Map, then handingthat map to an Engine before calling play to make the game work.

What You Should See

Make sure you understand the game and that you tried to solve it yourselffirst. One thing to do if you’re stumped is cheat a little by reading my code,then continue trying to solve it yourself.

When I run my game it looks like this:

Exercise 43 Session

$ python3.6 ex43.py

The Gothons of Planet Percal #25 have invaded your ship anddestroyed your entire crew. You are the last survivingmember and your last mission is to get the neutron destructbomb from the Weapons Armory, put it in the bridge, andblow the ship up after getting into an escape pod.

You're running down the central corridor to the WeaponsArmory when a Gothon jumps out, red scaly skin, dark grimyteeth, and evil clown costume flowing around his hatefilled body. He's blocking the door to the Armory andabout to pull a weapon to blast you.

> dodge!

Page 216: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Like a world class boxer you dodge, weave, slip andslide right as the Gothon's blaster cranks a laserpast your head. In the middle of your artful dodgeyour foot slips and you bang your head on the metalwall and pass out. You wake up shortly after only todie as the Gothon stomps on your head and eats you.

You're worse than your Dad's jokes.

Study Drills

1. Change it! Maybe you hate this game. It could be too violent, or maybeyou aren’t into sci-fi. Get the game working, then change it to what you like.This is your computer; you make it do what you want.

2. I have a bug in this code. Why is the door lock guessing 11 times?

3. Explain how returning the next room works.

4. Add cheat codes to the game so you can get past the more difficult rooms.I can do this with two words on one line.

5. Go back to my description and analysis, then try to build a small combatsystem for the hero and the various Gothons he encounters.

6. This is actually a small version of something called a “finite statemachine.” Read about them. They might not make sense, but try anyway.

Common Student Questions

Where can I find stories for my own games? You can make them up, justlike you would tell a story to a friend. Or you can take simple scenes from abook or movie you like.

Page 217: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 44. Inheritance VersusCompositionIn the fairy tales about heroes defeating evil villains there’s always a darkforest of some kind. It could be a cave, a forest, another planet, just someplace that everyone knows the hero shouldn’t go. Of course, shortly after thevillain is introduced you find out, yes, the hero has to go to that stupid forestto kill the bad guy. It seems the hero just keeps getting into situations thatrequire him to risk his life in this evil forest.

You rarely read fairy tales about the heroes who are smart enough to justavoid the whole situation entirely. You never hear a hero say, “Wait aminute, if I leave to make my fortunes on the high seas, leaving Buttercupbehind, I could die and then she’d have to marry some ugly prince namedHumperdink. Humperdink! I think I’ll stay here and start a Farm Boy forRent business.” If he did that there’d be no fire swamp, dying, reanimation,sword fights, giants, or any kind of story really. Because of this, the forest inthese stories seems to exist like a black hole that drags the hero in no matterwhat they do.

In object-oriented programming, inheritance is the evil forest. Experiencedprogrammers know to avoid this evil because they know that deep inside theDark Forest Inheritance is the Evil Queen Multiple Inheritance. She likes toeat software and programmers with her massive complexity teeth, chewingon the flesh of the fallen. But the forest is so powerful and so tempting thatnearly every programmer has to go into it and try to make it out alive with theEvil Queen’s head before they can call themselves real programmers. Youjust can’t resist the Inheritance Forest’s pull, so you go in. After theadventure you learn to just stay out of that stupid forest and bring an army ifyou are ever forced to go in again.

This is basically a funny way to say that I’m going to teach you somethingyou should use carefully called inheritance. Programmers who are currentlyin the forest battling the Queen will probably tell you that you have to go in.They say this because they need your help since what they’ve created is

Page 218: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

probably too much for them to handle. But you should always remember this:

Most of the uses of inheritance can be simplified or replaced withcomposition, and multiple inheritance should be avoided at all costs.

What Is Inheritance?

Inheritance is used to indicate that one class will get most or all of its featuresfrom a parent class. This happens implicitly whenever you write classFoo(Bar), which says “Make a class Foo that inherits from Bar.” When youdo this, the language makes any action that you do on instances of Foo alsowork as if they were done to an instance of Bar. Doing this lets you putcommon functionality in the Bar class, then specialize that functionality inthe Foo class as needed.

When you are doing this kind of specialization, there are three ways that theparent and child classes can interact:

1. Actions on the child imply an action on the parent.

2. Actions on the child override the action on the parent.

3. Actions on the child alter the action on the parent.

I will now demonstrate each of these in order and show you code for them.

44.1.1 Implicit Inheritance

First I will show you the implicit actions that happen when you define afunction in the parent but not in the child.

ex44a.py

1 class Parent(object): 2 3 def implicit(self): 4 print("PARENT implicit()") 5

Page 219: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

6 class Child(Parent): 7 pass 8 9 dad = Parent()10 son = Child()1112 dad.implicit()13 son.implicit()

The use of pass under the class Child: is how you tell Python that youwant an empty block. This creates a class named Child but says that there’snothing new to define in it. Instead it will inherit all of its behavior fromParent. When you run this code you get the following:

Exercise 44a Session

$ python3.6 ex44a.pyPARENT implicit()PARENT implicit()

Notice how even though I’m calling son.implicit() on line 16 and eventhough Child does not have an implicit function defined, it still works, andit calls the one defined in Parent. This shows you that if you put functions ina base class (i.e., Parent), then all subclasses (i.e., Child) will automaticallyget those features. Very handy for repetitive code you need in many classes.

44.1.2 Override Explicitly

The problem with having functions called implicitly is sometimes you wantthe child to behave differently. In this case you want to override the functionin the child, effectively replacing the functionality. To do this just define afunction with the same name in Child. Here’s an example:

ex44b.py

1 class Parent(object): 2 3 def override(self): 4 print("PARENT override()") 5

Page 220: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

6 class Child(Parent): 7 8 def override(self): 9 print("CHILD override()")1011 dad = Parent()12 son = Child()1314 dad.override()15 son.override()

In this example I have a function named override in both classes, so let’s seewhat happens when you run it.

Exercise 44b Session

$ python3.6 ex44b.pyPARENT override()CHILD override()

As you can see, when line 14 runs, it runs the Parent.override functionbecause that variable (dad) is a Parent. But when line 15 runs, it prints outthe Child.override messages because son is an instance of Child and Childoverrides that function by defining its own version.

Take a break right now and try playing with these two concepts beforecontinuing.

44.1.3 Alter Before or After

The third way to use inheritance is a special case of overriding where youwant to alter the behavior before or after the Parent class’s version runs. Youfirst override the function just like in the last example, but then you use aPython built-in function named super to get the Parent version to call.Here’s the example of doing that so you can make sense of this description:

ex44c.py

1 class Parent(object): 2

Page 221: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

3 def altered(self): 4 print("PARENT altered()") 5 6 class Child(Parent): 7 8 def altered(self): 9 print("CHILD, BEFORE PARENT altered()")10 super(Child, self).altered()11 print("CHILD, AFTER PARENT altered()")1213 dad = Parent()14 son = Child()1516 dad.altered()17 son.altered()

The important lines here are 9-11, where in the Child I do the followingwhen son.altered() is called:

1. Because I’ve overridden Parent.altered the Child.altered version runs,and line 9 executes like you’d expect.

2. In this case I want to do a before and after, so after line 9 I want to usesuper to get the Parent.altered version.

3. On line 10 I call super(Child, self).altered(), which is aware ofinheritance and will get the Parent class for you. You should be able to readthis as “call super with arguments Child and self, then call the functionaltered on whatever it returns.”

4. At this point, the Parent.altered version of the function runs, and thatprints out the Parent message.

5. Finally, this returns from the Parent.altered, and the Child.alteredfunction continues to print out the after message.

If you run this, you should see this:

Exercise 44c Session

$ python3.6 ex44c.py

Page 222: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

PARENT altered()CHILD, BEFORE PARENT altered()PARENT altered()CHILD, AFTER PARENT altered()

44.1.4 All Three Combined

To demonstrate all of these, I have a final version that shows each kind ofinteraction from inheritance in one file:

ex44d.py

1 class Parent(object): 2 3 def override(self): 4 print("PARENT override()") 5 6 def implicit(self): 7 print("PARENT implicit()") 8 9 def altered(self):10 print("PARENT altered()")1112 class Child(Parent):1314 def override(self):15 print("CHILD override()")1617 def altered(self):18 print("CHILD, BEFORE PARENT altered()")19 super(Child, self).altered()20 print("CHILD, AFTER PARENT altered()")2122 dad = Parent()23 son = Child()2425 dad.implicit()26 son.implicit()2728 dad.override()29 son.override()3031 dad.altered()32 son.altered()

Page 223: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Go through each line of this code, and write a comment explaining what thatline does and whether it’s an override or not. Then run it and confirm you getwhat you expected:

Exercise 44d Session

$ python3.6 ex44d.pyPARENT implicit()PARENT implicit()PARENT override()CHILD override()PARENT altered()CHILD, BEFORE PARENT altered()PARENT altered()CHILD, AFTER PARENT altered()

The Reason for super()

This should seem like common sense, but then we get into trouble with athing called multiple inheritance. Multiple inheritance is when you define aclass that inherits from one or more classes, like this:

class SuperFun (Child, BadStuff): pass

This is like saying, “Make a class named SuperFun that inherits from theclasses Child and BadStuff at the same time.”

In this case, whenever you have implicit actions on any SuperFun instance,Python has to look-up the possible function in the class hierarchy for bothChild and BadStuff, but it needs to do this in a consistent order. To do thisPython uses “method resolution order” (MRO) and an algorithm called C3 toget it straight.

Because the MRO is complex and a well-defined algorithm is used, Pythoncan’t leave it to you to get the MRO right. Instead, Python gives you thesuper() function, which handles all of this for you in the places that youneed the altering type of actions as I did in Child.altered. With super()you don’t have to worry about getting this right, and Python will find the

Page 224: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

right function for you.

44.2.1 Using super() with __init__

The most common use of super() is actually in __init__ functions in baseclasses. This is usually the only place where you need to do some things in achild, then complete the initialization in the parent. Here’s a quick example ofdoing that in the Child:

class Child (Parent):

def __init__(self, stuff): self.stuff = stuff super(Child, self).__init__( )

This is pretty much the same as the Child.altered example above, exceptI’m setting some variables in the __init__ before having the Parentinitialize with its Parent.__init__.

Composition

Inheritance is useful, but another way to do the exact same thing is just to useother classes and modules, rather than rely on implicit inheritance. If youlook at the three ways to exploit inheritance, two of the three involve writingnew code to replace or alter functionality. This can easily be replicated byjust calling functions in a module. Here’s an example of doing this:

ex44e.py

1 class Other(object): 2 3 def override(self): 4 print("OTHER override()") 5 6 def implicit(self): 7 print("OTHER implicit()") 8 9 def altered(self):10 print("OTHER altered()")11

Page 225: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

12 class Child(object):1314 def __init__(self):15 self.other = Other()1617 def implicit(self):18 self.other.implicit()1920 def override(self):21 print("CHILD override()")2223 def altered(self):24 print("CHILD, BEFORE OTHER altered()")25 self.other.altered()26 print("CHILD, AFTER OTHER altered()")2728 son = Child()2930 son.implicit()31 son.override()32 son.altered()

In this code I’m not using the name Parent, since there is not a parent-childis-a relationship. This is a has-a relationship, where Child has-a Otherthat it uses to get its work done. When I run this I get the following output:

Exercise 44e Session

$ python3.6 ex44e.pyOTHER implicit()CHILD override()CHILD, BEFORE OTHER altered()OTHER altered()CHILD, AFTER OTHER altered()

You can see that most of the code in Child and Other is the same toaccomplish the same thing. The only difference is that I had to define aChild.implicit function to do that one action. I could then ask myself if Ineed this Other to be a class, and could I just make it into a module namedother.py?

When to Use Inheritance or Composition

Page 226: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

The question of “inheritance versus composition” comes down to an attemptto solve the problem of reusable code. You don’t want to have duplicatedcode all over your software, since that’s not clean and efficient. Inheritancesolves this problem by creating a mechanism for you to have implied featuresin base classes. Composition solves this by giving you modules and thecapability to call functions in other classes.

If both solutions solve the problem of reuse, then which one is appropriate inwhich situations? The answer is incredibly subjective, but I’ll give you mythree guidelines for when to do which:

1. Avoid multiple inheritance at all costs, as it’s too complex to be reliable. Ifyou’re stuck with it, then be prepared to know the class hierarchy and spendtime finding where everything is coming from.

2. Use composition to package code into modules that are used in manydifferent unrelated places and situations.

3. Use inheritance only when there are clearly related reusable pieces of codethat fit under a single common concept or if you have to because ofsomething you’re using.

Do not be a slave to these rules. The thing to remember about object-orientedprogramming is that it is entirely a social convention programmers havecreated to package and share code. Because it’s a social convention, but onethat’s codified in Python, you may be forced to avoid these rules because ofthe people you work with. In that case, find out how they use things and thenjust adapt to the situation.

Study Drills

There is only one Study Drill for this exercise because it is a big exercise. Goand read http://www.python.org/dev/peps/pep-0008/ and start trying to use itin your code. You’ll notice that some of it is different from what you’ve beenlearning in this book, but now you should be able to understand theirrecommendations and use them in your own code. The rest of the code in thisbook may or may not follow these guidelines depending on whether it makes

Page 227: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

the code more confusing. I suggest you also do this, as comprehension ismore important than impressing everyone with your knowledge of esotericstyle rules.

Common Student Questions

How do I get better at solving problems that I haven’t seen before? Theonly way to get better at solving problems is to solve as many problems asyou can by yourself. Typically people hit a difficult problem and then rushout to find an answer. This is fine when you have to get things done, but ifyou have the time to solve it yourself, then take that time. Stop and bang yourhead against the problem for as long as possible, trying every possible thing,until you solve it or give up. After that the answers you find will be moresatisfying, and you’ll eventually get better at solving problems.

Aren’t objects just copies of classes? In some languages (like JavaScript)that is true. These are called prototype languages, and there are not manydifferences between objects and classes other than usage. In Python,however, classes act as templates that “mint” new objects, similar to howcoins were minted using a die (template).

Page 228: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 45. You Make a GameYou need to start learning to feed yourself. Hopefully as you have workedthrough this book, you have learned that all the information you need is onthe internet. You just have to go search for it. The only thing you have beenmissing are the right words and what to look for when you search. Now youshould have a sense of it, so it’s about time you struggled through a bigproject and tried to get it working.

Here are your requirements:

1. Make a different game from the one I made.

2. Use more than one file, and use import to use them. Make sure you knowwhat that is.

3. Use one class per room and give the classes names that fit their purpose(like GoldRoom, KoiPondRoom).

4. Your runner will need to know about these rooms, so make a class thatruns them and knows about them. There’s plenty of ways to do this, butconsider having each room return what room is next or setting a variable ofwhat room is next.

Other than that I leave it to you. Spend a whole week on this and make it thebest game you can. Use classes, functions, dicts, lists, anything you can tomake it nice. The purpose of this lesson is to teach you how to structureclasses that need other classes inside other files.

Remember, I’m not telling you exactly how to do this because you have to dothis yourself. Go figure it out. Programming is problem solving, and thatmeans trying things, experimenting, failing, scrapping your work, and tryingagain. When you get stuck, ask for help and show people your code. If theyare mean to you, ignore them, and focus on the people who are not mean andoffer to help. Keep working it and cleaning it until it’s good, then show itsome more.

Page 229: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Good luck, and see you in a week with your game.

Evaluating Your Game

In this exercise you will evaluate the game you just made. Maybe you gotpartway through it and you got stuck. Maybe you got it working but justbarely. Either way, we’re going to go through a bunch of things you shouldknow now and make sure you covered them in your game. We’re going tostudy properly formatting a class, common conventions in using classes, anda lot of “textbook” knowledge.

Why would I have you try to do it yourself and then show you how to do itright? From now on in the book I’m going to try to make you self-sufficient.I’ve been holding your hand mostly this whole time, and I can’t do that formuch longer. I’m now instead going to give you things to do, have you dothem on your own, and then give you ways to improve what you did.

You will struggle at first and probably be very frustrated, but stick with it andeventually you will build a mind for solving problems. You will start to findcreative solutions to problems rather than just copy solutions out oftextbooks.

Function Style

All the other rules I’ve taught you about how to make a nice function applyhere, but add these things:

• For various reasons, programmers call functions that are part of classes“methods”. It’s mostly marketing, but just be warned that every time you say“function” they’ll annoyingly correct you and say “method.” If they get tooannoying, just ask them to demonstrate the mathematical basis thatdetermines how a “method” is different from a “function” and they’ll shut up.

• When you work with classes much of your time is spent talking aboutmaking the class “do things.” Instead of naming your functions after what thefunction does, instead name it as if it’s a command you are giving to the

Page 230: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

class. Same as pop is saying “Hey list, pop this off.” It isn’t calledremove_from_end_of_list because even though that’s what it does, that’snot a command to a list.

• Keep your functions small and simple. For some reason when people startlearning about classes they forget this.

Class Style

• Your class should use “camel case” like SuperGoldFactory rather thansuper_gold_factory.

• Try not to do too much in your __init__ functions. It makes them harder touse.

• Your other functions should use “underscore format,” so writemy_awesome_hair and not myawesomehair or MyAwesomeHair.

• Be consistent in how you organize your function arguments. If your classhas to deal with users, dogs, and cats, keep that order throughout unless itreally doesn’t make sense. If you have one function that takes (dog, cat,user) and the other takes (user, cat, dog), it’ll be hard to use.

• Try not to use variables that come from the module or globals. They shouldbe fairly self-contained.

• A foolish consistency is the hobgoblin of little minds. Consistency is good,but foolishly following some idiotic mantra because everyone else does isbad style. Think for yourself.

• Always, always have class Name(object) format or else you will be in bigtrouble.

Code Style

• Give your code vertical space so people can read it. You will find somevery bad programmers who are able to write reasonable code but who do not

Page 231: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

add any spaces. This is bad style in any language because the human eye andbrain use space and vertical alignment to scan and separate visual elements.Not having space is the same as giving your code an awesome camouflagepaint job.

• If you can’t read it out loud, it’s probably hard to read. If you are having aproblem making something easy to use, try reading it out loud. Not only doesthis force you to slow down and really read it, but it also helps you finddifficult passages and things to change for readability.

• Try to do what other people are doing in Python until you find your ownstyle.

• Once you find your own style, do not be a jerk about it. Working with otherpeople’s code is part of being a programmer, and other people have reallybad taste. Trust me, you will probably have really bad taste too and not evenrealize it.

• If you find someone who writes code in a style you like, try writingsomething that mimics that style.

Good Comments

• Programmers will tell you that your code should be readable enough thatyou do not need comments. They’ll then tell you in their most officialsounding voice, “Ergo one should never write comments or documentation.QED.” Those programmers are either consultants who get paid more if otherpeople can’t use their code, or incompetents who tend to never work withother people. Ignore them and write comments.

• When you write comments, describe why you are doing what you are doing.The code already says how, but why you did things the way you did is moreimportant.

• When you write doc comments for your functions, make the commentsdocumentation for someone who will have to use your code. You do not haveto go crazy, but a nice little sentence about what someone can do with that

Page 232: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

function helps a lot.

• While comments are good, too many are bad, and you have to maintainthem. Keep your comments relatively short and to the point, and if youchange a function, review the comment to make sure it’s still correct.

Evaluate Your Game

I want you to now pretend you are me. Adopt a very stern look, print out yourcode, and take a red pen and mark every mistake you find, including anythingfrom this exercise and from other guidelines you’ve read so far. Once you aredone marking your code up, I want you to fix everything you came up with.Then repeat this a couple of times, looking for anything that could be better.Use all the tricks I’ve given you to break your code down into the smallest,tiniest little analysis you can.

The purpose of this exercise is to train your attention to detail on classes.Once you are done with this bit of code, find someone else’s code and do thesame thing. Go through a printed copy of some part of it and point out all themistakes and style errors you find. Then fix it and see if your fixes can bedone without breaking that program.

I want you to do nothing but evaluate and fix code for the week—your owncode and other people’s. It’ll be pretty hard work, but when you are doneyour brain will be wired tight like a boxer’s hands.

Page 233: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 46. A Project SkeletonThis will be where you start learning how to set up a good project “skeleton”directory. This skeleton directory will have all the basics you need to get anew project up and running. It will have your project layout, automated tests,modules, and install scripts. When you go to make a new project, just copythis directory to a new name and edit the files to get started.

macOS/Linux Setup

Before you can begin this exercise you need to install some software forPython by using a tool called pip3.6 (or just pip) to install new modules.The pip3.6 command should be included with your python3.6 installation.You’ll want to verify this using this command:

$ pip3.6 listpip (9.0.1)setuptools (28.8.0)$

You can ignore any deprecation warning if you see it. You may also see othertools installed, but the base shoudl be pip and setuptools. Once you’veverified this you can then install virtualenv:

$ sudo pip3.6 install virtualenvPassword:Collecting virtualenv Downloading virtualenv–15.1.0–py2.py3–none–any.whl (1.8MB) 100% ||||||||||||||||||||||||||||||||| 1.8MB 1.1MB/sInstalling collected packages: virtualenvSuccessfully installed virtualenv– 15.1.0$

This is for Linux or macOS systems. If you’re on Linux/macOS, you’ll wantto run the following command to make sure you use the correct virtualenv:

$ whereis virtualenv/Library/Frameworks/Python.framework/Versions/3.6/bin/virtualenv

Page 234: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

You should see something like the above on macOS, but Linux will bevariable. On Linux you might have an actual virtualenv3.6 command, or youmay be better off installing a package for it from your package managementsystem.

Once you’ve installed virtualenv you can use it to create a “fake” Pythoninstallation, which makes it easier to manage versions of your packages fordifferent projects. First, run this command, and I’ll explain what it’s doing:

$ mkdir ~/.venvs$ virtualenv –system–site –packages ~/.venvs/lpthw$ . ~/.venvs/lpthw/bin/activate(lpthw) $

Here’s what’s going on line-by-line:

1. You create a directory called .venvs in your HOME ~/ to store all yourvirtual environments.

2. You run virtualenv and tell it to include the system site packages (--system-site-packages), then instruct it to build the virtualenv in~/.venvs/lpthw.

3. You then “source” the lpthw virtual environment by using the . operator inbash, followed by the ~/.venvs/lpthw/bin/activate script.

4. Finally, your prompt changes to include (lpthw), so you know that you’reusing that virtual environment.

Now you can see where things are installed:

(lpthw) $ which python/Users/zedshaw/.venvs/lpthw/bin/python(lpthw) $ pythonPython 3.6.0rc2 (v3.6.0rc2:800a67f7806d, Dec 16 2016, 14:12:21)[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwinType "help", "copyright", "credits" or "license" for more information.>>> quit()(lpthw) $

You can see that the python that gets run is installed in the

Page 235: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

/Users/zedshaw/.venvs/lpthw/bin/python directory instead of the originallocation. This also solves the problem of having to type python3.6 since itinstalls both:

$ which python3.6/Users/zedshaw/.venvs/lpthw/bin/python3.6(lpthw) $

You’ll find the same thing for virtualenv and pip commands. The final stepin this setup is to install nose, a testing framework we’ll use in this exercise:

$ pip install noseCollecting nose Downloading nose—1.3.7—py3—none—any.whl (154kB) 100% | ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ | 163kB 3.2mb/sInstalling collected packages: noseSuccessfully installed nose —1.3.7(lpthw) $

Windows 10 Setup

The Windows 10 install is a little simpler than on Linux or macOS, but onlyif you have one version of Python installed. If you have both Python 3.6 andPython 2.7 installed then you are on your own as it is much too difficult tomanage multiple installations. If you have followed the book so far and haveonly Python 3.6, then here’s what you do. First, change to your homedirectory and confirm you’re running the right version of python:

> cd ~> pythonPython 3.6.0 (v3.6.0:41 df79263a11 , Dec 23 2016, 08:06:12) [MSC v.1900 64 bit (AMD64)] on Win32Type "help", "copyright", "credits" or "license" for more information.>>> quit()

Then you’ll want to run pip to confirm you have a basic install:

> pip listpip (9.0.1)setuptools (28.8.0)

You can safely ignore any deprecation warning, and it’s alright if you have

Page 236: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

other packages installed. Next, you’ll install virtualenv for setting up simplevirtual environments for the rest of the book:

> pip install virtualenvCollecting virtualenv Using cached virtualenv —15.1.0—py2.py3—none—any.whlInstalling collected packages : virtualenvSuccessfully installed virtualenv — 15.1.0

Once you have virtualenv installed you’ll need to make a .venvs directoryand fill it with a virtual environment:

> mkdir . venvs> virtualenv —system—site —packages.venvs/lpthwUsing base prefix 'c:\\users\\zedsh\\appdata\\local\\programs\\python\\python36'New python executable in C:\Users\zedshaw\.venvs\lpthw\Scripts\python.exeInstalling setuptools, pip, wheel ... done.

Those two commands create a .venvs folder for storing different virtualenvironments and then create your first one named lpthw. A virtualenvironment (virtualenv) is a “fake” place to install software so that you canhave different versions of different packages for each project you’re workingon. Once you have the virtualenv set up you need to activate it:

> .\.venvs\lpthw\Scripts\activate

That will run the activate script for PowerShell, which configures the lpthwvirtualenv for your current shell. Every time you want to use your softwarefor the book you’ll run this command. You’ll notice in our next commandthat there is now a (lpthw) added to the PowerShell prompt showing youwhich virtualenv you’re using. Finally, you just need to install nose forrunning tests later:

(lpthw) > pip install noseCollecting nose Downloading nose —1.3.7—py3—none—any.whl (154kB) 100% | ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ | i63kB i.2mb/sInstalling collected packages: noseSuccessfully installed nose—1.3.7(lpthw) >

Page 237: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

You’ll see that this installs nose, except pip will install it into your.venvs\lpthw virtual environment instead of the main system packagesdirectory. This lets you install conflicting versions of Python packages foreach project you work on without infecting your main system configuration.

Creating the Skeleton Project Directory

First, create the structure of your skeleton directory with these commands:

$ mkdir projects$ cd projects/$ mkdir skeleton$ cd skel eton$ mkdir bin NAME tests docs

I use a directory named projects to store all the various things I’m workingon. Inside that directory I have my skeleton directory that I put the basis ofmy projects into. The directory NAME will be renamed to whatever you arecalling your project’s main module when you use the skeleton.

Next, we need to set up some initial files. Here’s how you do that onLinux/macOS:

$ touch NAME/__init__. py$ touch tests/__init__. py

Here’s the same thing on Windows PowerShell:

$ new-item —type file NAME/__in it__. py$ new-item —type file tests/__init__. py

That creates an empty Python module directory we can put our code in. Thenwe need to create a setup.py file we can use to install our project later if wewant:

setup.py

1 try: 2 from setuptools import setup 3 except ImportError:

Page 238: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

4 from distutils.core import setup 5 6 config = { 7 'description': 'My Project', 8 'author': 'My Name', 9 'url': 'URL to get it at.',10 'download_url': 'Where to download it.',11 'author_email': 'My email.',12 'version': '0.1',13 'install_requires': ['nose'],14 'packages': ['NAME'],15 'scripts': [],16 'name': 'projectname'17 }1819 setup(**config)

Edit this file so that it has your contact information and is ready to go forwhen you copy it.

Finally, you will want a simple skeleton file for tests namedtests/NAME_tests.py:

NAME_tests.py

1 from nose.tools import * 2 import NAME 3 4 def setup(): 5 print("SETUP!") 6 7 def teardown(): 8 print("TEAR DOWN!") 910 def test_basic():11 print("I RAN!")

46.3.1 Final Directory Structure

When you are done setting all of this up, your directory should look like minehere:

skeleton /

Page 239: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

NAME/ __init__. py bin/ docs/ setup.py tests/ NAME_tests. py __init__. py

And from now on, you should run your commands from this directory. If youcan’t, do ls -R and if you don’t see this same structure, then you are in thewrong place. For example, people commonly go into the tests/ directory totry to run files there, which won’t work. To run your application’s tests, youwould need to be above tests/ and this location I have above. So, if you trythis:

$ cd tests/ # WRONG! WRONG! WRONG!$ n osetests

__________________________________________________________Ran 0 te sts i n 0.000 s

OK

Then that is wrong! You have to be above tests, so assuming you made thismistake, you would fix it by doing this:

$ cd .. # get out of tests/$ ls # CORRECT! you are now in the right spotNAME bin docs setup.py tests$ nosetests.__________________________________________________________Ran 1 test i n 0.004s

OK

Remember this because people make this mistake quite frequently.

Testing Your Setup

After you get all that installed you should be able to do this:

Page 240: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

$ nosetests.__________________________________________________________Ran 1 test in 0.007s

OK

I’ll explain what this nosetests thing is doing in the next exercise, but fornow if you do not see that, you probably got something wrong. Make sureyou put __init__.py files in your NAME and tests directories, and make sureyou got tests/NAME_tests.py right.

Using the Skeleton

You are now done with most of your yak shaving. Whenever you want tostart a new project, just do this:

1. Make a copy of your skeleton directory. Name it after your new project.

2. Rename (move) the NAME directory to be the name of your project orwhatever you want to call your root module.

3. Edit your setup.py to have all the information for your project.

4. Rename tests/NAME_tests.py to also have your module name.

5. Double check it’s all working by using nosetests again.

6. Start coding.

Required Quiz

This exercise doesn’t have Study Drills but a quiz you should complete:

1. Read about how to use all of the things you installed.

2. Read about the setup.py file and all it has to offer. Warning: it is not avery well-written piece of software, so it will be very strange to use.

Page 241: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

3. Make a project and start putting code into the module, then get the moduleworking.

4. Put a script in the bin directory that you can run. Read about how you canmake a Python script that’s runnable for your system.

5. Mention the bin script you created in your setup.py so that it getsinstalled.

6. Use your setup.py to install your own module and make sure it works,then use pip to uninstall it.

Common Student Questions

Do these instructions work on Windows? They should, but depending onthe version of Windows you may need to struggle with the setup a bit to get itworking. Just keep researching and trying it until you get it, or see if you canask a more experienced Python+Windows friend to help out.

What do I put in the config dictionary in my setup.py? Make sure youread the documentation for distutils athttp://docs.python3.6.org/distutils/setupscript.html.

I can’t seem to load the NAME module and just get an ImportError. Makesure you made the NAME/__init__.py file. If you’re on Windows, make sureyou didn’t accidentally name it NAME/__init__.py.txt, which happens bydefault with some editors.

Why do we need a bin/ folder at all? This is just a standard place to putscripts that are run on the command line, not a place to put modules.

My nosetests run only shows one test being run. Is that right? Yes,that’s what my output shows too.

Page 242: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 47. Automated TestingHaving to type commands into your game over and over to make sure it’sworking is annoying. Wouldn’t it be better to write little pieces of code thattest your code? Then when you make a change, or add a new thing to yourprogram, you just “run your tests” and the tests make sure things are stillworking. These automated tests won’t catch all your bugs, but they will cutdown on the time you spend repeatedly typing and running your code.

Every exercise after this one will not have a What You Should See section,but instead will have a What You Should Test section. You will be writingautomated tests for all of your code starting now, and this will hopefullymake you an even better programmer.

I won’t try to explain why you should write automated tests. I will only saythat you are trying to be a programmer, and programmers automate boringand tedious tasks. Testing a piece of software is definitely boring and tedious,so you might as well write a little bit of code to do it for you.

That should be all the explanation you need because your reason for writingunit tests is to make your brain stronger. You have gone through this bookwriting code to do things. Now you are going to take the next leap and writecode that knows about other code you have written. This process of writing atest that runs some code you have written forces you to understand clearlywhat you have just written. It solidifies in your brain exactly what it does andwhy it works and gives you a new level of attention to detail.

Writing a Test Case

We’re going to take a very simple piece of code and write one simple test.We’re going to base this little test on a new project from your projectskeleton.

First, make a ex47 project from your project skeleton. Here are the steps youwould take. I’m going to give these instructions in English rather than show

Page 243: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

you how to type them so that you have to figure it out.

1. Copy skeleton to ex47.

2. Rename everything with NAME to ex47.

3. Change the word NAME in all the files to ex47.

4. Finally, remove all the *.pyc files to make sure you’re clean.

Refer back to Exercise 46 if you get stuck, and if you can’t do this easily thenmaybe practice it a few times.

Warning!

Remember that you run the command nosetests to run the tests. You canrun them with python3.6 ex47_tests.py, but it won’t work as easily, andyou’ll have to do it for each test file.

Next, create a simple file ex47/game.py where you can put the code to test.This will be a very silly little class that we want to test with this code in it:

game.py

1 class Room(object): 2 3 def __init__(self, name, description): 4 self.name = name 5 self.description = description 6 self.paths = {} 7 8 def go(self, direction): 9 return self.paths.get(direction, None)1011 def add_paths(self, paths):12 self.paths.update(paths)

Once you have that file, change the unit test skeleton to this:

Page 244: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

ex47_tests.py

1 from nose.tools import * 2 from ex47.game import Room 3 4 5 def test_room(): 6 gold = Room("GoldRoom", 7 """This room has gold in it you can grab. There's a 8 door to the north.""") 9 assert_equal(gold.name, "GoldRoom")10 assert_equal(gold.paths, {})1112 def test_room_paths():13 center = Room("Center", "Test room in the center.")14 north = Room("North", "Test room in the north.")15 south = Room("South", "Test room in the south.")1617 center.add_paths({'north': north, 'south': south})18 assert_equal(center.go('north'), north)19 assert_equal(center.go('south'), south)2021 def test_map():22 start = Room("Start", "You can go west and down a hole.")23 west = Room("Trees", "There are trees here, you can go east."24 down = Room("Dungeon", "It's dark down here, you can go up."2526 start.add_paths({'west': west, 'down': down})27 west.add_paths({'east': start})28 down.add_paths({'up': start})2930 assert_equal(start.go('west'), west)31 assert_equal(start.go('west').go('east'), start)32 assert_equal(start.go('down').go('up'), start)

This file imports the Room class you made in the ex47.game module so thatyou can do tests on it. There is then a set of tests that are functions startingwith test_. Inside each test case there’s a bit of code that makes a room or aset of rooms, and then makes sure the rooms work the way you expect themto work. It tests out the basic room features, then the paths, then tries out awhole map.

The important functions here are assert_equal, which makes sure thatvariables you have set or paths you have built in a Room are actually what you

Page 245: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

think they are. If you get the wrong result, then nosetests will print out anerror message so you can go figure it out.

Testing Guidelines

Follow this general loose set of guidelines when making your tests:

1. Test files go in tests/ and are named BLAH_tests.py, otherwisenosetests won’t run them. This also keeps your tests from clashing withyour other code.

2. Write one test file for each module you make.

3. Keep your test cases (functions) short, but do not worry if they are a bitmessy. Test cases are usually kind of messy.

4. Even though test cases are messy, try to keep them clean and remove anyrepetitive code you can. Create helper functions that get rid of duplicate code.You will thank me later when you make a change and then have to changeyour tests. Duplicated code will make changing your tests more difficult.

5. Finally, do not get too attached to your tests. Sometimes, the best way toredesign something is to just delete it and start over.

What You Should See

Exercise 47 Session

$ nosetests...----------------------------------------------------------------------Ran 3 tests in 0.008s

OK

That’s what you should see if everything is working right. Try causing anerror to see what that looks like and then fix it.

Page 246: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Study Drills

1. Go read about nosetests more, and also read about alternatives.

2. Learn about Python’s “doc tests,” and see if you like them better.

3. Make your room more advanced, and then use it to rebuild your game yetagain, but this time unit test as you go.

Common Student Questions

I get a syntax error when I run nosetests. If you get that then look at whatthe error says, and fix that line of code or the ones above it. Tools likenosetests are running your code and the test code, so they will find syntaxerrors the same as running Python will.

I can’t import ex47.game? Make sure you create the ex47/__init__.py file.Refer to Exercise 46 again to see how it’s done. If that’s not the problem,then do this on macOS/Linux:

export PYTHONPATH=.

And on Windows:

$env :PYTHONPATH = "$env :PYTHONPATH ; . "

Finally, make sure you’re running the tests with nosetests, not with justPython.

I get UserWarning when I run nosetests. You probably have two versionsof Python installed, or you aren’t using distribute. Go back and installdistribute or pip as I describe in Exercise 46.

Page 247: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 48. Advanced User InputIn past games you handled the user’s input by simply expecting set strings. Ifthe user typed “run”, and exactly “run”, then the game worked. If they typedin similar phrases like “run fast” it would fail. What we need is a device thatlets users type phrases in various ways and then convert that into somethingthe computer understands. For example, we’d like to have all of these phraseswork the same:

• open door

• open the door

• go THROUGH the door

• punch bear

• Punch The Bear in the FACE

It should be alright for a user to write something a lot like English for yourgame and have your game figure out what it means. To do this, we’re goingto write a module that does just that. This module will have a few classes thatwork together to handle user input and convert it into something your gamecan work with reliably.

A simplified version of the English language could include the followingelements:

• Words separated by spaces.

• Sentences composed of the words.

• Grammar that structures the sentences into meaning.

That means the best place to start is figuring out how to get words from theuser and what kinds of words those are.

Page 248: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Our Game Lexicon

In our game we have to create a list of allowable words called a “lexicon“:

• Direction words: north, south, east, west, down, up, left, right, back

• Verbs: go, stop, kill, eat

• Stop words: the, in, of, from, at, it

• Nouns: door, bear, princess, cabinet

• Numbers: any string of 0 through 9 characters

When we get to nouns, we have a slight problem since each room could havea different set of nouns, but let’s just pick this small set to work with for nowand improve it later.

48.1.1 Breaking Up a Sentence

Once we have our lexicon we need a way to break up sentences so that wecan figure out what they are. In our case, we’ve defined a sentence as “wordsseparated by spaces,” so we really just need to do this:

stuff = input('> ')words = stuff.split()

That’s all we’ll worry about for now, but this will work really well for quite awhile.

48.1.2 Lexicon Tuples

Once we know how to break up a sentence into words, we just have to gothrough the list of words and figure out what “type” they are. To do thatwe’re going to use a handy little Python structure called a “tuple.” A tuple isnothing more than a list that you can’t modify. It’s created by putting datainside two () with a comma, like a list:

Page 249: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

first_word = ( 'verb ' , 'go ' )second_word = ( ' direction ' , ' north ' )third_word = ( ' direct ion ' , ' west ' )sentence = [ first_word , second_word , third_word ]

This creates a pair (TYPE, WORD) that lets you look at the word and dothings with it.

This is just an example, but that’s basically the end result. You want to takeraw input from the user, carve it into words with split, analyze those wordsto identify their type, and finally, make a sentence out of them.

48.1.3 Scanning Input

Now you are ready to write your scanner. This scanner will take a string ofraw input from a user and return a sentence that’s composed of a list of tupleswith the (TOKEN, WORD) pairings. If a word isn’t part of the lexicon, thenit should still return the WORD but set the TOKEN to an error token. Theseerror tokens will tell users they messed up.

Here’s where it gets fun. I’m not going to tell you how to do this. Instead I’mgoing to write a “unit test,” and you are going to write the scanner so that theunit test works.

48.1.4 Exceptions and Numbers

There is one tiny thing I will help you with first, and that’s convertingnumbers. In order to do this though, we’re going to cheat and use exceptions.An exception is an error that you get from some function you may have run.What happens is your function “raises” an exception when it encounters anerror, then you have to handle that exception. For example, if you type thisinto Python you get an exception:

Exercise 48 Python Session

Python 3.6.0 (default, Feb 2 2017, 12:48:29)[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwinType "help", "copyright", "credits" or "license" for more information.

Page 250: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

>>> int("hell")Traceback (most recent call last): File "<stdin>", line 1, in <module>ValueError: invalid literal for int() with base 10: 'hell'

That ValueError is an exception that the int() function threw because whatyou handed int() is not a number. The int()) function could have returneda value to tell you it had an error, but since it only returns integers, it’d have ahard time doing that. It can’t return -1 since that’s a number. Instead of tryingto figure out what to return when there’s an error, the int() function raisesthe ValueError exception and you deal with it.

You deal with an exception by using the try and except keywords:

ex48_convert.py

1 def convert_number(s):2 try:3 return int(s)4 except ValueError:5 return None

You put the code you want to “try” inside the try block, and then you put thecode to run for the error inside the except. In this case, we want to “try” tocall int() on something that might be a number. If that has an error, then we“catch” it and return None.

In your scanner that you write, you should use this function to test whethersomething is a number. You should also do it as the last thing you check forbefore declaring that word an error word.

A Test First Challenge

Test first is a programming tactic where you write an automated test thatpretends the code works, then you write the code to make the test actuallywork. This method works when you can’t visualize how the code isimplemented, but you can imagine how you have to work with it. Forexample, if you know how you need to use a new class in another module,but you don’t quite know how to implement that class yet, then write the test

Page 251: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

first.

You are going to take a test I give you and use it to write the code that makesit work. To do this exercise you’re going to follow this procedure:

1. Create one small part of the test I give you.

2. Make sure it runs and fails so you know that the test is actually confirminga feature works.

3. Go to your source file lexicon.py and write the code that makes this testpass.

4. Repeat until you have implemented everything in the test.

When you get to 3 it’s also good to combine our other method of writingcode:

1. Make the “skeleton” function or class that you need.

2. Write comments inside describing how that function works.

3. Write the code that does what the comments describe.

4. Remove any comments that just repeat the code.

This method of writing code is called “psuedo code” and works well if youdon’t know how to implement something, but you can describe it in your ownwords.

Combining the “test first” with the “psuedo code” tactics we have this simpleprocess for programming:

1. Write a bit of test that fails.

2. Write the skeleton function/module/class the test needs.

3. Fill the skeleton with comments in your own words explaining how itworks.

Page 252: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

4. Replace the comments with code until the test passes.

5. Repeat.

In this exercise you will practice this method of working by making a test Igive you run against the lexicon.py module.

What You Should Test

Here is the test case tests/lexicon_tests.py that you should use, but don’ttype this in yet:

lexicon_tests.py

1 from nose.tools import * 2 from ex48 import lexicon 3 4 5 def test_directions(): 6 assert_equal(lexicon.scan("north"), [('direction', 'north' 7 result = lexicon.scan("north south east") 8 assert_equal(result, [('direction', 'north'), 9 ('direction', 'south'),10 ('direction', 'east')])1112 def test_verbs():13 assert_equal(lexicon.scan("go"), [('verb', 'go')])14 result = lexicon.scan("go kill eat")15 assert_equal(result, [('verb', 'go'),16 ('verb', 'kill'),17 ('verb', 'eat')])181920 def test_stops():21 assert_equal(lexicon.scan("the"), [('stop', 'the')])22 result = lexicon.scan("the in of")23 assert_equal(result, [('stop', 'the'),24 ('stop', 'in'),25 ('stop', 'of')])262728 def test_nouns():29 assert_equal(lexicon.scan("bear"), [('noun', 'bear')])

Page 253: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

30 result = lexicon.scan("bear princess")31 assert_equal(result, [('noun', 'bear'),32 ('noun', 'princess')])3334 def test_numbers():35 assert_equal(lexicon.scan("1234"), [('number', 1234)])36 result = lexicon.scan("3 91234")37 assert_equal(result, [('number', 3),38 ('number', 91234)])394041 def test_errors():42 assert_equal(lexicon.scan("ASDFADFASDF"),43 [('error', 'ASDFADFASDF')])44 result = lexicon.scan("bear IAS princess")45 assert_equal(result, [('noun', 'bear'),46 ('error', 'IAS'),47 ('noun', 'princess')])

You will want to create a new project using the project skeleton just like youdid in Exercise 47. Then you’ll need to create this test case and thelexicon.py file it will use. Look at the top of the test case to see how it’sbeing imported to figure out where it goes.

Next, follow the procedure I gave you and write a little bit of the test case at atime. For example, here’s how I’d do it:

1. Write the import at the top. Get that to work.

2. Create an empty version of the first test case test_directions. Make surethat runs.

3. Write the first line of the test_directions test case. Make it fail.

4. Go to the lexicon.py file, and create an empty scan function.

5. Run the test, and make sure scan is at least running, even though it fails.

6. Fill in psuedo code comments for how scan should work to maketest_directions pass.

7. Write the code that matches the comments until test_directions passes.

Page 254: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

8. Go back to test_directions and write the rest of the lines.

9. Back to scan in lexicon.py and work on it to make this new test codepass.

10. Once you’ve done that you have your first passing test, and you move onto the next test.

As long as you keep following this procedure one little chunk at a time youcan successfully turn a large problem into smaller solvable problems. It’s likeclimbing a mountain by turning it into a bunch of little hills.

Study Drills

1. Improve the unit test to make sure you test more of the lexicon.

2. Add to the lexicon and then update the unit test.

3. Make sure your scanner handles user input in any capitalization and case.Update the test to make sure this actually works.

4. Find another way to convert the number.

5. My solution was 37 lines long. Is yours longer? Shorter?

Common Student Questions

Why do I keep getting ImportErrors? Import errors are usually caused byfour things. 1. You didn’t make a __init__.py in a directory that hasmodules in it. 2. you are in the wrong directory. 3. You are importing thewrong module because you spelled it wrong. 4. Your PYTHONPATH isn’t set to., so you can’t load modules from your current directory.

What’s the difference between try-except and if-else? The try-exceptconstruct is only used for handling exceptions that modules can throw. Itshould never be used as an alternative to if-else.

Page 255: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Is there a way to keep the game running while the user is waiting totype? I’m assuming you want to have a monster attack users if they don’treact quickly enough. It is possible, but it involves modules and techniquesthat are outside of this book’s domain.

Page 256: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 49. Making SentencesWhat we should be able to get from our little game lexicon scanner is a listthat looks like this:

Exercise 49 Python Session

Python 3.6.0 (default, Feb 2 2017, 12:48:29)[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwinType "help", "copyright", "credits" or "license" for more information.>>> from ex48 import lexicon>>> lexicon.scan("go northw")[('verb', 'go'), ('direction', 'north')]>>> lexicon.scan("kill the princess")[('verb', 'kill'), ('stop', 'the'), ('noun', 'princess')]>>> lexicon.scan("eat the bear")[('verb', 'eat'), ('stop', 'the'), ('noun', 'bear')]

This will also work on longer sentences such as lexicon.scan("open thedoor and smack the bear in the nose").

Now let us turn this into something the game can work with, which would besome kind of Sentence class. If you remember grade school, a sentence canbe a simple structure like:

Subject Verb Object

Obviously it gets more complex than that, and you probably did many daysof annoying sentence diagrams for English class. What we want is to turn thepreceding lists of tuples into a nice Sentence object that has subject, verb, andobject.

Match and Peek

To do this we need five tools:

1. A way to loop through the list of scanned words. That’s easy.

Page 257: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

2. A way to “match” different types of tuples that we expect in our SubjectVerb Object setup.

3. A way to “peek” at a potential tuple so we can make some decisions.

4. A way to “skip” things we do not care about, like stop words.

5. A Sentence object to put the results in.

We will be putting these functions in a module named ex48.parser in a filenamed ex48/parser.py in order to test it. We use the peek function to say“look at the next element in our tuple list, and then match to take one off andwork with it.”

The Sentence Grammar

Before you can write the code you need to understand how a basic Englishsentence grammar works. In our parser we want to produce a Sentence objectthat has three attributes:

Sentence.subject This is the subject of any sentence but could default to“player” most of the time since a sentence of “run north” is implying “playerrun north”. This will be a noun.

Sentence.verb This is the action of the sentence. In “run north” it would be“run”. This will be a verb.

Sentence.object This is another noun that refers to what the verb is done on.In our game we separate out directions which would also be objects. In “runnorth” the word “north” would be the object. In “hit bear” the word “bear”would be the object.

Our parser then has to use the functions we described and, given a scannedsentence, convert it into an List of Sentence objects to match the input.

A Word On Exceptions

Page 258: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

You briefly learned about exceptions but not how to raise them. This codedemonstrates how to do that with the ParserError at the top. Notice that ituses classes to give it the type of Exception. Also notice the use of the raisekeyword to raise the exception.

In your tests, you will want to work with these exceptions, which I’ll showyou how to do.

The Parser Code

If you want an extra challenge, stop right now and try to write this based onjust my description. If you get stuck you can come back and see how I did it,but trying to implement the parser yourself is good practice. I will now walkthrough the code so you can enter it into your ex48/parser.py. We start theparser with the exception we need for a parsing error:

parser.py

1 class ParserError(Exception):2 pass

This is how you make your own ParserError exception class you can throw.Next we need the Sentence object we’ll create:

parser.py

1 class Sentence(object):23 def __init__(self, subject, verb, obj):4 # remember we take ('noun','princess') tuples and convert them5 self.subject = subject[1]6 self.verb = verb[1]7 self.object = obj[1]

There’s nothing special about this code so far. You’re just making simpleclasses.

In our description of the problem we need a function that can peek at a list of

Page 259: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

words and return what type of word it is:

parser.py

1 def peek(word_list):2 if word_list:3 word = word_list[0]4 return word[0]5 else:6 return None

We need this function because we’ll have to make decisions about what kindof sentence we’re dealing with based on what the next word is. Then we cancall another function to consume that word and carry on.

To consume a word we use the match function, which confirms that theexpected word is the right type, takes it off the list, and returns the word.

parser.py

1 def match(word_list, expecting): 2 if word_list: 3 word = word_list.pop(0) 4 5 if word[0] == expecting: 6 return word 7 else: 8 return None 9 else:10 return None

Again, this is fairly simple, but make sure you understand this code. Alsomake sure you understand why I’m doing it this way. I need to peek at wordsin the list to decide what kind of sentence I’m dealing with, and then I need tomatch those words to create my Sentence.

The last thing I need is a way to skip words that aren’t useful to theSentence. These are the words labeled “stop words” (type ’stop’) that arewords like “the”, “and”, and “a”.

parser.py

Page 260: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

1 def skip(word_list, word_type):2 while peek(word_list) == word_type:3 match(word_list, word_type)

Remember that skip doesn’t skip one word, it skips as many words of thattype as it finds. This makes it so if someone types, “scream at the bear” youget “scream” and “bear.”

That’s our basic set of parsing functions, and with that we can actually parsejust about any text we want. Our parser is very simple though, so theremaining functions are short.

First we can handle parsing a verb:

parser.py

1 def parse_verb(word_list):2 skip(word_list, 'stop')34 if peek(word_list) == 'verb':5 return match(word_list, 'verb')6 else:7 raise ParserError("Expected a verb next.")

We skip any stop words, then peek ahead to make sure the next word is a“verb” type. If it’s not, then raise the ParserError to say why. If it is a“verb,” then match it, which takes it off the list. A similar function handlessentence objects:

parser.py

1 def parse_object(word_list):2 skip(word_list, 'stop')3 next_word = peek(word_list)45 if next_word == 'noun':6 return match(word_list, 'noun')7 elif next_word == 'direction':8 return match(word_list, 'direction')9 else:

Page 261: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

10 raise ParserError("Expected a noun or direction next."

Again, skip the stop words, peek ahead, and decide if the sentence is correctbased on what’s there. In the parse_object function, though, we need tohandle both “noun” and “direction” words as possible objects. Subjects arethen similar again, but since we want to handle the implied “player” noun, wehave to use peek:

parser.py

1 def parse_subject(word_list):2 skip(word_list, 'stop')3 next_word = peek(word_list)45 if next_word == 'noun':6 return match(word_list, 'noun')7 elif next_word == 'verb':8 return ('noun', 'player')9 else:10 raise ParserError("Expected a verb next.")

With that all out of the way and ready, our final parse_sentence function isvery simple:

parser.py

1 def parse_sentence(word_list):2 subj = parse_subject(word_list)3 verb = parse_verb(word_list)4 obj = parse_object(word_list)56 return Sentence(subj, verb, obj)

Playing With The Parser

To see how this works, you can play with it like this:

Exercise 49a Python Session

Page 262: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Python 3.6.0 (default, Feb 2 2017, 12:48:29)[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwinType "help", "copyright", "credits" or "license" for more information.>>> from ex48.parser import *>>> x = parse_sentence([('verb', 'run'), ('direction', 'north')])>>> x.subject'player'>>> x.verb'run'>>> x.object'north'>>> x = parse_sentence([('noun', 'bear'), ('verb', 'eat'), ('stop'... ('noun', 'honey')])>>> x.subject'bear'>>> x.verb'eat'>>> x.object'honey'

Try to map sentences to the correct pairings in a sentence. For example, howwould you say, “the bear run south?”

What You Should Test

For Exercise 49, write a complete test that confirms everything in this code isworking. Put the test in tests/parser_tests.py similar to the test file fromthe last exercise. That includes making exceptions happen by giving theparser bad sentences.

Check for an exception by using the function assert_raises from the nosedocumentation. Learn how to use this so you can write a test that is expectedto fail, which is very important in testing. Learn about this function (andothers) by reading the nose documentation.

When you are done, you should know how this bit of code works and how towrite a test for other people’s code even if they do not want you to. Trust me,it’s a very handy skill to have.

Study Drills

Page 263: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

1. Change the parse_ methods and try to put them into a class rather than usethem just as methods. Which design do you like better?

2. Make the parser more error-resistant so that you can avoid annoying yourusers if they type words your lexicon doesn’t understand.

3. Improve the grammar by handling more things like numbers.

4. Think about how you might use this Sentence class in your game to domore fun things with a user’s input.

Common Student Questions

I can’t seem to make assert_raises work right. Make sure you are writingassert_raises(exception, callable, parameters) and not writingassert_raises(exception, callable(parameters)). Notice how thesecond form is calling the function, then passing the result to assert_raises,which is wrong. You have to pass the function to call and its arguments toassert_raises.

Page 264: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 50. Your First WebsiteThese final three exercises will be very hard and you should take your timewith them. In this first one you’ll build a simple web version of one of yourgames. Before you attempt this exercise you must have completed Exercise46 successfully and have a working pip installed such that you can installpackages and know how to make a skeleton project directory. If you don’tremember how to do this, go back to Exercise 46 and do it all over again.

Installing Flask

Before creating your first web application, you’ll first need to install the “webframework” called flask. The term “framework” generally means “somepackage that makes it easier for me to do something.” In the world of webapplications, people create “web frameworks” to compensate for the difficultproblems they’ve encountered when making their own sites. They share thesecommon solutions in the form of a package you can download to bootstrapyour own projects.

In our case, we’ll be using the flask framework, but there are many, many,many others you can choose from. For now, learn flask, then branch out toanother one when you’re ready (or just keep using flask since it’s goodenough).

Using pip, install flask:

$ sudo pip install flask[ sudo ] password for zedshaw:Downloading/unpacking flask Running setup.py egg_info for package flask

Installing collected packages : flask Running setup.py install for flask

Successfully installed flaskCleaning up...

Page 265: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

This will work on Linux and macOS computers, but on Windows just dropthe sudo part of the pip install command and it should work. If not, goback to Exercise 46 and make sure you can do it reliably.

Make a Simple “Hello World” Project

Now you’re going to make an initial very simple “Hello World” webapplication and project directory using flask. First, make your projectdirectory:

$ cd projects$ mkdir gothonweb$ cd gothonweb$ mkdir bin gothonweb tests docs templates$ touch gothonweb/__init__.py$ touch tests/__init__.py

You’ll be taking the game from Exercise 43 and making it into a webapplication, so that’s why you’re calling it gothonweb. Before you do that, weneed to create the most basic flask application possible. Put the followingcode into app.py:

ex50.py

1 from flask import Flask2 app = Flask(__name__)34 @app.route('/')5 def hello_world():6 return 'Hello, World!'78 if __name__ == "__main__":9 app.run()

Then run the application like this:

(lpthw) $ python3.6 app.py* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

Finally, use your web browser and go to http://localhost:5000/, and you

Page 266: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

should see two things. First, in your browser you’ll see Hello, world!.Second, you’ll see your terminal with new output like this:

(lpthw) $ python3.6 app.py* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)127.0.0.1 –– [22/Feb/2017 14:28:50] ” GET / HTTP/1.1” 200–127.0.0.1 –– [22/Feb/2017 14:28:50] ” GET /favicon.ico HTTP/1.1” 404–127.0.0.1 –– [22/Feb/2017 14:28:50] ” GET /favicon.ico HTTP/1.1” 404–

Those are log messages that flask prints out so you can see that the server isworking and what the browser is doing behind the scenes. The log messageshelp you debug and figure out when you have problems. For example, it’ssaying that your browser tried to get /favicon.ico but that file didn’t exist,so it returned the 404 Not Found status code.

I haven’t explained the way any of this web stuff works yet, because I wantto get you set up and ready to roll so that I can explain it better in the nexttwo exercises. To accomplish this, I’ll have you break your flask applicationin various ways and then restructure it so that you know how it’s set up.

What’s Going On?

Here’s what’s happening when your browser hits your application:

1. Your browser makes a network connection to your own computer, which iscalled localhost and is a standard way of saying “whatever my owncomputer is called on the network.” It also uses port 5000.

2. Once it connects, it makes an HTTP request to the app.py application andasks for the / URL, which is commonly the first URL on any website.

3. Inside app.py you’ve got a list of URLs and what functions they match.The only one we have is the '/', 'index' mapping. This means thatwhenever someone goes to / with a browser, flask will find the def indexand run it to handle the request.

4. Now that flask has found def index, it calls it to actually handle therequest. This function runs and simply returns a string for what flask should

Page 267: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

send to the browser.

5. Finally, flask has handled the request and sends this response to thebrowser, which is what you are seeing.

Make sure you really understand this. Draw up a diagram of how thisinformation flows from your browser, to flask, then to def index and backto your browser.

Fixing Errors

First, delete line 8 where you assign the greeting variable, then hit refresh inyour browser. Then use CTRL-C to kill flask and start it again. Once it’srunning again refresh your browser, and you should see an “Internal ServerError”. Back in your terminal you’ll see this ([VENV] is the path to your.venvs/ directory):

(lpthw) $ python3.6 app.py* Running on http://127.0.0.1 :5000/ (Press CTRL+C to quit)[2017-02-22 14:35:54,256] ERROR in app: Exception on / [GET]Traceback ( most recent call last ): File “[VENV]/site-packages/flask/app.py”, line 1982, in wsgi_app response = self.full_dispatch_request() File “[VENV]/site-packages/flask/app.py”, line 1614, in full_dispatch_request rv = self . handle_user_exception(e) File “[VENV]/site-packages/flask/app.py”, line 1517, in handle_user_exception reraise(exc_type, exc_value, tb) File “[VENV]/site—packages/flask/_compat.py”, line 33, in reraise raise value File “[VENV]/site—packages/flask/app.py”,line 1612, in full_dispatch_request rv = self.dispatch_request() File “[VENV]/site —packages/flask/app.py”,line 1598, in dispatch_request return self.view_f unctions[rule.end point](**req. view_args) File“app.py”, line 8, in index return render_template(“index.html”, greeting=greeting)NameError: name 'greeting' is not defined127.0.0.1--[22/Feb/2017 14:35:54] “GET / HTTP/1.1” 500—

Page 268: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

This works well enough, but you can also run Flask in “debugger mode”.This will give you a better error page and more useful information. Theproblem with debugger mode is it’s not safe to run on the internet, so youhave to explicitly turn it on like this:

(lpthw) $ export FLASK_DEBUG=1(lpthw) $ python3.6 app.py * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) * Restarting with stat * Debugger is active! * Debugger pin code: 222—752—342

After this, you hit refresh in your browser, and you get a much more detailedpage with information you can use to debug the application and a live consoleto work with to find out more.

Warning!

It’s the Flask live debugging console and the improved output that makesdebug mode so dangerous on the internet. With this information an attackercan completely control your machine remotely. If you ever do place your webapplication on the internet do not activate debugger mode. In fact, I wouldavoid making FLASK_DEBUG easy to activate. It’s tempting to simply hack thisstartup so that you save a step during development, but then that hack will getonto your web server and it’ll turn into a real hack, not just something lazyyou did one night when you were tired.

Create Basic Templates

You can break your flask application, but did you notice that “Hello World”isn’t a very good HTML page? This is a web application, and as such it needsa proper HTML response. To do that you will create a simple template thatsays “Hello World” in a big green font.

The first step is to create a templates/index.html file that looks like this:

index.html

Page 269: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

<html> <head> <title>Gothons Of Planet Percal #25</title> </head><body>

{% if greeting %} I just wanted to say <em style="color: green; font-size: 2em;">{{ greeting }}</em>.{% else %} <em>Hello</em>, world!{% endif %}

</body></html>

If you know what HTML is, then this should look fairly familiar. If not,research HTML and try writing a few web pages by hand so you know how itworks. This HTML file, however, is a template, which means that flask willfill in “holes” in the text depending on variables you pass in to the template.Every place you see $greeting will be a variable you’ll pass to the templatethat alters its contents.

To make your app.py do this, you need to add some code to tell flask whereto load the template and to render it. Take that file and change it like this:

app.py

1 from flask import Flask 2 from flask import render_template 3 4 app = Flask(__name__) 5 6 @app.route("/") 7 def index(): 8 greeting = "Hello World" 9 return render_template("index.html", greeting=greeting)1011 if __name__ == "__main__":12 app.run()

Pay close attention to the new render variable and how I changed the last

Page 270: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

line of index.GET so it returns render.index(), passing in your greetingvariable.

Once you have that in place, reload the web page in your browser, and youshould see a different message in green. You should also be able to do a ViewSource on the page in your browser to see that it is valid HTML.

This may have flown by you very fast, so let me explain how a templateworks:

1. In your app.py you’ve imported a new function named render_templateat the top.

2. This render_template knows how to load .html files out of thetemplates/ directory because that is the default magic setting for a Flaskapplication.

3. Later in your code, when the browser hits the def index, instead of justreturning the string greeting, you call render_template and pass thegreeting to it as a variable.

4. This render_template method then loads the templates/index.html file(even though you didn’t explicitly say templates) and processes it.

5. In this templates/index.html file you have what looks like normalHTML, but then there’s “code” placed between two kinds of markers. One is{% %}, which marks pieces of “executable code” (if-statements, for-loops,etc). The other is {{ }} which marks variables to be converted into text andplaced into the HTML output. The {% %} executable code doesn’t show up inthe HTML. To learn more about this template language read the Jinja2Documentation.

To get deeper into this, change the greeting variable and the HTML to seewhat effect it has. Also create another template named templates/foo.htmland render that like before.

Study Drills

Page 271: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

1. Read the documentation at http://flask.pocoo.org/docs/0.12/, which is thesame as the flask project.

2. Experiment with everything you can find there, including their examplecode.

3. Read about HTML5 and CSS3 and make some other .html and .css filesfor practice.

4. If you have a friend who knows Django and is willing to help you, thenconsider doing Exercises 50, 51, and 52 in Django instead to see what that’slike.

Common Student Questions

I can’t seem to connect to http://localhost:5000/. Try going tohttp://127.0.0.1:5000/ instead.

What is the difference betwee flask and web.py? No difference. I simply“locked” web.py at a particular version so that it would be consistent forstudents, then named it flask. Later versions of web.py might be differentfrom this version.

I can’t find index.html (or just about anything). You probably are doingcd bin/ first and then trying to work with the project. Do not do this. All ofthe commands and instructions assume you are one directory above bin/, soif you can’t type python3.6 app.py then you are in the wrong directory.

Why do we assign greeting=greeting when we call the template? Youare not assigning to greeting. You are setting a named parameter to give tothe template. It’s sort of an assignment, but it only affects the call to thetemplate function.

I can’t use port 5000 on my computer. You probably have an anti-virusprogram installed that is using that port. Try a different port.

After installing flask I get ImportError "No module named web". Youmost likely have multiple versions of python installed and are using the

Page 272: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

wrong one, or you didn’t do the install correctly because of an old version ofpip. Try uninstalling flask and reinstalling it. If that doesn’t work, maketriple sure you’re using the right version of python.

Page 273: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 51. Getting Input from a BrowserWhile it’s exciting to see the browser display “Hello World,” it’s even moreexciting to let the user submit text to your application from a form. In thisexercise we’ll improve our starter web application by using forms and storinginformation about users into their “sessions.”

How the Web Works

Time for some boring stuff. You need to understand a bit more about how theweb works before you can make a form. This description isn’t complete, butit’s accurate and will help you figure out what might be going wrong withyour application. Also, creating forms will be easier if you know what theydo.

I’ll start with a simple diagram that shows you the different parts of a webrequest and how the information flows: I’ve labeled the lines with letters so Ican walk you through a regular request process:

Page 274: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

1. You type in the url http://test.com// into your browser, and it sends therequest on line (A) to your computer’s network interface.

2. Your request goes out over the internet on line (B) and then to the remotecomputer on line (C) where my server accepts the request.

3. Once my computer accepts it, my web application gets it on line (D), andmy Python code runs the index.GET handler.

4. The response comes out of my Python server when I return it, and it goesback to your browser over line (D) again.

5. The server running this site takes the response off line (D), then sends itback over the internet on line (C).

6. The response from the server then comes off the internet on line (B), andyour computer’s network interface hands it to your browser on line (A).

7. Finally, your browser then displays the response.

In this description there are a few terms you should know so that you have acommon vocabulary to work with when talking about your web application:

Browser The software that you’re probably using every day. Most peopledon’t know what a browser really does. They just call browsers “theinternet.” Its job is to take addresses (like http://test.com/) you type into theURL bar, then use that information to make requests to the server at thataddress.

Address This is normally a URL (Uniform Resource Locator) likehttp://test.com// and indicates where a browser should go. The first part,http, indicates the protocol you want to use, in this case “Hyper-TextTransport Protocol.” You can also try ftp://ibiblio.org/ to see how “FileTransport Protocol” works. The http://test.com/ part is the “hostname,” ahuman readable address you can remember and which maps to a numbercalled an IP address, similar to a telephone number for a computer on theinternet. Finally, URLs can have a trailing path like the /book/ part ofhttp://test.com//book/, which indicates a file or some resource on the server to

Page 275: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

retrieve with a request. There are many other parts, but those are the mainones.

Connection Once a browser knows what protocol you want to use (http),what server you want to talk to (http://test.com/), and what resource on thatserver to get, it must make a connection. The browser simply asks youroperating system (OS) to open a “port” to the computer, usually port 80.When it works, the OS hands back to your program something that workslike a file, but is actually sending and receiving bytes over the network wiresbetween your computer and the other computer at http://test.com/. This isalso the same thing that happens with http://localhost:8080/, but in this caseyou’re telling the browser to connect to your own computer (localhost) anduse port 8080 rather than the default of 80. You could also dohttp://test.com:80/ and get the same result, except you’re explicitly saying touse port 80 instead of letting it be that by default.

Request Your browser is connected using the address you gave. Now itneeds to ask for the resource it wants (or you want) on the remote server. Ifyou gave /book/ at the end of the URL, then you want the file (resource) at/book/, and most servers will use the real file /book/index.html but pretendit doesn’t exist. What the browser does to get this resource is send a requestto the server. I won’t get into exactly how it does this, but just understand thatit has to send something to query the server for the request. The interestingthing is that these “resources” don’t have to be files. For instance, when thebrowser in your application asks for something, the server is returningsomething your Python code generated.

Server The server is the computer at the end of a browser’s connection thatknows how to answer your browser’s requests for files/resources. Most webservers just send files, and that’s actually the majority of traffic. But you’reactually building a server in Python that knows how to take requests forresources and then return strings that you craft using Python. When you dothis crafting, you are pretending to be a file to the browser, but really it’s justcode. As you can see from Exercise 50, it also doesn’t take much code tocreate a response.

Response This is the HTML (CSS, JavaScript, or images) your server wantsto send back to the browser as the answer to the browser’s request. In the

Page 276: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

case of files, it just reads them off the disk and sends them to the browser, butit wraps the contents of the disk in a special “header” so the browser knowswhat it’s getting. In the case of your application, you’re still sending the samething, including the header, but you generate that data on the fly with yourPython code.

That is the fastest crash course in how a web browser accesses information onservers on the internet. It should work well enough for you to understand thisexercise, but if not, read about it as much as you can until you get it. A reallygood way to do that is to take the diagram and break different parts of theweb application you did in Exercise 50. If you can break your webapplication in predictable ways using the diagram, you’ll start to understandhow it works.

How Forms Work

The best way to play with forms is to write some code that accepts form data,and then see what you can do. Take your app.py file and make it look likethis:

form_test.py

1 from flask import Flask 2 from flask import render_template 3 from flask import request 4 5 app = Flask(__name__) 6 7 @app.route("/hello") 8 def index(): 9 name = request.args.get('name', 'Nobody')1011 if name:12 greeting = f"Hello, {name}"13 else: 14 greeting = "Hello World"1516 return render_template("index.html", greeting=greeting)1718 if __name__ == "__main__":

Page 277: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

19 app.run()

Restart it (hit CTRL-C and then run it again) to make sure it loads again, thenwith your browser go to http://localhost:5000/hello, which shoulddisplay, “I just wanted to say Hello, Nobody.” Next, change the URL in yourbrowser to http://localhost:5000/hello?name=Frank, and you’ll see itsay, “Hello, Frank.” Finally, change the name=Frank part to be your name.Now it’s saying hello to you.

Let’s break down the changes I made to your script.

1. Instead of just a string for greeting, I’m now using request.args to getdata from the browser. This is a simple dict that contains the form values askey=value pairs.

2. I then construct the greeting from the new name, which should be veryfamiliar to you by now.

3. Everything else about the file is the same as before.

You’re also not restricted to just one parameter on the URL. Change thisexample to give two variables like this: http://localhost:5000/hello?name=Frank&greet=Hola. Then change the code to get name and greet likethis:

greet = request.args.get( ' greet ' , ' Hello ' )greeting = f"{greet}, {name}"

You should also try not giving the greet and name parameters on the URL.You’ll simply send your browser to http://localhost:5000/hello to seethat the index now defaults to “Nobody” for name and “Hello” for greet.

Creating HTML Forms

Passing the parameters on the URL works, but it’s kind of ugly and not easyto use for regular people. What you really want is a “POST form,” which is aspecial HTML file that has a <form> tag in it. This form will collectinformation from the user, then send it to your web application just like you

Page 278: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

did above.

Let’s make a quick one so you can see how it works. Here’s the new HTMLfile you need to create, in templates/hello_form.html:

hello_form.html

<html> <head> <title>Sample Web Form</title> </head><body>

<h1>Fill Out This Form</h1>

<form action="/hello" method="POST"> A Greeting: <input type="text" name="greet"> <br/> Your Name: <input type="text" name="name"> <br/> <input type="submit"></form>

</body></html>

You should then change app.py to look like this:

app.py

1 from flask import Flask 2 from flask import render_template 3 from flask import request 4 5 app = Flask(__name__) 6 7 @app.route("/hello", methods=['POST', 'GET']) 8 def index(): 9 greeting = "Hello World"1011 if request.method == "POST":12 name = request.form['name']13 greet = request.form['greet']14 greeting = f"{greet}, {name}"

Page 279: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

15 return render_template("index.html", greeting=greeting)16 else:17 return render_template("hello_form.html")181920 if __name__ == "__main__":21 app.run()

Once you’ve got those written up, simply restart the web application againand hit it with your browser like before.

This time you’ll get a form asking you for “A Greeting” and “Your Name.”When you hit the Submit button on the form, it will give you the samegreeting you normally get, but this time look at the URL in your browser. Seehow it’s http://localhost:5000/hello even though you sent in parameters.

The part of the hello_form.html file that makes this work is the line with<form action="/hello" method="POST">. This tells your browser to:

1. Collect data from the user using the form fields inside the form.

2. Send them to the server using a POST type of request, which is just anotherbrowser request that “hides” the form fields.

3. Send that to the /hello URL (as shown in the action="/hello" part).

You can then see how the two <input> tags match the names of the variablesin your new code. Also notice that instead of just a GET method inside classindex, I have another method, POST. How this new application works is asfollows:

1. Your request goes to index() like normal, except now there is an if-statement that checks the request.method for either "POST" or "GET"methods. This is how the browser tells app.py that a request is either a formsubmission or URL parameters.

2. If request.method is "POST", then you process the form as if it were filledout and submitted, returning the proper greeting.

3. If request.method is anything else, then you simply return the

Page 280: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

hello_form.html for the user to fill out.

As an exercise, go into the templates/index.html file and add a link back tojust /hello so that you can keep filling out the form and seeing the results.Make sure you can explain how this link works and how it’s letting you cyclebetween templates/index.html and templates/hello_form.html andwhat’s being run inside this latest Python code.

Creating a Layout Template

When you work on your game in the next exercise, you’ll need to make abunch of little HTML pages. Writing a full web page each time will quicklybecome tedious. Luckily you can create a “layout” template, or a kind of shellthat will wrap all your other pages with common headers and footers. Goodprogrammers try to reduce repetition, so layouts are essential for being agood programmer.

Change templates/index.html to be like this:

index_laid_out.html

{% extends "layout.html" %}

{% block content %}{% if greeting %} I just wanted to say <em style="color: green; font-size: 2em;">{{ greeting }}</em>.{% else %} <em>Hello</em>, world!{% endif %}

{% endblock %}

Then change templates/hello_form.html to be like this:

hello_form_laid_out.html

{% extends "layout.html" %}

Page 281: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

{% block content %}

<h1>Fill Out This Form</h1>

<form action="/hello" method="POST"> A Greeting: <input type="text" name="greet"> <br/> Your Name: <input type="text" name="name"> <br/> <input type="submit"></form>

{% endblock %}

All we’re doing is stripping out the “boilerplate” at the top and the bottom,which is always on every page. We’ll put that back into a singletemplates/layout.html file that handles it for us from now on.

Once you have those changes, create a templates/layout.html file with thisin it:

layout.html

<html><head> <title>Gothons From Planet Percal #25</title></head><body>

{% block content %}

{% endblock %}</body></html>

This file looks like a regular template, except that it’s going to be passed thecontents of the other templates and used to wrap them. Anything you put inhere doesn’t need to be in the other templates. Your other HTML templateswill be inserted into the {% block content %} section. Flask knows to usethis layout.html as the layout because you put {% extends "layout.html"%} at the top of your templates.

Page 282: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Writing Automated Tests for Forms

It’s easy to test a web application with your browser by just hitting refresh,but come on, we’re programmers here. Why do some repetitive task when wecan write some code to test our application? What you’re going to do next iswrite a little test for your web application form based on what you learned inExercise 47. If you don’t remember Exercise 47, read it again.

Create a new file named tests/app_tests.py with this:

app_tests.py

1 from nose.tools import * 2 from app import app 3 4 app.config['TESTING'] = True 5 web = app.test_client() 6 7 def test_index(): 8 rv = web.get('/', follow_redirects=True) 9 assert_equal(rv.status_code, 404)1011 rv = web.get('/hello', follow_redirects=True)12 assert_equal(rv.status_code, 200)13 assert_in(b"Fill Out This Form", rv.data)1415 data = {'name': 'Zed', 'greet': 'Hola'}16 rv = web.post('/hello', follow_redirects=True, data=data)17 assert_in(b"Zed", rv.data)18 assert_in(b"Hola", rv.data)

Finally, use nosetests to run this test setup and test your web application:

$ nosetests.Ran 1 test in 0.059sOK

What I’m doing here is I’m actually importing the whole application from theapp.py module, then running it manually. The flask framework has a verysimple API for processing requests, which looks like this:

Page 283: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

data = {'name': 'Zed', 'greet': 'Hola'}rv = web.post('/hello', follow_redirects=True, data=data)

This means you can send a POST request using the post() method, and thengive it the form data as a dict. Everything else works the same as testingweb.get() requests.

In the tests/app_tests.py automated test I’m first making sure the / URLreturns a “404 Not Found” response, since it actually doesn’t exist. Then I’mchecking that /hello works with both a GET and a POST form. Following thetest should be fairly simple, even if you might not totally know what’s goingon.

Take some time studying this latest application, especially how the automatedtesting works. Make sure you understand how I imported the applicationfrom app.py and ran it directly for the automated test. This is an importanttrick that will lead to more learning.

Study Drills

1. Read even more about HTML, and give the simple form a better layout. Ithelps to draw what you want to do on paper and then implement it withHTML.

2. This one is hard, but try to figure out how you’d do a file upload form sothat you can upload an image and save it to the disk.

3. This is even more mind-numbing, but go find the HTTP RFC (which is thedocument that describes how HTTP works) and read as much of it as youcan. It is really boring but comes in handy once in a while.

4. This will also be really difficult, but see if you can find someone to helpyou set up a web server like Apache, Nginx, or thttpd. Try to serve a coupleof your .html and .css files with it just to see if you can. Don’t worry if youcan’t. Web servers kind of suck.

5. Take a break after this and just try making as many different webapplications as you can.

Page 284: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Breaking It

This is a great place to figure out how to break web applications. You shouldexperiment with the following:

1. How much damage can you do with the FLASK_DEBUG setting on? Becareful that you don’t wipe yourself out doing this.

2. Let’s say you don’t have default parameters for the forms. What could gowrong?

3. You’re checking for POST and then “anything else.” You can use the curlcommand line tool to generate different request types. What happens?

Page 285: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 52. The Start of Your Web GameWe’re coming to the end of the book, and in this exercise I’m going to reallychallenge you. When you’re done, you’ll be a reasonably competent Pythonbeginner. You’ll still need to go through a few more books and write a couplemore projects, but you’ll have the skills to complete them. The only thing inyour way will be time, motivation, and resources.

In this exercise, we won’t make a complete game, but instead we’ll make an“engine” that can run the game from Exercise 47 in the browser. This willinvolve refactoring Exercise 43, mixing in the structure from Exercise 47,adding automated tests, and finally creating a web engine that can run thegames.

This exercise will be huge, and I predict you could spend anywhere from aweek to months on it before moving on. It’s best to attack it in little chunksand do a bit a night, taking your time to make everything work before movingon.

Refactoring the Exercise 43 Game

You’ve been altering the gothonweb project for two exercises, and you’ll doit one more time in this exercise. The skill you’re learning is called“refactoring,” or as I like to call it, “fixing stuff.” Refactoring is a termprogrammers use to describe the process of taking old code and changing it tohave new features or just to clean it up. You’ve been doing this without evenknowing it, as it’s second nature to building software.

What you’ll do in this part is take the ideas from Exercise 47 of a testable“map” of Rooms and the game from Exercise 43 and combine them togetherto create a new game structure. It will have the same content, just“refactored” to have a better structure.

The first step is to grab the code from ex47/game.py, copy it togothonweb/planisphere.py, copy the tests/ex47_tests.py file to

Page 286: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

tests/planisphere_tests.py, and run nosetests again to make sure itkeeps working. The word “planisphere” is just a synonym for “map”, whichavoids Python’s built-in map function. The Thesaurus is your friend.

Warning!

From now on I won’t show you the output of a test run. Just assume that youshould be doing it and it’ll look like the preceding unless you have an error.

Once you have the code from Exercise 47 copied over, it’s time to refactor itto have the Exercise 43 map in it. I’m going to start off by laying down thebasic structure, and then you’ll have an assignment to make theplanisphere.py file and the planisphere_tests.py file complete.

Lay out the basic structure of the map using the Room class as it is now:

planisphere.py

1 class Room(object): 2 3 def __init__(self, name, description): 4 self.name = name 5 self.description = description 6 self.paths = {} 7 8 def go(self, direction): 9 return self.paths.get(direction, None) 10 11 def add_paths(self, paths): 12 self.paths.update(paths) 13 14 15 central_corridor = Room("Central Corridor", 16 """ 17 The Gothons of Planet Percal #25 have invaded your ship and destroyed 18 your entire crew. You are the last surviving member and your last 19 mission is to get the neutron destruct bomb from the Weapons Armory, put 20 it in the bridge, and blow the ship up after getting into an escape pod. 21 22 You're running down the central corridor to the Weapons Armory when a

Page 287: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

23 Gothon jumps out, red scaly skin, dark grimy teeth, and evil clown 24 costume flowing around his hate filled body. He's blocking the door to 25 the Armory and about to pull a weapon to blast you. 26 """) 27 28 29 laser_weapon_armory = Room("Laser Weapon Armory", 30 """ 31 Lucky for you they made you learn Gothon insults in the academy. You 32 tell the one Gothon joke you know: Lbhe zbgure vf fb sng, jura fur fvgf 33 nebhaq gur ubhfr, fur fvgf nebhaq gur ubhfr. The Gothon stops, tries 34 not to laugh, then busts out laughing and can't move. While he's 35 laughing you run up and shoot him square in the head putting him down, 36 then jump through the Weapon Armory door. 37 38 You do a dive roll into the Weapon Armory, crouch and scan the room for 39 more Gothons that might be hiding. It's dead quiet, too quiet. You 40 stand up and run to the far side of the room and find the neutron bomb 41 in its container. There's a keypad lock on the box and you need the 42 code to get the bomb out. If you get the code wrong 10 times then the 43 lock closes forever and you can't get the bomb. The code is 3 digits. 44 """) 45 46 47 the_bridge = Room("The Bridge", 48 """ 49 The container clicks open and the seal breaks, letting gas out. You 50 grab the neutron bomb and run as fast as you can to the bridge where you 51 must place it in the right spot. 52 53 You burst onto the Bridge with the netron destruct bomb under your arm 54 and surprise 5 Gothons who are trying to take control of the ship. Each 55 of them has an even uglier clown costume than the last. They haven't 56 pulled their weapons out yet, as they see the active bomb under your arm 57 and don't want to set it off. 58 """) 59 60 61 escape_pod = Room("Escape Pod", 62 """ 63 You point your blaster at the bomb under your arm and the Gothons put 64 their hands up and start to sweat. You inch backward to the door, open 65 it, and then carefully place the bomb on the floor, pointing your 66 blaster at it. You then jump back through the door, punch the close 67 button and blast the lock so the Gothons can't get out. Now that the 68 bomb is placed you run to the escape pod to get off this tin can. 69 70 You rush through the ship desperately trying to make it to the escape

Page 288: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

71 pod before the whole ship explodes. It seems like hardly any Gothons 72 are on the ship, so your run is clear of interference. You get to the 73 chamber with the escape pods, and now need to pick one to take. Some of 74 them could be damaged but you don't have time to look. There's 5 pods, 75 which one do you take? 76 """) 77 78 79 the_end_winner = Room("The End", 80 """ 81 You jump into pod 2 and hit the eject button. The pod easily slides out 82 into space heading to the planet below. As it flies to the planet, you 83 look back and see your ship implode then explode like a bright star, 84 taking out the Gothon ship at the same time. You won! 85 """) 86 87 88 the_end_loser = Room("The End", 89 """ 90 You jump into a random pod and hit the eject button. The pod escapes 91 out into the void of space, then implodes as the hull ruptures, crushing 92 your body into jam jelly. 93 """ 94 ) 95 96 escape_pod.add_paths({ 97 '2': the_end_winner, 98 '*': the_end_loser 99 })100101 generic_death = Room("death", "You died.")102103 the_bridge.add_paths({104 'throw the bomb': generic_death,105 'slowly place the bomb': escape_pod106 })107108 laser_weapon_armory.add_paths({109 '0132': the_bridge,110 '*': generic_death111 })112113 central_corridor.add_paths({114 'shoot!': generic_death,115 'dodge!': generic_death,116 'tell a joke': laser_weapon_armory117 })118

Page 289: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

119 START = 'central_corridor'120121 def load_room(name):122 """123 There is a potential security problem here.124 Who gets to set name? Can that expose a variable?125 """126 return globals().get(name)127128 def name_room(room):129 """130 Same possible security problem. Can you trust room?131 What's a better solution than this globals lookup?132 """133 for key, value in globals().items():134 if value == room:135 return key

You’ll notice that there are a couple of problems with our Room class and thismap:

1. We have to put the text that was in the if-else clauses that got printedbefore entering a room as part of each room. This means you can’t shuffle theplanisphere around, which would be nice. You’ll be fixing that up in thisexercise.

2. There are parts in the original game where we ran code that determinedthings like the bomb’s keypad code or the right pod. In this game we just picksome defaults and go with it, but later you’ll be given Study Drills to makethis work again.

3. I’ve just made a generic_death ending for all of the bad decisions, whichyou’ll have to finish for me. You’ll need to go back through and add in all theoriginal endings and make sure they work.

4. I’ve got a new kind of transition labeled "*" that will be used for a “catch-all” action in the engine.

Once you’ve got that basically written out, here’s the new automated testtests/planisphere_test.py that you should have to get yourself started:

planisphere_tests.py

Page 290: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

1 from nose.tools import * 2 from gothonweb.planisphere import * 3 4 def test_room(): 5 gold = Room("GoldRoom", 6 """This room has gold in it you can grab. There's a 7 door to the north.""") 8 assert_equal(gold.name, "GoldRoom") 9 assert_equal(gold.paths, {})1011 def test_room_paths():12 center = Room("Center", "Test room in the center.")13 north = Room("North", "Test room in the north.")14 south = Room("South", "Test room in the south.")1516 center.add_paths({'north': north, 'south': south})17 assert_equal(center.go('north'), north)18 assert_equal(center.go('south'), south)1920 def test_map():21 start = Room("Start", "You can go west and down a hole.")22 west = Room("Trees", "There are trees here, you can go east."23 down = Room("Dungeon", "It's dark down here, you can go up."2425 start.add_paths({'west': west, 'down': down})26 west.add_paths({'east': start})27 down.add_paths({'up': start})2829 assert_equal(start.go('west'), west)30 assert_equal(start.go('west').go('east'), start)31 assert_equal(start.go('down').go('up'), start)3233 def test_gothon_game_map():34 start_room = load_room(START)35 assert_equal(start_room.go('shoot!'), generic_death)36 assert_equal(start_room.go('dodge!'), generic_death)3738 room = start_room.go('tell a joke')39 assert_equal(room, laser_weapon_armory)

Your task in this part of the exercise is to complete the map and make theautomated test completely validate the whole map. This includes fixing allthe generic_death objects to be real endings. Make sure this works reallywell and that your test is as complete as possible because we’ll be changingthis map later, and you’ll use the tests to make sure it keeps working.

Page 291: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Creating an Engine

You should have your game map working and a good unit test for it. I nowwant you to make a simple little game engine that will run the rooms, collectinput from the player, and keep track of where a player is in the game. We’llbe using the sessions you just learned to make a simple game engine that willdo the following:

1. Start a new game for new users.

2. Present the room to the user.

3. Take input from the user.

4. Run user input through the game.

5. Display the results and keep going until the user dies.

To do this, you’re going to take the trusty app.py you’ve been hacking onand create a fully working, session-based game engine. The catch is I’mgoing to make a very simple one with basic HTML files, and it’ll be up to youto complete it. Here’s the base engine:

app.py

1 from flask import Flask, session, redirect, url_for, escape, request 2 from flask import render_template 3 from gothonweb import planisphere 4 5 app = Flask(__name__) 6 7 @app.route("/") 8 def index(): 9 # this is used to "setup" the session with starting values10 session['room_name'] = planisphere.START11 return redirect(url_for("game"))1213 @app.route("/game", methods=['GET', 'POST'])14 def game():15 room_name = session.get('room_name')

Page 292: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

1617 if request.method == "GET":18 if room_name:19 room = planisphere.load_room(room_name)20 return render_template("show_room.html", room=room)21 else:22 # why is there here? do you need it?'23 return render_template("you_died.html")24 else:25 action = request.form.get('action')2627 if room_name and action:28 room = planisphere.load_room(room_name)29 next_room = room.go(action)3031 if not next_room:32 session['room_name'] = planisphere.name_room(room)33 else:34 session['room_name'] = planisphere.name_room(next_room)3536 return redirect(url_for("game"))373839 # YOU SHOULD CHANGE THIS IF YOU PUT ON THE INTERNET40 app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'4142 if __name__ == "__main__":43 app.run()

There are even more new things in this script, but amazingly it’s an entireweb-based game engine in a small file. Before you run app.py you need tochange your PYTHONPATH environment variable. Don’t know what thatis? I know, it’s kind of dumb, but you have to learn what this is to run evenbasic Python programs, but that’s how Python people like things.

In your terminal, type:

export PYTHONPATH=$PYTHONPATH : .

On Windows PowerShell do:

$env :PYTHONPATH = "$env :PYTHONPATH ; . "

You should only have to do it once per shell session, but if you get an import

Page 293: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

error, then you probably need to do this or you did it wrong.

You should next delete templates/hello_form.html andtemplates/index.html and create the two templates mentioned in thepreceding code. Here’s a very simple templates/show_room.html:

show_room.html

{% extends "layout.html" %}

{% block content %}

<h1> {{ room.name }} </h1>

<pre>{{ room.description }}</pre>

{% if room.name in ["death", "The End"] %} <p><a href="/">Play Again?</a></p>{% else %} <p> <form action="/game" method="POST"> - <input type="text" name="action"> <input type="SUBMIT"> </form> </p>{% endif %}

{% endblock %}

That is the template to show a room as you travel through the game. Next youneed one to tell someone they died in the case that they got to the end of themap on accident, which is templates/you_died.html:

you_died.html

<h1>You Died!</h1>

<p>Looks like you bit the dust.</p><p><a href="/">Play Again</a></p>

Page 294: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

With those in place, you should now be able to do the following:

1. Get the test tests/app_tests.py working again so that you are testing thegame. You won’t be able to do much more than a few clicks in the gamebecause of sessions, but you should be able to do some basics. 3. Run thepython3.6 app.py script and test out the game.

You should be able to refresh and fix the game like normal. You should alsobe able to work with the game HTML and engine until it does all the thingsyou want it to do.

Your Final Exam

Do you feel like this was a huge amount of information thrown at you all atonce? Good, I want you to have something to tinker with while you buildyour skills. To complete this exercise, I’m going to give you a final set ofexercises for you to complete on your own. You’ll notice that what you’vewritten so far isn’t very well built; it is just a first version of the code. Yourtask now is to make the game more complete by doing these things:

1. Fix all the bugs I mention in the code and any that I didn’t mention. If youfind new bugs, let me know.

2. Improve all of the automated tests so that you test more of the application,and get to a point where you use a test rather than your browser to check theapplication while you work.

3. Make the HTML look better.

4. Research logins and create a signup system for the application so peoplecan have logins and high scores.

5. Complete the game map, making it as large and feature-complete aspossible.

6. Give people a “help” system that lets them ask what they can do at eachroom in the game.

Page 295: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

7. Add any other features you can think of to the game.

8. Create several “maps” and let people choose a game they want to run.Your app.py engine should be able to run any map of rooms you give it, soyou can support multiple games.

9. Finally, use what you learned in Exercises 48 and 49 to create a betterinput processor. You have most of the code necessary; you just need toimprove the grammar and hook it up to your input form and the GameEngine.

Good luck!

Common Student Questions

I’m using sessions in my game, and I can’t test it with nosetests. Readthe Flask Testing Documentation about “Other Testing Tricks” forinformation on creating fake sessions inside your tests.

I get an ImportError. It could be one or mor of these: wrong directory,wrong Python version, PYTHON-PATH not set, no __init__.py file, and/orspelling mistake in import.

Page 296: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 53. Next StepsYou’re not a programmer quite yet. I like to think of this book as giving youyour “programming black belt.” You know enough to start another book onprogramming and handle it just fine. This book should have given you themental tools and attitude you need to go through most Python books andactually learn something. It might even make it easy.

I recommend you check out some of these projects and try to build somethingwith them:

• Learn Ruby The Hard Way You will learn even more about programmingas you learn more programming languages, so try learning Ruby too.

• The Django Tutorial and try to build a web application with the DjangoWeb Framework.

• SciPy if you’re into science, math, and engineering.

• PyGame and see if you can make a game with graphics and sound.

• Pandas for doing data manipulation and analysis.

• Natural Language Tool Kit for analyzing written text and writing thingslike spam filters and chat bots. TensorFlow for machine learning andvisualization.

• Requests to learn the client side of HTTP and the web.

• ScraPy and try scraping some web sites to get information off them.

• Kivy for doing user interfaces on desktops and mobile platforms.

• Learn C The Hard Way after you’re familiar with Python and try learning Cand algorithms with my other book. Take it slow; C is different but a verygood thing to learn.

Page 297: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Pick one of the preceding resources, and go through any tutorials anddocumentation they have. As you go through documentation with code in it,type in all of the code and make it work. That’s how I do it. That’s how everyprogrammer does it. Reading programming documentation is not enough tolearn it; you have to do it. After you get through the tutorial and any otherdocumentation they have, make something. Anything will do, evensomething someone else has already written. Just make something.

Just understand anything you write will probably suck. That’s alright thoughI suck at every programming language I first start using. Nobody writes pureperfect gold when they’re a beginner, and anyone who tells you they did is ahuge liar.

How to Learn Any Programming Language

I’m going to teach you how to learn most of the programming languages youmay want to learn in the future. The organization of this book is based onhow I and many other programmers learn new languages. The process that Iusually follow is:

1. Get a book or some introductory text about the language.

2. Go through the book and type in all of the code making all of it run.

3. Read the book as you work on the code, taking notes.

4. Use the language to implement a small set of programs you are familiarwith in another language.

5. Read other people’s code in the language, and try to copy their patterns.

In this book, I forced you to go through this process very slowly and in smallchunks. Other books aren’t organized the same way, and this means you haveto extrapolate how I’ve made you do this to how their content is organized.Best way to do this is to read the book lightly and make a list of all the majorcode sections. Turn this list into a set of exercises based on the chapters, andthen simply do them in order one at a time.

Page 298: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

The preceding process also works for new technologies, assuming they havebooks you can read. For anything without books, you do the above processbut use online documentation or source code as your initial introduction.

Each new language you learn makes you a better programmer, and as youlearn more they become easier to learn. By your third or fourth language youshould be able to pick up similar languages in a week, with strangerlanguages taking longer. Now that you know Python you could potentiallylearn Ruby and JavaScript fairly quickly by comparison. This is simplybecause many languages share similar concepts, and once you learn theconcepts in one language they work in others.

The final thing to remember about learning a new language is this: Don’t be astupid tourist. A stupid tourist is someone who goes to another country andthen complains that the food isn’t like the food at home. “Why can’t I get agood burger in this stupid country!?” When you’re learning a new language,assume that what it does isn’t stupid, it’s just different, and embrace it so youcan learn it.

After you learn a language though, don’t be a slave to that language’s way ofdoing things. Sometimes the people who use a language actually do somevery idiotic things for no other reason than “that’s how we’ve always doneit.” If you like your style better and you know how everyone else does it, thenfeel free to break their rules if it improves things.

I really enjoy learning new programming languages. I think of myself as a“programmer anthropologist” and think of them as little insights about thegroup of programmers who use them. I’m learning a language they all use totalk to each other through computers, and I find this fascinating. Then againI’m kind of a weird guy, so just learn programming languages because youwant to.

Enjoy! This is really fun stuff.

Page 299: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 54. Advice from an OldProgrammerYou’ve finished this book and have decided to continue with programming.Maybe it will be a career for you, or maybe it will be a hobby. You’ll needsome advice to make sure you continue on the right path and get the mostenjoyment out of your newly chosen activity.

I’ve been programming for a very long time. So long that it’s incrediblyboring to me. At the time that I wrote this book, I knew about 20programming languages and could learn new ones in about a day to a weekdepending on how weird they were. Eventually though this just becameboring and couldn’t hold my interest anymore. This doesn’t mean I thinkprogramming is boring, or that you will think it’s boring, only that I find ituninteresting at this point in my journey.

What I discovered after this journey of learning is that it’s not the languagesthat matter but what you do with them. Actually, I always knew that, but I’dget distracted by the languages and forget it periodically. Now I never forgetit, and neither should you.

Which programming language you learn and use doesn’t matter. Do not getsucked into the religion surrounding programming languages as that will onlyblind you to their true purpose of being your tool for doing interesting things.

Programming as an intellectual activity is the only art form that allows you tocreate interactive art. You can create projects that other people can play with,and you can talk to them indirectly. No other art form is quite this interactive.Movies flow to the audience in one direction. Paintings do not move. Codegoes both ways.

Programming as a profession is only moderately interesting. It can be a goodjob, but you could make about the same money and be happier running a fastfood joint. You’re much better off using code as your secret weapon inanother profession.

Page 300: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

People who can code in the world of technology companies are a dime adozen and get no respect. People who can code in biology, medicine,government, sociology, physics, history, and mathematics are respected andcan do amazing things to advance those disciplines.

Of course, all of this advice is pointless. If you liked learning to writesoftware with this book, you should try to use it to improve your life any wayyou can. Go out and explore this weird, wonderful, new intellectual pursuitthat barely anyone in the last 50 years has been able to explore. Might as wellenjoy it while you can.

Finally, I’ll say that learning to create software changes you and makes youdifferent. Not better or worse, just different. You may find that people treatyou harshly because you can create software, maybe using words like “nerd.”Maybe you’ll find that because you can dissect their logic that they hatearguing with you. You may even find that simply knowing how a computerworks makes you annoying and weird to them.

To this I have just one piece of advice: they can go to hell. The world needsmore weird people who know how things work and who love to figure it allout. When they treat you like this, just remember that this is your journey, nottheirs. Being different is not a crime, and people who tell you it is are justjealous that you’ve picked up a skill they never in their wildest dreams couldacquire.

You can code. They cannot. That is pretty damn cool.

Page 301: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Appendix A. Command Line Crash CourseThis appendix is a quick super fast course in using the command line. It isintended to be done rapidly in about a day or two, and not meant to teach youadvanced shell usage.

Introduction: Shut Up and Shell

This appendix is a crash course in using the command line to make yourcomputer perform tasks. As a crash course, it's not as detailed or extensive asmy other books. It is simply designed to get you barely capable enough tostart using your computer like a real programmer does. When you're donewith this appendix, you will be able to give most of the basic commands thatevery shell user touches every day. You'll understand the basics of directoriesand a few other concepts.

The only piece of advice I am going to give you is this:

Shut up and type all of this in.

Sorry to be mean, but that's what you have to do. If you have an irrationalfear of the command line, the only way to conquer an irrational fear is to justshut up and fight through it.

You are not going to destroy your computer. You are not going to be throwninto some jail at the bottom of Microsoft's Redmond campus. Your friendswon't laugh at you for being a nerd. Simply ignore any stupid weird reasonsyou have for fearing the command line.

Why? Because if you want to learn to code, then you must learn this.Programming languages are advanced ways to control your computer withlanguage. The command line is the baby little brother of programminglanguages. Learning the command line teaches you to control the computerusing language. Once you get past that, you can then move on to writing codeand feeling like you actually own the hunk of metal you just bought.

Page 302: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

55.1.1 How to Use This Appendix

The best way to use this appendix is to do the following:

• Get yourself a small paper notebook and a pen.

• Start at the beginning of the appendix and do each exercise exactly as you'retold.

• When you read something that doesn't make sense or that you don'tunderstand, write it down in your notebook. Leave a little space so you canwrite an answer.

• After you finish an exercise, go back through your notebook and review thequestions you have. Try to answer them by searching online and askingfriends who might know the answer. Email me [email protected] and I'll help you too.

Just keep going through this process of doing an exercise, writing downquestions you have, then going back through and answering the questionsyou can. By the time you're done, you'll actually know a lot more than youthink about using the command line.

55.1.2 You Will Be Memorizing Things

I'm warning you ahead of time that I'm going to make you memorize thingsright away. This is the quickest way to get you capable at something, but forsome people memorization is painful. Just fight through it and do it anyway.Memorization is an important skill in learning things, so you should get overyour fear of it.

Here's how you memorize things:

• Tell yourself you will do it. Don't try to find tricks or easy ways out of it,just sit down and do it.

• Write what you want to memorize on some index cards. Put one half ofwhat you need to learn on one side, then another half on the other side.

Page 303: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

• Every day for about 15-30 minutes, drill yourself on the index cards, tryingto recall each one. Put any cards you don't get right into a different pile, justdrill those cards until you get bored, then try the whole deck and see if youimprove.

• Before you go to bed, drill just the cards you got wrong for about 5 minutes,then go to sleep.

There are other techniques, like you can write what you need to learn on asheet of paper, laminate it, then stick it to the wall of your shower. Whileyou're bathing, drill the knowledge without looking, and when you get stuckglance at it to refresh your memory.

If you do this every day, you should be able to memorize most things I tellyou to memorize in about a week to a month. Once you do, nearly everythingelse becomes easier and intuitive, which is the purpose of memorization. It'snot to teach you abstract concepts but rather to ingrain the basics so that theyare intuitive and you don't have to think about them. Once you've memorizedthese basics they stop being speed bumps preventing you from learning moreadvanced abstract concepts.

The Setup

In this appendix you will be instructed to do three things:

• Do some things in your shell (command line, Terminal, PowerShell).

• Learn about what you just did.

• Do more on your own.

For this first exercise you'll be expected to get your terminal open andworking so that you can do the rest of the appendix.

55.2.1 Do This

Get your Terminal, shell, or PowerShell working so you can access it quickly

Page 304: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

and know that it works.

macOS

For macOS you'll need to do this:

• Hold down the command key and hit the spacebar.

• In the top right the blue "search bar" will pop up.

• Type: terminal

• Click on the Terminal application that looks kind of like a black box.

• This will open Terminal.

• You can now go to your dock and CTRL-click to pull up the menu, thenselect Options->Keep In dock.

Now you have your Terminal open, and it's in your dock so you can get to it.

Linux

I'm assuming that if you have Linux then you already know how to get atyour terminal. Look through the menu for your window manager for anythingnamed "Shell" or "Terminal."

Windows

On Windows we're going to use PowerShell. People used to work with aprogram called cmd.exe, but it's not nearly as usable as PowerShell. If youhave Windows 7 or later, do this:

• Click Start.

• In "Search programs and files" type: powershell

• Hit Enter.

Page 305: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

If you don't have Windows 7, you should seriously consider upgrading. Ifyou still insist on not upgrading, then you can try installing Powershell fromMicrosoft's download center. Search online to find "powershell downloads"for your version of Windows. You are on your own, though, since I don'thave Windows XP, but hopefully the PowerShell experience is the same.

55.2.2 You Learned This

You learned how to get your terminal open so you can do the rest of thisappendix.

Warning!

If you have that really smart friend who already knows Linux, ignore himwhen he tells you to use something other than Bash. I'm teaching you Bash.That's it. He will claim that zsh will give you 30 more IQ points and win youmillions in the stock market. Ignore him. Your goal is to get capable enough,and at this level it doesn't matter which shell you use. The next warning isstay off IRC or other places where "hackers" hang out. They think it's funnyto hand you commands that can destroy your computer. The command rm -rf / is a classic that you must never type. Just avoid them. If you need help,make sure you get it from someone you trust and not from random idiots onthe internet.

55.2.3 Do More

This exercise has a large "do more" part. The other exercises are not asinvolved as this one, but I'm having you prime your brain for the rest of theappendix by doing some memorization. Just trust me: this will make thingssilky smooth later on.

Linux/macOS

Take this list of commands and create index cards with the names on the left

Page 306: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

on one side, and the definitions on the other side. Drill them every day whilecontinuing with the lessons in this appendix.

pwd print working directory

hostname my computer's network name

mkdir make directory

cd change directory

ls list directory

rmdir remove directory

pushd push directory

popd pop directory

cp copy a file or directory

mv move a file or directory

less page through a file

cat print the whole file

xargs execute arguments

find find files

grep find things inside files

man read a manual page

apropos find which man page is appropriate

env look at your environment

echo print some arguments

Page 307: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

export export/set a new environment variable

exit exit the shell

sudo DANGER! become super user root DANGER!

Windows

If you're using Windows then here's your list of commands:

pwd print working directory

hostname my computer's network name

mkdir make directory

cd change directory

ls list directory

rmdir remove directory

pushd push directory

popd pop directory

cp copy a file or directory

robocopy robust copy

mv move a file or directory

more page through a file

type print the whole file

forfiles run a command on lots of files

dir -r find files

Page 308: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

select-string find things inside files

help read a manual page

helpctr find what man page is appropriate

echo print some arguments

set export/set a new environment variable

exit exit the shell

runas DANGER! become super user root DANGER!

Drill, drill, drill! Drill until you can say these phrases right away when yousee that word. Then drill the inverse, so that you read the phrase and knowwhat command will do that. You're building your vocabulary by doing this,but don't spend so much time you go nuts and get bored.

Paths, Folders, Directories (pwd)

In this exercise you learn how to print your working directory with the pwdcommand.

55.3.1 Do This

I'm going to teach you how to read these "sessions" that I show you. Youdon't have to type everything I list here, just some of the parts:

• You do not type in the $ (Unix) or > (Windows). That's just me showingyou my session so you can see what I got.

• You type in the stuff after $ or >, then hit Enter. So if I have $ pwd, youtype just pwd and hit Enter.

• You can then see what I have for output followed by another $ or > prompt.That content is the output, and you should see the same output.

Page 309: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Let's do a simple first command so you can get the hang of this:

Linux/macOS

Exercise 2 Session

$ pwd/Users/zedshaw$

Windows

Exercise 2 Windows Session

PS C:\Users\zed> pwd

Path----C:\Users\zed

PS C:\Users\zed>

Warning!

In this appendix I need to save space so that you can focus on the importantdetails of the commands. To do this, I'm going to strip out the first part of theprompt (the PS C:\Users\zed above) and leave just the little > part. Thismeans your prompt won't look exactly the same, but don't worry about that.Remember that from now on I'll only have the > to tell you that's the prompt.I'm doing the same thing for the Unix prompts, but Unix prompts are sovaried that most people get used to $ meaning "just the prompt."

55.3.2 You Learned This

Your prompt will look different from mine. You may have your user namebefore the $ and the name of your computer. On Windows it will probably

Page 310: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

look different too. The key is that you see the pattern of:

• There's a prompt.

• You type a command there. In this case, it's pwd.

• It printed something.

• Repeat.

You just learned what pwd does, which means "print working directory."What's a directory? It's a folder. Folder and directory are the same thing, andthey're used interchangeably. When you open your file browser on yourcomputer to graphically find files, you are walking through folders. Thosefolders are the exact same things as these "directories" we're going to workwith.

55.3.3 Do More

• Type pwd 20 times and each time say "print working directory."

• Write down the path that this command gives you. Find it with yourgraphical file browser of choice.

• No, seriously, type it 20 times and say it out loud. Sssh. Just do it.

If You Get Lost

As you go through these instructions you may get lost. You may not knowwhere you are or where a file is and have no idea how to continue. To solvethis problem I am going to teach you the commands to type to stop being lost.

Whenever you get lost, it is most likely because you were typing commandsand have no idea where you've ended up. What you should do is type pwd toprint your current directory. This tells you where you are.

The next thing is you need to have a way of getting back to where you are

Page 311: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

safe, your home. To do this type cd ~ and you are back in your home.

This means if you get lost at any time type:

pwd cd ~

The first command pwd tells you where you are. The second command cd ~takes you home so you can try again.

55.4.1 Do This

Right now figure out where you are, and then go home using pwd and cd ~.This will make sure you are always in the right place.

55.4.2 You Learned This

How to get back to your home if you ever get lost.

Make a Directory (mkdir)

In this exercise you learn how to make a new directory (folder) using themkdir command.

55.5.1 Do This

Remember! You need to go home first! Do your pwd then cd ~ before doingthis exercise. Before you do all exercises in this appendix, always go homefirst!

Linux/macOS

Exercise 4 Session

$ pwd$ cd ~

Page 312: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

$ mkdir temp$ mkdir temp/stuff$ mkdir temp/stuff/things$ mkdir -p temp/stuff/things/orange/apple/pear/grape$

Windows

Exercise 4 Windows Session

> pwd> cd ~> mkdir temp

Directory: C:\Users\zed

Mode LastWriteTime Length Name---- ------------- ------ ----d---- 12/17/2011 9:02 AM temp

> mkdir temp/stuff

Directory: C:\Users\zed\temp

Mode LastWriteTime Length Name---- ------------- ------ ----d---- 12/17/2011 9:02 AM stuff

> mkdir temp/stuff/things

Directory: C:\Users\zed\temp\stuff

Mode LastWriteTime Length Name---- ------------- ------ ----d---- 12/17/2011 9:03 AM things

> mkdir temp/stuff/things/orange/apple/pear/grape

Page 313: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Directory: C:\Users\zed\temp\stuff\things\orange\apple\pear

Mode LastWriteTime Length Name---- ------------- ------ ----d---- 12/17/2011 9:03 AM grape

>

This is the only time I'll list the pwd and cd ~ commands. They are expectedin the exercises every time. Do them all the time.

55.5.2 You Learned This

Now we get into typing more than one command. These are all the differentways you can run mkdir. What does mkdir do? It make directories. Why areyou asking that? You should be doing your index cards and getting yourcommands memorized. If you don't know that "mkdir makes directories" thenkeep working the index cards.

What does it mean to make a directory? You might call directories "folders."They're the same thing. All you did above is create directories insidedirectories inside of more directories. This is called a "path" and it's a way ofsaying "first temp, then stuff, then things and that's where I want it." It's a setof directions to the computer of where you want to put something in the treeof folders (directories) that make up your computer's hard disk.

Warning!

In this appendix I'm using the / (slash) character for all paths since they workthe same on all computers now. However, Windows users will need to knowthat you can also use the \ (backslash) character and other Windows userswill typically expect that at times.

Page 314: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

55.5.3 Do More

• The concept of a "path" might confuse you at this point. Don't worry. We'lldo a lot more with them, and then you'll get it.

• Make 20 other directories inside the temp directory in various levels. Golook at them with a graphical file browser.

• Make a directory with a space in the name by putting quotes around it:mkdir "I Have Fun"

• If the temp directory already exists then you'll get an error. Use cd to changeto a work directory that you can control and try it there. On WindowsDesktop is a good place.

Change Directory (cd)

In this exercise you learn how to change from one directory to another usingthe cd command.

55.6.1 Do This

I'm going to give you the instructions for these sessions one more time:

• You do not type in the $ (Unix) or > (Windows).

• You type in the stuff after this, then hit Enter. If I have $ cd temp, you justtype cd temp and hit Enter.

• The output comes after you hit Enter, followed by another $ or > prompt.

• Always go home first! Do pwd and then cd ~, so you go back to yourstarting point.

Linux/macOS

Exercise 5 Session

Page 315: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

$ cd temp$ pwd~/temp$ cd stuff$ pwd ~/temp/stuff$ cd things$ pwd~/temp/stuff/things$ cd orange/$ pwd~/temp/stuff/things/orange$ cd apple/$ pwd~/temp/stuff/things/orange/apple$ cd pear/$ pwd~/temp/stuff/things/orange/apple/pear$ cd grape/$ pwd~/temp/stuff/things/orange/apple/pear/grape$ cd ..$ cd ..$ pwd~/temp/stuff/things/orange/apple$ cd ..$ cd ..$ pwd~/temp/stuff/things$ cd ../../..$ pwd~/$ cd temp/stuff/things/orange/apple/pear/grape$ pwd~/temp/stuff/things/orange/apple/pear/grape$ cd ../../../../../../../$ pwd~/$

Windows

Exercise 5 Windows Session

Page 316: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

> cd temp> pwd

Path----C:\Users\zed\temp

> cd stuff> pwd

Path----C:\Users\zed\temp\stuff

> cd things> pwd

Path----C:\Users\zed\temp\stuff\things

> cd orange> pwd

Path----C:\Users\zed\temp\stuff\things\orange

> cd apple> pwd

Path----C:\Users\zed\temp\stuff\things\orange\apple

> cd pear> pwd

Path----C:\Users\zed\temp\stuff\things\orange\apple\pear

Page 317: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

> cd grape> pwd

Path----C:\Users\zed\temp\stuff\things\orange\apple\pear\grape

> cd ..> cd ..> cd ..> pwd

Path----C:\Users\zed\temp\stuff\things\orange

> cd ../..> pwd

Path----C:\Users\zed\temp\stuff

> cd ..> cd ..> cd temp/stuff/things/orange/apple/pear/grape> cd ../../../../../../../> pwd

Path----C:\Users\zed

>

55.6.2 You Learned This

You made all these directories in the last exercise, and now you're justmoving around inside them with the cd command. In my session above I alsouse pwd to check where I am, so remember not to type the output that pwdprints. For example, on line 3 you see ~/temp, but that's the output of pwd

Page 318: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

from the prompt above it. Do not type this in.

You should also see how I use the .. to move "up" in the tree and path.

55.6.3 Do More

A very important part of learning to use the command line interface (CLI) ona computer with a graphical user interface (GUI) is figuring out how theywork together. When I started using computers there was no "GUI", and youdid everything with the DOS prompt (the CLI). Later, when computersbecame powerful enough that everyone could have graphics, it was simplefor me to match CLI directories with GUI windows and folders.

Most people today, however, have no comprehension of the CLI, paths, anddirectories. In fact, it's very difficult to teach it to them, and the only way tolearn about the connection is for you to constantly work with the CLI untilone day it clicks that things you do in the GUI will show up in the CLI.

The way you do this is by spending some time finding directories with yourGUI file browser, then going to them with your CLI. This is what you'll donext.

• cd to the apple directory with one command.

• cd back to temp with one command, but not further above that.

• Find out how to cd to your "home directory" with one command.

• cd to your Documents directory, then find it with your GUI file browser(Finder, Windows Explorer, etc.).

• cd to your Downloads directory, then find it with your file browser.

• Find another directory with your file browser, then cd to it.

• Remember when you put quotes around a directory with spaces in it? Youcan do that with any command. For example, if you have a directory I HaveFun, then you can do: cd "I Have Fun"

Page 319: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

List Directory (ls)

In this exercise you learn how to list the contents of a directory with the lscommand.

55.7.1 Do This

Before you start, make sure you cd back to the directory above temp. If youhave no idea where you are, use pwd to figure it out and then move there.

Linux/macOS

Exercise 6 Session

$ cd temp$ lsstuff$ cd stuff$ lsthings$ cd things$ lsorange$ cd orange$ lsapple$ cd apple$ lspear$ cd pear$ ls$ cd grape$ ls$ cd ..$ lsgrape$ cd ../../../$ lsorange$ cd ../../$ lsstuff

Page 320: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

$

Windows

Exercise 6 Windows Session

> cd temp> ls

Directory: C:\Users\zed\temp

Mode LastWriteTime Length Name---- ------------- ------ ----d---- 12/17/2011 9:03 AM stuff

> cd stuff> ls

Directory: C:\Users\zed\temp\stuff

Mode LastWriteTime Length Name---- ------------- ------ ----d---- 12/17/2011 9:03 AM things

> cd things> ls

Directory: C:\Users\zed\temp\stuff\things

Mode LastWriteTime Length Name---- ------------- ------ ----d---- 12/17/2011 9:03 AM orange

> cd orange> ls

Page 321: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Directory: C:\Users\zed\temp\stuff\things\orange

Mode LastWriteTime Length Name---- ------------- ------ ----d---- 12/17/2011 9:03 AM apple

> cd apple> ls

Directory: C:\Users\zed\temp\stuff\things\orange\apple

Mode LastWriteTime Length Name---- ------------- ------ ----d---- 12/17/2011 9:03 AM pear

> cd pear> ls

Directory: C:\Users\zed\temp\stuff\things\orange\apple\pear

Mode LastWriteTime Length Name---- ------------- ------ ----d---- 12/17/2011 9:03 AM grape

> cd grape> ls> cd ..> ls

Directory: C:\Users\zed\temp\stuff\things\orange\apple\pear

Mode LastWriteTime Length Name---- ------------- ------ ----d---- 12/17/2011 9:03 AM grape

> cd ..

Page 322: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

> ls

Directory: C:\Users\zed\temp\stuff\things\orange\apple

Mode LastWriteTime Length Name---- ------------- ------ ----d---- 12/17/2011 9:03 AM pear

> cd ../../..> ls

Directory: C:\Users\zed\temp\stuff

Mode LastWriteTime Length Name---- ------------- ------ ----d---- 12/17/2011 9:03 AM things

> cd ..> ls

Directory: C:\Users\zed\temp

Mode LastWriteTime Length Name---- ------------- ------ ----d---- 12/17/2011 9:03 AM stuff

>

55.7.2 You Learned This

The ls command lists out the contents of the directory you are currently in.You can see me use cd to change into different directories and then list what'sin them so I know which directory to go to next.

There are a lot of options for the ls command, but you'll learn how to gethelp on those later when we cover the help command.

Page 323: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

55.7.3 Do More

• Type every one of these commands in! You have to actually type these tolearn them. Just reading them is not good enough. I'll stop yelling now.

• On Unix, try the ls -lR command while you're in temp.

• On Windows do the same thing with dir -R.

• Use cd to get to other directories on your computer, and then use ls to seewhat's in them.

• Update your notebook with new questions. I know you probably have some,because I'm not covering everything about this command.

• Remember that if you get lost, use ls and pwd to figure out where you are,and then go to where you need to be with cd.

Remove Directory (rmdir)

In this exercise you learn how to remove an empty directory.

55.8.1 Do This

Linux/macOS

Exercise 7 Session

$ cd temp$ lsstuff$ cd stuff/things/orange/apple/pear/grape/$ cd ..$ rmdir grape$ cd ..$ rmdir pear$ cd ..$ ls apple

Page 324: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

$ rmdir apple$ cd ..$ ls orange$ rmdir orange$ cd ..$ ls things$ rmdir things$ cd ..$ ls stuff$ rmdir stuff$ pwd~/temp$

Warning!

If you try to do rmdir on macOS and it refuses to remove the directory eventhough you are positive it's empty, then there is actually a file in there called.DS_Store. In that case, type rm -rf <dir> instead (replace <dir> with thedirectory name).

Windows

Exercise 7 Windows Session

> cd temp> ls

Directory: C:\Users\zed\temp

Mode LastWriteTime Length Name---- ------------- ------ ----d---- 12/17/2011 9:03 AM stuff

> cd stuff/things/orange/apple/pear/grape/> cd ..> rmdir grape> cd ..

Page 325: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

> rmdir pear> cd ..> rmdir apple> cd ..> rmdir orange> cd ..> ls

Directory: C:\Users\zed\temp\stuff

Mode LastWriteTime Length Name---- ------------- ------ ----d---- 12/17/2011 9:14 AM things

> rmdir things> cd ..> ls

Directory: C:\Users\zed\temp

Mode LastWriteTime Length Name---- ------------- ------ ----d---- 12/17/2011 9:14 AM stuff

> rmdir stuff> pwd

Path----C:\Users\zed\temp

> cd ..>

55.8.2 You Learned This

I'm now mixing up the commands, so make sure you type them exactly andpay attention. Every time you make a mistake, it's because you aren't paying

Page 326: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

attention. If you find yourself making many mistakes, then take a break orjust quit for the day. You've always got tomorrow to try again.

In this example you'll learn how to remove a directory. It's easy. You just goto the directory right above it, then type rmdir <dir>, replacing <dir> withthe name of the directory to remove.

55.8.3 Do More

• Make 20 more directories and remove them all.

• Make a single path of directories that is 10 deep and remove them one at atime just like I did previously.

• If you try to remove a directory with contents, you will get an error. I'llshow you how to remove those in later exercises.

Moving Around (pushd, popd)

In this exercise you learn how to save your current location and go to a newlocation with pushd. You then learn how to return to the saved location withpopd.

55.9.1 Do This

Linux/macOS

Exercise 8 Session

$ cd temp$ mkdir i/like/icecream$ pushd i/like/icecream~/temp/i/like/icecream ~/temp$ popd~/temp$ pwd~/temp$ pushd i/like

Page 327: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

~/temp/i/like ~/temp$ pwd~/temp/i/like$ pushd icecream~/temp/i/like/icecream ~/temp/i/like ~/temp$ pwd~/temp/i/like/icecream$ popd~/temp/i/like ~/temp$ pwd~/temp/i/like$ popd~/temp$ pushd i/like/icecream~/temp/i/like/icecream ~/temp$ pushd~/temp ~/temp/i/like/icecream$ pwd~/temp$ pushd~/temp/i/like/icecream ~/temp$ pwd~/temp/i/like/icecream$

Windows

Exercise 8 Windows Session

> cd temp> mkdir i/like/icecream

Directory: C:\Users\zed\temp\i\like

Mode LastWriteTime Length Name---- ------------- ------ ----d---- 12/20/2011 11:05 AM icecream

> pushd i/like/icecream> popd> pwd

Page 328: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Path----C:\Users\zed\temp

> pushd i/like> pwd

Path----C:\Users\zed\temp\i\like

> pushd icecream> pwd

Path----C:\Users\zed\temp\i\like\icecream

> popd> pwd

Path----C:\Users\zed\temp\i\like

> popd>

Warning!

In Windows you normally don't need the -p option like you do in Linux.However, I believe this is a more recent development, so you may run intoolder Windows PowerShell that do require the -p. If you have moreinformation on this please email me at [email protected], so Ican sort out whether to mention -p for Windows or not.

55.9.2 You Learned This

Page 329: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

You're getting into programmer territory with these commands, but they're sohandy I have to teach them to you. These commands let you temporarily goto a different directory and then come back, easily switching between thetwo.

The pushd command takes your current directory and "pushes" it into a listfor later, then it changes to another directory. It's like saying, "Save where Iam, then go here."

The popd command takes the last directory you pushed and "pops" it off,taking you back there.

Finally, on Unix pushd, if you run it by itself with no arguments, it willswitch between your current directory and the last one you pushed. It's aneasy way to switch between two directories. This does not work inPowerShell.

55.9.3 Do More

• Use these commands to move around directories all over your computer.

• Remove the i/like/icecream directories and make your own, then movearound in them.

• Explain to yourself the output that pushd and popd will print out for you.Notice how it works like a stack?

• You already know this, but remember that mkdir -p (on Linux/macOS) willmake an entire path even if all the directories don't exist. That's what I didvery first for this exercise.

• Remember that Windows will make a full path and does not need the -p.

Making Empty Files (Touch, New-Item)

In this exercise you learn how to make an empty file using the touch (new-item on Windows) command.

Page 330: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

55.10.1 Do This

Linux/macOS

Exercise 9 Session

$ cd temp$ touch iamcool.txt$ lsiamcool.txt$

Windows

Exercise 9 Windows Session

> cd temp> New-Item iamcool.txt -type file> ls

Directory: C:\Users\zed\temp

Mode LastWriteTime Length Name---- ------------- ------ -----a--- 12/17/2011 9:03 AM iamcool.txt

>

55.10.2 You Learned This

You learned how to make an empty file. On Unix touch does this, and it alsochanges the times on the file. I rarely use it for anything other than makingempty files. On Windows you don't have this command, so you learned howto use the New-Item command, which does the same thing but can also makenew directories.

Page 331: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

55.10.3 Do More

• Unix: Make a directory, change to it, and then make a file in it. Then changeone level up and run the rmdir command in this directory. You should get anerror. Try to understand why you got this error.

• Windows: Do the same thing, but you won't get an error. You'll get aprompt asking if you really want to remove the directory.

Copy a File (cp)

In this exercise you learn how to copy a file from one location to another withthe cp command.

55.11.1 Do This

Linux/macOS

Exercise 10 Session

$ cd temp$ cp iamcool.txt neat.txt$ lsiamcool.txt neat.txt$ cp neat.txt awesome.txt$ lsawesome.txt iamcool.txt neat.txt$ cp awesome.txt thefourthfile.txt$ lsawesome.txt iamcool.txt neat.txt thefourthfile.txt$ mkdir something$ cp awesome.txt something/$ lsawesome.txt iamcool.txt neat.txt something thefourthfile.txt$ ls something/awesome.txt$ cp -r something newplace$ ls newplace/awesome.txt$

Page 332: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Windows

Exercise 10 Windows Session

> cd temp> cp iamcool.txt neat.txt> ls

Directory: C:\Users\zed\temp

Mode LastWriteTime Length Name---- ------------- ------ -----a--- 12/22/2011 4:49 PM 0 iamcool.txt-a--- 12/22/2011 4:49 PM 0 neat.txt

> cp neat.txt awesome.txt> ls

Directory: C:\Users\zed\temp

Mode LastWriteTime Length Name---- ------------- ------ -----a--- 12/22/2011 4:49 PM 0 awesome.txt-a--- 12/22/2011 4:49 PM 0 iamcool.txt-a--- 12/22/2011 4:49 PM 0 neat.txt

> cp awesome.txt thefourthfile.txt> ls

Directory: C:\Users\zed\temp

Mode LastWriteTime Length Name---- ------------- ------ -----a--- 12/22/2011 4:49 PM 0 awesome.txt-a--- 12/22/2011 4:49 PM 0 iamcool.txt-a--- 12/22/2011 4:49 PM 0 neat.txt-a--- 12/22/2011 4:49 PM 0 thefourthfile.txt

Page 333: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

> mkdir something

Directory: C:\Users\zed\temp

Mode LastWriteTime Length Name---- ------------- ------ ----d---- 12/22/2011 4:52 PM something

> cp awesome.txt something/> ls

Directory: C:\Users\zed\temp

Mode LastWriteTime Length Name---- ------------- ------ ----d---- 12/22/2011 4:52 PM something-a--- 12/22/2011 4:49 PM 0 awesome.txt-a--- 12/22/2011 4:49 PM 0 iamcool.txt-a--- 12/22/2011 4:49 PM 0 neat.txt-a--- 12/22/2011 4:49 PM 0 thefourthfile.txt

> ls something

Directory: C:\Users\zed\temp\something

Mode LastWriteTime Length Name---- ------------- ------ -----a--- 12/22/2011 4:49 PM 0 awesome.txt

> cp -recurse something newplace> ls newplace

Directory: C:\Users\zed\temp\newplace

Mode LastWriteTime Length Name---- ------------- ------ ----

Page 334: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

-a--- 12/22/2011 4:49 PM 0 awesome.txt

>

55.11.2 You Learned This

Now you can copy files. It's simple to just take a file and copy it to a newone. In this exercise I also make a new directory and copy a file into thatdirectory.

I'm going to tell you a secret about programmers and system administratorsnow. They are lazy. I'm lazy. My friends are lazy. That's why we usecomputers. We like to make computers do boring things for us. In theexercises so far you have been typing repetitive boring commands so that youcan learn them, but usually it's not like this. Usually, if you find yourselfdoing something boring and repetitive there's probably a programmer whohas figured out how to make it easier. You just don't know about it.

The other thing about programmers is they aren't nearly as clever as youthink. If you overthink what to type, then you'll probably get it wrong.Instead, try to imagine what the name of a command is to you and try it.Chances are that it's a name or some abbreviation similar to what you thoughtit was. If you still can't figure it out intuitively, then ask around and searchonline. Hopefully, it's not something really stupid like ROBOCOPY.

55.11.3 Do More

• Use the cp -r command to copy more directories with files in them.

• Copy a file to your home directory or desktop.

• Find these files in your graphical user interface and open them in a texteditor.

• Notice how sometimes I put a / (slash) at the end of a directory? Thatmakes sure the file is really a directory, so if the directory doesn't exist I'll getan error.

Page 335: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Moving a File (mv)

In this exercise you learn how to move a file from one location to anotherusing the mv command.

55.12.1 Do This

Linux/macOS

Exercise 11 Session

$ cd temp$ mv awesome.txt uncool.txt$ lsnewplace uncool.txt$ mv newplace oldplace$ lsoldplace uncool.txt$ mv oldplace newplace$ lsnewplace uncool.txt$

Windows

Exercise 11 Windows Session

> cd temp> mv awesome.txt uncool.txt> ls

Directory: C:\Users\zed\temp

Mode LastWriteTime Length Name---- ------------- ------ ----d---- 12/22/2011 4:52 PM newplaced---- 12/22/2011 4:52 PM something-a--- 12/22/2011 4:49 PM 0 iamcool.txt

Page 336: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

-a--- 12/22/2011 4:49 PM 0 neat.txt-a--- 12/22/2011 4:49 PM 0 thefourthfile.txt-a--- 12/22/2011 4:49 PM 0 uncool.txt

> mv newplace oldplace> ls

Directory: C:\Users\zed\temp

Mode LastWriteTime Length Name---- ------------- ------ ----d---- 12/22/2011 4:52 PM oldplaced---- 12/22/2011 4:52 PM something-a--- 12/22/2011 4:49 PM 0 iamcool.txt-a--- 12/22/2011 4:49 PM 0 neat.txt-a--- 12/22/2011 4:49 PM 0 thefourthfile.txt-a--- 12/22/2011 4:49 PM 0 uncool.txt

> mv oldplace newplace> ls newplace

Directory: C:\Users\zed\temp\newplace

Mode LastWriteTime Length Name---- ------------- ------ -----a--- 12/22/2011 4:49 PM 0 awesome.txt

> ls

Directory: C:\Users\zed\temp

Mode LastWriteTime Length Name---- ------------- ------ ----d---- 12/22/2011 4:52 PM newplaced---- 12/22/2011 4:52 PM something-a--- 12/22/2011 4:49 PM 0 iamcool.txt-a--- 12/22/2011 4:49 PM 0 neat.txt-a--- 12/22/2011 4:49 PM 0 thefourthfile.txt-a--- 12/22/2011 4:49 PM 0 uncool.txt

Page 337: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

>

55.12.2 You Learned This

Moving files or, rather, renaming them. It's easy: give the old name and thenew name.

55.12.3 Do More

• Move a file in the newplace directory to another directory, then move itback.

View a File (less, MORE)

To do this exercise you're going to do some work using the commands youknow so far. You'll also need a text editor that can make plain text (.txt) files.Here's what you do:

• Open your text editor and type some stuff into a new file. On macOS thiscould be TextWrangler. On Windows this might be Notepad++. On Linuxthis could be gedit. Any editor will work.

• Save that file to your desktop and name it test.txt.

• In your shell use the commands you know to copy this file to your tempdirectory that you've been working with.

Once you've done that, complete this exercise.

55.13.1 Do This

Linux/macOS

Exercise 12 Session

Page 338: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

$ less test.txt[displays file here]$

That's it. To get out of less just type q (as in quit).

Windows

Exercise 12 Windows Session

> more test.txt[displays file here]>

Warning!

In the preceding output I'm showing [displays file here] to "abbreviate"what that program shows. I'll do this when I mean to say, "Showing you theoutput of this program is too complex, so just insert what you see on yourcomputer here and pretend I did show it to you." Your screen will notactually show this.

55.13.2 You Learned This

This is one way to look at the contents of a file. It's useful because if the filehas many lines, it will "page" so that only one screenful at a time is visible. Inthe Do More section you'll play with this some more.

55.13.3 Do More

• Open your text file again and repeatedly copy-paste the text so that it'sabout 50-100 lines long.

• Copy it to your temp directory again so you can look at it.

• Now do the exercise again, but this time page through it. On Unix you use

Page 339: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

the spacebar and w (the letter w) to go down and up. Arrow keys also work.On Windows just hit the spacebar to page through.

• Look at some of the empty files you created too.

• The cp command will overwrite files that already exist, so be carefulcopying files around.

Stream a File (cat)

You're going to do some more setup for this one so you get used to makingfiles in one program and then accessing them from the command line. Withthe same text editor from the last exercise, create another file namedtest2.txt but, this time save it directly to your temp directory.

55.14.1 Do This

Linux/macOS

Exercise 13 Session

$ less test2.txt[displays file here]$ cat test2.txtI am a fun guy.Don't you know why?Because I make poems,that make babies cry.$ cat test.txtHi there this is cool.$

Windows

Exercise 13 Windows Session

> more test2.txt[displays file here]

Page 340: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

> cat test2.txtI am a fun guy.Don't you know why?Because I make poems,that make babies cry.> cat test.txtHi there this is cool.>

Remember that when I say [displays file here] I'm abbreviating theoutput of that command so I don't have to show you exactly everything.

55.14.2 You Learned This

Do you like my poem? Totally going to win a Nobel. Anyway, you alreadyknow the first command, and I'm just having you check that your file is there.Then you cat the file to the screen. This command just spews the whole fileto the screen with no paging or stopping. To demonstrate that, I have you dothis to the test.txt which should just spew a bunch of lines from thatexercise.

55.14.3 Do More

• Make a few more text files and work with cat.

• Unix: Try cat test.txt test2.txt, and see what it does.

• Windows: Try cat test.txt,test2.txt, and see what it does.

Removing a File (rm)

In this exercise you learn how to remove (delete) a file using the rmcommand.

55.15.1 Do This

Linux

Page 341: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Exercise 14 Session

$ cd temp$ lsuncool.txt iamcool.txt neat.txt something thefourthfile.txt$ rm uncool.txt$ lsiamcool.txt neat.txt something thefourthfile.txt$ rm iamcool.txt neat.txt thefourthfile.txt$ lssomething$ cp -r something newplace$$ rm something/awesome.txt$ rmdir something$ rm -rf newplace$ ls$

Windows

Exercise 14 Windows Session

> cd temp> ls

Directory: C:\Users\zed\temp

Mode LastWriteTime Length Name---- ------------- ------ ----d---- 12/22/2011 4:52 PM newplaced---- 12/22/2011 4:52 PM something-a--- 12/22/2011 4:49 PM 0 iamcool.txt-a--- 12/22/2011 4:49 PM 0 neat.txt-a--- 12/22/2011 4:49 PM 0 thefourthfile.txt-a--- 12/22/2011 4:49 PM 0 uncool.txt

> rm uncool.txt> ls

Page 342: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Directory: C:\Users\zed\temp

Mode LastWriteTime Length Name---- ------------- ------ ----d---- 12/22/2011 4:52 PM newplaced---- 12/22/2011 4:52 PM something-a--- 12/22/2011 4:49 PM 0 iamcool.txt-a--- 12/22/2011 4:49 PM 0 neat.txt-a--- 12/22/2011 4:49 PM 0 thefourthfile.txt

> rm iamcool.txt> rm neat.txt> rm thefourthfile.txt> ls

Directory: C:\Users\zed\temp

Mode LastWriteTime Length Name---- ------------- ------ ----d---- 12/22/2011 4:52 PM newplaced---- 12/22/2011 4:52 PM something

> cp -r something newplace> rm something/awesome.txt> rmdir something> rm -r newplace> ls

>

55.15.2 You Learned This

Here we clean up the files from the last exercise. Remember when I had youtry to rmdir on a directory with something in it? Well, that failed because youcan't remove a directory with files in it. To do that you have to remove thefile or recursively delete all of its contents. That's what you did at the end ofthis.

Page 343: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

55.15.3 Do More

• Clean up everything in temp from all the exercises so far.

• Write in your notebook to be careful when running recursive remove onfiles.

Exiting Your Terminal (exit)

55.16.1 Do This

Linux/macOS

Exercise 23 Session

$ exit

Windows

Exercise 23 Windows Session

> exit

55.16.2 You Learned This

Your final exercise is how to exit a Terminal. Again this is very easy, but I'mgoing to have you do more.

55.16.3 Do More

For your last set of exercises I'm going to have you use the help system tolook up a set of commands you should research and learn how to use on yourown.

Here's the list for Unix:

Page 344: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

• xargs

• sudo

• chmod

• chown

For Windows look up these things:

• forfiles

• runas

• attrib

• icacls

Find out what these are, play with them, and then add them to your indexcards.

Command Line Next Steps

You have completed the crash course. At this point you should be a barelycapable shell user. There's a whole huge list of tricks and key sequences youdon't know yet, and I'm going to give you a few final places to go researchmore.

55.17.1 Unix Bash References

The shell you've been using is called Bash. It's not the greatest shell, but it'severywhere and has a lot of features, so it's a good start. Here's a short list oflinks about Bash you should go read:

Bash Cheat Sheethttps://learncodethehardway.org/unix/bash_cheat_sheet.pdf created byRaphael and CC licensed.

Page 345: Learn Python 3 the Hard Way: A Very Simple Introduction to ... A... · The fourth edition of Learn Python The Hard Way now uses Python 3.6. I’ve standardized on this version of

Reference Manual http://www.gnu.org/software/bash/manual/bashref.html

55.17.2 PowerShell References

On Windows there's really only PowerShell. Here's a list of useful links foryou related to PowerShell:

Owner's Manual http://technet.microsoft.com/en-us/library/ee221100.aspx

Cheat Sheet https://download.microsoft.com/download/2/1/2/2122F0B9-0EE6-4E6D-BFD6-F9DCD27C07F9/WS12_QuickRef_Download_Files/PowerShell_LangRef_v3.pdf

Master PowerShell http://powershell.com/cs/blogs/ebook/default.aspx