SlideShare a Scribd company logo
Exercise 1: A Good First Program



      Remember, you should have spent a good amount of time in Exercise 0 learning how to install a text editor, run the
1   print editor, run the Terminal, and work with both of them. If you haven’t done that then do not go on. You will not
      text    "Hello World!"
2   print a good time. This is the only time I’ll start an exercise with a warning that you should not skip or get ahead of
      have "Hello Again"
3   print
      yourself."I like typing this."
4   print
5   print
6   print      "This is fun."
7   print
                'Yay! Printing.'
              "I'd much rather you 'not'."
    Type the above into a single file named ex1.py. This is important as python works best with files ending in .py.
               'I "said" do not touch this.'


     Warning: Do not type the numbers on the far left of these lines. Those are called "line numbers" and they are

     used by programmers to talk about what part of a program is wrong. Python will tell you errors related to these line

     numbers,butyoudonottypethemin.



    Then in Terminal run the file by typing:
    python ex1.py


    If you did it right then you should see the same output I have below. If not, you have done something wrong. No, the
    computeris notwrong.




    What You Should See

    $ python ex1.py
    Hello     World!
    Hello Again
    I like   typing  this.
    This is fun.
    Yay! Printing.
    I'd much rather you          'not'.
    I "said" do not touch        this.
    $

    You may see the name of your directory before the $ which is fine, but if your output is not exactly the same, find out why
Learn Python The Hard Way, Release 1.0




 $ python ex/ex1.py

     File "ex/ex1.py", line 3

       print "I like typing this.

                                  ^
 SyntaxError: EOL while scanning string literal

 It’s important that you can read these since you will be making many of these mistakes. Even I make many of these
 mistakes.Let’slookatthisline-by-line.

     1. Here we ran our command in the terminal to run the ex1.py script.

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

     3. It then prints this line for us.

     4.Thenitputs a^(caret)charactertopointatwheretheproblemis.Noticethemissing"(double-quote)character?

     5. Finally, it prints out a "SyntaxError" and tells us something about what might be the error. Usually these are

        very cryptic,butifyoucopy that textinto asearch engine,you willfindsomeoneelse who’s hadthaterrorand

        youcanprobablyfigureouthowtofixit.




 Extra Credit

 You will also have Extra Credit. The Extra Credit contains things you should try to do. If you can’t, skip it and come
 backlater.

 Forthisexercise,trythesethings:

     1. Makeyourscriptprint another line.

     2. Makeyourscriptprint onlyone 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.

 Fromnowon,Iwon’texplainhoweachexerciseworks unlessanexerciseis different.
 Note: An ‘octothorpe’ is also called a ‘pound’, ‘hash’, ‘mesh’, or any number of names. Pick the one that makes you
 chillout.




12                                                                                  Exercise 1: A Good First Program
Exercise 2: Comments And Pound
    Characters



1   Comments are very important in your programs. They are used to tell you what something does in English, and they
2
3
    also comment,to disable you can your program if youlater. to remove them temporarily. Here’s how you use comments
     # A are used this is so parts of read your program need
4   inPython: after the # is ignored by python.
     # Anything
5
    print "I could have code like this." # and the comment after is ignored
6

7
8
9   # You can also use a comment to "disable" or comment out a piece of code:
    # print "This won't run."
    print "This will run."




    What You Should See

    $ python ex2.py
    I could have code        like   this.
    This will run.
    $




    Extra Credit


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

          orpoundcharacter).

       2. Take your ex2.py file and review each line going backwards. Start at the last line, and check each word in

          reverseagainstwhatyoushouldhavetyped.

       3. Did you find more mistakes? Fix them.

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

          Fixthem.
Learn python
Exercise 3: Numbers And Math



     Every programming language has some kind of way of doing numbers and math. Do not worry, programmers lie
     frequently about being math geniuses when they really aren’t. If they were math geniuses, they would be doing math, not
     writingadsandsocialnetworkgamestostealpeople’smoney.

     This exercise has lots of math symbols. Let’s name them right away so you know what they are called. As you type this
     onein,say the names.Whensayingthemfeelsboring youcanstopsayingthem.Hereare thenames:

             • +plus

             • -minus

             • /slash

             • *asterisk

             • %percent

             • <less-than

          • >greater-than
     print "I will now count my chickens:"
1
          • <=less-than-equal

2
              >=greater-than-equal
     print • "Hens", 25 + 30 / 6
     print "Roosters", 100 - 25 missing? After you type in the code for this exercise, go back and figure out what each of
     Notice how the operations are * 3 % 4
3
     thesedoesandcompletethetable.Forexample,+doesaddition.
     print "Now I will count the eggs:"
4
     print 3 + 2 + 1 - 5 + 4 % 2 - 1 / 4 + 6
5



6    print     "Is    it    true    that   3      +     2   <   5   -   7?"

7
     print 3 + 2 < 5 - 7
8



9    print "What is 3 + 2?", 3 + 2
10
     print "What is 5 - 7?", 5 - 7
11

12

13   print     "Oh,        that's   why    it's       False."
14

15                                                                                                                    15
16   print "How about some more."
17

18

19
     print "Is it greater?", 5 > -2
Learn Python The Hard Way, Release 1.0



22

23
     print "Is it greater or equal?", 5 >=              -2
     print "Is it less or equal?", 5 <= -2




     What You Should See

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




     Extra Credit


          1.Above eachline,usethe #to writeacommenttoyourself explaining whattheline does.

          2. Remember in Exercise 0 when you started python? Start python this way again and using the above characters

             andwhatyouknow,usepythonasacalculator.

          3. Find somethingyou need to calculate andwrite anew .py file that does it.

          4. Notice the math seems "wrong"? There are no fractions, only whole numbers. Find out why by researching

             what a "floating point"numberis.

          5. Rewrite ex3.py to use floating point numbers so it’s more accurate (hint: 20.0 is floating point).




     16                                                                                      Exercise 3: Numbers And Math
Exercise 4: Variables And Names



     Now you can print things with print and you can do math. The next step is to learn about variables. In programming
     a variable is nothing more than a name for something so you can use the name rather than the something as you
     code. Programmers use these variable names to make their code read more like English, and because they have lousy
     memories. If they didn’t use good names for things in their software, they’d get lost when they tried to read their code
     again.

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

        1. Writeacomment aboveeachline explainingto yourself whatitdoes inEnglish.
         cars = 100
1
         space_in_a_car = 4.0
        2. Read your30 file backwards.
         drivers = .py
2
         passengers = 90
        3. Read your .py file out loudsaying eventhe characters.
         cars_not_driven = cars - drivers
3
         cars_driven = drivers
         carpool_capacity = cars_driven * space_in_a_car
4        average_passengers_per_car = passengers / cars_driven

5
11   print
12
 6   print        "There are", cars, "cars available."
13   print
14
 7   print       "There are only", drivers, "drivers available."
15
     print      "There will be", cars_not_driven, "empty cars today."
16
 8   print      "We can transport", carpool_capacity, "people today."
                "We have", passengers, "to carpool today."
9               "We need to put about", average_passengers_per_car, "in each car."
     Note: The _ in space_in_a_car is called an underscore character. Find out how to type it if you do not
10
     alreadyknow.Weusethischaracteralottoputanimaginaryspacebetweenwordsinvariablenames.




     What You Should See

     $ python ex4.py
     There 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 in each car.
     $
Learn Python The Hard Way, Release 1.0




     Traceback (most recent call last):

 Extra "ex4.py",
   File
        Credit        line 8, in <module>                             /   passenger

       average_passengers_per_car = car_pool_capacity
  NameError: name 'car_pool_capacity' is not defined
 Explain this error in your own words. Make sure you use line numbers and explain why.
 WhenI wrotethis programthefirsttimeIhada mistake, and pythontold me aboutitlikethis:
 Here’s moreextracredit:

      1.Explainwhythe4.0isusedinsteadofjust4.

      2. Rememberthat 4.0is a"floating point"number. Findout whatthat means.

      3.Writecommentsaboveeachofthevariableassignments.

      4. Makesureyouknow what = is called(equals) andthatit’s making names forthings.

      5.Remember_isanunderscorecharacter.

      6. Try running python as a calculator like you did before and use variable names to do your calculations. Popular

         variablenames arealsoi,x,andj.




18                                                                               Exercise 4: Variables And Names
Exercise 5: More Variables And Printing



     Now we’ll do even more typing of variables and printing them out. This time we’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 how you
     makesomethingthatyour program might give to a human. Youprint them,savethemtofiles, send them to web servers,all
     sortsofthings.

     Strings are really handy, so in this exercise you will learn how to make strings that have variables embedded in them. You
1    embed variables insideShaw ' by using specialized format sequences and then putting the variables at the end with a
      my_name = 'Zed A. a string
2
     specialsyntax35 # not a lie
      my_age = thattells Python,"Hey,thisis aformatstring,putthesevariables inthere."
3     my_height = 74 # inches
4    As usual,justtypethisinevenifyoudonotunderstanditandmakeitexactly thesame.
      my_weight = 180 # lbs
5
      my_eyes = 'Blue'
6     my_teeth = 'White'
7
      my_hair = 'Brown'
8


      print     "Let's talk about %s." % my_name
9     print
      print      "He's %d inches tall." % my_height
10

11
      print     "He's %d pounds heavy." % my_weight
12    print
13    print      "Actually that's not too heavy."
14              "He's got %s eyes and %s hair." %            (my_eyes, my_hair)
16              "His teeth are usually %s depending         on the coffee." % my_teeth
15
       # this line is tricky, try to get it exactly           right
17

18
       print "If I add %d, %d, and %d I get %d."             % (

              my_age, my_height, my_weight, my_age + my_height + my_weight)




       What You Should See

       $ python ex5.py
       Let'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.
       $
                                                                                                                         19
Learn Python The Hard Way, Release 1.0




 Extra Credit


     1. Change all the variables so there isn’t the my_ in front. Make sure you change the name everywhere, not just

        whereyouused=tosetthem.

     2. Try more format characters.%r is avery useful one. It’s like saying "print this no matterwhat".

     3.SearchonlineforallofthePythonformatcharacters.

     4. Try to write some variables that convert the inches and pounds to centimeters and kilos. Do not just type in the

        measurements.WorkoutthemathinPython.




20                                                                        Exercise 5: More Variables And Printing
Exercise 6: Strings And Text



     While you have already been writing strings, you still do not know what they do. In this exercise we create a bunch of
     variables withcomplexstrings soyoucanseewhatthey arefor.Firstanexplanationofstrings.

     A stringis usually a bit oftext you want to display to someone, or "export" out ofthe program you are writing. Python knows
     you want something to be a string when you put either " (double-quotes) or ’ (single-quotes) around the text. You saw
     this many times with your use of print when you put the text you want to go to the string inside " or ’ after the print.
     Then Python prints it.

     Strings may contain the format characters you have discovered so far. You simply put the formatted variables in the
     string, and then a % (percent) character, followed by the variable. The only catch is that if you want multiple formats
     in yourstringtoprintmultiplevariables,you needto puttheminside( )(parenthesis)separatedby,(commas).It’s
     as if you were telling me to buy you a list of items from the store and you said, "I want milk, eggs, bread, and soup." Onlyas
     aprogrammerwesay,"(milk,eggs,bread,soup)".
     We will now type in a are %d types of people." % 10 formats, and print them. You will also practice using short
              x = "There whole bunch of strings, variables,
1             binary = "binary"
     abbreviated variable names. Programmers love saving themselves time at your expense by using annoying cryptic
              do_not = "don't"
     variablenames,solet’sgetyoustartedbeingabletoreadandwritethemearlyon.
2             y = "Those who know %s and those who %s." % (binary, do_not)

3

             print x
4            print y

5

             print "I said: %r." % x
6            print "I also said: '%s'." % y

7

             hilarious = False
8
             joke_evaluation    =   "Isn't   that   joke   so   funny?!   %r"
9
             print joke_evaluation % hilarious
10

11           w = "This is the left side of..."
12           e = "a string with a right side."
13
14

15           print w + e
16

17

18

19
20


             What You Should See
                                                                                                                            21


             $ python ex6.py
Learn Python The Hard Way, Release 1.0




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?! False
This is the left side of...a string with a right side.
$




Extra Credit


     1.Gothroughthis programand write acomment above eachline explainingit.

     2.Findalltheplaces whereastringis putinsideastring.Therearefourplaces.

     3. Are you sure there’s only four places? How do you know? Maybe I like lying.

     4. Explainwhy addingthetwostringw andewith+ makes alonger string.




22                                                                                    Exercise 6: Strings And Text
Exercise 7: More Printing



1    print
      Now we are going to do alittle lamb."
                 "Mary had a bunch of exercises where you just type code in and make it run. I won’t be explaining much
2    print
3
      since it is justfleece ofwas same. The purpose is 'snow ' up your chops. See you in a few exercises, and do not skip!
     print      "Its more the white as %s." % to build
4     Donotpaste! everywhere that Mary went."
     print      "And
5

                  "." * 10   # what'd that do?
     end1    =     "C"
6    end2    =
     end3    =    "h"
7    end4    =
     end5    =    "e"
8    end6    =
     end7    =    "e"
9    end8    =
     end9    =     "s"
10

11   end10    =
     end11    =    "e"
12
13   end12   =    "B"
14
19
15       # watch "u"
                   that comma at the end. try removing it to see what happens
20
16       print end1 + end2 + end3 + end4 + end5 + end6,
21
17                "r"
         print end7 + end8 + end9 + end10 + end11 + end12
18
                  "g"

                   "e"
                  "r"
         What You Should See

        $ python
        Mary had a little lamb.
               Burger
     Cheese fleece was white as snow.
        Its
     $ And everywhere that Mary went.




     Extra Credit

     Forthesenextfewexercises,youwillhavetheexactsameextracredit.

        1.Gobackthroughandwriteacommentonwhateachlinedoes.
Learn Python The Hard Way, Release 1.0




     2.Readeachonebackwardsoroutloudtofindyourerrors.

     3.Fromnowon,whenyoumakemistakes writedownonapieceofpaperwhatkindofmistakeyoumade.

     4.Whenyougotothenextexercise,look atthelastmistakes youmadeandtry nottomaketheminthis newone.

     5. Remember that everyone makes mistakes. Programmers are like magicians who like everyone to think they are

       perfectandneverwrong,butit’s allanact.They makemistakes allthetime.




24                                                                                   Exercise 7: More Printing
Exercise 8: Printing, Printing


1      formatter = "%r %r %r %r"

2

       print formatter % (1, 2, 3, 4)
3      print formatter % ("one", "two", "three", "four")
       print formatter % (True, False, False, True)
4      print formatter % (formatter, formatter, formatter,          formatter)
       print formatter % (
5

             "I had this thing.",
6

             "That       you    could   type   up   right.",
7

             "But it didn't sing.",
8

             "So     I   said    goodnight."
9      )
10

11

12




       What You Should See

       $ python ex8.py
       1234
       'one' 'two' 'three' 'four'
       True False False True
       '%r %r %r %r' '%r %r %r %r' '%r %r %r %r' '%r %r %r %r'
       'I had this thing.' 'That you could type up right.' "But it didn't sing." 'So I said goodnight.'
       $




       Extra Credit


           1. Doyourchecks of your work,write downyour mistakes,try notto makethemonthe nextexercise.

           2. Notice that the last line of output uses both single and double quotes for individual pieces. Why do you think

              thatis?
Learn Python The Hard Way, Release 1.0




26                                        Exercise 8: Printing, Printing
Exercise 9: Printing, Printing, Printing


1    # Here's some new strange stuff, remember type it exactly.

2
     days = "Mon Tue Wed Thu Fri Sat Sun"
3    months = "JannFebnMarnAprnMaynJunnJulnAug"

4
     print "Here are the days: ", days
5    print "Here are the months: ", months

6
     print """
7    There's something going on here.
     With the three double-quotes.
8    We'll be able to type as much as we like.
     """
9

10

11

12
13

     What You Should See

     $ python ex9.py
     Here's the days: Mon Tue Wed Thu Fri Sat Sun
     Here's the months: Jan
     Feb
     Mar
     Apr
     May
     Jun
     Jul
     Aug


     There's something going on here.
     With the three double-quotes.
     We'll be able to type as much as we like.
     $




     Extra Credit                                                                                     27



         1. Doyourchecks of your work,write downyour mistakes,try notto makethemonthe nextexercise.
Learn Python The Hard Way, Release 1.0




28                                        Exercise 9: Printing, Printing, Printing
Exercise 10: What Was That?



     In Exercise 9 I threw you some new stuff, just to keep you on your toes. I showed you two ways to make a string that goes
     across multiple lines. In the first way, I put the characters n (back-slash n) between the names of the months. What these
     twocharacters dois put anew line characterintothestring at that point.

     This use of the  (back-slash) character is a way we can put difficult-to-type characters into a string. There are plenty of
     these "escape sequences" available for different characters you might want to put in, but there’s a special one, the double
     back-slash which is just two of them . These two characters will print just one back-slash. We’ll try afewofthese
     sequencessoyoucanseewhatImean.

     Another 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 a double-quote in for the output. If you do this "I "understand" joe." then
     Python will get confused since it will think the " around "understand" actually ends the string. You need a way totell
     Pythonthatthe"insidethestring isn’tareal double-quote. inside string
       "I am 6'2" tall."           # escape double-quote
       'I am 6'2" tall.'           # escape single-quote inside string
     To solve this problem you escape double-quotes and single-quites so Python knows to include in the string. Here’s an
     example:
         Thesecondway is by usingtriple-quotes,whichisjust"""andworks likeastring,butdoes youalsocanputasmany
        lines of text you as want until you type """ again. We’ll also play with these.

         tabby_cat = "tI'm tabbed in."
1
         persian_cat = "I'm splitnon a line."
         backslash_cat = "I'm  a  cat."
2



3
          fat_cat = """
          I'll do a list:
4
          t* Cat food
          t* Fishies
5
          t* Catnipnt* Grass
          """
12
 6
      print    tabby_cat
13    print    persian_cat
14
 7
      print
15    print     backslash_cat
8
               fat_cat

     What You Should See
9

10

11




     Look forthetabcharacters thatyoumade.Inthis exercisethespacingis importanttogetright.
Learn Python The Hard Way, Release 1.0



$ python ex10.py
                                    in.
                 I'm       tabbed
I'm split
on a line.
I'm  a  cat.

I'll    do   a     list:

                 * Cat food

                 * Fishies

                 * Catnip

                 * Grass

$




Extra Credit


       1.Searchonlinetoseewhatotherescapesequencesareavailable.

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

       3.Combineescapesequencesandformatstringstocreateamorecomplexformat.

       4. Rememberthe %rformat? Combine %r with double-quote andsingle-quote escapes and print themout. Com-

          pare %r with %s. Notice how %r prints it the way you’d write it in your file, but %s prints it the way you’d like

          toseeit?




30                                                                                         Exercise 10: What Was That?
Exercise 11: Asking Questions



    Now it is time to pick up the pace. I have got you doing a lot of printing so that you get used to 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 tricky because
    you have learn to do two things that may not makesense right away, but trust me and do it anyway. It will makesensein
    afewexercises.

    Mostofwhatsoftwaredoesisthefollowing:

       1.Takesomekindofinputfromaperson.

       2. Change it.

1
       3.Printoutsomethingtoshowhowitchanged.
      print "How old are you?",
2
    So far you have only been printing, but you haven’t been able to get any input from a person, or change it. You may not
3     age = raw_input()
    even know what "input" means, so rather than talk about it, let’s have you do some and see if you get it. Next exercise
4     print "How tall are you?",
5
    we’lldomoretoexplainit.
      height = raw_input()
6     print "How much do you weigh?",
7
      weight = raw_input()
8

9

     print "So, you're %r old, %r tall and %r heavy." % (

           age, height, weight)

     Note: Notice that we put a , (comma) at the end of each print line. This is so that print doesn’t end the line witha
     newlineandgotothenextline.




     What You Should See

     $ python ex11.py
     How old are you? 35
     How tall are you? 6'2"
     How much do you weigh? 180lbs
     So, you're '35' old, '6'2"' tall       and    '180lbs'   heavy.
     $




     Extra Credit
Learn Python The Hard Way, Release 1.0




       2. Canyoufind other ways to useit? Try some ofthesamples youfind.

       3.Writeanother"form"likethistoask someotherquestions.

       4. Related to escape sequences, try to find out why the last line has ’6’2"’ with that ’ sequence. See how the

          single-quoteneedstobe escapedbecause otherwiseitwouldendthestring?




32                                                                                  Exercise 11: Asking Questions
Exercise 12: Prompting People



    When you typed raw_input() you were typing the ( and ) characters which are parenthesis. This is similar
    towhenyouusedthemtodoaformatwithextravariables,asin"%s %s" % (x, y). For raw_input you can
    also put in a prompt to show to a person so they know what to type. Put a string that you want for the prompt inside the ()
    sothatitlooks likethis:
    y = raw_input("Name? ")

1

2   This prompts the user with "Name?" and puts the result into the variable y. This is how you ask someone a question and
     age = raw_input("How old are you? ")
3   gettheiranswer.
     height = raw_input("How tall are you? ")
4

    This means we can completely rewrite ouryou weigh? ") using just raw_input to do all the prompting.
     weight = raw_input("How much do previous exercise
5

6

     print "So, you're %r old, %r tall and %r heavy." % (

          age, height, weight)




     What You Should See

     $ python ex12.py
     How old are you? 35
     How many tall are you? 6'2"
     How much do you weight? 180lbs
     So, you're '35' old, '6'2"' tall and         '180lbs'   heavy.
     $




     Extra Credit


        1. In Terminal where you normally run python to run your scripts, type: pydoc raw_input. Read what it

           says.

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

        3. Go look online for what the pydoc command does.
Learn Python The Hard Way, Release 1.0




34                                        Exercise 12: Prompting People
Exercise 13: Parameters, Unpacking,
         Variables



         In this exercise we will cover one more input method you can use to pass variables to a script (script being another
1        name for your .py files). You know how you type python ex13.py to run the ex13.py file? Well the ex13.py
           from sys import argv
2
         partofthecommandis calledan"argument".Whatwe’lldonowis writeascriptthatalsoaccepts arguments.
3          script, first, second, third = argv
4        Type this program andI’llexplain it in detail:
5     print
6     print      "The script is called:", script
7     print
8     print      "Your first variable is:", first
                "Your second variable is:", second

    On line 1 we"Your what’s variable is:", third
                 have third called an "import". This is how you add features to your script from the Python feature set. Rather
    than give you all the features at once, Python asks you to say what you plan to use. This keeps your programs small, but it
    alsoactsasdocumentationforotherprogrammerswhoreadyourcodelater.

    The argv is the "argument variable", a very standard name in programming. that you will find used in many other
    languages. This variable holds the arguments you pass to your Python script when you run it. In the exercises you will get to
    playwiththismoreandseewhathappens.

    Line 3 "unpacks" argv so that, rather than holding all the arguments, it gets assigned to four variables you can work
    with: script, first, second, and third. This may look strange, but "unpack" is probably the best word to
    describe what it does. It just says, "Take whatever is in argv, unpack it, and assign it to all of these variables on the left
    inorder."

    After that wejust print them out like normal.




    Hold Up! Features Have Another Name

    I call them "features here" (these little things you import to make your Python program do more) but nobody else
    calls them features. I just used that name because I needed to trick you into learning what they are without jargon.
    Before youcancontinue,youneed to learn their real name:modules.
    From now on we will be calling these "features" that we import modules. I’ll say things like, "You want to import the
    sys module."They are alsocalled "libraries"byother programmers, but let’s juststick withmodules.
Learn Python The Hard Way, Release 1.0




 What You Should See

 Runtheprogramlikethis:
 python ex13.py first 2nd 3rd


 This iswhatyoushouldseewhenyoudoafewdifferentruns withdifferentarguments:
 $ python ex13.py first 2nd 3rd
 The script is called: ex/ex13.py
 Your first variable is: first
 Your second variable is: 2nd
 Your third variable is: 3rd


 $ python ex13.py cheese apples bread
 The script is called: ex/ex13.py
 Your first variable is: cheese
 Your second variable is: apples
 Your third variable is: bread

You can actuallyreplace "first", "2nd", and "3rd"with anythree things.      You do not have to give theseparameters
 $ python ex13.py Zed A. Shaw
either,you can give any 3strings youwant:
 The script is called: ex/ex13.py
 Your first variable is: Zed
python second variable is: A.
 Your     ex13.py stuff I like
python third variable is: Shaw
 Your ex13.py anything 6 7


If you do not runit correctly, then you will get an error likethis:
python ex13.py first 2nd
Traceback (most recent call last):

     File "ex/ex13.py", line 3, in <module>

     script, first, second, third = argv
ValueError: need more than 3 values to unpack


This happens whenyou do not put enough arguments onthe command whenyou runit (inthis casejustfirst           2nd).
Notice when Irun itI give itfirst     2nd 3rd, which caused it to give an error about "need more than 3 values to
unpack"tellingyou thatyou didn’t give it enough parameters.




Extra Credit


     1. Try giving fewer than three arguments toyourscript.Seethaterroryou get? Seeifyoucan explainit.

     2. Write a script that has fewer arguments and one that has more. Make sure you give the unpacked variables good

        names.
36                                                               Exercise 13: Parameters, Unpacking, Variables
     3. Combine raw_input with argv to make a script that gets more input from a user.

     4.Rememberthatmodules giveyoufeatures.Modules.Modules.Rememberthis becausewe’llneeditlater.
Exercise 14: Prompting And Passing



1     from sys import argv
       Let’s do one exercise that uses argv and raw_input together to ask the user something specific. You will need this for
2

3
       the next exercise where we learn to read and write files. In this exercise we’ll use raw_input slightly differently by
4     script, it justprint asimpleargv
       having user_name = >prompt. This is similarto a game like Zork or Adventure.
5
       prompt = '>    '
     print
6    print     "Hi    %s, I'm   the   %s script." % (user_name,       script)
     print
7    likes     "I'd   like to ask you a few questions."
              "Do     you like me %s?" % user_name
 8
11

12   print "Where raw_input(prompt)
               = do you live %s?" % user_name
 9
13   lives = raw_input(prompt)
14
10
15

16   print "What kind of computer do you have?"
17   computer = raw_input(prompt)
18

19
20
     print """
21
     Alright, so you said %r about liking me.
     You live in %r. Not sure where that is.
     And you have a %r computer. Nice.
     """ % (likes, lives, computer)


     Notice though that we make a variable prompt that is set to the prompt we want, and we give that to raw_input
     instead of typing it over and over. Now if we want to make the prompt something else, we just change it in this one
     spotandrerunthescript.
     Veryhandy.




     What You Should See

     Whenyou runthis,rememberthatyouhave to givethescript yournameforthe argv arguments.

     $ python ex14.py Zed
     Hi Zed, I'm the ex14.py script.
     I'd like to ask you a few questions.
     Do you like me Zed?
     > yes
     Where do you live Zed?
     > America
     What kind of computer do you have?
Learn Python The Hard Way, Release 1.0




     > Tandy


     Alright, so you said 'yes' about liking me.
     You live in 'America'.    Not sure where that           is.
     And you have a 'Tandy' computer. Nice.




     Extra Credit


       1. Find out whatZork and Adventure were. Try to find acopyand play it.

       2. Change the prompt variable to something else entirely.

       3.Addanotherargumentanduseitinyourscript.

       4. Make sure you understand how I combined a """ style multi-line string with the % format activator as the last

          print.




38                                                                            Exercise 14: Prompting And Passing
Exercise 15: Reading Files



     Everything you’ve learned about raw_input and argv is so you can start reading files. You may have to play with this
     exercise the most to understand what’s going on, so do it carefully and remember your checks. Working with files is aneasy
     waytoeraseyourworkifyouarenotcareful.

     This exercise involves writing two files. One is your usual ex15.py file that you will run, but the other is named
     ex15_sample.txt. This second file isn’t a script but a plain text file we’ll be reading in our script. Here are the
     contentsofthatfile:
     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
          from sys import argv
     name ex15_sample.txt into our script. "Hard coding" means putting some bit of information that should come
1
     from script, filename = right in our program. That’s bad because we want it to load other files later. The solution is
           the user as a string argv
     touse argv andraw_input to ask the user whatfilethey wantinstead of"hard coding"thefile’s name.
2
          txt = open(filename)
3



4         print "Here's your      file   %r:"   %   filename
          print txt.read()
5


12
 6        print "I'll also ask you to type           it   again:"
13     txt_again = = raw_input("> ")
          file_again      open(file_again)
14
 7
15
      print txt_again.read()
8



9
      A few fancy things are going on inthis file,so let’s break it down realquick:
10

11    Line 1-3 should be a familiar use of argv to get a filename. Next we have line 5 where we use a new command open.
      Right now, run pydoc open and read the instructions. Notice how like your own scripts and raw_input, it takes a
      parameterandreturnsavalueyoucansettoyourownvariable.Youjustopenedafile.
      Line 7 we print a little line, but on line 8 we have something very new and exciting. We call a function on txt. What
      you got back from open is a file, and it’s also got commands you can give it. You give a file a command by using the .
      (dot or period), the name of the command, and parameters. Just like with open and raw_input. The difference is
      that when you say txt.read() you are saying, "Hey txt! Do your read command with no parameters!"
      Theremainderofthefileis moreofthesame,butwe’llleavetheanalysis toyouintheextracredit.
Learn Python The Hard Way, Release 1.0




     What You Should See

     Imadeafilecalled"ex15_sample.txt"andranmyscript.
     $ python ex15.py ex15_sample.txt
     Here'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.




     I'll also ask you to type it again: >
     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.




     $




     Extra Credit

     Thisis abigjumpsobesureyoudothisextracreditas bestyoucanbeforemovingon.

         1.AboveeachlinewriteoutinEnglishwhatthatlinedoes.

         2. If you are not sure ask someone for help or search online. Many times searching for "python THING" will find

            answers for whatthat THINGdoes in Python.Trysearchingfor "python open".

         3. I usedthe name "commands"here, but they arealsocalled "functions"and "methods".Search around online

            tosee what other peopledoto definethese. Donot worry ifthey confuseyou.It’s normalfor aprogrammerto

            confuseyouwiththeirvastextensiveknowledge.

         4. Get rid of the part from line 10-15 where you use raw_input and try the script then.

         5. Use only raw_input and try the script that way. Think of why one way of getting the filename would be better

            thananother.

         6. Run pydoc file and scroll down until you see the read() command (method/function). See all the other

            ones youcan use? Skiptheones that have__ (two underscores)in frontbecausethoseare junk. Try some of

40          theothercommands.                                                               Exercise 15: Reading Files
         7. Startup python again and use open from the prompt. Notice how you can open files and run read on them

            rightthere?
Exercise 16: Reading And Writing Files



     If you did the extra credit from the last exercise you should have seen all sorts of commands (methods/functions) you can
     givetofiles.Here’sthelistofcommandsIwantyoutoremember:

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

         •read-Reads thecontents ofthefile,youcanassigntheresulttoavariable.

         • readline -Readsjust oneline of a text file.

         •truncate-Emptiesthefile,watchoutifyoucareaboutthefile.

        from sys import argv to the file.
         • write(stuff) - Writes stuff
1
     For script, filename = argv commands you need to know. Some of them take parameters, but we do not really
         now these are the important
     careabout that. Youonly need torememberthat writetakes a parameter of astringyou want to writeto thefile.
2

     Let’susesomeofthistomakeasimplelittletexteditor:
3        print "We're going to erase %r." % filename print
         "If you don't want that, hit CTRL-C (^C)."
4        print "If you do want that, hit RETURN."

5
        raw_input("?")
6


14
 7
       print "Truncating the file.
        print "Opening the file..."            Goodbye!"
15     target.truncate()
        target = open(filename, 'w ')
16
 8

17      print "Now I'm going to ask you for three lines."
 9
18

19
10
20
11      line1 = raw_input("line 1: ")
21
12      line2 = raw_input("line 2: ")
22
13      line3 = raw_input("line 3: ")
23

24

25
        print "I'm going to write these to the file."
26
27

28

29
        target.write(line1)
30
        target.write("n")
        target.write(line2)
        target.write("n")
        target.write(line3)
        target.write("n")                                                                                              41
Learn Python The Hard Way, Release 1.0



32

33
          print "And finally,      we    close   it."
          target.close()
     31




          That’s a large file, probably the largest you have typed in. So go slow, do your checks, and make it run. One trick is to
          getbits ofitrunningatatime.Getlines1-8running,then5more,thenafewmore,etc.,untilit’salldoneandrunning.




          What You Should See

          There are actually twothings you willsee, firstthe output ofyour new script:

          $ python ex16.py test.txt
          We'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: To all the people out there.
          line 2: I say I don't like my hair.
          line 3: I need to shave it off.
          I'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 and check it out. Neat right?




          Extra Credit


               1. If you feel you do not understand this, go back through and use the comment trick to get it squared away in your

                  mind.OnesimpleEnglishcommentaboveeachlinewillhelpyouunderstand,oratleastletyouknowwhatyou

                  needtoresearchmore.

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

               3. There’s too much repetition in this file. Use strings, formats, and escapes to print out line1, line2, and

                  line3 with just one target.write() command instead of 6.

               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

                  explicitlysayyou wantto writea file.


          42                                                                             Exercise 16: Reading And Writing Files
Exercise 17: More Files



     from sys import argv things with files. We’re going to actually write a Python script to copy one file to another. It’ll
       Now let’s do a few more
1
     from os.path but willgiveyousomeideas about otherthings youcan do withfiles.
       bevery short import exists
2


     script, from_file, to_file = argv
3



4
     print "Copying from %s to %s" % (from_file, to_file)
5



6
     # we could do these two on one line too, how?
     input = open(from_file)
7
     indata = input.read()

8
     print "The input file is %d bytes long" % len(indata)
9

10
     print "Does the output file exist? %r" % exists(to_file)
11
     print "Ready, hit RETURN to continue, CTRL-C to abort."
12
13
     raw_input()
14
15

16   output = open(to_file,       'w ')
17   output.write(indata)
18

19
20   print "Alright, all done."
21

22

23   output.close()
24   input.close()


     You should immediately notice that we import another handy command named exists. This returns True if a
     file exists, based on it’s name in a string as an argument. It returns False if not. We’ll be using this function in the
     second halfofthis book to dolots of things, butright nowyou shouldsee howyoucanimport it.

     Using import is a way to get tons of free code other better (well, usually) programmers have written so you do not
     havetowriteit.




     What You Should See
Learn Python The Hard Way, Release 1.0




     Ready,    hit   RETURN        to   continue,   CTRL-C        to   abort.


     Alright, all done.

     $ cat copied.txt
     To all the people out there.
     I say I don't like my hair.
     I need to shave it off.
     $


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

      Warning: Did you see that trick I did with cat? It only works on Linux or OSX, sorry Windows people!




     Extra Credit


        1. Go read up on Python’s import statement, and start python to try it out. Try importing some things and see

           if you can get it right. It’s alright if you do not.

        2. This script is really annoying. There’s no need to ask you before doing the copy, and it prints too much out to

           thescreen.Trytomakeitmorefriendlytousebyremovingfeatures.

        3.Seehowshortyoucan makethescript.Icould makethis 1 linelong.

        4. Notice at the end of the WYSS I used something called cat? It’s an old command that "con*cat*enates" files

           together,but mostly it’s justan easy way toprint afiletothescreen. Type man cattoread aboutit.

        5. Windows people, find the alternative to cat that Linux/OSX people have. Do not worry about man since there

           is nothing like that.

        6. Find out why you had to do output.close() in the code.




44                                                                                             Exercise 17: More Files
Exercise 18: Names, Variables, Code,
        Functions



        Big 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 different ideas about how they work and what they do, but I will give you the simplest
        explanationyoucanuserightnow.

        Functionsdothreethings:

           1.They namepiecesofcodethewayvariablesnamestringsandnumbers.

           2. Theytakearguments the way yourscripts take argv.

     # this3. one is and #2 they let you make your own "mini scripts"or "tiny commands".
              Using #1 like your scripts with argv
1    def print_two(*args):
        You can create a function by using the word def in Python. I’m going to have you make four different functions that
2          arg1, arg2 = args
        worklikeyourscripts,andthenshowyouhoweachoneisrelated.
3         print "arg1: %r, arg2: %r" % (arg1, arg2)

4

     # ok, that *args is actually pointless,        we    can just   do this
5    def print_two_again(arg1, arg2):

6         print "arg1: %r, arg2: %r" % (arg1, arg2)

7

     # this just takes one         argument
8
     def print_one(arg1):

9         print "arg1: %r" % arg1
10

11

12   # this one takes     no   arguments
13   def print_none():
14

15        print "I got nothin'."
16

17

18

19
20

21
     print_two("Zed","Shaw ")
22
     print_two_again("Zed","Shaw ")
     print_one("First!")
     print_none()


     Let’s break down the first function, print_two which is the most similar to what you already know from making
     scripts:
Learn Python The Hard Way, Release 1.0




        3. Then we tell it we want *args (asterisk args) which is a lot like your argv parameter but for functions. This

           has to go inside () parenthesisto work.

        4. Then we endthis line with a: colon, andstart indenting.

        5. After the colon all the lines that are indented 4 spaces will become attached to this name, print_two. Our

           firstindentedlineisonethatunpacks thearguments thesameas withyourscripts.

        6. To demonstratehowit works weprintthese arguments out,justlike we wouldin ascript.

     Now, the problem with print_two is that it’s not the easiest way to make a function. In Python we can skip the
     whole unpacking args and just use the 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 one argument in print_one.

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



      Warning: This is very important. Do not get discouraged right now if this doesn’t quite make sense. We’re

      going to do a few exercises linking functions to your scripts and show you how to make more. For now just keep

 $ python ex18.py
     thinking"miniscript" whenIsay "function" andkeepplaying withthem.
 arg1: 'Zed', arg2:         'Shaw'
 arg1: 'Zed', arg2:         'Shaw'
 arg1: 'First!'
 I got     nothin'.
 $


     What You can see howSee
     Right away you Should a function works.          Notice that you used your functions the way you use things like
     exists, open, and other "commands". In fact, I’ve been tricking you because in Python those "commands" are just
     functions.Thismeansyoucanmakeyourowncommandsandusetheminyourscriptstoo.

     Ifyouruntheabovescriptyoushouldsee:



     Extra Credit

     Write out a function checklist for later exercises. Write these on an index card and keep it by you while you
     completetherestoftheseexercises oruntilyoufeelyoudonotneedit:

        1. Did you start your function definition with def?

        2.Doesyourfunctionnamehaveonlycharactersand_ (underscore)characters?

        3.Didyouputanopenparenthesis(rightafterthefunctionname?

        4.Didyouputyourarguments aftertheparenthesis (separatedby commas?

        5.Didyoumakeeachargumentunique(meaningnoduplicatednames).

        6.Didyouputacloseparenthesisandacolon):afterthearguments?

        7. Didyouindent alllines ofcodeyou wantinthe function4 spaces? No more, noless.
46                                                              Exercise 18: Names, Variables, Code, Functions
        8. Did you "end" your function by going back to writing with no indent (dedenting we call it)? And

     whenyourun(aka"use"or"call")afunction,checkthesethings:
Learn Python The Hard Way, Release 1.0




    1. Did youcall/use/run this function bytyping its name?

    2. Did you put(character afterthe name to runit?

    3.Didyouputthevaluesyouwantintotheparenthesisseparatedbycommas?

    4. Did you endthe function callwith a )character.

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

 Finally,repeatthisafewtimes:

 "To ‘run’, ‘call’, or ‘use’afunction all mean the same thing."




Extra Credit                                                                                                 47
Learn Python The Hard Way, Release 1.0




48                                        Exercise 18: Names, Variables, Code, Functions
Exercise 19: Functions And Variables



      Functions may have been a mind-blowing amount of information, but do not worry. Just keep doing these exercises and
1
      def
      goingthroughyourchecklistfromthelastexercise andyou willeventually getit.
2               cheese_and_crackers(cheese_count,      boxes_of_crackers):
3     There is one tiny pointhave %d cheeses!" not have realized which we’ll reinforce right now: The variables in your
               print "You though that you might % cheese_count
4     functionarenotconnectedtothevariablesinyourscript.Here’s anexercisetogetyouthinkingaboutthis:
               print "You have %d boxes of crackers!" % boxes_of_crackers
5              print "Man that's enough for a party!"
6              print "Get a blanket.n"
7




     print "We can just give the           function   numbers    directly:"
8
     cheese_and_crackers(20, 30)
9

10

11

12
     print "OR, we can use variables from our script:"
13

14
     amount_of_cheese = 10
15
     amount_of_crackers = 50
16

17

18   cheese_and_crackers(amount_of_cheese, amount_of_crackers)
19

20
21

22

23   print "We can even do math inside too:"
24
     cheese_and_crackers(10 + 20, 5 + 6)




     print "And we can combine the two, variables and math:"
     cheese_and_crackers(amount_of_cheese + 100, amount_of_crackers + 1000)

     This shows all different ways we’re able to give our function cheese_and_crackers the values it needs to print
     them. We can give it straight numbers. We can give it variables. We can give it math. We can even combine math and
     variables.
     In a way, the arguments to a function are kind of like our = character when we make a variable. In fact, if you can use = to
     namesomething,youcanusually passittoafunctionasanargument.




     What You Should See
Learn Python The Hard Way, Release 1.0




     $ python ex19.py
     We 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.
     $




     Extra Credit


       1.Goback throughthescriptandtypeacommentaboveeachlineexplaininginEnglishwhatitdoes.

       2.Startatthebottomandreadeachlinebackwards,sayingalltheimportantcharacters.

       3. Writeatleast one morefunctionofyour owndesign, andrunit10different ways.




50                                                                        Exercise 19: Functions And Variables
Exercise 20: Functions And Files


1      from sys import argv
2

3      script, input_file checklist for functions, then do this exercise paying close attention to how functions and files can
       Remember your = argv
4      worktogethertomakeusefulstuff.
     def
                  print_all(f):
5
              print f.read()
6



7    def
             rewind(f):
11
 8
           f.seek(0)
      def print_a_line(line_count, f):
12

13
 9
              print line_count, f.readline()
14

15
10
16
      current_file = open(input_file)
17

18

19
20
      print   "First    let's     print   the   whole   file:n"
21

22

23    print_all(current_file)
24

25

26    print   "Now      let's     rewind,   kind   of   like   a   tape."
27

28

29    rewind(current_file)
30

31

32
      print "Let's print three lines:"
33




      current_line = 1
      print_a_line(current_line, current_file)


      current_line = current_line + 1
      print_a_line(current_line, current_file)


      current_line = current_line + 1
      print_a_line(current_line, current_file)

                                                                                                                            51
      Pay close attention to how we pass in the current line number each time we run print_a_line.
Learn Python The Hard Way, Release 1.0




     To all the people out there.
     I say I don't like my hair.
     I need to shave it off.


     Now let's rewind, kind of like           a   tape.
     Let's print three lines:
     1 To all the people out there.


     2 I say I don't like my hair.

     3 I need to shave it off.


     $




     Extra Credit


         1.Gothroughand write Englishcomments for eachlineto understand what’s goingon.

         2. Each time print_a_line is run you are passing in a variable current_line.   Write out what

            current_line is equal to on each function call, and trace how it becomes line_count in

            print_a_line.

         4.Findeachplaceafunctionisused,andgocheckits deftomakesurethatyouaregivingittherightarguments.

         5. Research online what the seek function for file does. Try pydoc file and see if you can figure it out

            fromthere.

         6.Researchtheshorthandnotation+=andrewritethescripttousethat.




52                                                                               Exercise 20: Functions And Files
Exercise 21: Functions Can Return
     Something



     You have been using the = character to name variables and set them to numbers or strings. We’re now going to blow your
       def add(a, b):
     mind again by showing you how to use = and a new Python word return to set variables to be a value from a function.
1
     There willbeone thingtopay close %d" % (a, b) typethis in:
            print "ADDING %d + attentionto,butfirst
2

            return a + b
3



4      def subtract(a, b):

5           print "SUBTRACTING %d - %d" % (a, b)

6           return a - b

7

       def multiply(a, b):
8

            print "MULTIPLYING %d * %d" % (a, b)
9

10
            return a * b
11
12

13     def divide(a, b):
14

15          print "DIVIDING %d / %d" % (a, b)
16

17          return a / b
18

19
20

21

22

23
       print "Let's do some math with just functions!"
24

25
26     age = add(30, 5)
27     height  =    subtract(78,4)
28     weight = multiply(90, 2)
29     iq = divide(100, 2)
30

31

32     print "Age: %d, Height: %d, Weight: %d, IQ: %d" % (age, height, weight, iq)
33




       # A puzzle for the extra credit, type it in anyway.
Learn Python The Hard Way, Release 1.0



     3. Then we tell Python to dosomething kind of backward: we returnthe addition of a            +b. You might saythis

        as, "I add a andb thenreturnthem."
     4.Python adds the two numbers.Then whenthefunction ends any linethat runs it willbe able toassignthis a               +

        b resultto avariable.

As with many other things in this book, you should take this real slow, break it down and try to trace what’s going on. To
helpthere’sextracredittogetyoutosolveapuzzleandlearnsomethingcool.




What You Should See

$ python ex21.py
Let's do some math with just functions!
ADDING 30 + 5
SUBTRACTING 78 - 4
MULTIPLYING 90 * 2
DIVIDING 100 / 2
Age: 35, Height: 74, Weight: 180, IQ: 50
Here is a puzzle.
DIVIDING 50 / 2
MULTIPLYING 180 * 25
SUBTRACTING 74 - 4500
ADDING 35 + -4426
That becomes:    -4391 Can you do it by hand?
$




Extra Credit


     1. If you aren’t really sure what return does, try writing a few of your own functions and have them return some

        values.Youcanreturnanythingthatyoucanputtotherightofan=.

     2. Attheend ofthescriptis apuzzle.I’m takingthereturnvalue ofonefunction,and usingitas the argumentof

        another function. I’m doing this in a chain so that I’m kind of creating a formula using the functions. It looks

        really weird,butifyourunthescriptyoucanseetheresults.Whatyoushoulddois try tofigureoutthenormal

        formulathatwouldrecreatethissamesetofoperations.

     3. Once you have the formula worked out for the puzzle, get in there and see what happens when you modify the

        partsofthefunctions.Try tochangeitonpurposetomakeanothervalue.

     4. Finally,dotheinverse. Write out asimple formula and usethefunctions inthesame way to calculateit.

This exercise might really whack your brain out, but take it slow and easy and treat it like a little game. Figuring out
puzzles likethis is what makes programming fun,so I’llbe giving you more little problems like this as wego.


54                                                                    Exercise 21: Functions Can Return Something
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 WYSS or Extra Credit either. In fact, this
    exerciseislikeonegiantExtraCredit.I’mgoingtohaveyoudoaformofreviewwhatyouhavelearnedsofar.

  First, go back through every exercise you have done so far and write down every word and symbol (another name for
  ‘character’)thatyouhaveused.Makesureyourlistofsymbolsis complete.

  Next to each word or symbol, write its name and what it does. If you can’t find a name for a symbol in this book, then
  look for it online. If you do not know what a word or symbol does, then go read about it again and try using it in some
  code.

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

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

  Once you have memorized the list and what they do, then you should step it up by writing out tables of symbols, their
  names, and what they do from memory. When you 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."




 What You are Learning

It’s important when you are doing a boring mindless memorization exercise like this to know why. It helps you focus on a
goalandknowthepurposeofallyourefforts.

In this exercise you are learning the names of symbols so that you can read source code more easily. It’s similar to
learningthealphabetandbasicwords ofEnglish,exceptthisPythonalphabethas extrasymbolsyoumightnotknow.

Just take it slow and do not hurt your brain. Hopefully by now these symbols are natural for you so this isn’t a big
effort. It’s best to take 15 minutes at a time with your list and then take a break. Giving your brain a rest will help you learn
fasterwithlessfrustration.




                                                                                                                          55
Learn Python The Hard Way, Release 1.0




56                                        Exercise 22: What Do You Know So Far?
Exercise 23: Read Some Code

You should have spent last week getting your list of symbols straight and locked in your mind. Now you get to apply this to
another week reading code on the internet. This exercise will be daunting at first. I’m going to throw you in the deep end for
a few days and have you just try your best to read and understand some source code from real projects. The goal isn’t to get
youtounderstandcode,buttoteachyouthefollowingthreeskills:

      1.FindingPythonsourcecodeforthingsyouneed.
      2.Readingthroughthecodeandlookingforfiles.

      3.Tryingtounderstandcodeyoufind.
 At your level you really do not have the skills to evaluate the things you find, but you can benefit from getting exposure and
 seeinghowthingslook.

When you do this exercise, think of yourself as an anthropologist, trucking through a new land with just barely enough of the
local language to get around and survive. Except, of course, that you will actually get out alive because the internet
isn’t a jungle. Anyway.

Here’swhatyoudo:
      1. Go to bitbucket.org withyour favorite webbrowser and searchfor "python".

      2. Avoid any project with "Python 3" mentioned. That’ll only confuse you.
      3. Pick arandom projectandclick on it.

          4. Click on the Source tab and browse through the list of files and directories until you find a .py file (but not
       setup.py,that’suseless).

        5.Startatthetopandreadthroughit,takingnotes onwhatyouthinkitdoes.

       6.Ifany symbols orstrangewords seemtointerestyou,writethemdowntoresearchlater.

  That’s it. Your job is to use what you know so far and see if you can read the code and get a grasp of what it does. Try
  skimming the code first, and then read it in detail. Maybe also try taking very difficult parts and reading each symbol you
  knowoutloud.
  Nowtryseveralthreeothersites:

      • github.com

      • launchpad.net

      • koders.com

     On each of these sites you may find weird files ending in .c so stick to .py files like the ones you have written in this
     book.

   A final fun thing to do is use the above four sources of Python code and type in topics you are interested in instead of
   "python". Search for "journalism", "cooking", "physics", or anything you are curious about. Chances are there’s some
   codeoutthereyoucoulduserightaway.



                                                                                                                           57
Learn Python The Hard Way, Release 1.0




58                                        Exercise 23: Read Some Code
Exercise 24: More Practice



     You are getting to the end of this section. You should have enough Python "under your fingers" to move onto learning about
     howprint "Let's practice everything." should do some more practice. This exercise is longer and all about building
         programming really works, but you
        print 'You'd need to know 'bout escapes with  that
1
     upstamina. The next exercise willbesimilar. Dothem, getthem exactly right,anddoyourchecks.
                                                                                  do n newlines and t tabs.'
2
        poem = """
3       tThe lovely world
        with logic so firmly planted
4       cannot discern n the needs of love nor
        comprehend passion from intuition and
5       requires an explanation
        nttwhere there is none.
6       """

7
        print     "--------------"
8       print poem
        print "--------------"
9

10

11

12
13      five = 10 - 2 + 3 - 6
14      print "This should be five: %s" % five
15

16

17      def secret_formula(started):
18

19            jelly_beans = started * 500
20

21            jars    =   jelly_beans   /   1000
22

23            crates = jars / 100
24

25
              return jelly_beans, jars, crates
26

27

28

29

30

31      start_point = 10000
32      beans, jars, crates = secret_formula(start_point)
33
34

35      print "With a starting point of: %d" % start_point
36      print "We'd have %d beans, %d jars, and %d crates." %                                                          59
37



        start_point = start_point / 10
Learn Python The Hard Way, Release 1.0




 What You Should See

 $ python ex24.py           tabs.
  newlines and
 Let's practice everything.
--------------
 You'd need to know 'bout escapes with  that do

           The lovely world
 with logic so firmly planted
 cannot discern
                                           intuition
  the needs of love
 nor comprehend passion from
 and requires an explanation
                         where there is none.


     --------------
     This should be five: 5
     With a starting point of: 10000
     We'd have 5000000 beans, 5000 jars, and 50 crates.
     We can also do that this way:
     We'd have 500000 beans, 500 jars, and 5 crates.
     $




     Extra Credit


       1.Makesuretodoyourchecks:readitbackwards,readitoutloud,putcomments aboveconfusingparts.

       2.Break the fileonpurpose, then runittosee whatkinds of errors you get. Makesureyoucanfix it.




60                                                                                      Exercise 24: More Practice
Exercise 25: Even More Practice



     We’re going to do some more practice involving functions and variables to make sure you know them well. This
     exerciseshouldbestraightforwardforyoutotypein,breakdown,andunderstand.
     def break_words(stuff):is a little different. You won’t be running it. Instead you will import it into your python and run the
      However, this exercise
1
      functions yourself.
           """This function will break up words for us."""
2

          words       =    stuff.split('     ')
3

          return words
4



5    def sort_words(words):

6          """Sorts the words."""

7         return sorted(words)

8

     def print_first_word(words):
9

10
          """Prints       the   first      word    after    popping     it    off."""
11

12        word = words.pop(0)
13

14        print word
15

16

17   def print_last_word(words):
18

19        """Prints       the   last       word    after    popping     it    off."""
20

21
          word = words.pop(-1)
22

23
          print word
24

25
26

27
     def sort_sentence(sentence):
28

29
          """Takes        in    a   full    sentence        and    returns     the      sorted   words."""
30

31
          words = break_words(sentence)
32
33        return sort_words(words)
34

35

     def print_first_and_last(sentence):

          """Prints       the   first      and    last     words   of   the     sentence."""
Learn Python The Hard Way, Release 1.0




           What You Should See

           In this exercise we’re going to interact with your .py file inside the python interpreter you used periodically to do
           calculations.

          $ Here’s what it looks like whenI do it:
             python
1         Python 2.5.1 (r251:54863, Feb            6 2009, 19:02:12)
          [GCC 4.0.1 (Apple Inc. build 5465)] on darwin
2         Type "help", "copyright", "credits" or "license" for more information.
          >>> import ex25
3         >>> sentence = "All good things come to those who wait."
          >>> words = ex25.break_words(sentence)
4         >>> words
          ['All', 'good', 'things', 'come', 'to', 'those', 'who', 'wait.']
5
          >>> sorted_words = ex25.sort_words(words)
          >>> sorted_words
6
          ['All', 'come', 'good', 'things', 'those', 'to', 'wait.', 'who']
          >>> ex25.print_first_word(words)
7
          All
          >>>      ex25.print_last_word(words)
8
          wait.
          >>> wrods
9
          Traceback (most recent call last):
10

11            File "<stdin>", line 1, in <module>
12        NameError: name 'wrods' is not defined
13
          >>> words
14
          ['good', 'things', 'come', 'to', 'those', 'who']
15
          >>> ex25.print_first_word(sorted_words)
16
          All
17
          >>>       ex25.print_last_word(sorted_words)
18

19
          who
20
          >>> sorted_words
21
          ['come', 'good', 'things', 'those', 'to', 'wait.']
22
          >>> sorted_words = ex25.sort_sentence(sentence)
23
          >>> sorted_words
24        ['All', 'come', 'good', 'things', 'those', 'to', 'wait.',   'who']
25        >>> ex25.print_first_and_last(sentence)
26        All
27        wait.
28        >>>       ex25.print_first_and_last_sorted(sentence)
29        All
30        who
31        >>> ^D
32
          $
33

34
          Let’s break this downline by lineto makesure youknow what’s going on:
35

36
              • Line 5 you import your ex25.py python file, just like other imports you have done. Notice you do not need to
37

38
                put the .py at the end to import it. When you do this you make a module that has all your functions in it to
39


                use.

              • Line 6 you made a sentence to work with.

              • Line 7 you use the ex25 module and call your first function ex25.break_words. The . (dot, period)
     62                                                                                   Exercise 25: Even More Practice
                symbol is how you tell python, "Hey, inside ex25 there’s a function called break_words and I want to run

                it."
Learn Python The Hard Way, Release 1.0




     • Line 8 we just type words, and python will print out what’s in that variable (line 9). It looks weird but this is a list

     which you will learn about later.

     • Lines 10-11 we do the same thing with ex25.sort_words to get a sorted sentence.

     • Lines 13-16 we use ex25.print_first_word and ex25.print_last_word to get the first and last word

     printedout.

     • Line 17 is interesting. I made a mistake and typed the words variable as wrods so python gave me an error on

     Lines18-20.

     • Line 21-22 is where we print the modified words list. Notice that since we printed the first and last one, those

     wordsarenowmissing.

 Theremaininglines areforyoutofigureoutandanalyzeintheextracredit.




 Extra Credit


    1. Take the remaining lines of the WYSS output and figure out what they are doing. Make sure you understand

       how you are runningyour functions inthe ex25module.

    2. Try doing this: help(ex25) and also help(ex25.break_words). Notice how you get help for your

       module, and how the help is those odd """strings you put after each function in ex25? Those special strings

       are called documentation comments and we’llbeseeing more of them.

    3. Type ex25. is annoying. A shortcut is to do your import like this: from ex25        import * which is like

       saying,"Importeverythingfromex25."Programmerslikesayingthings backwards.Startanewsessionandsee howall

       yourfunctionsarerightthere.

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

       CTRL-D(CTRL-Z on windows)to be able toreload it.




Extra Credit                                                                                                                63
Learn Python The Hard Way, Release 1.0




64                                        Exercise 25: Even More Practice
Exercise 26: Congratulations, Take A Test!

     You are almost done with the first half of the book. The second half is where things get interesting. You will learn
     logicandbeabletodousefulthingslikemakedecisions.

   Before you continue, I have a quiz for you. This quiz will be very hard because it requires you to fix someone
   else’s code. When you are a programmer you often have to deal with another programmer’s code, and also with their
   arrogance.Theywillveryfrequentlyclaimthattheircodeisperfect.

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

   In this exercise, you will practice dealing with a bad programmer by fixing a bad programmer’s code. I have poorly
   copied exercises 24 and 25 into a file and removed random characters and added flaws. Most of the errors are things
   Python will tell you, while some of them are math errors you should find. Others are formatting errors or spelling
   mistakesinthestrings.
  Alloftheseerrors areverycommonmistakesallprogrammersmake.Evenexperiencedones.

     Your job in this exercise is to correct this file. Use all of your skills to make this file better. Analyze it first, maybe
     printing it out to edit it like you would a school term paper. Fix each flaw and keep running it and fixing it until the
     scriptruns perfectly.Try nottogethelp,andinsteadifyougetstuck takeabreak andcomeback toitlater.

     Evenifthistakesdaystodo,bustthroughitandmakeitright.
     Finally,the pointofthis exercise isn’ttotypeitin,buttofix anexistingfile.To dothat,youmustgoto:
    •http://learnpythonthehardway.com/wiki?name=Exercise26

   Copy-pastethe code intoa filenamed ex26.py. This is the only time youare allowed tocopy-paste.




                                                                                                                              65
Learn Python The Hard Way, Release 1.0




66                                        Exercise 26: Congratulations, Take A Test!
Exercise 27: Memorizing Logic

  Today is the day you start learning about logic. Up to this point you have done everything you possibly can reading and
  writingfiles,totheterminal,andhavelearnedquitealotofthemathcapabilitiesofPython.

From now on, you will be learning logic. You won’t learn complex theories that academics love to study, but just the simple
basiclogicthatmakesrealprograms workandthatrealprogrammersneedeveryday.

Learning logic has to come after you do some memorization. I want you to do this exercise for an entire week. Do not falter.
Even if you are bored out of your mind, keep doing it. This exercise has a set of logic tables you must memorize to make it
easierforyoutodothelaterexercises.

  I’m warning you this won’t be fun at first. It will be downright boring and tedious but this is to teach you a very
  important skill you will need as a programmer. You will need to be able to memorize important concepts as you go in
  your life. Most of these concepts will be exciting once you get them. You will struggle with them, like wrestling a squid,
  then oneday snapyou willunderstandit. Allthat work memorizingthe basics pays off biglater.

Here’s a tip on how to memorize something without going insane: Do a tiny bit at a time throughout the day and mark down
what you need to work on most. Do not try to sit down for two hours straight and memorize these tables. This won’t work.
Your brainwill really only retainwhateveryoustudiedinthefirst15 or 30minutes anyway.

Instead, what you should do is create a bunch of index cards with each column on the left on one side (True or False) and
the column on the right on the back. You should then pull them out, see the "True or False" and be able to
immediately say "True!"Keep practicing until youcan dothis.

Once you can do that, start writing out your own truth tables each night into a notebook. Do not just copy them. Try to do
them from memory, and when you get stuck glance quickly at the ones I have here to refresh your memory. Doing this will
trainyourbraintorememberthewholetable.
    Donotspendmorethanoneweekonthis,becauseyouwillbeapplyingitasyougo.



 The Truth Terms

 In python we have the following terms (characters and phrases) for determining if something is "True" or "False".
 Logic on a computer is all about seeing if some combination of these characters and some variables is True at that point
 intheprogram.

     • and

     • or
      • not

     • !=(not equal)

     • ==(equal)
     • >=(greater-than-equal)



                                                                                                                       67
Learn Python The Hard Way, Release 1.0




      • <=(less-than-equal)

      • True

      • False

You actually have run into these characters before, but maybe not the phrases. The phrases (and, or, not) actually work the
wayyouexpectthemto,justlikeinEnglish.


   NOT             True?

The Truth True
  notFals
  e       Tables
          False
   notTrue
   OR                   True?

  TrueorFalse    True
Wewillnowusethesecharacters tomakethetruthtablesyouneedtomemorize.
  TrueorTrue     True
  FalseorTrue    True
  FalseorFalse   False
   AND                     True?

   TrueandFalse            False
   TrueandTrue             True
   FalseandTrue            False
   FalseandFalse           False
   NOTOR                      True?

   not(TrueorFalse)           False
   not(TrueorTrue)            False
   not(FalseorTrue)           False
   not(FalseorFalse)          True
   NOTAND                          True?

   not(TrueandFalse)            True
   not(TrueandTrue)             False
   not(FalseandTrue)            True
   not(FalseandFalse)           True
   !=           True?

   1!=0         True
   1!=1         False
   0!=1         True
   0!=0         False
   ==           True?

   1==0         False
   1==1         True
   0==1         False
   0==0         True




 68                                                                                 Exercise 27: Memorizing Logic
Exercise 28: Boolean Practice



The logic combinations you learned from the last exercise are called "boolean" logic expressions. Boolean logic is
used everywhere in programming. They are essential fundamental parts of computation and knowing them very well is
akintoknowingyourscalesinmusic.

In this exercise you will be taking the logic exercises you memorized and start trying them out in python. Take each
of these logic problems, and write out what you 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 your terminal and type them 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 == 1

 11. "test" != "testing"
  17. not ("testing" == "testing" and                  "Zed"     == "Cool     Guy")
 12. "test" == 1
  18. 1 == 1 and not ("testing" == 1 or 1 == 0)
 13. not (True == "bacon" and not (3 == 4 or 3 == 3)
  19. "chunky" and False)

 14.20. 3 == == andand 0("testing" == "testing" or "Python" ==
     not (1 3 1     not    != 1)                                                         "Fun")

I 15. also give you a1trick to help == 1000) out the more complicated ones toward the end.
  will not (10 ==        or 1000 you figure
Whenever you see these boolean logic statements, you can solve them easily by this simple process:
16. not (1 != 10 or 3 == 4)
  1. Find equality test (== or !=) and replace it with its truth.




                                                                                                                          69
Learn Python The Hard Way, Release 1.0




     2.Findeachand/orinsideaparenthesisandsolvethosefirst.

     3.Findeachnotandinvertit.

     4.Findany remainingand/orandsolveit.

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

  demonstratewithavariationon#20:

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

  Here’s megoingthrougheachofthesteps andshowingyouthetranslationuntilI’veboileditdowntoasingleresult:
               "Python")
             (b) "testing" != "test" is True:                   True and not (True or "Python" ==
    1. Solve each equality test:
                  "Python")


             (c) "Python" == "Python": True and not (True or True)

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

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

    3. Find each not and invert it:

             (a) not (True) is False: True and False

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

             (a) True and False is False

 Withthatwe’redoneandknowtheresultisFalse.

  Warning: The more complicated ones may seem very hard at first. You should be able to give a good first stab at

  solving them, but do not get discouraged. I’m just getting you primed for more of these "logic gymnastics" so that

  later cool stuff is much easier. Just stick with it, and keep track of what you get wrong, but do not worry that it’s not

  gettinginyourheadquiteyet.It’llcome.




 What You Should See

 After you have tried to guess at these, this is what your session with python might look like:
 $ python
 Python 2.5.1 (r251:54863, Feb      6 2009, 19:02:12)
 [GCC 4.0.1 (Apple Inc. build 5465)] on darwin
 Type "help", "copyright", "credits" or "license" for            more   information.
 >>> True and True
 True
70
 >>> 1 == 1 and 2 == 2                                                                 Exercise 28: Boolean Practice
 True
Learn Python The Hard Way, Release 1.0




  Extra Credit


     1. There are a lot of operators in Python similar to != and ==. Try to find out as many "equality operators" as you

        can.Theyshouldbelike:<or<=.

     2.Write outthenames ofeachoftheseequality operators.For example,Icall!= "notequal".

     3. Play with the python by typing out new boolean operators, and before you hit enter try to shout out what it is.

        Donotthink about it,justthefirstthingthatcomes to mind. Writeitdownthen hitenter, andkeeptrack of how

        many yougetrightandwrong.

     4. Throw away that pieceofpaperfrom #3 away soyoudo notaccidentally try touseitlater.




Extra Credit                                                                                                         71
Learn Python The Hard Way, Release 1.0




72                                        Exercise 28: Boolean Practice
Exercise 29: What If



     people the20 script of Python you will enter, which introduces you to the if-statement. Type this in, make it run
      Here is = next
1
     cats = right,and then we’lltry seeifyour practice has paid off.
      exactly 30
     dogs = 15
2



3



4
     if people < cats:
5
          print   "Too many cats! The world is doomed!"

6


     if people > cats:
7

          print   "Not many cats! The world is saved!"
8



9
     if people < dogs:
10

11        print   "The world is drooled on!"
12

13
14
     if people > dogs:
15

16
          print   "The world is dry!"
17

18

19
20

21

22   dogs += 5
23

24

25   if people >= dogs:
26

27        print   "People are greater than equal to dogs."
28

29

     if people <= dogs:

          print   "People are less than equal to dogs."




     if people == dogs:                                                                                              73

          print   "People are dogs."
Learn Python The Hard Way, Release 1.0




     Extra Credit

     In this extra credit, try to guess what you think the if-statement is and what it does. Try to answer these questions in
     yourownwordsbeforemovingontothenextexercise:

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

        2.Whydoesthecodeundertheifneedtobeindented4spaces?

        3. What happens if it isn’t indented?

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

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




74                                                                                                   Exercise 29: What If
Exercise 30: Else And If



      In the last exercise you worked out some if-statements, and then tried to guess what they are and how they work.
      Before you learn more I’ll explain what everything is by answering the questions you had from extra credit. You did the
      extracreditright?

         1. What do you think the if does to the code under it? An if statement creates what is called a "branch" in the

            code.It’s kindof likethosechooseyour own adventure books whereyouareaskedtoturntoone pageifyou

            make one choice, and another if you go a different direction. The if-statement tells your script, "If this

            booleanexpressionis True,thenrunthecodeunderit,otherwiseskipit."

         2. Why does the code under the if need to be indented 4 spaces? A colon at the end of a line is how you tell

            Python youare going tocreate a new "block"of code, and then indenting 4 spaces tells Python what lines of

            code are in that block. This is exactly the same thing you did when you made functions in the first half of the

            book.

         3. What happens if it isn’t indented? If it isn’t indented, you will most likely create a Python error. Python expects

            youtoindentsomethingafteryouendalinewitha:(colon).
1    people = 30
2    cars4.= 40you put other boolean expressions from Ex. 26 in the if statement? Try it. Yes you can, and they can be
           Can
3    buses = 15
4
            as complex as youlike,althoughreallycomplex things generally arebadstyle.
5
          5. What happens if you change the initial variables for people, cats, and dogs? Because you are comparing
     if cars >
                      people:
6            numbers, if you change the numbers, different if-statements will evaluate to True and the blocks of code
            print    "We should take the cars."
     elif cars       < people:
7            under them will run. Go back and put different numbers in and see if you can figure out in your head what
                     "We should not take the cars."
            print
8            blocks of code will run.
     else:
13
 9      if buses > "We can't decide."
                      cars:
      Compare my answers to your answers, and make sure you really understand the concept of a "block" of code. This is
            print
14
10    importantforwhenyoudothenextexercisewhereyouwritealltheparts ofif-statements thatyoucanuse.
15            print "That's too many buses."
11
16
12
      Typethisoneinandmakeitworktoo.
        elif buses < cars:
17

               print "Maybe   we could take the buses."
       else:
                                                                                                                              75
Learn Python The Hard Way, Release 1.0



18

19

20
                  print "We still can't decide."
21

22
23        if people > buses:

                  print   "Alright,   let's   just   take   the   buses."
          else:

                  print "Fine, let's stay home then."




          What You Should See

          $ python ex.py
          We should take the cars.
          Maybe we could take the buses.
          Alright, let's just take the buses.
          $




          Extra Credit


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

             2. Change the numbers of cars, people, and buses and then trace through each if-statement to see what

                   will be printed.

             3. Trysome morecomplex boolean expressions likecars > people and buses < cars.

             4.AboveeachlinewriteanEnglishdescriptionofwhatthelinedoes.




     76                                                                                      Exercise 30: Else And If
Exercise 31: Making Decisions



     In the first half of this book you mostly just printed out things and called functions, but everything was basically in a
     straight line. Your scripts ran starting at the top, and went to the bottom where they ended. If you made a function you could
     run that function later, but it still didn’t have the kind of branching you need to really make decisions. Now that you have if,
1    else, andelifyoucan starttodark room with two doors.
          print "You enter a makescripts thatdecidethings.                  Do you go through door #1 or door #2?"
2

3    In the last = raw_input("> out a simple set of tests asking some questions. In this script you will ask the user questions and
          door script you wrote ")
4    makedecisionsbasedontheiranswers.Writethisscript,and thenplaywith itquite alottofigure itout.
           if door == "1":
                                                                                          What do you do?"
5
                  print "There's a giant bear here eating a cheese cake.
6
                 print "1. Take the cake."
7
                 print   "2.      Scream    at    the    bear."
12
 8               if bear == "1":
13
                 bear = raw_input("> ")
14
 9
                       print "The bear eats               your    face    off.     Good       job!"
15
10
                 elif bear == "2":
16
11
17                       print    "The     bear   eats    your    legs    off.     Good       job!"
18              else:
19     elif door           == "2":
20                       print "Well, doing %s is endless abyss at Bear runs away." % bear
                           "You stare into the      probably better. Cthuhlu's retina."
21          print          "1. Blueberries."
22                         "2. Yellow jacket clothespins."
23          print
            print     "3.        Understanding           revolvers       yelling       melodies."
24

25          print
              insanity = raw_input("> ")
26

27            if insanity == "1" or insanity == "2":
28                                                                                                             Good    job!"
29                    print      "Your   body     survives   powered       by      a   mind     of    jello.
30            else:
31                                                                                                             Good job!"
32       else:        print "The insanity rots your eyes into a pool of muck.
33                                                                                                        Good job!"
                 print "You stumble around and fall on a knife and die.
       A key point here is that you are now putting the if-statements inside if-statements as code that can run.
       Thisisverypowerfuland canbe usedtocreate"nested"decisions,where one branch leads toanother andanother.

       Makesureyou understandthis conceptofif-statements inside if-statements.Infact, dothe extracredittoreally nail




                                                                                                                               77
Learn Python The Hard Way, Release 1.0




 it.




 What You Should See
 $ python ex31.py
 You enter a dark room with two doors. Do you go through          door #1 or door #2?
 >1
 There's a giant bear here eating a cheese cake. What do
 Hereismeplayingthislittleadventuregame.Idonotdosowell.
 1. Take the cake.                                                you do?
 2. Scream at the bear.
 >2
 The bear eats your legs off. Good job!


 $ python ex31.py
 You enter a dark room with two doors. Do you go through
 >1
 There's a giant bear here eating a cheese cake. What do
 1. Take the cake.
 2. Scream at the bear.
 >1
 The bear eats your face off. Good job!                           door #1 or door #2?


 $ python ex31.py                                           you do?
 You enter a dark room with two doors. Do you go through
 >2
 You stare into the endless abyss at Cthuhlu's retina.
 1. Blueberries.
 2. Yellow jacket clothespins.
 3. Understanding revolvers yelling melodies.
 >1
 $ python ex31.py
 Your body survives powered by a mind of jello. Good job!
 You enter a dark room with two doors. Do you go through door    #1 or door #2?
 >2
 You stare into the endless abyss at Cthuhlu's retina.
 1. Blueberries.
 2. Yellow jacket clothespins.
 3. Understanding revolvers yelling melodies.               door #1 or door #2?
 >3
 The insanity rots your eyes into a pool of muck. Good job!


 $ python ex31.py
 You enter a dark room with two doors. Do you       go through door
 > stuff
 You stumble around and fall on a knife and die.     Good job!
 $ python ex31.py
 You enter a dark room with two doors. Do you       go through door   #1 or door #2?
 >1
 There's a giant bear here eating a cheese cake.     What do you do?
 1. Take the cake.
 2. Scream at the bear. >
                                                                        #1 or door #2?
 apples
 Well, doing apples is probably better. Bear runs   away.


78                                                                     Exercise 31: Making Decisions
Learn Python The Hard Way, Release 1.0




  Extra Credit

  Makenewparts ofthegameandchangewhatdecisions peoplecanmake.Expandthegameoutas muchas youcan before
  itgetsridiculous.




Extra Credit                                                                                          79
Learn Python The Hard Way, Release 1.0




80                                        Exercise 31: Making Decisions
Exercise 32: Loops And Lists



     You 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 combine all the other things you have learned with if-statements and boolean
     expressionstomakeyourprogramsdosmartthings.

     However, programs also need to do repetitive things very quickly. We are going to use a for-loop in this exercise to
     build and print various lists. When you do the exercise, you will start to figure out what they are. I won’t tell you right
     now.Youhavetofigureitout.

     Before you can use a for-loop, you need a way to store the results ofloops somewhere. The best way to do this is with a list.
     A list is exactly what its name says, a container of things that are organized in order. It’s not complicated; you just
     havetolearnanewsyntax.First,there’s howyoumakealist:
     hairs = ['brown', 'blond', 'red']
     eyes = ['brown', 'blue', 'green']
     weights = [1, 2, 3, 4]

     What you do is start the list with the [ (left-bracket) which "opens" the list. Then you put each item you want in the list
     separated by commas, just like when you did function arguments. Lastly you end the list with a ] (right-bracket) to
     indicatethatit’s over.Pythonthentakes thislistandallitscontents,andassigns themtothevariable.



      Warning: This is where things get tricky for people who can’t program. Your brain has been taught that the world is flat.

      Remember in the last exercise where you put if-statements inside if-statements? That probably made your
         the_count = [1, 2, 3, 4, 5]
      brain hurt because most people do not ponder how to "nest" things inside things. In programming this is all over the
1
         fruits = ['apples', 'oranges', 'pears', 'apricots']
         change = [1, 'pennies', 2, 'dimes', 3, 'quarters']
      place. You will find functions that call other functions that have if-statements that have lists withlists inside lists.
2

      If you see a structure like this that you can’t figure out, take out pencil and paper and break it down manually bit by bit
3
          # this first kind of for-loop goes through a list
          for number in the_count:
      untilyouunderstandit.
4
                print "This is count %d" % number
5

     Wenowwillbuildsomelistsusingsomeloopsandprintthemout:
6       # same as above
        for fruit in fruits:
7
                print "A fruit of type: %s" % fruit
8



9         # also we can go through mixed lists too
          # notice we have to use %r since we don't know what's in it                                                              81
10

11
          for i in change:
12
13
                print "I got %r" % i
Learn Python The Hard Way, Release 1.0




18

19

20
              # we can also      build   lists, first   start   with   an   empty   one
21 17
              elements = []
22

23

24            # then use the range function to do 0 to 20 counts
25            for i in range(0, 6):
26

27                 print "Adding %d to the list." % i
28

29                 # append is a function that lists understand

                   elements.append(i)


              # now we can print them out too
              for i in elements:

                   print "Element was: %d" % i




              What You Should See

              $ python ex32.py
              This is count 1
              This is count 2
              This is count 3
              This is count 4
              This is count 5
              A fruit of type: apples
              A fruit of type: oranges
              A fruit of type: pears
              A fruit of type: apricots
              I got 1
              I got 'pennies'
              I got 2
              I got 'dimes'
              I got 3
              I got 'quarters'
              Adding 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: 0
              Element was: 1
              Element was: 2
              Element was: 3
              Element was: 4
              Element was: 5
              $



        82                                                                                Exercise 32: Loops And Lists

              Extra Credit
Learn Python The Hard Way, Release 1.0




    3. Find the Python documentation on lists and read about them. What other operations can you do to lists besides

       append?




Extra Credit                                                                                                    83
Learn Python The Hard Way, Release 1.0




84                                        Exercise 32: Loops And Lists
Exercise 33: While Loops



     Now to totally blow your mind with a new loop, the while-loop. A while-loop will keep executing the code block
     underitaslongasabooleanexpressionisTrue.

     Wait, you have been keeping up with the terminology right? That if we write a line and end it with a : (colon) then that
     tells Python to start a new block of code? Then we indent and that’s the new code. This is all about structuring your
     programs so that Python knows what you mean. If you do not get that idea then go back and do some more work with
     if-statements,functions,andthefor-loopuntilyougetit.

     Later on we’ll have some exercises that will train your brain to read these structures, similar to how we burned boolean
     expressionsintoyourbrain.
     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. It keeps doing this until the expression is
     False.

     Here’s the problem with while-loops: Sometimes they do not stop. This is great if your intention is to just keep
     loopinguntiltheendoftheuniverse.Otherwiseyoualmostalways wantyourloops toendeventually.

     Toavoidtheseproblems,there’ssomerulestofollow:

        1. Make sure that you use while-loops sparingly. Usually a for-loop is better.

        2.Review yourwhilestatements andmakesurethatthethingyouaretestingwillbecomeFalse atsome point.
     i = 0
1
     numbers = []
        3. When in doubt, print out your test variable at the top and bottom of the while-loop to see what it’s doing. In
2
     this exercise,6: will learn the while-loop by doing the above three things:
      while i < you
3
           print "At the top i is %d" % i
4
           numbers.append(i)
5



6
           i = i + 1
7
           print "Numbers now: ", numbers
8
           print "At the bottom i is %d" % i
9

10

11

12
13   print "The numbers: "
14
                                                                                                                            85
15

16   for num in     numbers:

           print num
Learn Python The Hard Way, Release 1.0




 What You Should See

Numbers now: [0]
 $ python ex.py
At the bottom is i 0 is 1
 At the top i
At the top i is 1
Numbers now:     [0, 1]
At the bottom i is 2
At the top i is 2
Numbers now:     [0, 1, 2]
At the bottom i is 3
At the top i is 3
Numbers now:     [0, 1, 2, 3]
At the bottom i is 4
At the top i is 4
Numbers now:     [0, 1, 2, 3, 4]
At the bottom i is 5
At the top i is 5                           5]
Numbers now:     [0, 1, 2, 3, 4,
At the bottom i is 6
The numbers:
0
1
2
3
4
5




Extra Creditwhile loop to a function that you can call, and replace 10 in the test (i
 1. Convert this                                                                                 < 10) with a variable.

     2. Now usethisfunctionto rewrite thescript totry different numbers.

       3.Addanothervariable tothefunction arguments thatyoucanpass inthatlets you changethe +                 1online8so

          youcanchangehowmuchitincrementsby.

        4.Rewritethescriptagaintousethis functiontoseewhateffectthathas.

        5. Now, write it to use for-loops and range instead. Do you need the incrementor in the middle anymore?

           Whathappensifyoudonotgetridofit?

     If at any time that you are doing this it goes crazy (it probably will), just hold down CTRL and hit c (CTRL-c) and the
     programwillabort.




86                                                                                            Exercise 33: While Loops
Exercise 34: Accessing Elements Of Lists



   animals = ['bear',            'tiger',   'penguin',       'zebra']
  Lists are pretty useful, but unless you can get at the things in them they aren’t all that good. You can already go
   bear = animals[0]
  through the elements of a list in order, but what if you want say, the 5th element? You need to know how to access the
  elements ofalist.Here’s howyouwouldaccessthefirstelementofalist:
You take a list of animals, and then you get the first one using 0?! How does that work? Because of the way math
works, Python start its lists at 0 rather than 1. It seems weird, but there’s many advantages to this, even though it is mostly
arbitrary.

The best way to explain why is by showing you the difference between how you use numbers and how programmers use
numbers.

Imagine you are watching the four animals in our list above ([’bear’,     ’tiger’, ’penguin’, ’zeebra’])
run in a race. They win in the order we have them in this list. The race was really exciting because, the animals didn’t eat
each other and somehow managed to run a race. Your friend however shows up late and wants to know who won. Does
yourfriendsay,"Hey,whocameinzeroth?"No,hesays, "Heysays,hey whocameinfirst?"

This is because the order of the animals is important. You can’t have the second animal without the first animal, and can’t
have the third without the second. It’s also impossible to have a "zeroth" animal since zero means nothing. How can you
have a nothing win a race? It just doesn’t makesense. We call these kinds of numbers "ordinal"numbers, becausethey
indicateanorderingofthings.

Programmers, however, can’t think this way because they can pick any element out of a list at any point. To a
programmer, the above list is more like a deck of cards. If they want the tiger, they grab it. If they want the zeebra,
they can take it too. This need to pull elements out of lists at random means that they need a way to indicate elements
consistently by an address, or an "index", and the best way to do that is tostart the indices at 0.Trust me on this, the mathis
way easier for these kinds of accesses. This kind of number is a "cardinal" number and means you can pick at random, so
thereneedstobea0element.

So, how does this help you work with lists? Simple, every time you say to yourself, "I want the 3rd animal," you
translate this "ordinal" number to a "cardinal" number by subtracting 1. The "3rd" animal is at index 2 and is the
penguin. You have to do this because you have spent your whole life using ordinal numbers, and now you have to
thinkincardinal.Justsubtract1andyouwillbegood.

Remember:ordinal==ordered,1st;cardinal==cardsatrandom,0.

Let’s practice this. Take this list of animals, and follow the exercises where I tell you to write down what animal you get
for that ordinal or cardinal number. Remember if I say "first", "second", etc. then I’m using ordinal, so subtract 1. IfI give you
cardinal(0,1,2)thenuseitdirectly.
animals = ['bear', 'python', 'peacock', 'kangaroo', 'whale', 'platypus']



   1. The animal at 1.

   2. The 3rd animal.
Learn Python The Hard Way, Release 1.0




     3. The 1st animal.

     4. The animal at 3.

     5. The 5th animal.

     6. The animal at 2.

     7. The 6th animal.

     8. The animal at 4.

For each of these, write out a full sentence of the form: "The 1st animal is at 0 and is a bear." Then say it backwards, "The
animalat0isthe1stanimalandisabear."

Useyourpythontocheckyouranswers.




Extra Credit


     1.Readaboutordinalandcardinalnumbersonline.

     2. With what you know of the difference between these types of numbers, can you explain why this really is 2010?

        (Hint,youcan’tpickyearsatrandom.)

     3. Writesome morelists and work outsimilarindexes untilyou cantranslatethem.

     4.UsePythontocheckyouranswerstothisaswell.



 Warning: Programmers will tell you to read this guy named "Dijkstra" on this subject. I recommend you avoid his

 writings on this unless you enjoy being yelled at by someone who stopped programming at the same time

 programmingstarted.




88                                                                       Exercise 34: Accessing Elements Of Lists
Exercise 35: Branches and Functions



     from have learned to do if-statements, functions, and arrays. Now it’s time to bend your mind. Type this in, and see
     You sys import exit
1
     ifyoucanfigureoutwhatit’sdoing.

2    def gold_room():

3
          print "This room is full of gold.                 How much do you take?"

4



5
          next = raw_input("> ")

6
          if "0"    in      next     or "1"    in   next:

7
                  how_much = int(next)

8
          else:

9
                  dead("Man, learn to type a number.")
10

11

12

13
          if how_much < 50:
14
15
                  print     "Nice,    you're    not   greedy,   you   win!"
16

17                exit(0)
18

19        else:
20
21                dead("You greedy bastard!")
22

23

24

25

26
     def bear_room():
27

28
          print "There is a bear here."
29

30
          print "The bear has a bunch of honey."
31

32

33
          print "The fat bear is in front of another door."
34

35
          print "How are you going to move the bear?"
36

37        bear_moved = False                                                                                          89
38

39
40

41        while True:
Learn Python The Hard Way, Release 1.0




44

45

46
            print      "He, it,       whatever          stares   at   you     and   you      go insane."
47

48
            print "Do you flee for your life or eat your head?"
49

50

51

52          next = raw_input("> ")
53

54
55

56          if     "flee"   in      next:
57

58                   start()
59

60          elif "head" in next:
61
62
                     dead("Well           that    was     tasty!")
63

64
            else:
65

66
                     cthulu_room()
67

68
69

70

71

72    def dead(why):
73
74          print      why,      "Good        job!"
75

76          exit(0)


      def   start():

            print "You are in a dark room."

            print      "There        is   a      door    to   your    right   and   left."

            print "Which one do you take?"



            next = raw_input("> ")



            if     next     ==      "left":

                     bear_room()

            elif     next      ==     "right":

                     cthulu_room()

            else:

                     dead("You stumble around the room until you starve.")


     90                                                                                             Exercise 35: Branches and Functions


      start()
Learn Python The Hard Way, Release 1.0




 Extra Credit


    1.Drawamapofthegameandhowyouflowthroughit.

    2. Fix all ofyour mistakes, including spelling mistakes.

    3.Writecomments forthefunctions youdonotunderstand.Rememberdoc comments?

    4.Add moretothe game. Whatcan youdotobothsimplify andexpandit.

    5. The gold_room has a weird way of getting you to type a number. What are all the bugs in this way of doing

       it? Can you make it better than just checking if "1" or "0" are in the number? Look at how int() works for

       clues.




Extra Credit                                                                                                        91
Learn Python The Hard Way, Release 1.0




92                                        Exercise 35: Branches and Functions
Exercise 36: Designing and Debugging

  Now that you know if-statements, I’m going to give you some rules for for-loops and while-loops that
  will keep you out of trouble. I’m also going to give you some tips on debugging so that you can figure out problems
  withyour program. Finally,you aregoingtodesigna similar littlegame as in thelast exercise but withaslighttwist.



 Rules For If-Statements

     1. Every if-statement must have an else.

     2. If this else should never be run because it doesn’t make sense, then you must use a die function in the else
        thatprints outanerrormessageanddies,justlikewedidinthelastexercise.This willfindmany errors.

        3. Never nest if-statements more than 2 deep and always try to do them 1 deep. This means if you put an
       if in an if then you should be looking to move that second if into another function.
      4. Treat if-statements like paragraphs, where each if,elif,else grouping is like a set of sentences. Put
     blanklinesbeforeandafter.

     5. Your boolean tests should be simple. If they are complex, move their calculations to variables earlier in your
     functionanduseagoodnameforthevariable.

  Ifyoufollowthesesimplerules,youwillstartwritingbettercodethanmostprogrammers. Goback tothelastexercise andsee
  ifIfollowedalloftheserules.Ifnot,fixit.

   Warning: Never be a slave to the rules in real life. For training purposes you need to follow these rules to make
   your mind strong, but in real life sometimes these 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
    languagesaredifferent.

      2. Use a for-loop for all other kinds of looping, especially if there is a fixed or 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 a sick person. You do not get any specific
       usefulinformation,andyoufindawholelotofinformationthatdoesn’thelpandisjustconfusing.



                                                                                                                         93
Learn Python The Hard Way, Release 1.0




     2. The best way to debug a program is to use print to print out the values of variables at points in the program

        toseewheretheygowrong.

     3. Make sure parts of your programs work as you work on them. Do not write massive files of code before you try

        torunthem.Codealittle,runalittle,fixalittle.




Homework

Now write a similar game to the one that I created in the last exercise. It can be any kind of game you want in the
same flavor. Spend a week on it making it as interesting as possible. For extra credit, use lists, functions, and modules
(remember those from Ex. 13?) as much as possible, and find as many new pieces of Python as you can to make the
gamework.

There is one catch though, write up your idea for the game first. Before you start coding you must write up a map for your
game.Create the rooms,monsters,and traps thattheplayer mustgothroughon paperbeforeyoucode.

Onceyouhaveyourmap,try tocodeitup.Ifyoufindproblemswiththemapthenadjustitandmakethecodematch.

One final word of advice: Every programmer becomes paralyzed by irrational fear starting a new large project. They
then use procrastination to avoid confronting this fear and end up not getting their program working or even started. I
do this. Everyone does this. The best way to avoid this is to make a list of things you should do, and then do them one
atatime.

Juststartdoingit,doasmallversion,makeitbigger,keepalistofthings todo,anddothem.




94                                                                           Exercise 36: Designing and Debugging
Exercise 37: Symbol Review

It’s time to review the symbols and Python words you know, and to try to pick up a few more for the next few lessons. What
I’vedonehereis writtenoutallthePythonsymbolsandkeywords that areimportanttoknow.

   In this lesson take each keyword, and first try to write out what it does from memory. Next, search online for it and
   seewhatitreally does.It maybehardbecausesomeofthesearegoing to beimpossibletosearchfor,butkeep trying.
   If you get one of these wrong from memory, write up an index card with the correct definition and try to "correct" your
   memory.Ifyou justdidn’t know about it, write it down, andsave it for later.
Finally, use each of these in a small Python program, or as many as you can get done. The key here is to find out what the
symboldoes,makesureyougotitright,correctitifyou do not,thenuse ittolockitin.



 Keywords

     • and
     • del

     • from

     • not

     • while
     • as

     • elif

      • global
      • or

     • with

      • assert
      • else

      • if

     • pass
     • yield

      • break

      • except
      • import

      • print


                                                                                                                       95
Learn Python The Hard Way, Release 1.0




         • class

         • exec

         • in

         • raise

         • continue

         • finally

         • is

         • return

         • def

         • for

         • lambda

         • try




     Data Types

     For data types, write out what makes up each one. For example, with strings write out how you create a string. For
     numberswriteoutafewnumbers.

         • True

         • False

         • None

         • strings

         • numbers

         • floats

         • lists




     String Escapes Sequences

     Forstring escape sequences,usetheminstringsto makesure theydowhatyouthink they do.
96                                                                                         Exercise 37: Symbol Review
         • 

         • ’
Learn Python The Hard Way, Release 1.0




      • v




  String Formats

  Samethingforstringformats:usetheminsomestrings toknowwhatthey do.

      • %d

      • %i

      • %o

      • %u

      • %x

      • %X

      • %e

      • %E

      • %f

      • %F

      • %g

      • %G

      • %c

      • %r

      • %s

      • %%




  Operators

  Some of these may be unfamiliar to you, but look them up anyway. Find out what they do, and if you still can’t figure
  it out, save it for later.

      • +

       • -
String Formats                                                                                                     97
      • *

      • **
Learn Python The Hard Way, Release 1.0




         • ==

         • !=

         • <>

         • ()

         • []

         • {}

         • @

         • ,

         • :

         •

         • =

         • ;

         • +=

         • -=

         • *=

         • /=

         • //=

         • %=

         • **=
     Spend about a week on this, but if you finish faster that’s great. The point is to try to get coverage on all these symbols
     and make sure they are locked in your head. What’s also important is to find out what you do not know so you can fix
     it later.




98                                                                                         Exercise 37: Symbol Review
Exercise 38: Reading Code

    Now go find some Python code to read. You should be reading any Python code you can and trying to steal ideas that
    you find. You actually should have enough knowledge to be able to read, but maybe not understand what the code
    does. What I’m going to teach you in this lesson is how to apply things you have learned to understand other people’s
    code.

First, print out the code you want to understand. Yes, print it out, because your eyes and brain are more used to reading paper
thancomputerscreens.Make sureyouonlyprintafew pagesatatime.

Second,gothroughyourprintoutandtakenotes ofthefollowing:
      1.Functionsandwhattheydo.
      2.Whereeachvariableisfirstgivenavalue.

       3.Any variables withthesamenames indifferentparts oftheprogram.Thesemay betroublelater.

       4. Any if-statements without else clauses. Are they right?

       5. Any while-loops that might not end.
       6.Finally,any parts ofcodethatyoucan’tunderstandforwhateverreason.

      Third, once you have all of this marked up, try to explain it to yourself by writing comments as you go. Explain the
      functions,howtheyareused,whatvariablesareinvolved,anythingyoucantofigurethiscodeout.

       Lastly, on all of the difficult parts, trace the values of each variable line by line, function by function. In fact, do
       anotherprintoutandwriteinthemarginthevalueofeachvariablethatyouneedto"trace".

 Once you have a good idea of what the code does, go back to the computer and read it again to see if you find new things.
 Keep finding morecodeanddoing this untilyoudo not needthe printouts anymore.



   Extra Credit

      1. Find out whata "flow chart"is and write a few.

        2.Ifyoufinderrors incodeyouarereading,try tofix themandsendtheauthoryourchanges.

        3. Another technique for when you are not using paper is to put # comments with your notes in the code. Some-
        times,thesecouldbecometheactualcommentstohelpthenextperson.




                                                                                                                              99
Learn Python The Hard Way, Release 1.0




100                                       Exercise 38: Reading Code
Exercise 39: Doing Things To Lists

You have learned about lists. When you learned about while-loops you "appended" numbers to the end of a list and
printed them out. There was also extra credit where you were supposed to find all the other things you can do to lists in the
Python documentation. That was a while back, so go find in the book where you did that and review if you do not know
whatI’mtalkingabout.

 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 understand what’s going on so let’s see what we can do to lists, and how doing things with
 "on"themworks.

       When you type Python code that reads mystuff.append(’hello’) you are actually setting off a chain of events
       inside Python to cause something to happen to the mystuff list. Here’s how it works:

     1. Python sees you mentioned mystuff and looks up that variable. It might have to look backwards to see if you

        createdwith=,look andseeifitis afunctionargument,ormaybeit’s aglobalvariable.Eitherway ithas tofind

       2. Once it finds mystuff it then hits the . (period) operator and starts to look at variables that are a part of
        themystufffirst.
           mystuff. Since mystuff is a list, it knows that mystuff has a bunch of functions.

        3. It then hits append and compares the name "append" to all the ones that mystuff says it owns. If append is
        inthere(itis)thenitgrabsthattouse.

      4. Next Python sees the ( (parenthesis) and realizes, "Oh hey, this should be a function." At this point it calls (aka
        runs, executes)the functionjustlikenormally,butinsteaditcalls the function with an extra argument.

        5. That extra argument is ... mylist! I know, weird right? But that’s how Python works so it’s best to just

           rememberitandassumethat’salright.Whathappens then,attheendofallthisisafunctioncallthatlookslike:

  For the most part you do not have to know that this is going on, but it helps when you get error messages from python
            append(mystuff, ’hello’)insteadofwhatyoureadwhichis mystuff.append(’hello’).
  likethis:

 $ python
   Python 2.6.5 (r265:79063, Apr 16 2010, 13:57:41)
   [GCC 4.4.3] on linux2
        Type "help", "copyright", "credits" or "license" for              more   information.
        >>> class Thing(object):
            def test(hi):
                      print "hi"

 >>> a = Thing()
   >>> a.test("hello")
   Traceback (most recent call last):

     TypeError: test() line 1, in <module>argument
      File "<stdin>",     takes exactly 1                   (2   given)
     >>>




                                                                                                                          101
Learn Python The Hard Way, Release 1.0




     What was all that? Well, this is me typing into the Python shell and showing you some magic. You haven’t seen class
     yet but we’ll get into those later. For now you see how Python said test() takes exactly 1 argument (2
     given). If you see this it means that python changed a.test("hello") to test(a, "hello") and that
     somewheresomeonemessedupanddidn’taddtheargumentfora.
     That might be a lot to take in, but we’re going to spend a few exercises getting this concept firm in your brain. To kick things
                 ten_things = "Apples Oranges Crows Telephone Light Sugar"
     off,here’s anexercisethatmixes stringsandlistsforallkinds offun.
1
                print "Wait there's not 10 things in that list, let's fix that."
2



3               stuff = ten_things.split(' ')
                more_stuff = ["Day", "Night", "Song", "Frisbee", "Corn", "Banana", "Girl", "Boy"]
4



5               while len(stuff) != 10:

6
                      next_one = more_stuff.pop()

7
                      print   "Adding:     ",   next_one

8
                      stuff.append(next_one)

18
 9
       print          print "There's %d items now." %              len(stuff)
19     print         stuff[1]
10
20     print    print "There #wewhoa! ",fancy
                    stuff[-1]        go:    stuff
11
21     print        stuff.pop()
12
22
       print    print '.join(stuff) some things with stuff."
                    ' "Let's do # what? cool!
13
14
                    '#'.join(stuff[3:5])   #    super   stellar!
15

16

17
               What You Should See

               $ python ex39.py


               Wait there's not 10 things in that list, let's fix that.
               Adding: Boy
               There's 7 items now.
               Adding: Girl
               There's 8 items now.
               Adding: Banana
               There's 9 items now.
               Adding: Corn
               There's 10 items now.
               There we go:    ['Apples', 'Oranges', 'Crows', 'Telephone', 'Light', 'Sugar',

                      'Boy', 'Girl', 'Banana', 'Corn']
               Let's do some things with stuff.
               Oranges
               Corn
               Corn
               Apples Oranges Crows Telephone Light Sugar Boy Girl Banana
               Telephone#Light




      102                                                                               Exercise 39: Doing Things To Lists
Learn Python The Hard Way, Release 1.0




Extra Credit


   1. Take each function that is called, and go through the steps outlined above to translate them to what Python does.

      For example, ’ ’.join(things) is join(’   ’, things).

   2. Translate these two ways to view the function calls in English. For example, ’   ’.join(things) reads

      as, "Join things with ‘ ‘ between them." Meanwhile, join(’   ’, things) means, "Call join with ‘ ‘ and

      things." Understand how they are really the same thing.

   2. Go read about "Object Oriented Programming" online. Confused? Yeah I was too. Do not worry. You will learn

      enoughtobedangerous,andyoucanslowlylearnmorelater.

   3. Read up on what a "class" is in Python. Do not read about how other languages use the word "class". That

      will only mess youup.

   4. What’s the relationship between dir(something) and the "class" of something?

   5. If you do not have any idea what I’m talking about do not worry. Programmers like to feel smart so they

      inventedObjectOrientedProgramming,nameditOOP,andthenuseditway toomuch.Ifyouthink that’s hard,

      youshouldtrytouse"functionalprogramming".




Extra Credit                                                                                                     103
Learn Python The Hard Way, Release 1.0




104                                       Exercise 39: Doing Things To Lists
Exercise 40: Dictionaries, Oh Lovely
Dictionaries

  Now I have to hurt you with another container you can use, because once you learn this container a massive world of
  ultra-coolwillbeyours.Itis themostusefulcontainerever:thedictionary.

Python calls them "dicts", other languages call them, "hashes". I tend to use both names, but it doesn’t matter. What does
matteris whatthey dowhencomparedtolists.Yousee,alistletsyoudothis:

      >>> things = ['a', 'b', 'c', 'd']
      >>> print things[1]
      b
  >>> things[1] = 'z'
  >>>     print  things[1]
  z
  >>> print things
    ['a',  'z', 'c',   'd']
    >>>

You can use numbers to "index" into a list,meaning you can use numbers to find out what’s inlists. You shouldknow this by
now, but what a dict does is let you use anything, not just numbers. Yes, a dict associates one thing to another, no matter
whatitis.Takealook:

      >>> stuff = {'name': 'Zed', 'age': 36,          'height':   6*12+2}
      >>> print stuff['name']
      Zed
   >>>    print  stuff['age']
   36
    >>>    print  stuff['height']
    74
   >>> stuff['city'] = "San Francisco"
   >>> print stuff['city']
   San Francisco
   >>>

    You will see that instead of just numbers we’re using strings to say what we want from the stuff dictionary. We can
    alsoputnewthingsintothedictionary withstrings.Itdoesn’thavetobestringsthough,wecanalsodothis:

  >>> stuff[1] = "Wow "
  >>> stuff[2] = "Neato"
  >>> print stuff[1]
  Wow
  >>>      print  stuff[2]
  Neato
  >>> print stuff
    {'city': 'San Francisco', 2: 'Neato',

          'name': 'Zed', 1: 'Wow', 'age': 36,

                                                                                                                   105
Learn Python The Hard Way, Release 1.0



             'height': 74}
     >>>

        Inthis oneIjustusednumbers.Icoulduseanything.Wellalmostbutjustpretendyoucanuseanythingfornow.
        Of course, a dictionary that you can only put things in is pretty stupid, so here’s how you delete things, with the del
        keyword:

       >>> del stuff['city']
       >>> del stuff[1]
       >>> del stuff[2]
       >>> stuff
       {'name': 'Zed', 'age':                      36,          'height':      74}
       >>>

       We’ll now do an exercise that you must study very carefully. I want you to type this exercise in and try to understand
       what’s going on. Itis avery interesting exercisethat willhopefully makea biglightturnoninyour headvery soon.

1           cities     =     {'CA':       'San     Francisco',        'MI':    'Detroit',
2

3                                                       'FL':     'Jacksonville'}
4
5

6           cities['NY '] = 'New York'
     def    cities['OR'] = 'Portland'
                find_city(themap, state):
7
              if state in themap:
8
                      return           themap[state]
9
              else:
13
     # ok pay attention! "Not found."
                     return
10
14
11
15
12
     cities['_find'] = find_city
16
17

18   while True:
19

20         print     "State?          (ENTER       to    quit)",
21

22         state = raw_input("> ")
23
24



           if not state: break



           # this     line       is     the    most      important          ever!    study!

           city_found        =        cities['_find'](cities,      state)

           print city_found



       Warning: Notice how I use themap instead of map? That’s because Python has a function called map, so if you try

       tousethatyoucanhaveproblemslater.




     106                                                                                      Exercise 40: Dictionaries, Oh Lovely Dictionaries


     What You Should See
Learn Python The Hard Way, Release 1.0




 Portland
 State? (ENTER to quit) >           VT
 Not found.
 State? (ENTER to quit) >




 Extra Credit


    1.Gofindthe Pythondocumentationfor dictionaries (a.k.a.dicts,dict) andtry todoeven more things to them.

    2.Findoutwhatyoucan’tdowithdictionaries. Abigone is thatthey donothaveorder,sotryplayingwiththat.

    3. Try doing a for-loop over them, and then try the items() function in a for-loop.




Extra Credit                                                                                                   107
Learn Python The Hard Way, Release 1.0




108                                       Exercise 40: Dictionaries, Oh Lovely Dictionaries
Exercise 41: A Room With A View Of A
 Bear With A Broadsword

Did you figure out the secret of the function in the dict from the last exercise? Can you explain it to yourself? Let me explain
itandyoucancompareyourexplanationwithmine.Herearethelines ofcodewearetalkingabout:

      cities['_find'] = find_city
         city_found = cities['_find'](cities,     state)

   Remember that functions can be variables too. The def find_city just makes another variable name in your
   current module that you can use anywhere. In this code first we are putting the function find_city into the dict
   cities as ’_find’. This is the same as all the others where we set states to some cities, but in this case it’s actually the
   functionweputinthere.

      Alright, so once we know that find_city is in the dict at _find, that means we can do work with it. The 2nd line of
      code(usedlaterinthepreviousexercise)canbebrokendownlikethis:

      1. Python sees city_found = and knows we want to make a new variable.

      2. It then reads cities and finds that variable, it’s a dict.
           3. Then there’s [’_find’] which will index into the cities dict and pull out whatever is at _find.

             4. What is at [’_find’] is our function find_city so Python then knows it’s got a function, and when it hits
       ( it does the function call.

              5. The parameters cities, state are passed to this function find_city, and it runs because it’s called.

              6. find_city then tries to look up states inside cities, and returns what it finds or a message saying it
       didn’t find anything.

           7. Python takes what find_city returned, and finally that is what is assigned to city_found all the way at
       thebeginning.

I’m goingto teachyou a trick. Sometimes these things read better in Englishifyou read thecode backwards, solet’s try that.
Here’s howIwoulddoitforthatsameline(rememberbackwards):
    1. state and city are...

    2.passedasparametersto...

    3. a function at...

      4. ’_find’ inside...

      5. the dict cities...
      6. and finally assigned to city_found.

 Here’s anotherwaytoreadit,thistime"inside-out".

      1. Find the center item of the expression, in this case [’_find’].


                                                                                                                            109
Learn Python The Hard Way, Release 1.0




            2. Go counter-clock-wise and you have a dict cities, so this finds the element _find in cities.

            3.Thatgives us afunction.Keepgoingcounter-clock-wiseandyougettotheparameters.
            5. Finally, we are at the city_found =assignment,andwehaveourendresult.
            4.Theparametersarepassedtothefunction,andthatreturnsaresult.Gocounter-clock-wiseagain.
     After decades of programming I do not eventhink aboutthese three ways toread code.I just glance at it andknow whatit
     means, and I can even glanceat a whole screen of code, and all the bugs and errors jump out at me. That took an incredibly
     long time and quite a bit more study than is sane. To get that way, I learned these three ways of reading most any
     programminglanguage:

       1. Front to back.

       2. Back to front.

       3. Counter-clock-wise.

     Trythemoutwhenyouhaveadifficultstatementtofigureout.

     Let’s nowtypeinyournextexercise,andthengooverafterthat.This oneisgonnabefun.
1       from sys import exit
2       from random import randint
3
4

5       def death():
6

7             quips = ["You died.        You kinda suck at this.",
8

9                       "Your mom would be proud. If she were smarter.",
10             print quips[randint(0,    len(quips)-1)]
11             exit(1)  "Such a luser.",
12

13                         "I have a small puppy that's better at this."]

14          def princess_lives_here():
15

16                print "You see a beautiful Princess with a shiny crown."
17

18                print "She offers you some cake."
19

20

21

22                eat_it = raw_input("> ")
23
24

25

26
                  if eat_it == "eat it":
27

28
                        print "You explode like a pinata full of frogs."
29
30
                        print "The Princess cackles and eats the frogs. Yum!"
31

32

33
                        return 'death'
34

35
36
                  elif eat_it == "do not eat it":
37               else:
38
                        print "She throws the cake at you and it cuts off your head."
39                     print "The princess looks at you confused and just points at the cake."
                        print "The last thing you see is her munching on your torso. Yum!"
                       return 'princess_lives_here'
      110               return 'death'



                  elif eat_it == "make her eat it":
Learn Python The Hard Way, Release 1.0




41        def gold_koi_pond():
42                                              with a koi pond in the center."
43             print "There is a garden         see a massive fin poke out."
44   40

45             print "You walk close and         creepy looking huge Koi stares at you."
46

47             print "You peek in and a          waiting for food."
48

               print "It opens its mouth
49                 if feed_it == "feed it":
50

51                      print "The Koi jumps up, and rather than eating the cake, eats your arm."
52             feed_it = raw_input("> ")
53                      print "You fall in and the Koi shrugs than eats you."
54

55                      print   "You are then   pooped   out    sometime later."
56

57                      return 'death'
58
59

60
                  elif feed_it == "do not feed it":
61

62
                        print "The Koi grimaces, then thrashes around for a second."
63

64
                        print "It rushes to the other end of the pond, braces against the wall..."
65

66
                        print "then it *lunges* out of the water, up in the air and over your"
67

68

69
                        print "entire body, cake and all."
70

71                      print "You are then pooped out a week later."
72

73                      return 'death'
74

75

                   elif feed_it == "throw it in":
76        def bear_with_sword():
77
                         print "The Koi wiggles, then leaps into the air to eat the cake."
78            print "Puzzled, you are        about to pick up the fish poop diamond when"
79
                         print "You can see it's happy, it then grunts, thrashes..."
80            print "a bear bearing a           load bearing sword walks in."
                         print "and finally rolls over and poops you get diamond into the air"
                                               diamond! Where'd a magic that!?"'
81

82            print '"Hey!raw_input("> ")
                give_it =     That' my        out and looks at you."
83
                         print "at your feet."
84
              print "It holds "give paw
              if give_it == its it":
85                                                     your hand to grab the diamond and"
86                  print "The bear swipes at
87                       return 'bear_with_sword'       in the process. It then looks at"
88                  print "rips your hand off          and says, "Oh crap, sorry about that."'
89

                  else: 'your bloody stump
                   print                               hand back on, but you collapse."
90

91
                                                      see is the bear shrug and eat you."
92                 elif give_it"The to putno": annoyed and wiggles a bit."
                    printprint tries "say gets
                           "It    == Koi    your
93
94                  printreturn "The bear looks shocked.
                           "The last thing you
                          print 'gold_koi_pond'                Nobody ever told a bear"
95

96                  return 'death' a broadsword 'no'.
                         print "with                       It asks, "
97

                        print '"Is it because it's   not a katana?     I   could go get one!"'

                        print "It then runs off and now you notice a big iron gate."
                                                                                                                       111
                        print '"Where the hell did that come from?" You say.'
Learn Python The Hard Way, Release 1.0




 99
                            return    'big_iron_gate'
100 98
                    else:
101

102
103
                            print "The bear look puzzled as to why you'd do that."
104

105
                            return "bear_with_sword"
106

107

108            def big_iron_gate():
109

110                 print "You walk up to the big iron gate and see there's a handle."
111

112                 open_it = raw_input("> ")
113

114                 if open_it == 'open it':
115

116
117               else: print "You open it and you are free!"
118                                                              I mean, the door's        right     there."
119                     print "That doesn't mountains. And berries! And..."
                         print "There are seem sensible.
120

121                     return "Oh, but then the bear comes with his katana and
                          print 'big_iron_gate'                                           stabs you."
122

123
         ROOMS = { print '"Who's laughing now!?           Love this katana."'
124
                'death': death,
125

126

127
                'princess_lives_here':
                         return 'death' princess_lives_here,
128

129
                'gold_koi_pond': gold_koi_pond,
130

131             'big_iron_gate': big_iron_gate,
132

133             'bear_with_sword': bear_with_sword
134      }
135

136
137

138

139
         def    runner(map,      start):

                next = start



                while True:

                     room = map[next]

                     print    "n--------"

                     next = room()


         runner(ROOMS, 'princess_lives_here')


         It’s alotofcode,butgothroughit,makesureitworks,playit.

         112                                            Exercise 41: A Room With A View Of A Bear With A Broadsword



         What You Should See
Learn Python The Hard Way, Release 1.0




 She points to a tiny door and says, 'The Koi needs cake too.'
 She gives you the very last bit of cake and shoves you in.

 --------
 There is a garden with a koi pond in the center.
 You walk close and see a massive fin poke out.
 You peek in and a creepy looking huge Koi stares at you. It
 opens its mouth waiting for food.
 > throw it in
 The Koi wiggles, then leaps into the air to eat the cake.
 You can see it's happy, it then grunts, thrashes...
 and finally rolls over and poops a magic diamond into the air at
 your feet.


 --------
 Puzzled, you are about to pick up the fish poop diamond when
 a bear bearing a load bearing sword walks in.
 "Hey! That' my diamond! Where'd you get that!?"
 It holds its paw out and looks at you.
 > say no
 The bear looks shocked.      Nobody ever told a bear
 with a broadsword 'no'. It asks,
 "Is it because it's not a katana? I could go get one!" It
 then runs off and now you notice a big iron gate. "Where
 the hell did that come from?" You say.


 --------
 You walk up to the big iron gate and see there's a handle. >
 open it
 You open it and you are free!
 There are mountains. And berries! And...
 Oh, but then the bear comes with his katana and stabs you.
 "Who's laughing now!? Love this katana."


 --------
 I have     a   small   puppy   that's   better   at   this.
 $




 Extra Credit


    1. Explain how returning the nextroom works.

    2.Createmorerooms,makingthegamebigger.

    3. Instead of having each function print itself, learn about "doc comments". See if you can write the room descrip-

Extra Credit
       tionasdoccomments,andchangetherunnertoprintthem.                                                           113

    4.Onceyouhavedoccomments astheroomdescription,doyouneedtohavethe functionprompteven?Havethe
Learn Python The Hard Way, Release 1.0




114                                       Exercise 41: A Room With A View Of A Bear With A Broadsword
Exercise 42: Getting Classy



While it’s fun to put functions inside of dictionaries, you’d think there’d be something in Python that does this for you. There
is and it’s the class keyword. Using class is how you create an even more awesome "dict with functions" than the
one you made in the last exercise. Classes have all sorts of powerful features and uses that I could never go into in this
book.Instead,youwilljustusethemlikethey arefancy dictionaries withfunctions.

A programming language that uses classes is called an "Object Oriented Programming". This is an old style of
programming where you make "things" and you "tell" those things to do work. You have been doing a lot of this. A
whole lot. You just didn’tknowit. Remember whenyou weredoing this:
stuff = ['Test', 'This', 'Out']
print ' '.join(stuff)


You were actually using classes. The variable stuff is actually a list class. The ’           ’.join(stuff) is
calling the join function of the string ’ ’ (just an empty space) is also a class, a string class. It’s all classes!
        def
                   __init__(self):
Well, and objects, but let’s just skip that word for now. You will learn what those are after you make some classes.
               self.number = 0
Howdo youmakeclasses?Verysimilar tohowyoumade theROOMSdict,buteasier:

class TheThing(object):
       def
                   some_function(self):
              print "I got called."



 # two def
        different things a
               add_me_up(self,   more):
 = TheThing() self.number += more
 b = TheThing()
              return self.number


 a.some_function()
 b.some_function()


 print    a.add_me_up(20)
 print    a.add_me_up(20)
 print    b.add_me_up(30)
 print b.add_me_up(30)


 print a.number
 print b.number
Learn Python The Hard Way, Release 1.0




       Warning: Alright, this is where you start learning about "warts". Python is an old language with lots of really

       ugly obnoxious pieces that were bad decisions. To cover up these bad decisions they make new bad decisions and

       then yell at people to adopt the new bad decisions. The phrase class TheThing(object) is an example of a

       bad decision. I won’t get into it right here, but you shouldn’t worry about why your class has to have (object)

       after its name, just type it this way all the time or other Python programmers will yell at you. We’ll get into why

       later.



     You see that self in the parameters? You know what that is? That’s right, it’s the "extra" parameter that Python
     creates so you can type a.some_function() and then it will translate that to really be some_function(a). Why
     use self? Your function has no idea what you are calling any one "instance" of TheThing or another, you just use a
     generic name self. That way you can write your function and it will always work.

     You could actually use another name rather than self but then every Python programmer on the planet would hate
     you, so do not. Only jerks change things like that and I taught you better. Be nice to people who have to read what you
     writebecausetenyearslaterallcodeishorrible.
      from sys import exit
     Next, see the __init__ function? That is how you setup a Python class with internal variables. You can set them on
      from random import randint
1    self with the . (period) just like I will show you here. See also how we then use this in add_me_up() later which
     lets you add to the self.number you created. Later you can see how we use this to add to our number and print it.
2
     class Game(object):
     Classes are very powerful, so you should go read about them. Read everything you can and play with them. You
3    actually know how to use them, you just have to try it. In fact, I want to go play some guitar right now so I’m not
     goingtogiveyouanexercisetotype.Youaregoingtogowriteanexerciseusingclasses.
4
          def __init__(self, start):
     Here’showwewoulddoexercise41usingclassesinsteadofthethingwecreated:
5
                  self.quips = [
6
                        "You died.          You kinda suck at this.",
7
                          "Your mom would be proud. If she were smarter.",
8
                          "Such a luser.",
9
                          "I    have    a    small     puppy    that's   better   at   this."
10

11
                  ]
12

13
                   self.start = start
14
24              def death(self):
15
25                                                                 len(self.quips)-1)]
16
26                    print     self.quips[randint(0,
17
27
18
            def play(self):
28                 exit(1)
19
29
20              next = self.start
            def princess_lives_here(self):
30
21
31
22                print "You see a beautiful Princess with a shiny crown."
32
23

                  while "She offers you some cake."
                  print True:

                        print     "n--------"
     116
                        room =         getattr(self,    next)

                        next = room()
Learn Python The Hard Way, Release 1.0




33            eat_it = raw_input("> ")
34
35

36            if eat_it == "eat it":
37

38                 print "You explode like a pinata full of frogs."
39

40                 print "The Princess cackles and eats the frogs. Yum!"
41

42
                   return 'death'
43

44

45
              elif eat_it == "do not eat it":
46
47
                   print "She throws the cake at you and it cuts off your head."
48

49

50
                   print "The last thing you see is her munching on your torso. Yum!"
51
52
                   return 'death'
53
54

55            elif eat_it == "make her eat it":

56   def gold_koi_pond(self): Princess screams as you cram the cake in her mouth."
                   print "The
57                                       with a koi pond in the center."
58        print "There is"Then she smilessee a cries and fin poke you for saving her."
                   print   a garden        and massive thanks out."
59

60       print "You walk close and to a creepydoor and huge Koi stares needs cake too.'"
                  print "She points      tiny   looking says, 'The Koi at you."
61

62       print "You peek in gives a you the very for food." of cake and shoves you in."
                  print "She and         waiting last bit
63

         print "It opens 'gold_koi_pond'
                    return its mouth
64            if feed_it == "feed it":
65
66                print "The Koi jumps up, and rather than eating the cake, eats your arm."
             else:
67
         feed_it = raw_input("> ")
68                print "You fall in and the Koi shrugs than eats you."
69
                   print "The princess looks at you confused and just points at the cake."
70                print "You are then pooped      out   sometime later."
71
                  return 'princess_lives_here'
72
                  return 'death'
73
74

75

76
             elif feed_it == "do not feed it":
77
                  print "The Koi grimaces, then thrashes around for a second."
78

79
80
                  print "It rushes to the other end of the pond, braces against the wall..."
81

82                print "then it *lunges* out of the water, up in the air and over your"
83

84                print "entire body, cake and all."
85

86                print "You are then pooped out a week later."
87

88                return 'death'

89

90
             elif feed_it == "throw it in":

                  print "The Koi wiggles, then leaps into the air to eat the cake."

                  print "You can see it's happy, it then grunts, thrashes..."
                                                                                                         117
                  print "and finally rolls over and poops a magic diamond into the air"
Learn Python The Hard Way, Release 1.0



 91          def bear_with_sword(self):
 92

 93                print "Puzzled, you are           about to pick up the fish poop diamond when"
 94
 95                print "a bear bearing a            load bearing sword walks in."
 96                                                  diamond! Where'd you get that!?"'
 97                print '"Hey!raw_input("> ")
                    give_it =    That' my           out and looks at you."
 98

                   print "It holds "give paw
                   if give_it == its it":
 99
                                                                your hand to grab the diamond and"
                         print "The bear swipes at
100
                                                                in the process. It then looks at"
101
                         print "rips your hand off              and says, "Oh crap, sorry about that."'
102

103
                         print 'your bloody stump                hand back on, but you collapse."
104

105
                                                                see is the bear shrug and eat you."
106
                         print "It tries to put your
107

108                    elif give_it == "say no":you
                          print "The last thing
109
110
                         return 'death' bear looks shocked.
                            print "The                              Nobody ever told a bear"
111

112                         print "with a broadsword 'no'.        It asks, "
113

114                         print '"Is it because it's    not a katana?       I   could go get one!"'
115

116                         print "It then runs off and now you notice a big iron gate."
117

118
                            print '"Where the hell did that come from?" You say.'
119

120

121

122
                            return 'big_iron_gate'
123

124

125

126              def big_iron_gate(self):
127

128
                       print "You walk up to the big iron gate and see there's a handle."

129                   open_it = raw_input("> ")
130                  else:                                            I mean, the door's right there."
131                   if open_it == 'open it':
132                        print "That doesn't seem sensible.
133                          print "You open it and you are free!"
134                        return 'big_iron_gate'
135                          print "There are mountains. And berries! And..."

                            print "Oh, but then the bear comes with his katana and stabs you."

       What You Should See laughing
                   print '"Who's
       a_game = Game("princess_lives_here")             now!?    Love this katana."'
        a_game.play()

       The output from this version of the game should be exactly the same as the previous version, and in fact you will
                          return 'death'
       notice that some of the code is nearly the same. Compare this new version of the game and with the last one so you
       understandthechangesthatweremade.Keythingstoreallygetare:

            1. How you made a class Game(object) and put functions inside it.

            2. How __init__ is a special intialization method that sets up important variables.

            3. How you added functions to the class by indenting them so they were deeper under the class keyword. This
      118                                                                                  Exercise 42: Getting Classy
Learn Python The Hard Way, Release 1.0




         isimportantsostudycarefullyhowindentationcreatestheclassstructure.

      4.Howyouindentedagaintoputthecontents ofthefunctionsundertheirnames.

      5.Howcolonsarebeingused.

      6. The concept of self and how it’s used in __init__, play, and death.

      7. Go find out what getattr does inside play so that you understand what’s going on with the operation of

         play. In fact, try doing this by hand inside Python to really get it.

      8. How a Gamewascreatedat the end and then toldto play() and howthat got everything started.




   Extra Credit


      1. Go find out what the __dict__ is and figure out how to get at it.

      2. Try addingsome rooms to makesureyou knowhowto work with aclass.

      3. Create a two-class version of this, where one is the Map and the other is the Engine. Hint: play goes in the

         Engine.




Extra Credit                                                                                                        119
Learn Python The Hard Way, Release 1.0




120                                       Exercise 42: Getting Classy
Exercise 43: You Make A Game

  You need to start learning to feed yourself. Hopefully as you have worked through this book, you have learned that all the
  information you need is on the internet, you just have to go search for it. The only thing you have been missing are the
  right words and what to look for when you search. Now you should have a sense of it, so it’s about time you struggled
  throughabigprojectandtriedtogetitworking.
  Hereareyourrequirements:
       1.MakeadifferentgamefromtheoneImade.

       2. Use more than one file, and use import to use them. Make sure you know what that is.

       3. Use oneclass perroom and give theclasses names thatfit their purpose.LikeGoldRoom, KoiPondRoom.
       4.Yourrunnerwillneedtoknow abouttheserooms,somake aclassthatrunsthemandknows aboutthem.There’s

          plenty of ways todothis,butconsider having each roomreturn what roomis next orsetting a variable of what

           roomisnext.
Other than that I leave it to you. Spend a whole week on this and make it the best game you can. Use classes, functions, dicts,
lists anything you can to make it nice. The purpose of this lesson is to teach you how to structure classes that need other
classesinsideotherfiles.

   Remember, I’m not telling you exactly how to do this because you have to do this yourself. Go figure it out. Program-
   ming is problem solving, and that means trying things, experimenting, failing, scrapping your work, and trying again.
   When you get stuck, ask for help and show people your code. If they are mean to you, ignore them, focus on the
   people who arenot mean and offertohelp. Keep workingitandcleaning ituntilit’s good,thenshowitsome more.
   Goodluck,andseeyouinaweekwithyourgame.




                                                                                                                     121
Learn Python The Hard Way, Release 1.0




122                                       Exercise 43: You Make A Game
Exercise 44: Evaluating Your Game

  In this exercise you will evaluate the game you just made. Maybe you got part-way through it and you got stuck.
  Maybe you got it working but just barely. Either way, we’re going to go through a bunch of things you should know
  now and make sure you covered them in your game. We’re going to study how to properly format a class, common
  conventionsinusingclasses,andalotof"textbook"knowledge.

Why would I have you try to do it yourself and then show you how to do it right? 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 for much longer.
I’m now instead going to give you things to do, have you do them on your own, and then give you ways to improve
whatyoudid.

     You will struggle at first and probably be very frustrated but stick with it and eventually you will build a mind for
     solvingproblems.Youwillstarttofindcreativesolutionstoproblems ratherthanjustcopy solutions outoftextbooks.



Function Style

   AlltheotherrulesI’vetaughtyouabouthowtomakeafunctionniceapply here,butaddthesethings:

       • 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,justaskthemtodemonstratethemathematicalbasis thatdetermines howa"method"is different
      from a "function"and they’llshut up.

      • When you work with classes much of your time is spent talking about making the class "do things". Instead of
      naming your functions after what the function does, instead name it as if it’s a command you are giving to the
      class. Sameas popis saying"Heylist,popthis off."It isn’tcalled remove_from_end_of_listbecause
      eventhoughthat’swhatitdoes,that’snotacommandtoalist.

      • Keep your functions small and simple. For some reason when people start learning about classes they forget
      this.



Class Style

         • Your class should use "camel case" like SuperGoldFactory rather than super_gold_factory.

         • Try not to do too much in your __init__ functions. It makes them harder to use.

       • Your other functions should use "underscore format" so write my_awesome_hair and not myawesomehair or
       MyAwesomeHair.

  • Be consistent in how you organize your function arguments. If your class has to deal with users, dogs, and cats, keep
  that order throughout unless it really doesn’t make sense. If you have one function takes (dog, cat, user) and
  the other takes (user, cat, dog), it’ll be hard to use.



                                                                                                                        123
Learn Python The Hard Way, Release 1.0




   • Try notto usevariables that comefrom the moduleor globals.They shouldbefairly self-contained.

   •        Afoolishconsistencyisthehobgoblinoflittleminds.Consistencyisgood,butfoolishlyfollowingsomeidiotic

   mantrabecauseeveryoneelsedoesisbadstyle.Thinkforyourself.

   • Always, always have class Name(object) format or else you will be in big trouble.




Code Style


   • Give your code vertical space so people can read it. You will find some very bad programmers who are able to

   write reasonable code, but who do not add any spaces. This is bad style in any language because the human eye

   andbrainusespaceandverticalalignmenttoscanandseparatevisualelements.Nothavingspaceisthesame

       asgivingyourcodeanawesomecamouflagepaintjob.

   • If you can’t read it out loud, it’s probably hard to read. If you are having a problem making something easy to

   use, try reading it out loud. Not only does this force you to slow down and really read it, but it also helps you find

   difficultpassagesandthingstochangeforreadability.

   • Tryto do what other peopleare doing in Python untilyou find yourown style.

   • Once you find your own style, do not be a jerk about it. Working with other people’s code is part of being a

   programmer,andother people have really badtaste. Trust me,you willprobably have really badtastetoo and noteven

   realizeit.

   • If you find someone who writes code in a style you like, try writing something that mimics their style.




Good Comments


   • There are programmers who will tell you that your code should be readable enough that you do not need com-

   ments. They’ll then tell you in their most official sounding voice that, "Ergo you should never write comments."

   Thoseprogrammers are either consultants who get paid more ifother people can’t usetheircode, orincompe-

       tents whotendtoneverwork withotherpeople.Ignorethemandwritecomments.

   • When you write comments, describe why you are doing what you are doing. The code already says how, but

  124
   whyyou did thingsthe way you did is more important.                              Exercise 44: Evaluating Your Game

   • When you write doc comments for your functions , make the comments documentation for someone who will
Learn Python The Hard Way, Release 1.0




I want you to do nothing but evaluate and fix code for the week. Your own code and other people’s. It’ll be pretty hard work,
butwhenyouaredoneyourbrainwillbewiredtightlikeaboxer’s hands.




  Evaluate Your Game                                                                                                125
Learn Python The Hard Way, Release 1.0




126                                       Exercise 44: Evaluating Your Game
Exercise 45: Is-A, Has-A, Objects, and
Classes

An important concept that you have to understand is the difference between a Class and an Object. The problem is,
there is no real "difference" between a class and an object. They are actually the same thing at different points in time. I will
demonstrateby aZenkoan:
      What is the difference between a Fish and a Salmon?

Did that question sort of confuse you? Really sit down and think about it for a minute. I mean, a Fish and a Salmon are
differentbut,wait,they arethesamethingright?A Salmonis a kindofFish,soImeanit’s notdifferent.Butatthe same time,
becase a Salmon is a particular type of Fish and so it’s actually different from all other Fish. That’s what makes it aSalmon
andnotaHalibut.SoaSalmonandaFisharethesamebutdifferent.Weird.

This question is confusing because most people do not think about real things this way, but they intuitively understand
them. You do not need to think about the difference between a Fish and a Salmon because you know how they are
related.YouknowaSalmonisakindofFishandthatthereareotherkinds ofFishwithouthavingtounderstandthat.

Let’s take itone stepfurther,let’ssayyou have a bucketfullof3 Salmon and becauseyouare a nice person,you have decided
toname themFrank,Joe,andMary.Now,thinkaboutthis question:
      What is the difference between Mary and a Salmon?

   Againthis is aweirdquestion,but it’s abiteasierthantheFishvs.Salmon question.YouknowthatMary is aSalmon, and so
   she’s not really different. She’s just a specific "instance" of a Salmon. Joe and Frank are also instances of Salmon.
   But, what do I mean when I say instance? I mean they were created from some other Salmon and now represent a
   realthingthathasSalmon-likeattributes.

   Now for the mind bending idea: Fish is a Class, and Salmon is a Class, and Mary is an Object. Think about that for a
   second.Alrightlet’s break itdownrealslow andseeifyouget it.

       A Fish is a Class, meaning it’s not a real thing, but rather a word we attach to instances of things with similar
       attributes. Got fins? Got gills? Lives in water? Alright it’s probably a Fish.

  Someone with a Ph.D. then comes along and says, "No my young friend, this Fish is actually Salmo salar, affection-
  ately known as a Salmon." This professor 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? Ok, probably
  aSalmon.

Finally, a cook comes along and tells the Ph.D., "No, you see this Salmon right here, I’ll call her Mary and I’m going to
make a tasty fillet out of her with a nicesauce." Now you havethis instanceof a Salmon (which alsois an instance of aFish)
namedMary turnedintosomethingrealthatis fillingyourbelly.Ithas becomeanObject.
    There you have it: Mary is a kind of Salmon that is a kind of Fish. Object is a Class is a Class.




                                                                                                                        127
Learn Python The Hard Way, Release 1.0




     How This Looks In Code

     This is a weird concept, but to be very honest you only have to worry about it when you make new classes, and when you
     useaclass.Iwillshowyoutwotricks tohelpyoufigureoutwhethersomethingis aClass orObject.

     First, you need to learn two catch phrases "is-a" and "has-a". You use the phrase is-a when you talk about objects and
     classes being related to each other by a class relationship. You use has-a when you talk about objects and classes that are
     relatedonlybecausetheyreferenceeachother.

     Now, go through this piece of code and replace each ##?? comment with a replacement comment that says whether the
     next line represents an is-a or a has-a relationship, and what that relationship is. In the beginning of the code, I’ve laid
1            ## Animal is-a object (yes, sort of confusing) look at the extra credit
     outafewexamples,soyoujusthavetowritetheremainingones.
2            class Animal(object):
3    Remember,is-a istherelationshipbetween Fish and Salmon,whilehas-aistherelationship betweenSalmonandGills.
4                  pass
5

6

7           ## ??
            def
            class Dog(Animal):
8
                    __init__(self, name):
                  ## ??
9                 self.name = name
12
10
        ## ??
13
11
        class Cat(Animal):
14

15          def
16                    __init__(self, name):
17                   ## ??
18                   self.name = name
19       ## ??
20       class Person(object):
21

22          def
23                   __init__(self, name):
24                  ## ??
25                  self.name = name
26

27

28
                    ## Person has-a pet of some kind
29    ## ??         self.pet = None
30    class Employee(Person):
31
32          def __init__(self, name, salary):
33

34                 ## ?? hmm what is this strange magic?
35

36
                   super(Employee, self).__init__(name)
37
38
                   ## ??
39

40
                   self.salary = salary
41

42

43

44
      ## ??
      class Fish(object):

            pass
      128                                                                 Exercise 45: Is-A, Has-A, Objects, and Classes

      ## ??
      class Salmon(Fish):
Learn Python The Hard Way, Release 1.0




46

47   ## ??
48   class
     45       Halibut(Fish):
49
50         pass
51

52

53

54

55
     ## rover is-a Dog
56
     rover = Dog("Rover")
57

58

59

60
     ## ??
61
     satan = Cat("Satan")
62

63
64   ## ??
65   mary = Person("Mary")
66

67

68   ## ??
69   mary.pet = satan
70

71

72
     ## ??
73
     frank = Employee("Frank", 120000)
74

75
76
     ## ??
     frank.pet = rover


     ## ??
     flipper = Fish()


     ## ??
     crouse = Salmon()


     ## ??
     harry = Halibut()




     About class Name(object)

     Remember how I was yelling at you to always use class Name(object) and I couldn’t tell you why? Now I can tell
     you, because you just learned about the difference between a class and an object. I couldn’t tell you until now
     becauseyouwouldhavejustbeenconfusedandcouldn’tlearntousethetechnology.

     What happened is Python’s original rendition of class was broken in many serious ways. By the time they admitted the
     fault it was too late, and they had to support it. In order to fix the problem, they needed some "new class" style so that the
     "oldclasses"wouldkeepworkingbutyoucouldusethenewmorecorrectversion.

     This is where "class is-a object"comes in. They decided that they would use the word "object", lowercased, to be the "class"
     that youThis Looks In Code a class. Confusing right? A class inherits from the class named object to make a class 129 it’s
        How inherit from to make                                                                                         but
     notanobjectreallyit’s aclass,butdonotforgettoinheritfromobject.

     Exactly. The choice of one single word meant that I couldn’t teach you about this until now. Now you can try to
Learn Python The Hard Way, Release 1.0




      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 that make them do things. See what happens

         whenfunctionsareina"baseclass"likeAnimalvs.insayDog.

      4.Findotherpeople’s codeandwork outalltheis-aandhas-arelationships.

      5.Makesomenewrelationships thatarelists anddicts soyoucanalsohave"has-many"relationships.

      6. Do you think there’s a such thing as a "is-many" relationship? Read about "multiple inheritance", then avoid it

         ifyoucan.




130                                                                Exercise 45: Is-A, Has-A, Objects, and Classes
Exercise 46: A Project Skeleton



     This will be where you start learning how to setup a good project "skeleton" directory. This skeleton directory will
     have all the basics you need to get a new 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 copy this directory to a new name and edit the
     filestogetstarted.




     Skeleton Contents: Linux/OSX

     First,createthestructureofyourskeletondirectory withthesecommands:
     ~ $ mkdir -p projects
     ~ $ cd projects/
     ~/projects $ mkdir skeleton
     ~/projects $ cd skeleton
     ~/projects/skeleton $ mkdir bin NAME tests docs


     I use a directory named projects to store all the various things I’m working on. Inside that directory I have my
     skeleton directory that I put the basis of my projects into. The directory NAME will be renamed to whatever you are
     callingyourproject’smainmodulewhenyouusetheskeleton.
        try:
1    Nextweneedtosetupsomeinitialfiles:
             from setuptools import setup
2    ~/projects/skeleton
       except ImportError:$      touch  NAME/__init__.py
     ~/projects/skeleton $ touch tests/__init__.py
3
             from distutils.core import setup

4    That creates empty Python module directories we can put our code in. Then we need to create a setup.py file we can
       config = {
     usetoinstallourprojectlaterifwewant:
5
            'description':    'My    Project',
6
            'author': 'My Name',
7
            'url': 'URL to get it at.',
8
            'download_url':       'Where   to    download   it.',
9
            'author_email': 'My email.',
10

11
                                                                                                                     131
            'version':   '0.1',
12

13

14
            'install_requires':     ['nose'],
Learn Python The Hard Way, Release 1.0




19        setup(**config)


     18
          Edit this file so that it has your contact information and is ready to go for when you copy it.

          Finally you will want a simple skeleton file for tests named tests/NAME_tests.py:

          from nose.tools      import   *
          import NAME


          def setup():
1
                print "SETUP!"
 2
10        def
                   test_basic():
11
 3
          def teardown():
                print "I RAN!"
               print "TEAR DOWN!"
4



5
     Installing Python Packages
6


     Make sure you have some packages installed that makes these things work. Here’s the problem though. You are at a
7
     point where it’s difficult for me to help you do that and keep this book sane and clean. There are so many ways to install
8
     software onsomany computers that I’d havetospend 10 pages walking you through every step, andletmetell youIam a
     lazyguy.
9
     Rather than tell you how to do it exactly, I’m going to tell you what you should install, and then tell you to figure it
     out and get it working. This will be really good for you since it will open a whole world of software you can use that
     otherpeoplehavereleasedtotheworld.

     Next,nstallthefollowingpythonpackages:

           1. pip from http://pypi.python.org/pypi/pip

           2. distribute from http://pypi.python.org/pypi/distribute

           3. nose from http://pypi.python.org/pypi/nose/

           4. virtualenv from http://pypi.python.org/pypi/virtualenv

     Do not just download these packages and install them by hand. Instead see how other people recommend you install
     these packages and use them for your particular system. The process will be different for most versions of Linux,
     OSX, and definitely different for Windows.
     I am warning you, this will be frustrating. In the business we call this "yak shaving". Yak shaving is any activity that
     is mind numblingly irritatingly boring and tedious that you have to do before you can do something else that’s more
     fun. You want to create cool Python projects, but you can’t do that until you setup a skeleton directory, but you can’t
     setup a skeleton directory until you install some packages, but you can’t install pacakages until you install package
     installers, and you can’t install package installers until you figure out how your system installs software in general,
     andsoon.
     Struggle through this anyway. Consider it your trial-by-annoyance to get into the programmer club. Every programmer has
     todo theseannoying tedioustasksbeforetheycando somethingcool.




     Testing Your Setup
          132                                                                                   Exercise 46: A Project Skeleton

     Afteryougetallthatinstalledyoushouldbeabletodothis:
Learn Python The Hard Way, Release 1.0




~/projects/skeleton $ nosetests


----------------------------------------------------------------------
Ran 1 test in 0.007s


OK

I’ll explain what this nosetests thing is doing in the next exercise, but for now if you do not see that, you probably got
something wrong. Make sure you put __init__.py files in your NAME and tests directory and make sure you got
tests/NAME_tests.py right.




Using The Skeleton

Youarenowdone withmostofyouryak shaving.Wheneveryouwanttostartanewproject,justdothis:

    1.Makeacopy ofyourskeleton directory.Nameitafteryournew project.

    2. Rename (move) the NAME module to be the name of your project or whatever you want to call your root

        module.

    3. Edit yoursetup.pyto haveall the information foryour project.

    4. Rename tests/NAME_tests.py to also have your module name.

    5. Double check it’s all working using nosetests again.

    6. Start coding.




Required Quiz

Thisexercisedoesn’thaveextracreditbutaquizyoushouldcomplete:

    1.Readabouthowtouseallofthethingsyouinstalled.

    2. Read about the setup.py file and all it has to offer. Warning, it is not a very well-written piece of software,

        soitwillbeverystrangetouse.

    3. Make aprojectandstart puttingcodeintothe module,then getthe module working.

    4. Put a script in the bin directory that you can run. Read about how you can make a Python script that’s runnable

Using The Skeleton
      foryoursystem.                                                                                                     133

    5. Mention the bin script you created in your setup.py so that it gets installed.
Learn Python The Hard Way, Release 1.0




134                                       Exercise 46: A Project Skeleton
Exercise 47: Automated Testing



     Having to type commands into your game over and over to make sure it’s workingis annoying. Wouldn’tit be better towrite
     little pieces of code that test your code? Then when you make a change, or add a new thing to your program, you just "run
     your tests" and the tests make sure things are still working. These automated tests won’t catch all your bugs, but they will
     cutdownonthetimeyouspendrepeatedly typing and runningyour code.

     Every exercise after this one will not have a What You Should See section, but instead it will have a What You
     Should Test section. You will be writing automated tests for all of your code starting now, and this will hopefully
     makeyouanevenbetterprogrammer.

     I won’t try to explain why you should write automated tests. I will only say that, you are trying to be a programmer, and
     programmers automate boring and tedious tasks. Testing a piece of software is definitely boring and tedious, so you might
     aswellwritealittlebitofcodetodoitforyou.

     That should be all the explanation you need because your reason for writing unit tests is to make your brain stronger. You
     have gone through this book writing code to do things. Now you are going to take the next leap and write code that
     knows about other code you have written. This process of writing a test that runs some code you have written forces
     you to understand clearly what you have just written. It solidifies in your brain exactly what it does and why it works and
     givesyouanewlevelofattentiontodetail.




     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
     fromyourprojectskeleton.
            class Room(object):
1
     First, make a ex47 project from your project skeleton. Make sure you do it right and rename the module and get that first
     tests/ex47_tests.py test file going right. Also make sure nose runs this test file. IMPORTANT make sure you also
2
     delete tests/skel_tests.pyc if it’s there.
                   def __init__(self, name, description):
3
     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
                       self.name = name
     wanttotestwiththiscodeinit:
4
                       self.description = description
5
11           def       self.paths = {}
12                    add_paths(self,    paths):
 6
                     self.paths.update(paths)
7
                   def go(self, direction):
8                                                                                                                             135
                        return self.paths.get(direction, None)
9

10
Learn Python The Hard Way, Release 1.0




      Onceyouhavethatfile,changeunittestskeletontothis:
        from nose.tools import *
1       from ex47.game import Room

2



3

         def test_room():
4
               gold = Room("GoldRoom",
5
                                """This room has gold in it you can grab. There's a
6
                                door to the north.""")
7
               assert_equal(gold.name,      "GoldRoom")
 8
17             assert_equal(gold.paths, {}) north, 'south':
                 center.add_paths({'north':                              south})
18               assert_equal(center.go('north'), north)
 9
19               assert_equal(center.go('south'), south)
10
20
11       def test_room_paths():
21
12
        def test_map():
22
13            center = Room("Center", "Test room in the center.")
23
14
             start = Room("Start", "You can go west and down a hole.")
24
15            north = Room("North", "Test room in the north.")
25
16
             west = Room("Trees", "There are trees here, you can go east.")
26             start.add_paths({'west': "Test 'down':  down})
              south = Room("South", west, room in the south.")
27
             down = Room("Dungeon", "It's dark down here, you can go up.")
               west.add_paths({'east': start})
28             down.add_paths({'up': start})
29

30

31

32        assert_equal(start.go('west'), west)

          assert_equal(start.go('west').go('east'), start)

          assert_equal(start.go('down').go('up'), start)


     This file imports the Room class you made in the ex47.game module so that you can do tests on it. There are then a
     set of tests that are functions starting with test_. Inside each test case there’s a bit of code that makes a Room or a set
     of Rooms, and then makes sure the rooms work the way you expect them to work. It tests out the basic room
     features,thenthepaths,thentriesoutawholemap.

     The important functions here are assert_equal which makes sure that variables you have set or paths you have
     built in a Room are actually what you think they are. If you get the wrong result, then nosetests will print out an
     errormessagesoyoucangofigureitout.




     Testing Guidelines

     Followthesegeneralloosesetofguidelineswhenmakingyourtests:

        1. Test files go in tests/ and are named BLAH_tests.py otherwise nosetests won’t run them. This also

           keepsyourtestsfromclashingwithyourothercode.
     136                                                                                   Exercise 47: Automated Testing
       2.Writeonetestfileforeachmoduleyoumake.

        3. Keep your test cases (functions) short, but do not worry if they are a bit messy. Test cases are usually kind of
Learn Python The Hard Way, Release 1.0




        changeyourtests. Duplicatedcode willmakechangingyourtests more difficult.

    5. Finally, do not get too attached to your tests. Sometimes, the best way to redesign something is to just delete it,

        thetests,andstartover.




What You Should See

~/projects/simplegame $ nosetests

----------------------------------------------------------------------
Ran 3 tests in 0.007s


OK

That’s what you should see if everything is working right. Try causing an error to see what that looks like and then fix
it.




Extra Credit


    1.Goreadaboutnosetestsmore,andalsoreadaboutalternatives.

    2.LearnaboutPython’s"doctests"andseeifyoulikethembetter.

    3. Make your Room more advanced, and then use it to rebuild your game yet again but this time, unit test as you

        go.




What You Should See                                                                                                 137
Learn Python The Hard Way, Release 1.0




138                                       Exercise 47: Automated Testing
Exercise 48: Advanced User Input

 Your game probably was coming along great, but I bet how you handled what the user typed was becoming tedious.
 Each room needed its own very exact set of phrases that only worked if your player typed them perfectly. What you’d
 rather have is a device that lets users type phrases in various ways. For example, we’d like to have all of these phrases
 workthesame:
     • open door
     • open the door

     • go THROUGH the door

     • punch bear
      •PunchTheBearintheFACE

It should be alright for a user to write something a lot like English for your game, and have your game figure out what it
means. To do this, we’re going to write a module that does just that. This module will have a few classes that work together
tohandle useinput andconvertitintosomethingyour gamecan work withreliably.

InasimpleversionofEnglishthefollowingelements:
     •Wordsseparatedbyspaces.

     •Sentencescomposedofthewords.

     •Grammarthatstructuresthesentencesintomeaning.

    Thatmeans thebestplacetostartis figuringouthowtogetwordsfromtheuserandwhatkindsofwordsthoseare.



 Our Game Lexicon

  InourgamewehavetocreateaLexiconofwords:

       • Directionwords: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:anystringof0through9characters.

 When we get to nouns, we have a slight problem since each room could have a different set of Nouns, but let’s just pick
 thissmallsettoworkwithfornowandimproveitlater.




                                                                                                                   139
Learn Python The Hard Way, Release 1.0




Breaking Up A Sentence


Once we have our lexicon of words we need a way to break up sentences so that we can figure out what they are. In our
case,we’ve defined asentence as"wordsseparatedbyspaces",sowereally justneed to dothis:
stuff = raw_input('> ')
words = stuff.split()


That’s really all we’ll worry about for now, but this will work really well for quite a while.



Lexicon Tuples


Once we know how to break upa sentence into words, we justhave togo through the listof words and figure out what "type"
they are. To do that we’re goingto use a handy littlePython structure called a"tuple". A tuple is nothing morethan a listthat
youcan’tmodify.It’s created by putting datainside two () witha comma,like alist:
first_word = ('direction', 'north')
second_word = ('verb', 'go')
sentence = [first_word, second_word]

This creates apair of(TYPE, WORD)thatlets youlook atthe word and dothings withit.

This is just an example, but that’s basically the end result. You want to take raw input from the user, carve it into words with
split,thenanalyzethosewords toidentify theirtype,andfinallymakeasentenceoutofthem.




Scanning Input

Now you are ready to write your scanner. This scanner will take a string of raw input from a user and return a sentence
that’s composed of a list of tuples with the (TOKEN, WORD) pairings. If a word isn’t part of the lexicon then it should
stillreturnthe WORD, butsetthe TOKENtoan errortoken. Theseerrortokens willtellthe userthey messed up.

Here’s where it gets fun. I’m not going to tell you how to do this. Instead I’m going to write a unit test und you are
goingtowritethescannersothattheunittestworks.




Exceptions And Numbers

There is one tiny thing I will help you with first, and that’s converting numbers. 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 an error, then you have to handle that exception. For
example,ifyoutypethisintopython:

~/projects/simplegame $ python
Python 2.6.5 (r265:79063, Apr 16 2010, 13:57:41)
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more                  information.
>>> int("hell")
 140                                                                                      Exercise 48: Advanced User Input
Traceback (most recent call last):

  File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with          base    10:   'hell'
Learn Python The Hard Way, Release 1.0




     You deal with an exception by using the try and except keywords:

     def convert_number(s):

          try:

                 return int(s)

          except       ValueError:

                 return None

     You put the code you want to "try" inside the try block, and then you put the code to run for the error inside the
     except. In this case, we want to "try" to call int() on something that might be a number. If that has an error, then we
     "catch"itandreturnNone.

     In your scanner that you write, you should use this function to test if something is a number. You should also do it as the
     lastthingyoucheck forbeforedeclaringthatwordanerror word.
       from nose.tools import *
1

2     from ex48 import lexicon
3

4

             def test_directions():
5    What You Should Test                                                                          'north')])
                    assert_equal(lexicon.scan("north"),         [('direction',
6
                   result = lexicon.scan("north south east")
7
     Here are the files tests/lexicon_tests.py that you should use:
                   assert_equal(result,     [('direction', 'north'),
 8         def test_verbs():
12
                                                    ('direction',        'south'), 'go')])
13
 9
14                 assert_equal(lexicon.scan("go"),    [('verb',
                                                 ('direction', 'east')])
15
10
16
11                 result = lexicon.scan("go kill eat")
17

18                 assert_equal(result, [('verb', 'go'),
19

20                                                ('verb',    'kill'),
21
22                                                ('verb',   'eat')])
23

24

25

26

27
           def test_stops():
28       def test_nouns():                                                           'the')])
29              assert_equal(lexicon.scan("the"),      [('stop',                       'bear')])
30            assert_equal(lexicon.scan("bear"),      [('noun',
31              result = lexicon.scan("the in of")
32            result = lexicon.scan("bear princess")
33              assert_equal(result, [('stop', 'the'),
34            assert_equal(result, [('noun', 'bear'),
35                                             ('stop', 'in'),
36
                                            ('noun', 'princess')])
37                                            ('stop', 'of')])
38


         def test_numbers():

                 assert_equal(lexicon.scan("1234"),        [('number',                 1234)])
                                                                                                                                141
                 result = lexicon.scan("3 91234")

                 assert_equal(result, [('number', 3),
Learn Python The Hard Way, Release 1.0




41            def test_errors():
42                                                                                        'ASDFADFASDF')])
43 39              assert_equal(lexicon.scan("ASDFADFASDF"),           [('error',
44 40

45                 result = lexicon.scan("bear IAS princess")
46

                   assert_equal(result,    [('noun',   'bear'),

        Rememberthat you will want tomake a new project'IAS'),
                                              ('error', withyour skeleton, typeinthis testcase (do notcopy-paste!) and write
        yourscannersothatthetestruns.Focusonthedetails andmakesureeverythingworksright.
                                             ('noun', 'princess')])




        Design Hints

        Focus on getting one test working at a time. Keep this simple and just put all the words in your lexicon in lists that are in
        your lexicon.py module. Do not modify the input list of words, but instead make your own new list with your
        lexicon tuples in it. Also, use the in keyword with these lexicon lists to check if a word is in the lexicon.




        Extra Credit


           1.Improvetheunittesttomakesureyoucovermoreofthelexicon.

           2.Addtothelexiconandthenupdatetheunittest.

           3. Make your scanner handles user input in any capitalization and case. Update the test to make sure this actually

               works.

           4.Findanotherwaytoconvertthenumber.

           5.Mysolutionwas 37lineslong.Isyourslonger?Shorter?




        142                                                                                 Exercise 48: Advanced User Input
Exercise 49: Making Sentences

  What weshould be ableto get from ourlittlegamelexiconscanneris alistthatlooks likethis:

  >>> from ex48 import lexicon
    >>> print lexicon.scan("go north")
     [('verb', 'go'), ('direction', 'north')]
     >>> print lexicon.scan("kill the princess")
             [('verb', 'kill'), ('stop', 'the'), ('noun', 'princess')]
             >>> print lexicon.scan("eat the bear")
          [('verb', 'eat'), ('stop', 'the'), ('noun', 'bear')]
      >>> print lexicon.scan("open the door and smack the bear in the nose")
      [('error', 'open'), ('stop', 'the'), ('noun', 'door'), ('error', 'and'),
      ('error', 'smack'), ('stop', 'the'), ('noun', 'bear'), ('stop', 'in'),
      ('stop', 'the'), ('error', 'nose')]
      >>>

Now let us turn this into something the game can work with, which would be some kind of Sentence class. If you

remembergradeschool,asentencecanbeasimplestructurelike:
       SubjectVerbObject

   Obviously it gets more complex than that, and you probably did many days of annoying sentence graphs for English
   class.WhatwewantistoturntheabovelistsoftuplesintoaniceSentenceobjectthathassubject,verb,andobject.



 Match And Peek

 Todothisweneedfourtools:

     1.Away toloopthroughthelistoftuples.That’s easy.

     2.A way to"match"differenttypes oftuples that weexpectin ourSubject Verb Objectsetup.

     3.Awayto"peek"atapotentialtuplesowecanmakesomedecisions.

     4. A way to"skip"things we do not care about, like stop words.
    Weusethepeek functiontosay look atthenextelementinourtuplelist,andthenmatchtotake oneoffandwork withit.Let’s
    takealookatafirstpeekfunction:
   def peek(word_list):
       if word_list:
             word    =   word_list[0]
             return word[0]
      else:
            return None

 Veryeasy.Nowforthematchfunction:


                                                                                                                 143
Learn Python The Hard Way, Release 1.0



def
            match(word_list,           expecting):
          if word_list:

                     word = word_list.pop(0)

                if    word[0]    ==     expecting:

                        return word

                else:

                        return None

        else:

                return None

 Again,veryeasy,andfinallyourskipfunction:
 def skip(word_list, word_type):

        while        peek(word_list)     ==     word_type:

                match(word_list, word_type)

 Bynowyoushouldbeabletofigureoutwhatthesedo.Makesureyouunderstandthem.




 The Sentence Grammar

 Withourtools wecannowbegintobuildSentenceobjectsfromourlistoftuples.Whatwedois aprocess of:

      1. Identify the next word with peek.

      2. If that word fits in our grammar, we call a function to handle that part of the grammar, say parse_subject.

      3. If it doesn’t, we raise an error, which you will learn about in this lesson.

      4.Whenwe’realldone,weshouldhaveaSentenceobjecttowork withinourgame.

 The best way to demonstrate this is to give you the code to read, but here’s where this exercise is different from the
 previous one: You will write the test for the parser code I give you. Rather than giving you the test so you can write the
 code,Iwillgiveyouthecode,andyouhavetowritethetest.
 Here’s the code that I wrote for parsing simple sentences using the ex48.lexicon module:
def
 class ParserError(Exception):
         peek(word_list):
      if word_list:
      pass

                word      =     word_list[0]

            return word[0]
      else:
 class Sentence(object):
    def match(word_list, expecting):
            return None

144     def __init__(self, subject, verb, object):                                             Exercise 49: Making Sentences

                # remember        we     take   ('noun','princess')   tuples   and   convert   them

                self.subject = subject[1]
Learn Python The Hard Way, Release 1.0




         if     word_list:

                  word = word_list.pop(0)



                  if     word[0]   ==     expecting:

                          return word

                  else:
def
               parse_verb(word_list):
                     return None
         skip(word_list, 'stop')
         else:
         if peek(word_list) == 'verb':
               return None
                return    match(word_list,         'verb')        next.")

          else:

            raise ParseError("Expected a verb
  def skip(word_list, word_type):

         while          peek(word_list)    ==   word_type:

       if next == 'noun': word_type)
           match(word_list,
  def parse_object(word_list):
            return match(word_list, 'noun') if
      skip(word_list,    'stop')
       next == 'direction':                                                              next.")
      next = peek(word_list)
            return    match(word_list, 'direction')

              else:

                       raise ParseError("Expected a noun or direction



def
             parse_sentence(word_list):
      def parse_subject(word_list, subj):
          skip(word_list, 'stop')
          verb     =      parse_verb(word_list)

          start == parse_object(word_list)
          obj       peek(word_list)
             if start == 'noun':

                     subj = match(word_list, 'noun')
              return Sentence(subj, verb, obj)
                     return  parse_subject(word_list,         subj)

                elif start == 'verb':                                                              verb not: %s" % start)

                         # assume the subject is the player then

                         return    parse_subject(word_list,   ('noun',      'player'))

                else:

                         raise ParserError("Must start with subject, object, or                                             145
Learn Python The Hard Way, Release 1.0




A Word On Exceptions

You briefly learned about exceptions, but not how to raise them. This code demonstrates how to do that with the
ParserException at the top. Notice that it uses classes to give it the type of Exception. Also notice the use of
raise keyword to raise the exception.

In your tests, youwillwant toworkwith these exceptions, which I’ll showyou howto do.




What You Should Test

For Exercise 49 is write a complete test that confirms everything in this code is working. That includes making
exceptionshappenbygivingitbadsentences.

Check for an exception by using the function assert_raises from the nose documentation. Learn how to use this so
youcan write a test thatis expected to fail, which is very importantintesting. Learnabout this function (andothers) by reading
thenosedocumentation.
When you are done, you should know how this bit of code works, and how to write a test for other people’s code even if they
donotwantyouto.Trustme,it’saveryhandyskilltohave.




Extra Credit


   1. Change the parse_ methods and try to put them into a class rather than be just methods. Which design do you

       likebetter?

   2. Make the parser more error resistant so that you can avoid annoying your users if they type words your lexicon

       doesn’tunderstand.

   3.Improvethegrammarbyhandlingmorethingslikenumbers.

   4.Think abouthowyoumightusethis Sentenceclassinyourgametodomorefunthings withauser’sinput.




 146                                                                                  Exercise 49: Making Sentences
Exercise 50: Your First Work Assignment

I’m now going to give you a work assignment, similar to what you might get as a professional programmer. The
assignment will be to convert the list of features I give you into a complete little game that I may buy. Your job is to take
myvaguedescriptionsofthingsIwantandmakesomethingIcanuse.
  The purpose of this exercise is to see if you have grasped the concepts you have learned so far. We only have 2
  exercisesafterthis,butthis willbeyourlastactualassignedpieceofcoding.



Review What You Know

At this pointyoushould knowhow to do the following:

   •Createclassesandstructureroomsfromthem.
   •Throwandraiseexceptions.

   •Usefunctions,variables,dictionaries,lists,andtuples.

     •Turnauser’sinputintoalistoftuplesusingalexiconscanner.

     •TurnthelistoftuplesintoaSentenceyoucananalyzeusingaparser.

  Makesureyouknowhowtodothesethings as youwillbeusingthemtocompletethisassignment.



Implementing A Feature List

 Typically when you work on software you will be given a list vague and inconsistent features they want. This sucks, I
 won’t lie to you. Typically people have no ability to think clearly about the things they want, and even less ability to
 describethem.

  As a programmer, it is your job to take the vague things they tell you and work with them to create something they
  want. Infact,sometimes you willhave aproblem articulating whatyou want.

  The best way toimplementa feature listlikethis is tofollowthis pattern:

    1.Dumpeverything outoftheperson’s headwithoutcriticizing orjudgingtheideas.

    2.Asyoudump,writethesedowninaspreadsheetoronindexcards.
      3. Take a break, collect all the features and go back through to prioritize them into MUST (have) or NICE (to
    have).

    4.Sortthelistsothatyoucansee whatis MUSTvs. whatis NICE to have.
    5. Pick apiece ofthe MUST work,and startworking on it.




                                                                                                                      147
Learn Python The Hard Way, Release 1.0




      6. After about a week, show the person who wants the software your, and repeat this process again based on your

        newfeedback.

 Thispatterncanbefoundinoneformoranotherindifferent"methodologies"programmersusetoorganizetheirwork.

 I’m going to give you a list of features that I want in my game, and I’ve already prioritized them so this is just the
 MUST requirements. Yourjobis tospend one week workingonthelistand gettingitdone.




 The Feature List


      • Iwantagamethatissetonanalienspaceship.

      • The gameshould have ahumanhero who has to escapefrom theclutches ofan alien race who has enslaved him.

      • The game willbe atextadventuregame,likethat bear and broadswordgameyoudid.Ilike games likethat.

      • Oh,lasers.Totallygottahavelasers.

      • Butnottoopowerfullasers.Itshouldbehardtofinishthegame.

      • But nottoo hard tofinishthe game,just righttokeep players interested. Youknow,likeWorlf of

        Warcraft.IhearpeoplemaketonsofmoneyoffWoW.

      • Theshipshould have about10 rooms atfirst,then we wantto expandthem.

      • I’dliketo be abletochangethe description ofthe rooms withoutchangingthecode. Canyou dothat?

      • My friendsays farms are big now,sohaveascene wherethere’s afarm andstuff.

      • The aliens should besomekindof Mafia aliens. Mafia stuffis huge nowtoo.

      • Ishould be ableto move around with realsentences like"go north", "open door", etc.

      • It’s alrightifthe way therooms arelaid outis incode,but players willneed aprinted map. Can youkeeptrack

        ofthemap?

      • Thereneedstobeastorybehindthis,andmaybealoveinterest.

      • Probably acouple ofgeek culturereferences. But noStar Trek!Ok,firstseasonis coolbut nothing afterthat.

      • Iwant to be abletoinstalliton my computer with pythonsocanyou makeitinstallfrom asetup.py? That’ll

        makeiteasytopackagelater.




 Tips On Working The List
148                                                                        Exercise 50: Your First Work Assignment

      1.Makeyourmap,characters,andstoryfirstonpaper.
Exercise 51: Reviewing Your Game

  You worked hard on your Mafia Alien Slave Ship game. You made a great story, filled out rooms, created a nice game
  engine, and got it working. You are now going to get your game reviewed by a real user and take notes on what they
  find wrong. This is called "usability testing" and it helps you get good feedback on your game and find new bugs you
  didn’tanticipate.

 Whenyou wroteyourgameyou probably only tested thethings youknew about.Theproblem is someoneelsedoesn’tknow
 how your game is structured, so they’ll try weird things you wouldn’t have thought they’d do. The only way to findthese
 weirdactionsis toactuallyputyourgamebeforeahumanandletthemtrashit.

 Find one person, preferably a relative or a friend. You could even get together with a bunch of other people going
 through this book and have a little sharing session to try out your games. Turn it into a competition even. Anything to get
 peopletotryyourgamein-person.



 How To Study A User

   Studyingauseris easy.Puttheminfrontofyourgameandwatchtwothings:

   1.Thescreenwhiletheyuseit.

   2. Their face while they use it.
    Sitataslightanglesoyoucanglanceatbothwhilethey play yourgame. This willhelpyouseehowthey are reacting toyour
    gameby watchingtheirface.

   Let them play your game, but have them talk out loud about your game. They will probably not give you feedback if
   you donottellthem totalk while they play, butifyou getthem totalk andplaythey’lltellyouallsorts ofthings.

 Once they are playing and talking, take notes on paper and do not judge or argue. Just write down what they say and
 continue. You want their honest feedback to your game and taking their comments personally will mean you do not get
 realfeedback.

Let them struggle with parts they have a problem with, then help them to move things forward. You should be writing down
parts that aretoohard, broken, too difficultto navigate, and anything thatis just plainconfusing.

  Finally, thank them for helping you out and review what you found with them. They’ll usually want to do it again if you
  dothat,andit’sjustpolite.



 Implement The Changes

With your list of defects you will make a new list of things you have to change. Spend one week changing them and try to
getyourfriend(s)toreviewyour gameonemoretime.




                                                                                                                     149
Learn Python The Hard Way, Release 1.0




Whether they enjoyed your game or not doesn’t matter. What does matter is you have completed a full project with
vague specifications and got feedback from a person, then fixed your game to meet their demands. Your game can suck
hard,butyouatleastwroteone.

Take this lesson seriously. Even though there is no code, it is probably the most important less you can have. It teaches you
thatsoftwareis writtenforpeople,socaringabouttheiropinions isimportant.




 150                                                                            Exercise 51: Reviewing Your Game
Learn python

More Related Content

Similar to Learn python (20)

PDF
python 34💭.pdf
AkashdeepBhattacharj1
 
PDF
python notes.pdf
RohitSindhu10
 
PPT
Python week 1 2020-2021
Osama Ghandour Geris
 
PDF
Notes1
hccit
 
PPT
Python week 2 2019 2020 for g10 by eng.osama ghandour
Osama Ghandour Geris
 
PPTX
Python for beginner, learn python from scratch.pptx
olieee2023
 
PPTX
Python-Certification-Training-Day-1-2.pptx
muzammildev46gmailco
 
PDF
Python Programming - II. The Basics
Ranel Padon
 
PPTX
made it easy: python quick reference for beginners
SumanMadan4
 
PDF
Python Tutorial For Beginners | Python Crash Course - Python Programming Lang...
Edureka!
 
PPTX
Python programing
hamzagame
 
DOCX
python isn't just a snake
geekinlibrariansclothing
 
PPTX
PPT_1_9102501a-a7a1-493e-818f-cf699918bbf6.pptx
myatminsoe180
 
PPTX
Bikalpa_Thapa_Python_Programming_(Basics).pptx
Bikalpa Thapa
 
PPTX
Python
MeHak Gulati
 
PDF
python.pdf
BurugollaRavi1
 
PDF
Python for Beginners - Simply understand programming concepts
Macowtdy
 
PPTX
Python Basics
primeteacher32
 
DOCX
Python Math Concepts Book
Rohan Karunaratne
 
PDF
pyton Notes1
Amba Research
 
python 34💭.pdf
AkashdeepBhattacharj1
 
python notes.pdf
RohitSindhu10
 
Python week 1 2020-2021
Osama Ghandour Geris
 
Notes1
hccit
 
Python week 2 2019 2020 for g10 by eng.osama ghandour
Osama Ghandour Geris
 
Python for beginner, learn python from scratch.pptx
olieee2023
 
Python-Certification-Training-Day-1-2.pptx
muzammildev46gmailco
 
Python Programming - II. The Basics
Ranel Padon
 
made it easy: python quick reference for beginners
SumanMadan4
 
Python Tutorial For Beginners | Python Crash Course - Python Programming Lang...
Edureka!
 
Python programing
hamzagame
 
python isn't just a snake
geekinlibrariansclothing
 
PPT_1_9102501a-a7a1-493e-818f-cf699918bbf6.pptx
myatminsoe180
 
Bikalpa_Thapa_Python_Programming_(Basics).pptx
Bikalpa Thapa
 
Python
MeHak Gulati
 
python.pdf
BurugollaRavi1
 
Python for Beginners - Simply understand programming concepts
Macowtdy
 
Python Basics
primeteacher32
 
Python Math Concepts Book
Rohan Karunaratne
 
pyton Notes1
Amba Research
 

Recently uploaded (9)

PDF
ExpoGestão 2025 - Networking – O Poder das Conexões Humanas
ExpoGestão
 
PPTX
Understanding Emotional Intelligence: A Comprehensive Overview
siddharthjaan
 
PPTX
LESSON 1 IN PHILOSOPHY- INTRODUCTION TO PHILOSOPHY
MaimaiAlleraAcpal
 
PDF
The Story of Al-Fitra by Mr. Saidi Adam Younes
ademyounessaidi
 
PPTX
Free Preparation and Survival Apps that can save your life
Bob Mayer
 
PPTX
Impact_of_Power_Outages_Presentation.pptx
mansisingh27077
 
PPTX
AAM - NQAS Orientation CHALLANGES & SOLUTION 24 & 25 FEB24.pptx
minikashyap9528
 
PPTX
Remote_Work_Productivity_Strategies.pptx
MuhammadUzair504018
 
PDF
UCSP-Quarter1_M5.pdf POLITICS AND POLITICL
jaredcagampan86
 
ExpoGestão 2025 - Networking – O Poder das Conexões Humanas
ExpoGestão
 
Understanding Emotional Intelligence: A Comprehensive Overview
siddharthjaan
 
LESSON 1 IN PHILOSOPHY- INTRODUCTION TO PHILOSOPHY
MaimaiAlleraAcpal
 
The Story of Al-Fitra by Mr. Saidi Adam Younes
ademyounessaidi
 
Free Preparation and Survival Apps that can save your life
Bob Mayer
 
Impact_of_Power_Outages_Presentation.pptx
mansisingh27077
 
AAM - NQAS Orientation CHALLANGES & SOLUTION 24 & 25 FEB24.pptx
minikashyap9528
 
Remote_Work_Productivity_Strategies.pptx
MuhammadUzair504018
 
UCSP-Quarter1_M5.pdf POLITICS AND POLITICL
jaredcagampan86
 
Ad

Learn python

  • 1. Exercise 1: A Good First Program Remember, you should have spent a good amount of time in Exercise 0 learning how to install a text editor, run the 1 print editor, run the Terminal, and work with both of them. If you haven’t done that then do not go on. You will not text "Hello World!" 2 print a good time. This is the only time I’ll start an exercise with a warning that you should not skip or get ahead of have "Hello Again" 3 print yourself."I like typing this." 4 print 5 print 6 print "This is fun." 7 print 'Yay! Printing.' "I'd much rather you 'not'." Type the above into a single file named ex1.py. This is important as python works best with files ending in .py. 'I "said" do not touch this.' Warning: Do not type the numbers on the far left of these lines. Those are called "line numbers" and they are used by programmers to talk about what part of a program is wrong. Python will tell you errors related to these line numbers,butyoudonottypethemin. Then in Terminal run the file by typing: python ex1.py If you did it right then you should see the same output I have below. If not, you have done something wrong. No, the computeris notwrong. What You Should See $ python ex1.py Hello World! Hello Again I like typing this. This is fun. Yay! Printing. I'd much rather you 'not'. I "said" do not touch this. $ You may see the name of your directory before the $ which is fine, but if your output is not exactly the same, find out why
  • 2. Learn Python The Hard Way, Release 1.0 $ python ex/ex1.py File "ex/ex1.py", line 3 print "I like typing this. ^ SyntaxError: EOL while scanning string literal It’s important that you can read these since you will be making many of these mistakes. Even I make many of these mistakes.Let’slookatthisline-by-line. 1. Here we ran our command in the terminal to run the ex1.py script. 2. Python then tells us that the file ex1.py has an error on line 3. 3. It then prints this line for us. 4.Thenitputs a^(caret)charactertopointatwheretheproblemis.Noticethemissing"(double-quote)character? 5. Finally, it prints out a "SyntaxError" and tells us something about what might be the error. Usually these are very cryptic,butifyoucopy that textinto asearch engine,you willfindsomeoneelse who’s hadthaterrorand youcanprobablyfigureouthowtofixit. Extra Credit You will also have Extra Credit. The Extra Credit contains things you should try to do. If you can’t, skip it and come backlater. Forthisexercise,trythesethings: 1. Makeyourscriptprint another line. 2. Makeyourscriptprint onlyone 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. Fromnowon,Iwon’texplainhoweachexerciseworks unlessanexerciseis different. Note: An ‘octothorpe’ is also called a ‘pound’, ‘hash’, ‘mesh’, or any number of names. Pick the one that makes you chillout. 12 Exercise 1: A Good First Program
  • 3. Exercise 2: Comments And Pound Characters 1 Comments are very important in your programs. They are used to tell you what something does in English, and they 2 3 also comment,to disable you can your program if youlater. to remove them temporarily. Here’s how you use comments # A are used this is so parts of read your program need 4 inPython: after the # is ignored by python. # Anything 5 print "I could have code like this." # and the comment after is ignored 6 7 8 9 # You can also use a comment to "disable" or comment out a piece of code: # print "This won't run." print "This will run." What You Should See $ python ex2.py I could have code like this. This will run. $ Extra Credit 1. Find out if you were right about what the # character does and make sure you know what it’s called (octothorpe orpoundcharacter). 2. Take your ex2.py file and review each line going backwards. Start at the last line, and check each word in reverseagainstwhatyoushouldhavetyped. 3. Did you find more mistakes? Fix them. 4. Read what you typed above out loud, including saying each character by its name. Did you find more mistakes? Fixthem.
  • 5. Exercise 3: Numbers And Math Every programming language has some kind of way of doing numbers and math. Do not worry, programmers lie frequently about being math geniuses when they really aren’t. If they were math geniuses, they would be doing math, not writingadsandsocialnetworkgamestostealpeople’smoney. This exercise has lots of math symbols. Let’s name them right away so you know what they are called. As you type this onein,say the names.Whensayingthemfeelsboring youcanstopsayingthem.Hereare thenames: • +plus • -minus • /slash • *asterisk • %percent • <less-than • >greater-than print "I will now count my chickens:" 1 • <=less-than-equal 2 >=greater-than-equal print • "Hens", 25 + 30 / 6 print "Roosters", 100 - 25 missing? After you type in the code for this exercise, go back and figure out what each of Notice how the operations are * 3 % 4 3 thesedoesandcompletethetable.Forexample,+doesaddition. print "Now I will count the eggs:" 4 print 3 + 2 + 1 - 5 + 4 % 2 - 1 / 4 + 6 5 6 print "Is it true that 3 + 2 < 5 - 7?" 7 print 3 + 2 < 5 - 7 8 9 print "What is 3 + 2?", 3 + 2 10 print "What is 5 - 7?", 5 - 7 11 12 13 print "Oh, that's why it's False." 14 15 15 16 print "How about some more." 17 18 19 print "Is it greater?", 5 > -2
  • 6. Learn Python The Hard Way, Release 1.0 22 23 print "Is it greater or equal?", 5 >= -2 print "Is it less or equal?", 5 <= -2 What You Should See $ python ex3.py I will now count my chickens: Hens 30 Roosters 97 Now I will count the eggs: 7 Is it true that 3 + 2 < 5 - 7? False What is 3 + 2? 5 What is 5 - 7? -2 Oh, that's why it's False. How about some more. Is it greater? True Is it greater or equal? True Is it less or equal? False $ Extra Credit 1.Above eachline,usethe #to writeacommenttoyourself explaining whattheline does. 2. Remember in Exercise 0 when you started python? Start python this way again and using the above characters andwhatyouknow,usepythonasacalculator. 3. Find somethingyou need to calculate andwrite anew .py file that does it. 4. Notice the math seems "wrong"? There are no fractions, only whole numbers. Find out why by researching what a "floating point"numberis. 5. Rewrite ex3.py to use floating point numbers so it’s more accurate (hint: 20.0 is floating point). 16 Exercise 3: Numbers And Math
  • 7. Exercise 4: Variables And Names Now you can print things with print and you can do math. The next step is to learn about variables. In programming a variable is nothing more than a name for something so you can use the name rather than the something as you code. Programmers use these variable names to make their code read more like English, and because they have lousy memories. If they didn’t use good names for things in their software, they’d get lost when they tried to read their code again. If you get stuck with this exercise, remember the tricks you have been taught so far of finding differences and focusing on details: 1. Writeacomment aboveeachline explainingto yourself whatitdoes inEnglish. cars = 100 1 space_in_a_car = 4.0 2. Read your30 file backwards. drivers = .py 2 passengers = 90 3. Read your .py file out loudsaying eventhe characters. cars_not_driven = cars - drivers 3 cars_driven = drivers carpool_capacity = cars_driven * space_in_a_car 4 average_passengers_per_car = passengers / cars_driven 5 11 print 12 6 print "There are", cars, "cars available." 13 print 14 7 print "There are only", drivers, "drivers available." 15 print "There will be", cars_not_driven, "empty cars today." 16 8 print "We can transport", carpool_capacity, "people today." "We have", passengers, "to carpool today." 9 "We need to put about", average_passengers_per_car, "in each car." Note: The _ in space_in_a_car is called an underscore character. Find out how to type it if you do not 10 alreadyknow.Weusethischaracteralottoputanimaginaryspacebetweenwordsinvariablenames. What You Should See $ python ex4.py There 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 in each car. $
  • 8. Learn Python The Hard Way, Release 1.0 Traceback (most recent call last): Extra "ex4.py", File Credit line 8, in <module> / passenger average_passengers_per_car = car_pool_capacity NameError: name 'car_pool_capacity' is not defined Explain this error in your own words. Make sure you use line numbers and explain why. WhenI wrotethis programthefirsttimeIhada mistake, and pythontold me aboutitlikethis: Here’s moreextracredit: 1.Explainwhythe4.0isusedinsteadofjust4. 2. Rememberthat 4.0is a"floating point"number. Findout whatthat means. 3.Writecommentsaboveeachofthevariableassignments. 4. Makesureyouknow what = is called(equals) andthatit’s making names forthings. 5.Remember_isanunderscorecharacter. 6. Try running python as a calculator like you did before and use variable names to do your calculations. Popular variablenames arealsoi,x,andj. 18 Exercise 4: Variables And Names
  • 9. Exercise 5: More Variables And Printing Now we’ll do even more typing of variables and printing them out. This time we’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 how you makesomethingthatyour program might give to a human. Youprint them,savethemtofiles, send them to web servers,all sortsofthings. Strings are really handy, so in this exercise you will learn how to make strings that have variables embedded in them. You 1 embed variables insideShaw ' by using specialized format sequences and then putting the variables at the end with a my_name = 'Zed A. a string 2 specialsyntax35 # not a lie my_age = thattells Python,"Hey,thisis aformatstring,putthesevariables inthere." 3 my_height = 74 # inches 4 As usual,justtypethisinevenifyoudonotunderstanditandmakeitexactly thesame. my_weight = 180 # lbs 5 my_eyes = 'Blue' 6 my_teeth = 'White' 7 my_hair = 'Brown' 8 print "Let's talk about %s." % my_name 9 print print "He's %d inches tall." % my_height 10 11 print "He's %d pounds heavy." % my_weight 12 print 13 print "Actually that's not too heavy." 14 "He's got %s eyes and %s hair." % (my_eyes, my_hair) 16 "His teeth are usually %s depending on the coffee." % my_teeth 15 # this line is tricky, try to get it exactly right 17 18 print "If I add %d, %d, and %d I get %d." % ( my_age, my_height, my_weight, my_age + my_height + my_weight) What You Should See $ python ex5.py Let'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. $ 19
  • 10. Learn Python The Hard Way, Release 1.0 Extra Credit 1. Change all the variables so there isn’t the my_ in front. Make sure you change the name everywhere, not just whereyouused=tosetthem. 2. Try more format characters.%r is avery useful one. It’s like saying "print this no matterwhat". 3.SearchonlineforallofthePythonformatcharacters. 4. Try to write some variables that convert the inches and pounds to centimeters and kilos. Do not just type in the measurements.WorkoutthemathinPython. 20 Exercise 5: More Variables And Printing
  • 11. Exercise 6: Strings And Text While you have already been writing strings, you still do not know what they do. In this exercise we create a bunch of variables withcomplexstrings soyoucanseewhatthey arefor.Firstanexplanationofstrings. A stringis usually a bit oftext you want to display to someone, or "export" out ofthe program you are writing. Python knows you want something to be a string when you put either " (double-quotes) or ’ (single-quotes) around the text. You saw this many times with your use of print when you put the text you want to go to the string inside " or ’ after the print. Then Python prints it. Strings may contain the format characters you have discovered so far. You simply put the formatted variables in the string, and then a % (percent) character, followed by the variable. The only catch is that if you want multiple formats in yourstringtoprintmultiplevariables,you needto puttheminside( )(parenthesis)separatedby,(commas).It’s as if you were telling me to buy you a list of items from the store and you said, "I want milk, eggs, bread, and soup." Onlyas aprogrammerwesay,"(milk,eggs,bread,soup)". We will now type in a are %d types of people." % 10 formats, and print them. You will also practice using short x = "There whole bunch of strings, variables, 1 binary = "binary" abbreviated variable names. Programmers love saving themselves time at your expense by using annoying cryptic do_not = "don't" variablenames,solet’sgetyoustartedbeingabletoreadandwritethemearlyon. 2 y = "Those who know %s and those who %s." % (binary, do_not) 3 print x 4 print y 5 print "I said: %r." % x 6 print "I also said: '%s'." % y 7 hilarious = False 8 joke_evaluation = "Isn't that joke so funny?! %r" 9 print joke_evaluation % hilarious 10 11 w = "This is the left side of..." 12 e = "a string with a right side." 13 14 15 print w + e 16 17 18 19 20 What You Should See 21 $ python ex6.py
  • 12. Learn Python The Hard Way, Release 1.0 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?! False This is the left side of...a string with a right side. $ Extra Credit 1.Gothroughthis programand write acomment above eachline explainingit. 2.Findalltheplaces whereastringis putinsideastring.Therearefourplaces. 3. Are you sure there’s only four places? How do you know? Maybe I like lying. 4. Explainwhy addingthetwostringw andewith+ makes alonger string. 22 Exercise 6: Strings And Text
  • 13. Exercise 7: More Printing 1 print Now we are going to do alittle lamb." "Mary had a bunch of exercises where you just type code in and make it run. I won’t be explaining much 2 print 3 since it is justfleece ofwas same. The purpose is 'snow ' up your chops. See you in a few exercises, and do not skip! print "Its more the white as %s." % to build 4 Donotpaste! everywhere that Mary went." print "And 5 "." * 10 # what'd that do? end1 = "C" 6 end2 = end3 = "h" 7 end4 = end5 = "e" 8 end6 = end7 = "e" 9 end8 = end9 = "s" 10 11 end10 = end11 = "e" 12 13 end12 = "B" 14 19 15 # watch "u" that comma at the end. try removing it to see what happens 20 16 print end1 + end2 + end3 + end4 + end5 + end6, 21 17 "r" print end7 + end8 + end9 + end10 + end11 + end12 18 "g" "e" "r" What You Should See $ python Mary had a little lamb. Burger Cheese fleece was white as snow. Its $ And everywhere that Mary went. Extra Credit Forthesenextfewexercises,youwillhavetheexactsameextracredit. 1.Gobackthroughandwriteacommentonwhateachlinedoes.
  • 14. Learn Python The Hard Way, Release 1.0 2.Readeachonebackwardsoroutloudtofindyourerrors. 3.Fromnowon,whenyoumakemistakes writedownonapieceofpaperwhatkindofmistakeyoumade. 4.Whenyougotothenextexercise,look atthelastmistakes youmadeandtry nottomaketheminthis newone. 5. Remember that everyone makes mistakes. Programmers are like magicians who like everyone to think they are perfectandneverwrong,butit’s allanact.They makemistakes allthetime. 24 Exercise 7: More Printing
  • 15. Exercise 8: Printing, Printing 1 formatter = "%r %r %r %r" 2 print formatter % (1, 2, 3, 4) 3 print formatter % ("one", "two", "three", "four") print formatter % (True, False, False, True) 4 print formatter % (formatter, formatter, formatter, formatter) print formatter % ( 5 "I had this thing.", 6 "That you could type up right.", 7 "But it didn't sing.", 8 "So I said goodnight." 9 ) 10 11 12 What You Should See $ python ex8.py 1234 'one' 'two' 'three' 'four' True False False True '%r %r %r %r' '%r %r %r %r' '%r %r %r %r' '%r %r %r %r' 'I had this thing.' 'That you could type up right.' "But it didn't sing." 'So I said goodnight.' $ Extra Credit 1. Doyourchecks of your work,write downyour mistakes,try notto makethemonthe nextexercise. 2. Notice that the last line of output uses both single and double quotes for individual pieces. Why do you think thatis?
  • 16. Learn Python The Hard Way, Release 1.0 26 Exercise 8: Printing, Printing
  • 17. Exercise 9: Printing, Printing, Printing 1 # Here's some new strange stuff, remember type it exactly. 2 days = "Mon Tue Wed Thu Fri Sat Sun" 3 months = "JannFebnMarnAprnMaynJunnJulnAug" 4 print "Here are the days: ", days 5 print "Here are the months: ", months 6 print """ 7 There's something going on here. With the three double-quotes. 8 We'll be able to type as much as we like. """ 9 10 11 12 13 What You Should See $ python ex9.py Here's the days: Mon Tue Wed Thu Fri Sat Sun Here's the months: Jan Feb Mar Apr May Jun Jul Aug There's something going on here. With the three double-quotes. We'll be able to type as much as we like. $ Extra Credit 27 1. Doyourchecks of your work,write downyour mistakes,try notto makethemonthe nextexercise.
  • 18. Learn Python The Hard Way, Release 1.0 28 Exercise 9: Printing, Printing, Printing
  • 19. Exercise 10: What Was That? In Exercise 9 I threw you some new stuff, just to keep you on your toes. I showed you two ways to make a string that goes across multiple lines. In the first way, I put the characters n (back-slash n) between the names of the months. What these twocharacters dois put anew line characterintothestring at that point. This use of the (back-slash) character is a way we can put difficult-to-type characters into a string. There are plenty of these "escape sequences" available for different characters you might want to put in, but there’s a special one, the double back-slash which is just two of them . These two characters will print just one back-slash. We’ll try afewofthese sequencessoyoucanseewhatImean. Another 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 a double-quote in for the output. If you do this "I "understand" joe." then Python will get confused since it will think the " around "understand" actually ends the string. You need a way totell Pythonthatthe"insidethestring isn’tareal double-quote. inside string "I am 6'2" tall." # escape double-quote 'I am 6'2" tall.' # escape single-quote inside string To solve this problem you escape double-quotes and single-quites so Python knows to include in the string. Here’s an example: Thesecondway is by usingtriple-quotes,whichisjust"""andworks likeastring,butdoes youalsocanputasmany lines of text you as want until you type """ again. We’ll also play with these. tabby_cat = "tI'm tabbed in." 1 persian_cat = "I'm splitnon a line." backslash_cat = "I'm a cat." 2 3 fat_cat = """ I'll do a list: 4 t* Cat food t* Fishies 5 t* Catnipnt* Grass """ 12 6 print tabby_cat 13 print persian_cat 14 7 print 15 print backslash_cat 8 fat_cat What You Should See 9 10 11 Look forthetabcharacters thatyoumade.Inthis exercisethespacingis importanttogetright.
  • 20. Learn Python The Hard Way, Release 1.0 $ python ex10.py in. I'm tabbed I'm split on a line. I'm a cat. I'll do a list: * Cat food * Fishies * Catnip * Grass $ Extra Credit 1.Searchonlinetoseewhatotherescapesequencesareavailable. 2. Use "’ (triple-single-quote) instead. Can you see why you might use that instead of """? 3.Combineescapesequencesandformatstringstocreateamorecomplexformat. 4. Rememberthe %rformat? Combine %r with double-quote andsingle-quote escapes and print themout. Com- pare %r with %s. Notice how %r prints it the way you’d write it in your file, but %s prints it the way you’d like toseeit? 30 Exercise 10: What Was That?
  • 21. Exercise 11: Asking Questions Now it is time to pick up the pace. I have got you doing a lot of printing so that you get used to 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 tricky because you have learn to do two things that may not makesense right away, but trust me and do it anyway. It will makesensein afewexercises. Mostofwhatsoftwaredoesisthefollowing: 1.Takesomekindofinputfromaperson. 2. Change it. 1 3.Printoutsomethingtoshowhowitchanged. print "How old are you?", 2 So far you have only been printing, but you haven’t been able to get any input from a person, or change it. You may not 3 age = raw_input() even know what "input" means, so rather than talk about it, let’s have you do some and see if you get it. Next exercise 4 print "How tall are you?", 5 we’lldomoretoexplainit. height = raw_input() 6 print "How much do you weigh?", 7 weight = raw_input() 8 9 print "So, you're %r old, %r tall and %r heavy." % ( age, height, weight) Note: Notice that we put a , (comma) at the end of each print line. This is so that print doesn’t end the line witha newlineandgotothenextline. What You Should See $ python ex11.py How old are you? 35 How tall are you? 6'2" How much do you weigh? 180lbs So, you're '35' old, '6'2"' tall and '180lbs' heavy. $ Extra Credit
  • 22. Learn Python The Hard Way, Release 1.0 2. Canyoufind other ways to useit? Try some ofthesamples youfind. 3.Writeanother"form"likethistoask someotherquestions. 4. Related to escape sequences, try to find out why the last line has ’6’2"’ with that ’ sequence. See how the single-quoteneedstobe escapedbecause otherwiseitwouldendthestring? 32 Exercise 11: Asking Questions
  • 23. Exercise 12: Prompting People When you typed raw_input() you were typing the ( and ) characters which are parenthesis. This is similar towhenyouusedthemtodoaformatwithextravariables,asin"%s %s" % (x, y). For raw_input you can also put in a prompt to show to a person so they know what to type. Put a string that you want for the prompt inside the () sothatitlooks likethis: y = raw_input("Name? ") 1 2 This prompts the user with "Name?" and puts the result into the variable y. This is how you ask someone a question and age = raw_input("How old are you? ") 3 gettheiranswer. height = raw_input("How tall are you? ") 4 This means we can completely rewrite ouryou weigh? ") using just raw_input to do all the prompting. weight = raw_input("How much do previous exercise 5 6 print "So, you're %r old, %r tall and %r heavy." % ( age, height, weight) What You Should See $ python ex12.py How old are you? 35 How many tall are you? 6'2" How much do you weight? 180lbs So, you're '35' old, '6'2"' tall and '180lbs' heavy. $ Extra Credit 1. In Terminal where you normally run python to run your scripts, type: pydoc raw_input. Read what it says. 2. Get out of pydoc by typing q to quit. 3. Go look online for what the pydoc command does.
  • 24. Learn Python The Hard Way, Release 1.0 34 Exercise 12: Prompting People
  • 25. Exercise 13: Parameters, Unpacking, Variables In this exercise we will cover one more input method you can use to pass variables to a script (script being another 1 name for your .py files). You know how you type python ex13.py to run the ex13.py file? Well the ex13.py from sys import argv 2 partofthecommandis calledan"argument".Whatwe’lldonowis writeascriptthatalsoaccepts arguments. 3 script, first, second, third = argv 4 Type this program andI’llexplain it in detail: 5 print 6 print "The script is called:", script 7 print 8 print "Your first variable is:", first "Your second variable is:", second On line 1 we"Your what’s variable is:", third have third called an "import". This is how you add features to your script from the Python feature set. Rather than give you all the features at once, Python asks you to say what you plan to use. This keeps your programs small, but it alsoactsasdocumentationforotherprogrammerswhoreadyourcodelater. The argv is the "argument variable", a very standard name in programming. that you will find used in many other languages. This variable holds the arguments you pass to your Python script when you run it. In the exercises you will get to playwiththismoreandseewhathappens. Line 3 "unpacks" argv so that, rather than holding all the arguments, it gets assigned to four variables you can work with: script, first, second, and third. This may look strange, but "unpack" is probably the best word to describe what it does. It just says, "Take whatever is in argv, unpack it, and assign it to all of these variables on the left inorder." After that wejust print them out like normal. Hold Up! Features Have Another Name I call them "features here" (these little things you import to make your Python program do more) but nobody else calls them features. I just used that name because I needed to trick you into learning what they are without jargon. Before youcancontinue,youneed to learn their real name:modules. From now on we will be calling these "features" that we import modules. I’ll say things like, "You want to import the sys module."They are alsocalled "libraries"byother programmers, but let’s juststick withmodules.
  • 26. Learn Python The Hard Way, Release 1.0 What You Should See Runtheprogramlikethis: python ex13.py first 2nd 3rd This iswhatyoushouldseewhenyoudoafewdifferentruns withdifferentarguments: $ python ex13.py first 2nd 3rd The script is called: ex/ex13.py Your first variable is: first Your second variable is: 2nd Your third variable is: 3rd $ python ex13.py cheese apples bread The script is called: ex/ex13.py Your first variable is: cheese Your second variable is: apples Your third variable is: bread You can actuallyreplace "first", "2nd", and "3rd"with anythree things. You do not have to give theseparameters $ python ex13.py Zed A. Shaw either,you can give any 3strings youwant: The script is called: ex/ex13.py Your first variable is: Zed python second variable is: A. Your ex13.py stuff I like python third variable is: Shaw Your ex13.py anything 6 7 If you do not runit correctly, then you will get an error likethis: python ex13.py first 2nd Traceback (most recent call last): File "ex/ex13.py", line 3, in <module> script, first, second, third = argv ValueError: need more than 3 values to unpack This happens whenyou do not put enough arguments onthe command whenyou runit (inthis casejustfirst 2nd). Notice when Irun itI give itfirst 2nd 3rd, which caused it to give an error about "need more than 3 values to unpack"tellingyou thatyou didn’t give it enough parameters. Extra Credit 1. Try giving fewer than three arguments toyourscript.Seethaterroryou get? Seeifyoucan explainit. 2. Write a script that has fewer arguments and one that has more. Make sure you give the unpacked variables good names. 36 Exercise 13: Parameters, Unpacking, Variables 3. Combine raw_input with argv to make a script that gets more input from a user. 4.Rememberthatmodules giveyoufeatures.Modules.Modules.Rememberthis becausewe’llneeditlater.
  • 27. Exercise 14: Prompting And Passing 1 from sys import argv Let’s do one exercise that uses argv and raw_input together to ask the user something specific. You will need this for 2 3 the next exercise where we learn to read and write files. In this exercise we’ll use raw_input slightly differently by 4 script, it justprint asimpleargv having user_name = >prompt. This is similarto a game like Zork or Adventure. 5 prompt = '> ' print 6 print "Hi %s, I'm the %s script." % (user_name, script) print 7 likes "I'd like to ask you a few questions." "Do you like me %s?" % user_name 8 11 12 print "Where raw_input(prompt) = do you live %s?" % user_name 9 13 lives = raw_input(prompt) 14 10 15 16 print "What kind of computer do you have?" 17 computer = raw_input(prompt) 18 19 20 print """ 21 Alright, so you said %r about liking me. You live in %r. Not sure where that is. And you have a %r computer. Nice. """ % (likes, lives, computer) Notice though that we make a variable prompt that is set to the prompt we want, and we give that to raw_input instead of typing it over and over. Now if we want to make the prompt something else, we just change it in this one spotandrerunthescript. Veryhandy. What You Should See Whenyou runthis,rememberthatyouhave to givethescript yournameforthe argv arguments. $ python ex14.py Zed Hi Zed, I'm the ex14.py script. I'd like to ask you a few questions. Do you like me Zed? > yes Where do you live Zed? > America What kind of computer do you have?
  • 28. Learn Python The Hard Way, Release 1.0 > Tandy Alright, so you said 'yes' about liking me. You live in 'America'. Not sure where that is. And you have a 'Tandy' computer. Nice. Extra Credit 1. Find out whatZork and Adventure were. Try to find acopyand play it. 2. Change the prompt variable to something else entirely. 3.Addanotherargumentanduseitinyourscript. 4. Make sure you understand how I combined a """ style multi-line string with the % format activator as the last print. 38 Exercise 14: Prompting And Passing
  • 29. Exercise 15: Reading Files Everything you’ve learned about raw_input and argv is so you can start reading files. You may have to play with this exercise the most to understand what’s going on, so do it carefully and remember your checks. Working with files is aneasy waytoeraseyourworkifyouarenotcareful. This exercise involves writing two files. One is your usual ex15.py file that you will run, but the other is named ex15_sample.txt. This second file isn’t a script but a plain text file we’ll be reading in our script. Here are the contentsofthatfile: 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 from sys import argv name ex15_sample.txt into our script. "Hard coding" means putting some bit of information that should come 1 from script, filename = right in our program. That’s bad because we want it to load other files later. The solution is the user as a string argv touse argv andraw_input to ask the user whatfilethey wantinstead of"hard coding"thefile’s name. 2 txt = open(filename) 3 4 print "Here's your file %r:" % filename print txt.read() 5 12 6 print "I'll also ask you to type it again:" 13 txt_again = = raw_input("> ") file_again open(file_again) 14 7 15 print txt_again.read() 8 9 A few fancy things are going on inthis file,so let’s break it down realquick: 10 11 Line 1-3 should be a familiar use of argv to get a filename. Next we have line 5 where we use a new command open. Right now, run pydoc open and read the instructions. Notice how like your own scripts and raw_input, it takes a parameterandreturnsavalueyoucansettoyourownvariable.Youjustopenedafile. Line 7 we print a little line, but on line 8 we have something very new and exciting. We call a function on txt. What you got back from open is a file, and it’s also got commands you can give it. You give a file a command by using the . (dot or period), the name of the command, and parameters. Just like with open and raw_input. The difference is that when you say txt.read() you are saying, "Hey txt! Do your read command with no parameters!" Theremainderofthefileis moreofthesame,butwe’llleavetheanalysis toyouintheextracredit.
  • 30. Learn Python The Hard Way, Release 1.0 What You Should See Imadeafilecalled"ex15_sample.txt"andranmyscript. $ python ex15.py ex15_sample.txt Here'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. I'll also ask you to type it again: > 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. $ Extra Credit Thisis abigjumpsobesureyoudothisextracreditas bestyoucanbeforemovingon. 1.AboveeachlinewriteoutinEnglishwhatthatlinedoes. 2. If you are not sure ask someone for help or search online. Many times searching for "python THING" will find answers for whatthat THINGdoes in Python.Trysearchingfor "python open". 3. I usedthe name "commands"here, but they arealsocalled "functions"and "methods".Search around online tosee what other peopledoto definethese. Donot worry ifthey confuseyou.It’s normalfor aprogrammerto confuseyouwiththeirvastextensiveknowledge. 4. Get rid of the part from line 10-15 where you use raw_input and try the script then. 5. Use only raw_input and try the script that way. Think of why one way of getting the filename would be better thananother. 6. Run pydoc file and scroll down until you see the read() command (method/function). See all the other ones youcan use? Skiptheones that have__ (two underscores)in frontbecausethoseare junk. Try some of 40 theothercommands. Exercise 15: Reading Files 7. Startup python again and use open from the prompt. Notice how you can open files and run read on them rightthere?
  • 31. Exercise 16: Reading And Writing Files If you did the extra credit from the last exercise you should have seen all sorts of commands (methods/functions) you can givetofiles.Here’sthelistofcommandsIwantyoutoremember: • close - Closes the file. Like File->Save.. in your editor. •read-Reads thecontents ofthefile,youcanassigntheresulttoavariable. • readline -Readsjust oneline of a text file. •truncate-Emptiesthefile,watchoutifyoucareaboutthefile. from sys import argv to the file. • write(stuff) - Writes stuff 1 For script, filename = argv commands you need to know. Some of them take parameters, but we do not really now these are the important careabout that. Youonly need torememberthat writetakes a parameter of astringyou want to writeto thefile. 2 Let’susesomeofthistomakeasimplelittletexteditor: 3 print "We're going to erase %r." % filename print "If you don't want that, hit CTRL-C (^C)." 4 print "If you do want that, hit RETURN." 5 raw_input("?") 6 14 7 print "Truncating the file. print "Opening the file..." Goodbye!" 15 target.truncate() target = open(filename, 'w ') 16 8 17 print "Now I'm going to ask you for three lines." 9 18 19 10 20 11 line1 = raw_input("line 1: ") 21 12 line2 = raw_input("line 2: ") 22 13 line3 = raw_input("line 3: ") 23 24 25 print "I'm going to write these to the file." 26 27 28 29 target.write(line1) 30 target.write("n") target.write(line2) target.write("n") target.write(line3) target.write("n") 41
  • 32. Learn Python The Hard Way, Release 1.0 32 33 print "And finally, we close it." target.close() 31 That’s a large file, probably the largest you have typed in. So go slow, do your checks, and make it run. One trick is to getbits ofitrunningatatime.Getlines1-8running,then5more,thenafewmore,etc.,untilit’salldoneandrunning. What You Should See There are actually twothings you willsee, firstthe output ofyour new script: $ python ex16.py test.txt We'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: To all the people out there. line 2: I say I don't like my hair. line 3: I need to shave it off. I'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 and check it out. Neat right? Extra Credit 1. If you feel you do not understand this, go back through and use the comment trick to get it squared away in your mind.OnesimpleEnglishcommentaboveeachlinewillhelpyouunderstand,oratleastletyouknowwhatyou needtoresearchmore. 2. Write a script similar to the last exercise that uses read and argv to read the file you just created. 3. There’s too much repetition in this file. Use strings, formats, and escapes to print out line1, line2, and line3 with just one target.write() command instead of 6. 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 explicitlysayyou wantto writea file. 42 Exercise 16: Reading And Writing Files
  • 33. Exercise 17: More Files from sys import argv things with files. We’re going to actually write a Python script to copy one file to another. It’ll Now let’s do a few more 1 from os.path but willgiveyousomeideas about otherthings youcan do withfiles. bevery short import exists 2 script, from_file, to_file = argv 3 4 print "Copying from %s to %s" % (from_file, to_file) 5 6 # we could do these two on one line too, how? input = open(from_file) 7 indata = input.read() 8 print "The input file is %d bytes long" % len(indata) 9 10 print "Does the output file exist? %r" % exists(to_file) 11 print "Ready, hit RETURN to continue, CTRL-C to abort." 12 13 raw_input() 14 15 16 output = open(to_file, 'w ') 17 output.write(indata) 18 19 20 print "Alright, all done." 21 22 23 output.close() 24 input.close() You should immediately notice that we import another handy command named exists. This returns True if a file exists, based on it’s name in a string as an argument. It returns False if not. We’ll be using this function in the second halfofthis book to dolots of things, butright nowyou shouldsee howyoucanimport it. Using import is a way to get tons of free code other better (well, usually) programmers have written so you do not havetowriteit. What You Should See
  • 34. Learn Python The Hard Way, Release 1.0 Ready, hit RETURN to continue, CTRL-C to abort. Alright, all done. $ cat copied.txt To all the people out there. I say I don't like my hair. I need to shave it off. $ It should work with any file. Try a bunch more and see what happens. Just be careful you do not blast an important file. Warning: Did you see that trick I did with cat? It only works on Linux or OSX, sorry Windows people! Extra Credit 1. Go read up on Python’s import statement, and start python to try it out. Try importing some things and see if you can get it right. It’s alright if you do not. 2. This script is really annoying. There’s no need to ask you before doing the copy, and it prints too much out to thescreen.Trytomakeitmorefriendlytousebyremovingfeatures. 3.Seehowshortyoucan makethescript.Icould makethis 1 linelong. 4. Notice at the end of the WYSS I used something called cat? It’s an old command that "con*cat*enates" files together,but mostly it’s justan easy way toprint afiletothescreen. Type man cattoread aboutit. 5. Windows people, find the alternative to cat that Linux/OSX people have. Do not worry about man since there is nothing like that. 6. Find out why you had to do output.close() in the code. 44 Exercise 17: More Files
  • 35. Exercise 18: Names, Variables, Code, Functions Big 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 different ideas about how they work and what they do, but I will give you the simplest explanationyoucanuserightnow. Functionsdothreethings: 1.They namepiecesofcodethewayvariablesnamestringsandnumbers. 2. Theytakearguments the way yourscripts take argv. # this3. one is and #2 they let you make your own "mini scripts"or "tiny commands". Using #1 like your scripts with argv 1 def print_two(*args): You can create a function by using the word def in Python. I’m going to have you make four different functions that 2 arg1, arg2 = args worklikeyourscripts,andthenshowyouhoweachoneisrelated. 3 print "arg1: %r, arg2: %r" % (arg1, arg2) 4 # ok, that *args is actually pointless, we can just do this 5 def print_two_again(arg1, arg2): 6 print "arg1: %r, arg2: %r" % (arg1, arg2) 7 # this just takes one argument 8 def print_one(arg1): 9 print "arg1: %r" % arg1 10 11 12 # this one takes no arguments 13 def print_none(): 14 15 print "I got nothin'." 16 17 18 19 20 21 print_two("Zed","Shaw ") 22 print_two_again("Zed","Shaw ") print_one("First!") print_none() Let’s break down the first function, print_two which is the most similar to what you already know from making scripts:
  • 36. Learn Python The Hard Way, Release 1.0 3. Then we tell it we want *args (asterisk args) which is a lot like your argv parameter but for functions. This has to go inside () parenthesisto work. 4. Then we endthis line with a: colon, andstart indenting. 5. After the colon all the lines that are indented 4 spaces will become attached to this name, print_two. Our firstindentedlineisonethatunpacks thearguments thesameas withyourscripts. 6. To demonstratehowit works weprintthese arguments out,justlike we wouldin ascript. Now, the problem with print_two is that it’s not the easiest way to make a function. In Python we can skip the whole unpacking args and just use the 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 one argument in print_one. Finally you have a function that has no arguments in print_none. Warning: This is very important. Do not get discouraged right now if this doesn’t quite make sense. We’re going to do a few exercises linking functions to your scripts and show you how to make more. For now just keep $ python ex18.py thinking"miniscript" whenIsay "function" andkeepplaying withthem. arg1: 'Zed', arg2: 'Shaw' arg1: 'Zed', arg2: 'Shaw' arg1: 'First!' I got nothin'. $ What You can see howSee Right away you Should a function works. Notice that you used your functions the way you use things like exists, open, and other "commands". In fact, I’ve been tricking you because in Python those "commands" are just functions.Thismeansyoucanmakeyourowncommandsandusetheminyourscriptstoo. Ifyouruntheabovescriptyoushouldsee: Extra Credit Write out a function checklist for later exercises. Write these on an index card and keep it by you while you completetherestoftheseexercises oruntilyoufeelyoudonotneedit: 1. Did you start your function definition with def? 2.Doesyourfunctionnamehaveonlycharactersand_ (underscore)characters? 3.Didyouputanopenparenthesis(rightafterthefunctionname? 4.Didyouputyourarguments aftertheparenthesis (separatedby commas? 5.Didyoumakeeachargumentunique(meaningnoduplicatednames). 6.Didyouputacloseparenthesisandacolon):afterthearguments? 7. Didyouindent alllines ofcodeyou wantinthe function4 spaces? No more, noless. 46 Exercise 18: Names, Variables, Code, Functions 8. Did you "end" your function by going back to writing with no indent (dedenting we call it)? And whenyourun(aka"use"or"call")afunction,checkthesethings:
  • 37. Learn Python The Hard Way, Release 1.0 1. Did youcall/use/run this function bytyping its name? 2. Did you put(character afterthe name to runit? 3.Didyouputthevaluesyouwantintotheparenthesisseparatedbycommas? 4. Did you endthe function callwith a )character. Use these two checklists on the remaining lessons until you do not need them anymore. Finally,repeatthisafewtimes: "To ‘run’, ‘call’, or ‘use’afunction all mean the same thing." Extra Credit 47
  • 38. Learn Python The Hard Way, Release 1.0 48 Exercise 18: Names, Variables, Code, Functions
  • 39. Exercise 19: Functions And Variables Functions may have been a mind-blowing amount of information, but do not worry. Just keep doing these exercises and 1 def goingthroughyourchecklistfromthelastexercise andyou willeventually getit. 2 cheese_and_crackers(cheese_count, boxes_of_crackers): 3 There is one tiny pointhave %d cheeses!" not have realized which we’ll reinforce right now: The variables in your print "You though that you might % cheese_count 4 functionarenotconnectedtothevariablesinyourscript.Here’s anexercisetogetyouthinkingaboutthis: print "You have %d boxes of crackers!" % boxes_of_crackers 5 print "Man that's enough for a party!" 6 print "Get a blanket.n" 7 print "We can just give the function numbers directly:" 8 cheese_and_crackers(20, 30) 9 10 11 12 print "OR, we can use variables from our script:" 13 14 amount_of_cheese = 10 15 amount_of_crackers = 50 16 17 18 cheese_and_crackers(amount_of_cheese, amount_of_crackers) 19 20 21 22 23 print "We can even do math inside too:" 24 cheese_and_crackers(10 + 20, 5 + 6) print "And we can combine the two, variables and math:" cheese_and_crackers(amount_of_cheese + 100, amount_of_crackers + 1000) This shows all different ways we’re able to give our function cheese_and_crackers the values it needs to print them. We can give it straight numbers. We can give it variables. We can give it math. We can even combine math and variables. In a way, the arguments to a function are kind of like our = character when we make a variable. In fact, if you can use = to namesomething,youcanusually passittoafunctionasanargument. What You Should See
  • 40. Learn Python The Hard Way, Release 1.0 $ python ex19.py We 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. $ Extra Credit 1.Goback throughthescriptandtypeacommentaboveeachlineexplaininginEnglishwhatitdoes. 2.Startatthebottomandreadeachlinebackwards,sayingalltheimportantcharacters. 3. Writeatleast one morefunctionofyour owndesign, andrunit10different ways. 50 Exercise 19: Functions And Variables
  • 41. Exercise 20: Functions And Files 1 from sys import argv 2 3 script, input_file checklist for functions, then do this exercise paying close attention to how functions and files can Remember your = argv 4 worktogethertomakeusefulstuff. def print_all(f): 5 print f.read() 6 7 def rewind(f): 11 8 f.seek(0) def print_a_line(line_count, f): 12 13 9 print line_count, f.readline() 14 15 10 16 current_file = open(input_file) 17 18 19 20 print "First let's print the whole file:n" 21 22 23 print_all(current_file) 24 25 26 print "Now let's rewind, kind of like a tape." 27 28 29 rewind(current_file) 30 31 32 print "Let's print three lines:" 33 current_line = 1 print_a_line(current_line, current_file) current_line = current_line + 1 print_a_line(current_line, current_file) current_line = current_line + 1 print_a_line(current_line, current_file) 51 Pay close attention to how we pass in the current line number each time we run print_a_line.
  • 42. Learn Python The Hard Way, Release 1.0 To all the people out there. I say I don't like my hair. I need to shave it off. Now let's rewind, kind of like a tape. Let's print three lines: 1 To all the people out there. 2 I say I don't like my hair. 3 I need to shave it off. $ Extra Credit 1.Gothroughand write Englishcomments for eachlineto understand what’s goingon. 2. Each time print_a_line is run you are passing in a variable current_line. Write out what current_line is equal to on each function call, and trace how it becomes line_count in print_a_line. 4.Findeachplaceafunctionisused,andgocheckits deftomakesurethatyouaregivingittherightarguments. 5. Research online what the seek function for file does. Try pydoc file and see if you can figure it out fromthere. 6.Researchtheshorthandnotation+=andrewritethescripttousethat. 52 Exercise 20: Functions And Files
  • 43. Exercise 21: Functions Can Return Something You have been using the = character to name variables and set them to numbers or strings. We’re now going to blow your def add(a, b): mind again by showing you how to use = and a new Python word return to set variables to be a value from a function. 1 There willbeone thingtopay close %d" % (a, b) typethis in: print "ADDING %d + attentionto,butfirst 2 return a + b 3 4 def subtract(a, b): 5 print "SUBTRACTING %d - %d" % (a, b) 6 return a - b 7 def multiply(a, b): 8 print "MULTIPLYING %d * %d" % (a, b) 9 10 return a * b 11 12 13 def divide(a, b): 14 15 print "DIVIDING %d / %d" % (a, b) 16 17 return a / b 18 19 20 21 22 23 print "Let's do some math with just functions!" 24 25 26 age = add(30, 5) 27 height = subtract(78,4) 28 weight = multiply(90, 2) 29 iq = divide(100, 2) 30 31 32 print "Age: %d, Height: %d, Weight: %d, IQ: %d" % (age, height, weight, iq) 33 # A puzzle for the extra credit, type it in anyway.
  • 44. Learn Python The Hard Way, Release 1.0 3. Then we tell Python to dosomething kind of backward: we returnthe addition of a +b. You might saythis as, "I add a andb thenreturnthem." 4.Python adds the two numbers.Then whenthefunction ends any linethat runs it willbe able toassignthis a + b resultto avariable. As with many other things in this book, you should take this real slow, break it down and try to trace what’s going on. To helpthere’sextracredittogetyoutosolveapuzzleandlearnsomethingcool. What You Should See $ python ex21.py Let's do some math with just functions! ADDING 30 + 5 SUBTRACTING 78 - 4 MULTIPLYING 90 * 2 DIVIDING 100 / 2 Age: 35, Height: 74, Weight: 180, IQ: 50 Here is a puzzle. DIVIDING 50 / 2 MULTIPLYING 180 * 25 SUBTRACTING 74 - 4500 ADDING 35 + -4426 That becomes: -4391 Can you do it by hand? $ Extra Credit 1. If you aren’t really sure what return does, try writing a few of your own functions and have them return some values.Youcanreturnanythingthatyoucanputtotherightofan=. 2. Attheend ofthescriptis apuzzle.I’m takingthereturnvalue ofonefunction,and usingitas the argumentof another function. I’m doing this in a chain so that I’m kind of creating a formula using the functions. It looks really weird,butifyourunthescriptyoucanseetheresults.Whatyoushoulddois try tofigureoutthenormal formulathatwouldrecreatethissamesetofoperations. 3. Once you have the formula worked out for the puzzle, get in there and see what happens when you modify the partsofthefunctions.Try tochangeitonpurposetomakeanothervalue. 4. Finally,dotheinverse. Write out asimple formula and usethefunctions inthesame way to calculateit. This exercise might really whack your brain out, but take it slow and easy and treat it like a little game. Figuring out puzzles likethis is what makes programming fun,so I’llbe giving you more little problems like this as wego. 54 Exercise 21: Functions Can Return Something
  • 45. 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 WYSS or Extra Credit either. In fact, this exerciseislikeonegiantExtraCredit.I’mgoingtohaveyoudoaformofreviewwhatyouhavelearnedsofar. First, go back through every exercise you have done so far and write down every word and symbol (another name for ‘character’)thatyouhaveused.Makesureyourlistofsymbolsis complete. Next to each word or symbol, write its name and what it does. If you can’t find a name for a symbol in this book, then look for it online. If you do not know what a word or symbol does, then go read about it again and try using it in some code. You may run into a few things you just can’t find out or know, so just keep those on the list and be ready to look them up whenyoufindthem. Once you have your list, spend a few days rewriting the list and double checking that it’s correct. This may get boring but pushthroughandreallynailitdown. Once you have memorized the list and what they do, then you should step it up by writing out tables of symbols, their names, and what they do from memory. When you 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." What You are Learning It’s important when you are doing a boring mindless memorization exercise like this to know why. It helps you focus on a goalandknowthepurposeofallyourefforts. In this exercise you are learning the names of symbols so that you can read source code more easily. It’s similar to learningthealphabetandbasicwords ofEnglish,exceptthisPythonalphabethas extrasymbolsyoumightnotknow. Just take it slow and do not hurt your brain. Hopefully by now these symbols are natural for you so this isn’t a big effort. It’s best to take 15 minutes at a time with your list and then take a break. Giving your brain a rest will help you learn fasterwithlessfrustration. 55
  • 46. Learn Python The Hard Way, Release 1.0 56 Exercise 22: What Do You Know So Far?
  • 47. Exercise 23: Read Some Code You should have spent last week getting your list of symbols straight and locked in your mind. Now you get to apply this to another week reading code on the internet. This exercise will be daunting at first. I’m going to throw you in the deep end for a few days and have you just try your best to read and understand some source code from real projects. The goal isn’t to get youtounderstandcode,buttoteachyouthefollowingthreeskills: 1.FindingPythonsourcecodeforthingsyouneed. 2.Readingthroughthecodeandlookingforfiles. 3.Tryingtounderstandcodeyoufind. At your level you really do not have the skills to evaluate the things you find, but you can benefit from getting exposure and seeinghowthingslook. When you do this exercise, think of yourself as an anthropologist, trucking through a new land with just barely enough of the local language to get around and survive. Except, of course, that you will actually get out alive because the internet isn’t a jungle. Anyway. Here’swhatyoudo: 1. Go to bitbucket.org withyour favorite webbrowser and searchfor "python". 2. Avoid any project with "Python 3" mentioned. That’ll only confuse you. 3. Pick arandom projectandclick on it. 4. Click on the Source tab and browse through the list of files and directories until you find a .py file (but not setup.py,that’suseless). 5.Startatthetopandreadthroughit,takingnotes onwhatyouthinkitdoes. 6.Ifany symbols orstrangewords seemtointerestyou,writethemdowntoresearchlater. That’s it. Your job is to use what you know so far and see if you can read the code and get a grasp of what it does. Try skimming the code first, and then read it in detail. Maybe also try taking very difficult parts and reading each symbol you knowoutloud. Nowtryseveralthreeothersites: • github.com • launchpad.net • koders.com On each of these sites you may find weird files ending in .c so stick to .py files like the ones you have written in this book. A final fun thing to do is use the above four sources of Python code and type in topics you are interested in instead of "python". Search for "journalism", "cooking", "physics", or anything you are curious about. Chances are there’s some codeoutthereyoucoulduserightaway. 57
  • 48. Learn Python The Hard Way, Release 1.0 58 Exercise 23: Read Some Code
  • 49. Exercise 24: More Practice You are getting to the end of this section. You should have enough Python "under your fingers" to move onto learning about howprint "Let's practice everything." should do some more practice. This exercise is longer and all about building programming really works, but you print 'You'd need to know 'bout escapes with that 1 upstamina. The next exercise willbesimilar. Dothem, getthem exactly right,anddoyourchecks. do n newlines and t tabs.' 2 poem = """ 3 tThe lovely world with logic so firmly planted 4 cannot discern n the needs of love nor comprehend passion from intuition and 5 requires an explanation nttwhere there is none. 6 """ 7 print "--------------" 8 print poem print "--------------" 9 10 11 12 13 five = 10 - 2 + 3 - 6 14 print "This should be five: %s" % five 15 16 17 def secret_formula(started): 18 19 jelly_beans = started * 500 20 21 jars = jelly_beans / 1000 22 23 crates = jars / 100 24 25 return jelly_beans, jars, crates 26 27 28 29 30 31 start_point = 10000 32 beans, jars, crates = secret_formula(start_point) 33 34 35 print "With a starting point of: %d" % start_point 36 print "We'd have %d beans, %d jars, and %d crates." % 59 37 start_point = start_point / 10
  • 50. Learn Python The Hard Way, Release 1.0 What You Should See $ python ex24.py tabs. newlines and Let's practice everything. -------------- You'd need to know 'bout escapes with that do The lovely world with logic so firmly planted cannot discern intuition the needs of love nor comprehend passion from and requires an explanation where there is none. -------------- This should be five: 5 With a starting point of: 10000 We'd have 5000000 beans, 5000 jars, and 50 crates. We can also do that this way: We'd have 500000 beans, 500 jars, and 5 crates. $ Extra Credit 1.Makesuretodoyourchecks:readitbackwards,readitoutloud,putcomments aboveconfusingparts. 2.Break the fileonpurpose, then runittosee whatkinds of errors you get. Makesureyoucanfix it. 60 Exercise 24: More Practice
  • 51. Exercise 25: Even More Practice We’re going to do some more practice involving functions and variables to make sure you know them well. This exerciseshouldbestraightforwardforyoutotypein,breakdown,andunderstand. def break_words(stuff):is a little different. You won’t be running it. Instead you will import it into your python and run the However, this exercise 1 functions yourself. """This function will break up words for us.""" 2 words = stuff.split(' ') 3 return words 4 5 def sort_words(words): 6 """Sorts the words.""" 7 return sorted(words) 8 def print_first_word(words): 9 10 """Prints the first word after popping it off.""" 11 12 word = words.pop(0) 13 14 print word 15 16 17 def print_last_word(words): 18 19 """Prints the last word after popping it off.""" 20 21 word = words.pop(-1) 22 23 print word 24 25 26 27 def sort_sentence(sentence): 28 29 """Takes in a full sentence and returns the sorted words.""" 30 31 words = break_words(sentence) 32 33 return sort_words(words) 34 35 def print_first_and_last(sentence): """Prints the first and last words of the sentence."""
  • 52. Learn Python The Hard Way, Release 1.0 What You Should See In this exercise we’re going to interact with your .py file inside the python interpreter you used periodically to do calculations. $ Here’s what it looks like whenI do it: python 1 Python 2.5.1 (r251:54863, Feb 6 2009, 19:02:12) [GCC 4.0.1 (Apple Inc. build 5465)] on darwin 2 Type "help", "copyright", "credits" or "license" for more information. >>> import ex25 3 >>> sentence = "All good things come to those who wait." >>> words = ex25.break_words(sentence) 4 >>> words ['All', 'good', 'things', 'come', 'to', 'those', 'who', 'wait.'] 5 >>> sorted_words = ex25.sort_words(words) >>> sorted_words 6 ['All', 'come', 'good', 'things', 'those', 'to', 'wait.', 'who'] >>> ex25.print_first_word(words) 7 All >>> ex25.print_last_word(words) 8 wait. >>> wrods 9 Traceback (most recent call last): 10 11 File "<stdin>", line 1, in <module> 12 NameError: name 'wrods' is not defined 13 >>> words 14 ['good', 'things', 'come', 'to', 'those', 'who'] 15 >>> ex25.print_first_word(sorted_words) 16 All 17 >>> ex25.print_last_word(sorted_words) 18 19 who 20 >>> sorted_words 21 ['come', 'good', 'things', 'those', 'to', 'wait.'] 22 >>> sorted_words = ex25.sort_sentence(sentence) 23 >>> sorted_words 24 ['All', 'come', 'good', 'things', 'those', 'to', 'wait.', 'who'] 25 >>> ex25.print_first_and_last(sentence) 26 All 27 wait. 28 >>> ex25.print_first_and_last_sorted(sentence) 29 All 30 who 31 >>> ^D 32 $ 33 34 Let’s break this downline by lineto makesure youknow what’s going on: 35 36 • Line 5 you import your ex25.py python file, just like other imports you have done. Notice you do not need to 37 38 put the .py at the end to import it. When you do this you make a module that has all your functions in it to 39 use. • Line 6 you made a sentence to work with. • Line 7 you use the ex25 module and call your first function ex25.break_words. The . (dot, period) 62 Exercise 25: Even More Practice symbol is how you tell python, "Hey, inside ex25 there’s a function called break_words and I want to run it."
  • 53. Learn Python The Hard Way, Release 1.0 • Line 8 we just type words, and python will print out what’s in that variable (line 9). It looks weird but this is a list which you will learn about later. • Lines 10-11 we do the same thing with ex25.sort_words to get a sorted sentence. • Lines 13-16 we use ex25.print_first_word and ex25.print_last_word to get the first and last word printedout. • Line 17 is interesting. I made a mistake and typed the words variable as wrods so python gave me an error on Lines18-20. • Line 21-22 is where we print the modified words list. Notice that since we printed the first and last one, those wordsarenowmissing. Theremaininglines areforyoutofigureoutandanalyzeintheextracredit. Extra Credit 1. Take the remaining lines of the WYSS output and figure out what they are doing. Make sure you understand how you are runningyour functions inthe ex25module. 2. Try doing this: help(ex25) and also help(ex25.break_words). Notice how you get help for your module, and how the help is those odd """strings you put after each function in ex25? Those special strings are called documentation comments and we’llbeseeing more of them. 3. Type ex25. is annoying. A shortcut is to do your import like this: from ex25 import * which is like saying,"Importeverythingfromex25."Programmerslikesayingthings backwards.Startanewsessionandsee howall yourfunctionsarerightthere. 4. Try breaking your file and see what it looks like in python when you use it. You will have to quit python with CTRL-D(CTRL-Z on windows)to be able toreload it. Extra Credit 63
  • 54. Learn Python The Hard Way, Release 1.0 64 Exercise 25: Even More Practice
  • 55. Exercise 26: Congratulations, Take A Test! You are almost done with the first half of the book. The second half is where things get interesting. You will learn logicandbeabletodousefulthingslikemakedecisions. Before you continue, I have a quiz for you. This quiz will be very hard because it requires you to fix someone else’s code. When you are a programmer you often have to deal with another programmer’s code, and also with their arrogance.Theywillveryfrequentlyclaimthattheircodeisperfect. These programmers are stupid people who care little for others. A good programmer assumes, like a good scientist, that there’s always some probability their code is wrong. Good programmers start from the premise that their software is broken and then work to rule out all possible ways it could be wrong before finally admitting that maybe it really is the other guy’s code. In this exercise, you will practice dealing with a bad programmer by fixing a bad programmer’s code. I have poorly copied exercises 24 and 25 into a file and removed random characters and added flaws. Most of the errors are things Python will tell you, while some of them are math errors you should find. Others are formatting errors or spelling mistakesinthestrings. Alloftheseerrors areverycommonmistakesallprogrammersmake.Evenexperiencedones. Your job in this exercise is to correct this file. Use all of your skills to make this file better. Analyze it first, maybe printing it out to edit it like you would a school term paper. Fix each flaw and keep running it and fixing it until the scriptruns perfectly.Try nottogethelp,andinsteadifyougetstuck takeabreak andcomeback toitlater. Evenifthistakesdaystodo,bustthroughitandmakeitright. Finally,the pointofthis exercise isn’ttotypeitin,buttofix anexistingfile.To dothat,youmustgoto: •http://learnpythonthehardway.com/wiki?name=Exercise26 Copy-pastethe code intoa filenamed ex26.py. This is the only time youare allowed tocopy-paste. 65
  • 56. Learn Python The Hard Way, Release 1.0 66 Exercise 26: Congratulations, Take A Test!
  • 57. Exercise 27: Memorizing Logic Today is the day you start learning about logic. Up to this point you have done everything you possibly can reading and writingfiles,totheterminal,andhavelearnedquitealotofthemathcapabilitiesofPython. From now on, you will be learning logic. You won’t learn complex theories that academics love to study, but just the simple basiclogicthatmakesrealprograms workandthatrealprogrammersneedeveryday. Learning logic has to come after you do some memorization. I want you to do this exercise for an entire week. Do not falter. Even if you are bored out of your mind, keep doing it. This exercise has a set of logic tables you must memorize to make it easierforyoutodothelaterexercises. I’m warning you this won’t be fun at first. It will be downright boring and tedious but this is to teach you a very important skill you will need as a programmer. You will need to be able to memorize important concepts as you go in your life. Most of these concepts will be exciting once you get them. You will struggle with them, like wrestling a squid, then oneday snapyou willunderstandit. Allthat work memorizingthe basics pays off biglater. Here’s a tip on how to memorize something without going insane: Do a tiny bit at a time throughout the day and mark down what you need to work on most. Do not try to sit down for two hours straight and memorize these tables. This won’t work. Your brainwill really only retainwhateveryoustudiedinthefirst15 or 30minutes anyway. Instead, what you should do is create a bunch of index cards with each column on the left on one side (True or False) and the column on the right on the back. You should then pull them out, see the "True or False" and be able to immediately say "True!"Keep practicing until youcan dothis. Once you can do that, start writing out your own truth tables each night into a notebook. Do not just copy them. Try to do them from memory, and when you get stuck glance quickly at the ones I have here to refresh your memory. Doing this will trainyourbraintorememberthewholetable. Donotspendmorethanoneweekonthis,becauseyouwillbeapplyingitasyougo. The Truth Terms In python we have the following terms (characters and phrases) for determining if something is "True" or "False". Logic on a computer is all about seeing if some combination of these characters and some variables is True at that point intheprogram. • and • or • not • !=(not equal) • ==(equal) • >=(greater-than-equal) 67
  • 58. Learn Python The Hard Way, Release 1.0 • <=(less-than-equal) • True • False You actually have run into these characters before, but maybe not the phrases. The phrases (and, or, not) actually work the wayyouexpectthemto,justlikeinEnglish. NOT True? The Truth True notFals e Tables False notTrue OR True? TrueorFalse True Wewillnowusethesecharacters tomakethetruthtablesyouneedtomemorize. TrueorTrue True FalseorTrue True FalseorFalse False AND True? TrueandFalse False TrueandTrue True FalseandTrue False FalseandFalse False NOTOR True? not(TrueorFalse) False not(TrueorTrue) False not(FalseorTrue) False not(FalseorFalse) True NOTAND True? not(TrueandFalse) True not(TrueandTrue) False not(FalseandTrue) True not(FalseandFalse) True != True? 1!=0 True 1!=1 False 0!=1 True 0!=0 False == True? 1==0 False 1==1 True 0==1 False 0==0 True 68 Exercise 27: Memorizing Logic
  • 59. Exercise 28: Boolean Practice The logic combinations you learned from the last exercise are called "boolean" logic expressions. Boolean logic is used everywhere in programming. They are essential fundamental parts of computation and knowing them very well is akintoknowingyourscalesinmusic. In this exercise you will be taking the logic exercises you memorized and start trying them out in python. Take each of these logic problems, and write out what you 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 your terminal and type them 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 == 1 11. "test" != "testing" 17. not ("testing" == "testing" and "Zed" == "Cool Guy") 12. "test" == 1 18. 1 == 1 and not ("testing" == 1 or 1 == 0) 13. not (True == "bacon" and not (3 == 4 or 3 == 3) 19. "chunky" and False) 14.20. 3 == == andand 0("testing" == "testing" or "Python" == not (1 3 1 not != 1) "Fun") I 15. also give you a1trick to help == 1000) out the more complicated ones toward the end. will not (10 == or 1000 you figure Whenever you see these boolean logic statements, you can solve them easily by this simple process: 16. not (1 != 10 or 3 == 4) 1. Find equality test (== or !=) and replace it with its truth. 69
  • 60. Learn Python The Hard Way, Release 1.0 2.Findeachand/orinsideaparenthesisandsolvethosefirst. 3.Findeachnotandinvertit. 4.Findany remainingand/orandsolveit. 5. When you are done you should have True or False. I will demonstratewithavariationon#20: 3 != 4 and not ("testing" != "test" or "Python" == "Python") (a) 3 != 4 is True: True and not ("testing" != "test" or "Python" == Here’s megoingthrougheachofthesteps andshowingyouthetranslationuntilI’veboileditdowntoasingleresult: "Python") (b) "testing" != "test" is True: True and not (True or "Python" == 1. Solve each equality test: "Python") (c) "Python" == "Python": True and not (True or True) 2. Find each and/or in parenthesis (): (a) (True or True) is True: True and not (True) 3. Find each not and invert it: (a) not (True) is False: True and False 4. Find any remaining and/or and solve them: (a) True and False is False Withthatwe’redoneandknowtheresultisFalse. Warning: The more complicated ones may seem very hard at first. You should be able to give a good first stab at solving them, but do not get discouraged. I’m just getting you primed for more of these "logic gymnastics" so that later cool stuff is much easier. Just stick with it, and keep track of what you get wrong, but do not worry that it’s not gettinginyourheadquiteyet.It’llcome. What You Should See After you have tried to guess at these, this is what your session with python might look like: $ python Python 2.5.1 (r251:54863, Feb 6 2009, 19:02:12) [GCC 4.0.1 (Apple Inc. build 5465)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> True and True True 70 >>> 1 == 1 and 2 == 2 Exercise 28: Boolean Practice True
  • 61. Learn Python The Hard Way, Release 1.0 Extra Credit 1. There are a lot of operators in Python similar to != and ==. Try to find out as many "equality operators" as you can.Theyshouldbelike:<or<=. 2.Write outthenames ofeachoftheseequality operators.For example,Icall!= "notequal". 3. Play with the python by typing out new boolean operators, and before you hit enter try to shout out what it is. Donotthink about it,justthefirstthingthatcomes to mind. Writeitdownthen hitenter, andkeeptrack of how many yougetrightandwrong. 4. Throw away that pieceofpaperfrom #3 away soyoudo notaccidentally try touseitlater. Extra Credit 71
  • 62. Learn Python The Hard Way, Release 1.0 72 Exercise 28: Boolean Practice
  • 63. Exercise 29: What If people the20 script of Python you will enter, which introduces you to the if-statement. Type this in, make it run Here is = next 1 cats = right,and then we’lltry seeifyour practice has paid off. exactly 30 dogs = 15 2 3 4 if people < cats: 5 print "Too many cats! The world is doomed!" 6 if people > cats: 7 print "Not many cats! The world is saved!" 8 9 if people < dogs: 10 11 print "The world is drooled on!" 12 13 14 if people > dogs: 15 16 print "The world is dry!" 17 18 19 20 21 22 dogs += 5 23 24 25 if people >= dogs: 26 27 print "People are greater than equal to dogs." 28 29 if people <= dogs: print "People are less than equal to dogs." if people == dogs: 73 print "People are dogs."
  • 64. Learn Python The Hard Way, Release 1.0 Extra Credit In this extra credit, try to guess what you think the if-statement is and what it does. Try to answer these questions in yourownwordsbeforemovingontothenextexercise: 1. What do you think the if does to the code under it? 2.Whydoesthecodeundertheifneedtobeindented4spaces? 3. What happens if it isn’t indented? 4. Can you put other boolean expressions from Ex. 26 in the if-statement? Try it. 5. What happens if you change the initial variables for people, cats, and dogs? 74 Exercise 29: What If
  • 65. Exercise 30: Else And If In the last exercise you worked out some if-statements, and then tried to guess what they are and how they work. Before you learn more I’ll explain what everything is by answering the questions you had from extra credit. You did the extracreditright? 1. What do you think the if does to the code under it? An if statement creates what is called a "branch" in the code.It’s kindof likethosechooseyour own adventure books whereyouareaskedtoturntoone pageifyou make one choice, and another if you go a different direction. The if-statement tells your script, "If this booleanexpressionis True,thenrunthecodeunderit,otherwiseskipit." 2. Why does the code under the if need to be indented 4 spaces? A colon at the end of a line is how you tell Python youare going tocreate a new "block"of code, and then indenting 4 spaces tells Python what lines of code are in that block. This is exactly the same thing you did when you made functions in the first half of the book. 3. What happens if it isn’t indented? If it isn’t indented, you will most likely create a Python error. Python expects youtoindentsomethingafteryouendalinewitha:(colon). 1 people = 30 2 cars4.= 40you put other boolean expressions from Ex. 26 in the if statement? Try it. Yes you can, and they can be Can 3 buses = 15 4 as complex as youlike,althoughreallycomplex things generally arebadstyle. 5 5. What happens if you change the initial variables for people, cats, and dogs? Because you are comparing if cars > people: 6 numbers, if you change the numbers, different if-statements will evaluate to True and the blocks of code print "We should take the cars." elif cars < people: 7 under them will run. Go back and put different numbers in and see if you can figure out in your head what "We should not take the cars." print 8 blocks of code will run. else: 13 9 if buses > "We can't decide." cars: Compare my answers to your answers, and make sure you really understand the concept of a "block" of code. This is print 14 10 importantforwhenyoudothenextexercisewhereyouwritealltheparts ofif-statements thatyoucanuse. 15 print "That's too many buses." 11 16 12 Typethisoneinandmakeitworktoo. elif buses < cars: 17 print "Maybe we could take the buses." else: 75
  • 66. Learn Python The Hard Way, Release 1.0 18 19 20 print "We still can't decide." 21 22 23 if people > buses: print "Alright, let's just take the buses." else: print "Fine, let's stay home then." What You Should See $ python ex.py We should take the cars. Maybe we could take the buses. Alright, let's just take the buses. $ Extra Credit 1. Try to guess what elif and else are doing. 2. Change the numbers of cars, people, and buses and then trace through each if-statement to see what will be printed. 3. Trysome morecomplex boolean expressions likecars > people and buses < cars. 4.AboveeachlinewriteanEnglishdescriptionofwhatthelinedoes. 76 Exercise 30: Else And If
  • 67. Exercise 31: Making Decisions In the first half of this book you mostly just printed out things and called functions, but everything was basically in a straight line. Your scripts ran starting at the top, and went to the bottom where they ended. If you made a function you could run that function later, but it still didn’t have the kind of branching you need to really make decisions. Now that you have if, 1 else, andelifyoucan starttodark room with two doors. print "You enter a makescripts thatdecidethings. Do you go through door #1 or door #2?" 2 3 In the last = raw_input("> out a simple set of tests asking some questions. In this script you will ask the user questions and door script you wrote ") 4 makedecisionsbasedontheiranswers.Writethisscript,and thenplaywith itquite alottofigure itout. if door == "1": What do you do?" 5 print "There's a giant bear here eating a cheese cake. 6 print "1. Take the cake." 7 print "2. Scream at the bear." 12 8 if bear == "1": 13 bear = raw_input("> ") 14 9 print "The bear eats your face off. Good job!" 15 10 elif bear == "2": 16 11 17 print "The bear eats your legs off. Good job!" 18 else: 19 elif door == "2": 20 print "Well, doing %s is endless abyss at Bear runs away." % bear "You stare into the probably better. Cthuhlu's retina." 21 print "1. Blueberries." 22 "2. Yellow jacket clothespins." 23 print print "3. Understanding revolvers yelling melodies." 24 25 print insanity = raw_input("> ") 26 27 if insanity == "1" or insanity == "2": 28 Good job!" 29 print "Your body survives powered by a mind of jello. 30 else: 31 Good job!" 32 else: print "The insanity rots your eyes into a pool of muck. 33 Good job!" print "You stumble around and fall on a knife and die. A key point here is that you are now putting the if-statements inside if-statements as code that can run. Thisisverypowerfuland canbe usedtocreate"nested"decisions,where one branch leads toanother andanother. Makesureyou understandthis conceptofif-statements inside if-statements.Infact, dothe extracredittoreally nail 77
  • 68. Learn Python The Hard Way, Release 1.0 it. What You Should See $ python ex31.py You enter a dark room with two doors. Do you go through door #1 or door #2? >1 There's a giant bear here eating a cheese cake. What do Hereismeplayingthislittleadventuregame.Idonotdosowell. 1. Take the cake. you do? 2. Scream at the bear. >2 The bear eats your legs off. Good job! $ python ex31.py You enter a dark room with two doors. Do you go through >1 There's a giant bear here eating a cheese cake. What do 1. Take the cake. 2. Scream at the bear. >1 The bear eats your face off. Good job! door #1 or door #2? $ python ex31.py you do? You enter a dark room with two doors. Do you go through >2 You stare into the endless abyss at Cthuhlu's retina. 1. Blueberries. 2. Yellow jacket clothespins. 3. Understanding revolvers yelling melodies. >1 $ python ex31.py Your body survives powered by a mind of jello. Good job! You enter a dark room with two doors. Do you go through door #1 or door #2? >2 You stare into the endless abyss at Cthuhlu's retina. 1. Blueberries. 2. Yellow jacket clothespins. 3. Understanding revolvers yelling melodies. door #1 or door #2? >3 The insanity rots your eyes into a pool of muck. Good job! $ python ex31.py You enter a dark room with two doors. Do you go through door > stuff You stumble around and fall on a knife and die. Good job! $ python ex31.py You enter a dark room with two doors. Do you go through door #1 or door #2? >1 There's a giant bear here eating a cheese cake. What do you do? 1. Take the cake. 2. Scream at the bear. > #1 or door #2? apples Well, doing apples is probably better. Bear runs away. 78 Exercise 31: Making Decisions
  • 69. Learn Python The Hard Way, Release 1.0 Extra Credit Makenewparts ofthegameandchangewhatdecisions peoplecanmake.Expandthegameoutas muchas youcan before itgetsridiculous. Extra Credit 79
  • 70. Learn Python The Hard Way, Release 1.0 80 Exercise 31: Making Decisions
  • 71. Exercise 32: Loops And Lists You 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 combine all the other things you have learned with if-statements and boolean expressionstomakeyourprogramsdosmartthings. However, programs also need to do repetitive things very quickly. We are going to use a for-loop in this exercise to build and print various lists. When you do the exercise, you will start to figure out what they are. I won’t tell you right now.Youhavetofigureitout. Before you can use a for-loop, you need a way to store the results ofloops somewhere. The best way to do this is with a list. A list is exactly what its name says, a container of things that are organized in order. It’s not complicated; you just havetolearnanewsyntax.First,there’s howyoumakealist: hairs = ['brown', 'blond', 'red'] eyes = ['brown', 'blue', 'green'] weights = [1, 2, 3, 4] What you do is start the list with the [ (left-bracket) which "opens" the list. Then you put each item you want in the list separated by commas, just like when you did function arguments. Lastly you end the list with a ] (right-bracket) to indicatethatit’s over.Pythonthentakes thislistandallitscontents,andassigns themtothevariable. Warning: This is where things get tricky for people who can’t program. Your brain has been taught that the world is flat. Remember in the last exercise where you put if-statements inside if-statements? That probably made your the_count = [1, 2, 3, 4, 5] brain hurt because most people do not ponder how to "nest" things inside things. In programming this is all over the 1 fruits = ['apples', 'oranges', 'pears', 'apricots'] change = [1, 'pennies', 2, 'dimes', 3, 'quarters'] place. You will find functions that call other functions that have if-statements that have lists withlists inside lists. 2 If you see a structure like this that you can’t figure out, take out pencil and paper and break it down manually bit by bit 3 # this first kind of for-loop goes through a list for number in the_count: untilyouunderstandit. 4 print "This is count %d" % number 5 Wenowwillbuildsomelistsusingsomeloopsandprintthemout: 6 # same as above for fruit in fruits: 7 print "A fruit of type: %s" % fruit 8 9 # also we can go through mixed lists too # notice we have to use %r since we don't know what's in it 81 10 11 for i in change: 12 13 print "I got %r" % i
  • 72. Learn Python The Hard Way, Release 1.0 18 19 20 # we can also build lists, first start with an empty one 21 17 elements = [] 22 23 24 # then use the range function to do 0 to 20 counts 25 for i in range(0, 6): 26 27 print "Adding %d to the list." % i 28 29 # append is a function that lists understand elements.append(i) # now we can print them out too for i in elements: print "Element was: %d" % i What You Should See $ python ex32.py This is count 1 This is count 2 This is count 3 This is count 4 This is count 5 A fruit of type: apples A fruit of type: oranges A fruit of type: pears A fruit of type: apricots I got 1 I got 'pennies' I got 2 I got 'dimes' I got 3 I got 'quarters' Adding 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: 0 Element was: 1 Element was: 2 Element was: 3 Element was: 4 Element was: 5 $ 82 Exercise 32: Loops And Lists Extra Credit
  • 73. Learn Python The Hard Way, Release 1.0 3. Find the Python documentation on lists and read about them. What other operations can you do to lists besides append? Extra Credit 83
  • 74. Learn Python The Hard Way, Release 1.0 84 Exercise 32: Loops And Lists
  • 75. Exercise 33: While Loops Now to totally blow your mind with a new loop, the while-loop. A while-loop will keep executing the code block underitaslongasabooleanexpressionisTrue. Wait, you have been keeping up with the terminology right? That if we write a line and end it with a : (colon) then that tells Python to start a new block of code? Then we indent and that’s the new code. This is all about structuring your programs so that Python knows what you mean. If you do not get that idea then go back and do some more work with if-statements,functions,andthefor-loopuntilyougetit. Later on we’ll have some exercises that will train your brain to read these structures, similar to how we burned boolean expressionsintoyourbrain. 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. It keeps doing this until the expression is False. Here’s the problem with while-loops: Sometimes they do not stop. This is great if your intention is to just keep loopinguntiltheendoftheuniverse.Otherwiseyoualmostalways wantyourloops toendeventually. Toavoidtheseproblems,there’ssomerulestofollow: 1. Make sure that you use while-loops sparingly. Usually a for-loop is better. 2.Review yourwhilestatements andmakesurethatthethingyouaretestingwillbecomeFalse atsome point. i = 0 1 numbers = [] 3. When in doubt, print out your test variable at the top and bottom of the while-loop to see what it’s doing. In 2 this exercise,6: will learn the while-loop by doing the above three things: while i < you 3 print "At the top i is %d" % i 4 numbers.append(i) 5 6 i = i + 1 7 print "Numbers now: ", numbers 8 print "At the bottom i is %d" % i 9 10 11 12 13 print "The numbers: " 14 85 15 16 for num in numbers: print num
  • 76. Learn Python The Hard Way, Release 1.0 What You Should See Numbers now: [0] $ python ex.py At the bottom is i 0 is 1 At the top i At the top i is 1 Numbers now: [0, 1] At the bottom i is 2 At the top i is 2 Numbers now: [0, 1, 2] At the bottom i is 3 At the top i is 3 Numbers now: [0, 1, 2, 3] At the bottom i is 4 At the top i is 4 Numbers now: [0, 1, 2, 3, 4] At the bottom i is 5 At the top i is 5 5] Numbers now: [0, 1, 2, 3, 4, At the bottom i is 6 The numbers: 0 1 2 3 4 5 Extra Creditwhile loop to a function that you can call, and replace 10 in the test (i 1. Convert this < 10) with a variable. 2. Now usethisfunctionto rewrite thescript totry different numbers. 3.Addanothervariable tothefunction arguments thatyoucanpass inthatlets you changethe + 1online8so youcanchangehowmuchitincrementsby. 4.Rewritethescriptagaintousethis functiontoseewhateffectthathas. 5. Now, write it to use for-loops and range instead. Do you need the incrementor in the middle anymore? Whathappensifyoudonotgetridofit? If at any time that you are doing this it goes crazy (it probably will), just hold down CTRL and hit c (CTRL-c) and the programwillabort. 86 Exercise 33: While Loops
  • 77. Exercise 34: Accessing Elements Of Lists animals = ['bear', 'tiger', 'penguin', 'zebra'] Lists are pretty useful, but unless you can get at the things in them they aren’t all that good. You can already go bear = animals[0] through the elements of a list in order, but what if you want say, the 5th element? You need to know how to access the elements ofalist.Here’s howyouwouldaccessthefirstelementofalist: You take a list of animals, and then you get the first one using 0?! How does that work? Because of the way math works, Python start its lists at 0 rather than 1. It seems weird, but there’s many advantages to this, even though it is mostly arbitrary. The best way to explain why is by showing you the difference between how you use numbers and how programmers use numbers. Imagine you are watching the four animals in our list above ([’bear’, ’tiger’, ’penguin’, ’zeebra’]) run in a race. They win in the order we have them in this list. The race was really exciting because, the animals didn’t eat each other and somehow managed to run a race. Your friend however shows up late and wants to know who won. Does yourfriendsay,"Hey,whocameinzeroth?"No,hesays, "Heysays,hey whocameinfirst?" This is because the order of the animals is important. You can’t have the second animal without the first animal, and can’t have the third without the second. It’s also impossible to have a "zeroth" animal since zero means nothing. How can you have a nothing win a race? It just doesn’t makesense. We call these kinds of numbers "ordinal"numbers, becausethey indicateanorderingofthings. Programmers, however, can’t think this way because they can pick any element out of a list at any point. To a programmer, the above list is more like a deck of cards. If they want the tiger, they grab it. If they want the zeebra, they can take it too. This need to pull elements out of lists at random means that they need a way to indicate elements consistently by an address, or an "index", and the best way to do that is tostart the indices at 0.Trust me on this, the mathis way easier for these kinds of accesses. This kind of number is a "cardinal" number and means you can pick at random, so thereneedstobea0element. So, how does this help you work with lists? Simple, every time you say to yourself, "I want the 3rd animal," you translate this "ordinal" number to a "cardinal" number by subtracting 1. The "3rd" animal is at index 2 and is the penguin. You have to do this because you have spent your whole life using ordinal numbers, and now you have to thinkincardinal.Justsubtract1andyouwillbegood. Remember:ordinal==ordered,1st;cardinal==cardsatrandom,0. Let’s practice this. Take this list of animals, and follow the exercises where I tell you to write down what animal you get for that ordinal or cardinal number. Remember if I say "first", "second", etc. then I’m using ordinal, so subtract 1. IfI give you cardinal(0,1,2)thenuseitdirectly. animals = ['bear', 'python', 'peacock', 'kangaroo', 'whale', 'platypus'] 1. The animal at 1. 2. The 3rd animal.
  • 78. Learn Python The Hard Way, Release 1.0 3. The 1st animal. 4. The animal at 3. 5. The 5th animal. 6. The animal at 2. 7. The 6th animal. 8. The animal at 4. For each of these, write out a full sentence of the form: "The 1st animal is at 0 and is a bear." Then say it backwards, "The animalat0isthe1stanimalandisabear." Useyourpythontocheckyouranswers. Extra Credit 1.Readaboutordinalandcardinalnumbersonline. 2. With what you know of the difference between these types of numbers, can you explain why this really is 2010? (Hint,youcan’tpickyearsatrandom.) 3. Writesome morelists and work outsimilarindexes untilyou cantranslatethem. 4.UsePythontocheckyouranswerstothisaswell. Warning: Programmers will tell you to read this guy named "Dijkstra" on this subject. I recommend you avoid his writings on this unless you enjoy being yelled at by someone who stopped programming at the same time programmingstarted. 88 Exercise 34: Accessing Elements Of Lists
  • 79. Exercise 35: Branches and Functions from have learned to do if-statements, functions, and arrays. Now it’s time to bend your mind. Type this in, and see You sys import exit 1 ifyoucanfigureoutwhatit’sdoing. 2 def gold_room(): 3 print "This room is full of gold. How much do you take?" 4 5 next = raw_input("> ") 6 if "0" in next or "1" in next: 7 how_much = int(next) 8 else: 9 dead("Man, learn to type a number.") 10 11 12 13 if how_much < 50: 14 15 print "Nice, you're not greedy, you win!" 16 17 exit(0) 18 19 else: 20 21 dead("You greedy bastard!") 22 23 24 25 26 def bear_room(): 27 28 print "There is a bear here." 29 30 print "The bear has a bunch of honey." 31 32 33 print "The fat bear is in front of another door." 34 35 print "How are you going to move the bear?" 36 37 bear_moved = False 89 38 39 40 41 while True:
  • 80. Learn Python The Hard Way, Release 1.0 44 45 46 print "He, it, whatever stares at you and you go insane." 47 48 print "Do you flee for your life or eat your head?" 49 50 51 52 next = raw_input("> ") 53 54 55 56 if "flee" in next: 57 58 start() 59 60 elif "head" in next: 61 62 dead("Well that was tasty!") 63 64 else: 65 66 cthulu_room() 67 68 69 70 71 72 def dead(why): 73 74 print why, "Good job!" 75 76 exit(0) def start(): print "You are in a dark room." print "There is a door to your right and left." print "Which one do you take?" next = raw_input("> ") if next == "left": bear_room() elif next == "right": cthulu_room() else: dead("You stumble around the room until you starve.") 90 Exercise 35: Branches and Functions start()
  • 81. Learn Python The Hard Way, Release 1.0 Extra Credit 1.Drawamapofthegameandhowyouflowthroughit. 2. Fix all ofyour mistakes, including spelling mistakes. 3.Writecomments forthefunctions youdonotunderstand.Rememberdoc comments? 4.Add moretothe game. Whatcan youdotobothsimplify andexpandit. 5. The gold_room has a weird way of getting you to type a number. What are all the bugs in this way of doing it? Can you make it better than just checking if "1" or "0" are in the number? Look at how int() works for clues. Extra Credit 91
  • 82. Learn Python The Hard Way, Release 1.0 92 Exercise 35: Branches and Functions
  • 83. Exercise 36: Designing and Debugging Now that you know if-statements, I’m going to give you some rules for for-loops and while-loops that will keep you out of trouble. I’m also going to give you some tips on debugging so that you can figure out problems withyour program. Finally,you aregoingtodesigna similar littlegame as in thelast exercise but withaslighttwist. Rules For If-Statements 1. Every if-statement must have an else. 2. If this else should never be run because it doesn’t make sense, then you must use a die function in the else thatprints outanerrormessageanddies,justlikewedidinthelastexercise.This willfindmany errors. 3. Never nest if-statements more than 2 deep and always try to do them 1 deep. This means if you put an if in an if then you should be looking to move that second if into another function. 4. Treat if-statements like paragraphs, where each if,elif,else grouping is like a set of sentences. Put blanklinesbeforeandafter. 5. Your boolean tests should be simple. If they are complex, move their calculations to variables earlier in your functionanduseagoodnameforthevariable. Ifyoufollowthesesimplerules,youwillstartwritingbettercodethanmostprogrammers. Goback tothelastexercise andsee ifIfollowedalloftheserules.Ifnot,fixit. Warning: Never be a slave to the rules in real life. For training purposes you need to follow these rules to make your mind strong, but in real life sometimes these 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 languagesaredifferent. 2. Use a for-loop for all other kinds of looping, especially if there is a fixed or 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 a sick person. You do not get any specific usefulinformation,andyoufindawholelotofinformationthatdoesn’thelpandisjustconfusing. 93
  • 84. Learn Python The Hard Way, Release 1.0 2. The best way to debug a program is to use print to print out the values of variables at points in the program toseewheretheygowrong. 3. Make sure parts of your programs work as you work on them. Do not write massive files of code before you try torunthem.Codealittle,runalittle,fixalittle. Homework Now write a similar game to the one that I created in the last exercise. It can be any kind of game you want in the same flavor. Spend a week on it making it as interesting as possible. For extra credit, use lists, functions, and modules (remember those from Ex. 13?) as much as possible, and find as many new pieces of Python as you can to make the gamework. There is one catch though, write up your idea for the game first. Before you start coding you must write up a map for your game.Create the rooms,monsters,and traps thattheplayer mustgothroughon paperbeforeyoucode. Onceyouhaveyourmap,try tocodeitup.Ifyoufindproblemswiththemapthenadjustitandmakethecodematch. One final word of advice: Every programmer becomes paralyzed by irrational fear starting a new large project. They then use procrastination to avoid confronting this fear and end up not getting their program working or even started. I do this. Everyone does this. The best way to avoid this is to make a list of things you should do, and then do them one atatime. Juststartdoingit,doasmallversion,makeitbigger,keepalistofthings todo,anddothem. 94 Exercise 36: Designing and Debugging
  • 85. Exercise 37: Symbol Review It’s time to review the symbols and Python words you know, and to try to pick up a few more for the next few lessons. What I’vedonehereis writtenoutallthePythonsymbolsandkeywords that areimportanttoknow. In this lesson take each keyword, and first try to write out what it does from memory. Next, search online for it and seewhatitreally does.It maybehardbecausesomeofthesearegoing to beimpossibletosearchfor,butkeep trying. If you get one of these wrong from memory, write up an index card with the correct definition and try to "correct" your memory.Ifyou justdidn’t know about it, write it down, andsave it for later. Finally, use each of these in a small Python program, or as many as you can get done. The key here is to find out what the symboldoes,makesureyougotitright,correctitifyou do not,thenuse ittolockitin. Keywords • and • del • from • not • while • as • elif • global • or • with • assert • else • if • pass • yield • break • except • import • print 95
  • 86. Learn Python The Hard Way, Release 1.0 • class • exec • in • raise • continue • finally • is • return • def • for • lambda • try Data Types For data types, write out what makes up each one. For example, with strings write out how you create a string. For numberswriteoutafewnumbers. • True • False • None • strings • numbers • floats • lists String Escapes Sequences Forstring escape sequences,usetheminstringsto makesure theydowhatyouthink they do. 96 Exercise 37: Symbol Review • • ’
  • 87. Learn Python The Hard Way, Release 1.0 • v String Formats Samethingforstringformats:usetheminsomestrings toknowwhatthey do. • %d • %i • %o • %u • %x • %X • %e • %E • %f • %F • %g • %G • %c • %r • %s • %% Operators Some of these may be unfamiliar to you, but look them up anyway. Find out what they do, and if you still can’t figure it out, save it for later. • + • - String Formats 97 • * • **
  • 88. Learn Python The Hard Way, Release 1.0 • == • != • <> • () • [] • {} • @ • , • : • • = • ; • += • -= • *= • /= • //= • %= • **= Spend about a week on this, but if you finish faster that’s great. The point is to try to get coverage on all these symbols and make sure they are locked in your head. What’s also important is to find out what you do not know so you can fix it later. 98 Exercise 37: Symbol Review
  • 89. Exercise 38: Reading Code Now go find some Python code to read. You should be reading any Python code you can and trying to steal ideas that you find. You actually should have enough knowledge to be able to read, but maybe not understand what the code does. What I’m going to teach you in this lesson is how to apply things you have learned to understand other people’s code. First, print out the code you want to understand. Yes, print it out, because your eyes and brain are more used to reading paper thancomputerscreens.Make sureyouonlyprintafew pagesatatime. Second,gothroughyourprintoutandtakenotes ofthefollowing: 1.Functionsandwhattheydo. 2.Whereeachvariableisfirstgivenavalue. 3.Any variables withthesamenames indifferentparts oftheprogram.Thesemay betroublelater. 4. Any if-statements without else clauses. Are they right? 5. Any while-loops that might not end. 6.Finally,any parts ofcodethatyoucan’tunderstandforwhateverreason. Third, once you have all of this marked up, try to explain it to yourself by writing comments as you go. Explain the functions,howtheyareused,whatvariablesareinvolved,anythingyoucantofigurethiscodeout. Lastly, on all of the difficult parts, trace the values of each variable line by line, function by function. In fact, do anotherprintoutandwriteinthemarginthevalueofeachvariablethatyouneedto"trace". Once you have a good idea of what the code does, go back to the computer and read it again to see if you find new things. Keep finding morecodeanddoing this untilyoudo not needthe printouts anymore. Extra Credit 1. Find out whata "flow chart"is and write a few. 2.Ifyoufinderrors incodeyouarereading,try tofix themandsendtheauthoryourchanges. 3. Another technique for when you are not using paper is to put # comments with your notes in the code. Some- times,thesecouldbecometheactualcommentstohelpthenextperson. 99
  • 90. Learn Python The Hard Way, Release 1.0 100 Exercise 38: Reading Code
  • 91. Exercise 39: Doing Things To Lists You have learned about lists. When you learned about while-loops you "appended" numbers to the end of a list and printed them out. There was also extra credit where you were supposed to find all the other things you can do to lists in the Python documentation. That was a while back, so go find in the book where you did that and review if you do not know whatI’mtalkingabout. 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 understand what’s going on so let’s see what we can do to lists, and how doing things with "on"themworks. When you type Python code that reads mystuff.append(’hello’) you are actually setting off a chain of events inside Python to cause something to happen to the mystuff list. Here’s how it works: 1. Python sees you mentioned mystuff and looks up that variable. It might have to look backwards to see if you createdwith=,look andseeifitis afunctionargument,ormaybeit’s aglobalvariable.Eitherway ithas tofind 2. Once it finds mystuff it then hits the . (period) operator and starts to look at variables that are a part of themystufffirst. mystuff. Since mystuff is a list, it knows that mystuff has a bunch of functions. 3. It then hits append and compares the name "append" to all the ones that mystuff says it owns. If append is inthere(itis)thenitgrabsthattouse. 4. Next Python sees the ( (parenthesis) and realizes, "Oh hey, this should be a function." At this point it calls (aka runs, executes)the functionjustlikenormally,butinsteaditcalls the function with an extra argument. 5. That extra argument is ... mylist! I know, weird right? But that’s how Python works so it’s best to just rememberitandassumethat’salright.Whathappens then,attheendofallthisisafunctioncallthatlookslike: For the most part you do not have to know that this is going on, but it helps when you get error messages from python append(mystuff, ’hello’)insteadofwhatyoureadwhichis mystuff.append(’hello’). likethis: $ python Python 2.6.5 (r265:79063, Apr 16 2010, 13:57:41) [GCC 4.4.3] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> class Thing(object): def test(hi): print "hi" >>> a = Thing() >>> a.test("hello") Traceback (most recent call last): TypeError: test() line 1, in <module>argument File "<stdin>", takes exactly 1 (2 given) >>> 101
  • 92. Learn Python The Hard Way, Release 1.0 What was all that? Well, this is me typing into the Python shell and showing you some magic. You haven’t seen class yet but we’ll get into those later. For now you see how Python said test() takes exactly 1 argument (2 given). If you see this it means that python changed a.test("hello") to test(a, "hello") and that somewheresomeonemessedupanddidn’taddtheargumentfora. That might be a lot to take in, but we’re going to spend a few exercises getting this concept firm in your brain. To kick things ten_things = "Apples Oranges Crows Telephone Light Sugar" off,here’s anexercisethatmixes stringsandlistsforallkinds offun. 1 print "Wait there's not 10 things in that list, let's fix that." 2 3 stuff = ten_things.split(' ') more_stuff = ["Day", "Night", "Song", "Frisbee", "Corn", "Banana", "Girl", "Boy"] 4 5 while len(stuff) != 10: 6 next_one = more_stuff.pop() 7 print "Adding: ", next_one 8 stuff.append(next_one) 18 9 print print "There's %d items now." % len(stuff) 19 print stuff[1] 10 20 print print "There #wewhoa! ",fancy stuff[-1] go: stuff 11 21 print stuff.pop() 12 22 print print '.join(stuff) some things with stuff." ' "Let's do # what? cool! 13 14 '#'.join(stuff[3:5]) # super stellar! 15 16 17 What You Should See $ python ex39.py Wait there's not 10 things in that list, let's fix that. Adding: Boy There's 7 items now. Adding: Girl There's 8 items now. Adding: Banana There's 9 items now. Adding: Corn There's 10 items now. There we go: ['Apples', 'Oranges', 'Crows', 'Telephone', 'Light', 'Sugar', 'Boy', 'Girl', 'Banana', 'Corn'] Let's do some things with stuff. Oranges Corn Corn Apples Oranges Crows Telephone Light Sugar Boy Girl Banana Telephone#Light 102 Exercise 39: Doing Things To Lists
  • 93. Learn Python The Hard Way, Release 1.0 Extra Credit 1. Take each function that is called, and go through the steps outlined above to translate them to what Python does. For example, ’ ’.join(things) is join(’ ’, things). 2. Translate these two ways to view the function calls in English. For example, ’ ’.join(things) reads as, "Join things with ‘ ‘ between them." Meanwhile, join(’ ’, things) means, "Call join with ‘ ‘ and things." Understand how they are really the same thing. 2. Go read about "Object Oriented Programming" online. Confused? Yeah I was too. Do not worry. You will learn enoughtobedangerous,andyoucanslowlylearnmorelater. 3. Read up on what a "class" is in Python. Do not read about how other languages use the word "class". That will only mess youup. 4. What’s the relationship between dir(something) and the "class" of something? 5. If you do not have any idea what I’m talking about do not worry. Programmers like to feel smart so they inventedObjectOrientedProgramming,nameditOOP,andthenuseditway toomuch.Ifyouthink that’s hard, youshouldtrytouse"functionalprogramming". Extra Credit 103
  • 94. Learn Python The Hard Way, Release 1.0 104 Exercise 39: Doing Things To Lists
  • 95. Exercise 40: Dictionaries, Oh Lovely Dictionaries Now I have to hurt you with another container you can use, because once you learn this container a massive world of ultra-coolwillbeyours.Itis themostusefulcontainerever:thedictionary. Python calls them "dicts", other languages call them, "hashes". I tend to use both names, but it doesn’t matter. What does matteris whatthey dowhencomparedtolists.Yousee,alistletsyoudothis: >>> things = ['a', 'b', 'c', 'd'] >>> print things[1] b >>> things[1] = 'z' >>> print things[1] z >>> print things ['a', 'z', 'c', 'd'] >>> You can use numbers to "index" into a list,meaning you can use numbers to find out what’s inlists. You shouldknow this by now, but what a dict does is let you use anything, not just numbers. Yes, a dict associates one thing to another, no matter whatitis.Takealook: >>> stuff = {'name': 'Zed', 'age': 36, 'height': 6*12+2} >>> print stuff['name'] Zed >>> print stuff['age'] 36 >>> print stuff['height'] 74 >>> stuff['city'] = "San Francisco" >>> print stuff['city'] San Francisco >>> You will see that instead of just numbers we’re using strings to say what we want from the stuff dictionary. We can alsoputnewthingsintothedictionary withstrings.Itdoesn’thavetobestringsthough,wecanalsodothis: >>> stuff[1] = "Wow " >>> stuff[2] = "Neato" >>> print stuff[1] Wow >>> print stuff[2] Neato >>> print stuff {'city': 'San Francisco', 2: 'Neato', 'name': 'Zed', 1: 'Wow', 'age': 36, 105
  • 96. Learn Python The Hard Way, Release 1.0 'height': 74} >>> Inthis oneIjustusednumbers.Icoulduseanything.Wellalmostbutjustpretendyoucanuseanythingfornow. Of course, a dictionary that you can only put things in is pretty stupid, so here’s how you delete things, with the del keyword: >>> del stuff['city'] >>> del stuff[1] >>> del stuff[2] >>> stuff {'name': 'Zed', 'age': 36, 'height': 74} >>> We’ll now do an exercise that you must study very carefully. I want you to type this exercise in and try to understand what’s going on. Itis avery interesting exercisethat willhopefully makea biglightturnoninyour headvery soon. 1 cities = {'CA': 'San Francisco', 'MI': 'Detroit', 2 3 'FL': 'Jacksonville'} 4 5 6 cities['NY '] = 'New York' def cities['OR'] = 'Portland' find_city(themap, state): 7 if state in themap: 8 return themap[state] 9 else: 13 # ok pay attention! "Not found." return 10 14 11 15 12 cities['_find'] = find_city 16 17 18 while True: 19 20 print "State? (ENTER to quit)", 21 22 state = raw_input("> ") 23 24 if not state: break # this line is the most important ever! study! city_found = cities['_find'](cities, state) print city_found Warning: Notice how I use themap instead of map? That’s because Python has a function called map, so if you try tousethatyoucanhaveproblemslater. 106 Exercise 40: Dictionaries, Oh Lovely Dictionaries What You Should See
  • 97. Learn Python The Hard Way, Release 1.0 Portland State? (ENTER to quit) > VT Not found. State? (ENTER to quit) > Extra Credit 1.Gofindthe Pythondocumentationfor dictionaries (a.k.a.dicts,dict) andtry todoeven more things to them. 2.Findoutwhatyoucan’tdowithdictionaries. Abigone is thatthey donothaveorder,sotryplayingwiththat. 3. Try doing a for-loop over them, and then try the items() function in a for-loop. Extra Credit 107
  • 98. Learn Python The Hard Way, Release 1.0 108 Exercise 40: Dictionaries, Oh Lovely Dictionaries
  • 99. Exercise 41: A Room With A View Of A Bear With A Broadsword Did you figure out the secret of the function in the dict from the last exercise? Can you explain it to yourself? Let me explain itandyoucancompareyourexplanationwithmine.Herearethelines ofcodewearetalkingabout: cities['_find'] = find_city city_found = cities['_find'](cities, state) Remember that functions can be variables too. The def find_city just makes another variable name in your current module that you can use anywhere. In this code first we are putting the function find_city into the dict cities as ’_find’. This is the same as all the others where we set states to some cities, but in this case it’s actually the functionweputinthere. Alright, so once we know that find_city is in the dict at _find, that means we can do work with it. The 2nd line of code(usedlaterinthepreviousexercise)canbebrokendownlikethis: 1. Python sees city_found = and knows we want to make a new variable. 2. It then reads cities and finds that variable, it’s a dict. 3. Then there’s [’_find’] which will index into the cities dict and pull out whatever is at _find. 4. What is at [’_find’] is our function find_city so Python then knows it’s got a function, and when it hits ( it does the function call. 5. The parameters cities, state are passed to this function find_city, and it runs because it’s called. 6. find_city then tries to look up states inside cities, and returns what it finds or a message saying it didn’t find anything. 7. Python takes what find_city returned, and finally that is what is assigned to city_found all the way at thebeginning. I’m goingto teachyou a trick. Sometimes these things read better in Englishifyou read thecode backwards, solet’s try that. Here’s howIwoulddoitforthatsameline(rememberbackwards): 1. state and city are... 2.passedasparametersto... 3. a function at... 4. ’_find’ inside... 5. the dict cities... 6. and finally assigned to city_found. Here’s anotherwaytoreadit,thistime"inside-out". 1. Find the center item of the expression, in this case [’_find’]. 109
  • 100. Learn Python The Hard Way, Release 1.0 2. Go counter-clock-wise and you have a dict cities, so this finds the element _find in cities. 3.Thatgives us afunction.Keepgoingcounter-clock-wiseandyougettotheparameters. 5. Finally, we are at the city_found =assignment,andwehaveourendresult. 4.Theparametersarepassedtothefunction,andthatreturnsaresult.Gocounter-clock-wiseagain. After decades of programming I do not eventhink aboutthese three ways toread code.I just glance at it andknow whatit means, and I can even glanceat a whole screen of code, and all the bugs and errors jump out at me. That took an incredibly long time and quite a bit more study than is sane. To get that way, I learned these three ways of reading most any programminglanguage: 1. Front to back. 2. Back to front. 3. Counter-clock-wise. Trythemoutwhenyouhaveadifficultstatementtofigureout. Let’s nowtypeinyournextexercise,andthengooverafterthat.This oneisgonnabefun. 1 from sys import exit 2 from random import randint 3 4 5 def death(): 6 7 quips = ["You died. You kinda suck at this.", 8 9 "Your mom would be proud. If she were smarter.", 10 print quips[randint(0, len(quips)-1)] 11 exit(1) "Such a luser.", 12 13 "I have a small puppy that's better at this."] 14 def princess_lives_here(): 15 16 print "You see a beautiful Princess with a shiny crown." 17 18 print "She offers you some cake." 19 20 21 22 eat_it = raw_input("> ") 23 24 25 26 if eat_it == "eat it": 27 28 print "You explode like a pinata full of frogs." 29 30 print "The Princess cackles and eats the frogs. Yum!" 31 32 33 return 'death' 34 35 36 elif eat_it == "do not eat it": 37 else: 38 print "She throws the cake at you and it cuts off your head." 39 print "The princess looks at you confused and just points at the cake." print "The last thing you see is her munching on your torso. Yum!" return 'princess_lives_here' 110 return 'death' elif eat_it == "make her eat it":
  • 101. Learn Python The Hard Way, Release 1.0 41 def gold_koi_pond(): 42 with a koi pond in the center." 43 print "There is a garden see a massive fin poke out." 44 40 45 print "You walk close and creepy looking huge Koi stares at you." 46 47 print "You peek in and a waiting for food." 48 print "It opens its mouth 49 if feed_it == "feed it": 50 51 print "The Koi jumps up, and rather than eating the cake, eats your arm." 52 feed_it = raw_input("> ") 53 print "You fall in and the Koi shrugs than eats you." 54 55 print "You are then pooped out sometime later." 56 57 return 'death' 58 59 60 elif feed_it == "do not feed it": 61 62 print "The Koi grimaces, then thrashes around for a second." 63 64 print "It rushes to the other end of the pond, braces against the wall..." 65 66 print "then it *lunges* out of the water, up in the air and over your" 67 68 69 print "entire body, cake and all." 70 71 print "You are then pooped out a week later." 72 73 return 'death' 74 75 elif feed_it == "throw it in": 76 def bear_with_sword(): 77 print "The Koi wiggles, then leaps into the air to eat the cake." 78 print "Puzzled, you are about to pick up the fish poop diamond when" 79 print "You can see it's happy, it then grunts, thrashes..." 80 print "a bear bearing a load bearing sword walks in." print "and finally rolls over and poops you get diamond into the air" diamond! Where'd a magic that!?"' 81 82 print '"Hey!raw_input("> ") give_it = That' my out and looks at you." 83 print "at your feet." 84 print "It holds "give paw if give_it == its it": 85 your hand to grab the diamond and" 86 print "The bear swipes at 87 return 'bear_with_sword' in the process. It then looks at" 88 print "rips your hand off and says, "Oh crap, sorry about that."' 89 else: 'your bloody stump print hand back on, but you collapse." 90 91 see is the bear shrug and eat you." 92 elif give_it"The to putno": annoyed and wiggles a bit." printprint tries "say gets "It == Koi your 93 94 printreturn "The bear looks shocked. "The last thing you print 'gold_koi_pond' Nobody ever told a bear" 95 96 return 'death' a broadsword 'no'. print "with It asks, " 97 print '"Is it because it's not a katana? I could go get one!"' print "It then runs off and now you notice a big iron gate." 111 print '"Where the hell did that come from?" You say.'
  • 102. Learn Python The Hard Way, Release 1.0 99 return 'big_iron_gate' 100 98 else: 101 102 103 print "The bear look puzzled as to why you'd do that." 104 105 return "bear_with_sword" 106 107 108 def big_iron_gate(): 109 110 print "You walk up to the big iron gate and see there's a handle." 111 112 open_it = raw_input("> ") 113 114 if open_it == 'open it': 115 116 117 else: print "You open it and you are free!" 118 I mean, the door's right there." 119 print "That doesn't mountains. And berries! And..." print "There are seem sensible. 120 121 return "Oh, but then the bear comes with his katana and print 'big_iron_gate' stabs you." 122 123 ROOMS = { print '"Who's laughing now!? Love this katana."' 124 'death': death, 125 126 127 'princess_lives_here': return 'death' princess_lives_here, 128 129 'gold_koi_pond': gold_koi_pond, 130 131 'big_iron_gate': big_iron_gate, 132 133 'bear_with_sword': bear_with_sword 134 } 135 136 137 138 139 def runner(map, start): next = start while True: room = map[next] print "n--------" next = room() runner(ROOMS, 'princess_lives_here') It’s alotofcode,butgothroughit,makesureitworks,playit. 112 Exercise 41: A Room With A View Of A Bear With A Broadsword What You Should See
  • 103. Learn Python The Hard Way, Release 1.0 She points to a tiny door and says, 'The Koi needs cake too.' She gives you the very last bit of cake and shoves you in. -------- There is a garden with a koi pond in the center. You walk close and see a massive fin poke out. You peek in and a creepy looking huge Koi stares at you. It opens its mouth waiting for food. > throw it in The Koi wiggles, then leaps into the air to eat the cake. You can see it's happy, it then grunts, thrashes... and finally rolls over and poops a magic diamond into the air at your feet. -------- Puzzled, you are about to pick up the fish poop diamond when a bear bearing a load bearing sword walks in. "Hey! That' my diamond! Where'd you get that!?" It holds its paw out and looks at you. > say no The bear looks shocked. Nobody ever told a bear with a broadsword 'no'. It asks, "Is it because it's not a katana? I could go get one!" It then runs off and now you notice a big iron gate. "Where the hell did that come from?" You say. -------- You walk up to the big iron gate and see there's a handle. > open it You open it and you are free! There are mountains. And berries! And... Oh, but then the bear comes with his katana and stabs you. "Who's laughing now!? Love this katana." -------- I have a small puppy that's better at this. $ Extra Credit 1. Explain how returning the nextroom works. 2.Createmorerooms,makingthegamebigger. 3. Instead of having each function print itself, learn about "doc comments". See if you can write the room descrip- Extra Credit tionasdoccomments,andchangetherunnertoprintthem. 113 4.Onceyouhavedoccomments astheroomdescription,doyouneedtohavethe functionprompteven?Havethe
  • 104. Learn Python The Hard Way, Release 1.0 114 Exercise 41: A Room With A View Of A Bear With A Broadsword
  • 105. Exercise 42: Getting Classy While it’s fun to put functions inside of dictionaries, you’d think there’d be something in Python that does this for you. There is and it’s the class keyword. Using class is how you create an even more awesome "dict with functions" than the one you made in the last exercise. Classes have all sorts of powerful features and uses that I could never go into in this book.Instead,youwilljustusethemlikethey arefancy dictionaries withfunctions. A programming language that uses classes is called an "Object Oriented Programming". This is an old style of programming where you make "things" and you "tell" those things to do work. You have been doing a lot of this. A whole lot. You just didn’tknowit. Remember whenyou weredoing this: stuff = ['Test', 'This', 'Out'] print ' '.join(stuff) You were actually using classes. The variable stuff is actually a list class. The ’ ’.join(stuff) is calling the join function of the string ’ ’ (just an empty space) is also a class, a string class. It’s all classes! def __init__(self): Well, and objects, but let’s just skip that word for now. You will learn what those are after you make some classes. self.number = 0 Howdo youmakeclasses?Verysimilar tohowyoumade theROOMSdict,buteasier: class TheThing(object): def some_function(self): print "I got called." # two def different things a add_me_up(self, more): = TheThing() self.number += more b = TheThing() return self.number a.some_function() b.some_function() print a.add_me_up(20) print a.add_me_up(20) print b.add_me_up(30) print b.add_me_up(30) print a.number print b.number
  • 106. Learn Python The Hard Way, Release 1.0 Warning: Alright, this is where you start learning about "warts". Python is an old language with lots of really ugly obnoxious pieces that were bad decisions. To cover up these bad decisions they make new bad decisions and then yell at people to adopt the new bad decisions. The phrase class TheThing(object) is an example of a bad decision. I won’t get into it right here, but you shouldn’t worry about why your class has to have (object) after its name, just type it this way all the time or other Python programmers will yell at you. We’ll get into why later. You see that self in the parameters? You know what that is? That’s right, it’s the "extra" parameter that Python creates so you can type a.some_function() and then it will translate that to really be some_function(a). Why use self? Your function has no idea what you are calling any one "instance" of TheThing or another, you just use a generic name self. That way you can write your function and it will always work. You could actually use another name rather than self but then every Python programmer on the planet would hate you, so do not. Only jerks change things like that and I taught you better. Be nice to people who have to read what you writebecausetenyearslaterallcodeishorrible. from sys import exit Next, see the __init__ function? That is how you setup a Python class with internal variables. You can set them on from random import randint 1 self with the . (period) just like I will show you here. See also how we then use this in add_me_up() later which lets you add to the self.number you created. Later you can see how we use this to add to our number and print it. 2 class Game(object): Classes are very powerful, so you should go read about them. Read everything you can and play with them. You 3 actually know how to use them, you just have to try it. In fact, I want to go play some guitar right now so I’m not goingtogiveyouanexercisetotype.Youaregoingtogowriteanexerciseusingclasses. 4 def __init__(self, start): Here’showwewoulddoexercise41usingclassesinsteadofthethingwecreated: 5 self.quips = [ 6 "You died. You kinda suck at this.", 7 "Your mom would be proud. If she were smarter.", 8 "Such a luser.", 9 "I have a small puppy that's better at this." 10 11 ] 12 13 self.start = start 14 24 def death(self): 15 25 len(self.quips)-1)] 16 26 print self.quips[randint(0, 17 27 18 def play(self): 28 exit(1) 19 29 20 next = self.start def princess_lives_here(self): 30 21 31 22 print "You see a beautiful Princess with a shiny crown." 32 23 while "She offers you some cake." print True: print "n--------" 116 room = getattr(self, next) next = room()
  • 107. Learn Python The Hard Way, Release 1.0 33 eat_it = raw_input("> ") 34 35 36 if eat_it == "eat it": 37 38 print "You explode like a pinata full of frogs." 39 40 print "The Princess cackles and eats the frogs. Yum!" 41 42 return 'death' 43 44 45 elif eat_it == "do not eat it": 46 47 print "She throws the cake at you and it cuts off your head." 48 49 50 print "The last thing you see is her munching on your torso. Yum!" 51 52 return 'death' 53 54 55 elif eat_it == "make her eat it": 56 def gold_koi_pond(self): Princess screams as you cram the cake in her mouth." print "The 57 with a koi pond in the center." 58 print "There is"Then she smilessee a cries and fin poke you for saving her." print a garden and massive thanks out." 59 60 print "You walk close and to a creepydoor and huge Koi stares needs cake too.'" print "She points tiny looking says, 'The Koi at you." 61 62 print "You peek in gives a you the very for food." of cake and shoves you in." print "She and waiting last bit 63 print "It opens 'gold_koi_pond' return its mouth 64 if feed_it == "feed it": 65 66 print "The Koi jumps up, and rather than eating the cake, eats your arm." else: 67 feed_it = raw_input("> ") 68 print "You fall in and the Koi shrugs than eats you." 69 print "The princess looks at you confused and just points at the cake." 70 print "You are then pooped out sometime later." 71 return 'princess_lives_here' 72 return 'death' 73 74 75 76 elif feed_it == "do not feed it": 77 print "The Koi grimaces, then thrashes around for a second." 78 79 80 print "It rushes to the other end of the pond, braces against the wall..." 81 82 print "then it *lunges* out of the water, up in the air and over your" 83 84 print "entire body, cake and all." 85 86 print "You are then pooped out a week later." 87 88 return 'death' 89 90 elif feed_it == "throw it in": print "The Koi wiggles, then leaps into the air to eat the cake." print "You can see it's happy, it then grunts, thrashes..." 117 print "and finally rolls over and poops a magic diamond into the air"
  • 108. Learn Python The Hard Way, Release 1.0 91 def bear_with_sword(self): 92 93 print "Puzzled, you are about to pick up the fish poop diamond when" 94 95 print "a bear bearing a load bearing sword walks in." 96 diamond! Where'd you get that!?"' 97 print '"Hey!raw_input("> ") give_it = That' my out and looks at you." 98 print "It holds "give paw if give_it == its it": 99 your hand to grab the diamond and" print "The bear swipes at 100 in the process. It then looks at" 101 print "rips your hand off and says, "Oh crap, sorry about that."' 102 103 print 'your bloody stump hand back on, but you collapse." 104 105 see is the bear shrug and eat you." 106 print "It tries to put your 107 108 elif give_it == "say no":you print "The last thing 109 110 return 'death' bear looks shocked. print "The Nobody ever told a bear" 111 112 print "with a broadsword 'no'. It asks, " 113 114 print '"Is it because it's not a katana? I could go get one!"' 115 116 print "It then runs off and now you notice a big iron gate." 117 118 print '"Where the hell did that come from?" You say.' 119 120 121 122 return 'big_iron_gate' 123 124 125 126 def big_iron_gate(self): 127 128 print "You walk up to the big iron gate and see there's a handle." 129 open_it = raw_input("> ") 130 else: I mean, the door's right there." 131 if open_it == 'open it': 132 print "That doesn't seem sensible. 133 print "You open it and you are free!" 134 return 'big_iron_gate' 135 print "There are mountains. And berries! And..." print "Oh, but then the bear comes with his katana and stabs you." What You Should See laughing print '"Who's a_game = Game("princess_lives_here") now!? Love this katana."' a_game.play() The output from this version of the game should be exactly the same as the previous version, and in fact you will return 'death' notice that some of the code is nearly the same. Compare this new version of the game and with the last one so you understandthechangesthatweremade.Keythingstoreallygetare: 1. How you made a class Game(object) and put functions inside it. 2. How __init__ is a special intialization method that sets up important variables. 3. How you added functions to the class by indenting them so they were deeper under the class keyword. This 118 Exercise 42: Getting Classy
  • 109. Learn Python The Hard Way, Release 1.0 isimportantsostudycarefullyhowindentationcreatestheclassstructure. 4.Howyouindentedagaintoputthecontents ofthefunctionsundertheirnames. 5.Howcolonsarebeingused. 6. The concept of self and how it’s used in __init__, play, and death. 7. Go find out what getattr does inside play so that you understand what’s going on with the operation of play. In fact, try doing this by hand inside Python to really get it. 8. How a Gamewascreatedat the end and then toldto play() and howthat got everything started. Extra Credit 1. Go find out what the __dict__ is and figure out how to get at it. 2. Try addingsome rooms to makesureyou knowhowto work with aclass. 3. Create a two-class version of this, where one is the Map and the other is the Engine. Hint: play goes in the Engine. Extra Credit 119
  • 110. Learn Python The Hard Way, Release 1.0 120 Exercise 42: Getting Classy
  • 111. Exercise 43: You Make A Game You need to start learning to feed yourself. Hopefully as you have worked through this book, you have learned that all the information you need is on the internet, you just have to go search for it. The only thing you have been missing are the right words and what to look for when you search. Now you should have a sense of it, so it’s about time you struggled throughabigprojectandtriedtogetitworking. Hereareyourrequirements: 1.MakeadifferentgamefromtheoneImade. 2. Use more than one file, and use import to use them. Make sure you know what that is. 3. Use oneclass perroom and give theclasses names thatfit their purpose.LikeGoldRoom, KoiPondRoom. 4.Yourrunnerwillneedtoknow abouttheserooms,somake aclassthatrunsthemandknows aboutthem.There’s plenty of ways todothis,butconsider having each roomreturn what roomis next orsetting a variable of what roomisnext. Other than that I leave it to you. Spend a whole week on this and make it the best game you can. Use classes, functions, dicts, lists anything you can to make it nice. The purpose of this lesson is to teach you how to structure classes that need other classesinsideotherfiles. Remember, I’m not telling you exactly how to do this because you have to do this yourself. Go figure it out. Program- ming is problem solving, and that means trying things, experimenting, failing, scrapping your work, and trying again. When you get stuck, ask for help and show people your code. If they are mean to you, ignore them, focus on the people who arenot mean and offertohelp. Keep workingitandcleaning ituntilit’s good,thenshowitsome more. Goodluck,andseeyouinaweekwithyourgame. 121
  • 112. Learn Python The Hard Way, Release 1.0 122 Exercise 43: You Make A Game
  • 113. Exercise 44: Evaluating Your Game In this exercise you will evaluate the game you just made. Maybe you got part-way through it and you got stuck. Maybe you got it working but just barely. Either way, we’re going to go through a bunch of things you should know now and make sure you covered them in your game. We’re going to study how to properly format a class, common conventionsinusingclasses,andalotof"textbook"knowledge. Why would I have you try to do it yourself and then show you how to do it right? 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 for much longer. I’m now instead going to give you things to do, have you do them on your own, and then give you ways to improve whatyoudid. You will struggle at first and probably be very frustrated but stick with it and eventually you will build a mind for solvingproblems.Youwillstarttofindcreativesolutionstoproblems ratherthanjustcopy solutions outoftextbooks. Function Style AlltheotherrulesI’vetaughtyouabouthowtomakeafunctionniceapply here,butaddthesethings: • 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,justaskthemtodemonstratethemathematicalbasis thatdetermines howa"method"is different from a "function"and they’llshut up. • When you work with classes much of your time is spent talking about making the class "do things". Instead of naming your functions after what the function does, instead name it as if it’s a command you are giving to the class. Sameas popis saying"Heylist,popthis off."It isn’tcalled remove_from_end_of_listbecause eventhoughthat’swhatitdoes,that’snotacommandtoalist. • Keep your functions small and simple. For some reason when people start learning about classes they forget this. Class Style • Your class should use "camel case" like SuperGoldFactory rather than super_gold_factory. • Try not to do too much in your __init__ functions. It makes them harder to use. • Your other functions should use "underscore format" so write my_awesome_hair and not myawesomehair or MyAwesomeHair. • Be consistent in how you organize your function arguments. If your class has to deal with users, dogs, and cats, keep that order throughout unless it really doesn’t make sense. If you have one function takes (dog, cat, user) and the other takes (user, cat, dog), it’ll be hard to use. 123
  • 114. Learn Python The Hard Way, Release 1.0 • Try notto usevariables that comefrom the moduleor globals.They shouldbefairly self-contained. • Afoolishconsistencyisthehobgoblinoflittleminds.Consistencyisgood,butfoolishlyfollowingsomeidiotic mantrabecauseeveryoneelsedoesisbadstyle.Thinkforyourself. • Always, always have class Name(object) format or else you will be in big trouble. Code Style • Give your code vertical space so people can read it. You will find some very bad programmers who are able to write reasonable code, but who do not add any spaces. This is bad style in any language because the human eye andbrainusespaceandverticalalignmenttoscanandseparatevisualelements.Nothavingspaceisthesame asgivingyourcodeanawesomecamouflagepaintjob. • If you can’t read it out loud, it’s probably hard to read. If you are having a problem making something easy to use, try reading it out loud. Not only does this force you to slow down and really read it, but it also helps you find difficultpassagesandthingstochangeforreadability. • Tryto do what other peopleare doing in Python untilyou find yourown style. • Once you find your own style, do not be a jerk about it. Working with other people’s code is part of being a programmer,andother people have really badtaste. Trust me,you willprobably have really badtastetoo and noteven realizeit. • If you find someone who writes code in a style you like, try writing something that mimics their style. Good Comments • There are programmers who will tell you that your code should be readable enough that you do not need com- ments. They’ll then tell you in their most official sounding voice that, "Ergo you should never write comments." Thoseprogrammers are either consultants who get paid more ifother people can’t usetheircode, orincompe- tents whotendtoneverwork withotherpeople.Ignorethemandwritecomments. • When you write comments, describe why you are doing what you are doing. The code already says how, but 124 whyyou did thingsthe way you did is more important. Exercise 44: Evaluating Your Game • When you write doc comments for your functions , make the comments documentation for someone who will
  • 115. Learn Python The Hard Way, Release 1.0 I want you to do nothing but evaluate and fix code for the week. Your own code and other people’s. It’ll be pretty hard work, butwhenyouaredoneyourbrainwillbewiredtightlikeaboxer’s hands. Evaluate Your Game 125
  • 116. Learn Python The Hard Way, Release 1.0 126 Exercise 44: Evaluating Your Game
  • 117. Exercise 45: Is-A, Has-A, Objects, and Classes An important concept that you have to understand is the difference between a Class and an Object. The problem is, there is no real "difference" between a class and an object. They are actually the same thing at different points in time. I will demonstrateby aZenkoan: What is the difference between a Fish and a Salmon? Did that question sort of confuse you? Really sit down and think about it for a minute. I mean, a Fish and a Salmon are differentbut,wait,they arethesamethingright?A Salmonis a kindofFish,soImeanit’s notdifferent.Butatthe same time, becase a Salmon is a particular type of Fish and so it’s actually different from all other Fish. That’s what makes it aSalmon andnotaHalibut.SoaSalmonandaFisharethesamebutdifferent.Weird. This question is confusing because most people do not think about real things this way, but they intuitively understand them. You do not need to think about the difference between a Fish and a Salmon because you know how they are related.YouknowaSalmonisakindofFishandthatthereareotherkinds ofFishwithouthavingtounderstandthat. Let’s take itone stepfurther,let’ssayyou have a bucketfullof3 Salmon and becauseyouare a nice person,you have decided toname themFrank,Joe,andMary.Now,thinkaboutthis question: What is the difference between Mary and a Salmon? Againthis is aweirdquestion,but it’s abiteasierthantheFishvs.Salmon question.YouknowthatMary is aSalmon, and so she’s not really different. She’s just a specific "instance" of a Salmon. Joe and Frank are also instances of Salmon. But, what do I mean when I say instance? I mean they were created from some other Salmon and now represent a realthingthathasSalmon-likeattributes. Now for the mind bending idea: Fish is a Class, and Salmon is a Class, and Mary is an Object. Think about that for a second.Alrightlet’s break itdownrealslow andseeifyouget it. A Fish is a Class, meaning it’s not a real thing, but rather a word we attach to instances of things with similar attributes. Got fins? Got gills? Lives in water? Alright it’s probably a Fish. Someone with a Ph.D. then comes along and says, "No my young friend, this Fish is actually Salmo salar, affection- ately known as a Salmon." This professor 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? Ok, probably aSalmon. Finally, a cook comes along and tells the Ph.D., "No, you see this Salmon right here, I’ll call her Mary and I’m going to make a tasty fillet out of her with a nicesauce." Now you havethis instanceof a Salmon (which alsois an instance of aFish) namedMary turnedintosomethingrealthatis fillingyourbelly.Ithas becomeanObject. There you have it: Mary is a kind of Salmon that is a kind of Fish. Object is a Class is a Class. 127
  • 118. Learn Python The Hard Way, Release 1.0 How This Looks In Code This is a weird concept, but to be very honest you only have to worry about it when you make new classes, and when you useaclass.Iwillshowyoutwotricks tohelpyoufigureoutwhethersomethingis aClass orObject. First, you need to learn two catch phrases "is-a" and "has-a". You use the phrase is-a when you talk about objects and classes being related to each other by a class relationship. You use has-a when you talk about objects and classes that are relatedonlybecausetheyreferenceeachother. Now, go through this piece of code and replace each ##?? comment with a replacement comment that says whether the next line represents an is-a or a has-a relationship, and what that relationship is. In the beginning of the code, I’ve laid 1 ## Animal is-a object (yes, sort of confusing) look at the extra credit outafewexamples,soyoujusthavetowritetheremainingones. 2 class Animal(object): 3 Remember,is-a istherelationshipbetween Fish and Salmon,whilehas-aistherelationship betweenSalmonandGills. 4 pass 5 6 7 ## ?? def class Dog(Animal): 8 __init__(self, name): ## ?? 9 self.name = name 12 10 ## ?? 13 11 class Cat(Animal): 14 15 def 16 __init__(self, name): 17 ## ?? 18 self.name = name 19 ## ?? 20 class Person(object): 21 22 def 23 __init__(self, name): 24 ## ?? 25 self.name = name 26 27 28 ## Person has-a pet of some kind 29 ## ?? self.pet = None 30 class Employee(Person): 31 32 def __init__(self, name, salary): 33 34 ## ?? hmm what is this strange magic? 35 36 super(Employee, self).__init__(name) 37 38 ## ?? 39 40 self.salary = salary 41 42 43 44 ## ?? class Fish(object): pass 128 Exercise 45: Is-A, Has-A, Objects, and Classes ## ?? class Salmon(Fish):
  • 119. Learn Python The Hard Way, Release 1.0 46 47 ## ?? 48 class 45 Halibut(Fish): 49 50 pass 51 52 53 54 55 ## rover is-a Dog 56 rover = Dog("Rover") 57 58 59 60 ## ?? 61 satan = Cat("Satan") 62 63 64 ## ?? 65 mary = Person("Mary") 66 67 68 ## ?? 69 mary.pet = satan 70 71 72 ## ?? 73 frank = Employee("Frank", 120000) 74 75 76 ## ?? frank.pet = rover ## ?? flipper = Fish() ## ?? crouse = Salmon() ## ?? harry = Halibut() About class Name(object) Remember how I was yelling at you to always use class Name(object) and I couldn’t tell you why? Now I can tell you, because you just learned about the difference between a class and an object. I couldn’t tell you until now becauseyouwouldhavejustbeenconfusedandcouldn’tlearntousethetechnology. What happened is Python’s original rendition of class was broken in many serious ways. By the time they admitted the fault it was too late, and they had to support it. In order to fix the problem, they needed some "new class" style so that the "oldclasses"wouldkeepworkingbutyoucouldusethenewmorecorrectversion. This is where "class is-a object"comes in. They decided that they would use the word "object", lowercased, to be the "class" that youThis Looks In Code a class. Confusing right? A class inherits from the class named object to make a class 129 it’s How inherit from to make but notanobjectreallyit’s aclass,butdonotforgettoinheritfromobject. Exactly. The choice of one single word meant that I couldn’t teach you about this until now. Now you can try to
  • 120. Learn Python The Hard Way, Release 1.0 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 that make them do things. See what happens whenfunctionsareina"baseclass"likeAnimalvs.insayDog. 4.Findotherpeople’s codeandwork outalltheis-aandhas-arelationships. 5.Makesomenewrelationships thatarelists anddicts soyoucanalsohave"has-many"relationships. 6. Do you think there’s a such thing as a "is-many" relationship? Read about "multiple inheritance", then avoid it ifyoucan. 130 Exercise 45: Is-A, Has-A, Objects, and Classes
  • 121. Exercise 46: A Project Skeleton This will be where you start learning how to setup a good project "skeleton" directory. This skeleton directory will have all the basics you need to get a new 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 copy this directory to a new name and edit the filestogetstarted. Skeleton Contents: Linux/OSX First,createthestructureofyourskeletondirectory withthesecommands: ~ $ mkdir -p projects ~ $ cd projects/ ~/projects $ mkdir skeleton ~/projects $ cd skeleton ~/projects/skeleton $ mkdir bin NAME tests docs I use a directory named projects to store all the various things I’m working on. Inside that directory I have my skeleton directory that I put the basis of my projects into. The directory NAME will be renamed to whatever you are callingyourproject’smainmodulewhenyouusetheskeleton. try: 1 Nextweneedtosetupsomeinitialfiles: from setuptools import setup 2 ~/projects/skeleton except ImportError:$ touch NAME/__init__.py ~/projects/skeleton $ touch tests/__init__.py 3 from distutils.core import setup 4 That creates empty Python module directories we can put our code in. Then we need to create a setup.py file we can config = { usetoinstallourprojectlaterifwewant: 5 'description': 'My Project', 6 'author': 'My Name', 7 'url': 'URL to get it at.', 8 'download_url': 'Where to download it.', 9 'author_email': 'My email.', 10 11 131 'version': '0.1', 12 13 14 'install_requires': ['nose'],
  • 122. Learn Python The Hard Way, Release 1.0 19 setup(**config) 18 Edit this file so that it has your contact information and is ready to go for when you copy it. Finally you will want a simple skeleton file for tests named tests/NAME_tests.py: from nose.tools import * import NAME def setup(): 1 print "SETUP!" 2 10 def test_basic(): 11 3 def teardown(): print "I RAN!" print "TEAR DOWN!" 4 5 Installing Python Packages 6 Make sure you have some packages installed that makes these things work. Here’s the problem though. You are at a 7 point where it’s difficult for me to help you do that and keep this book sane and clean. There are so many ways to install 8 software onsomany computers that I’d havetospend 10 pages walking you through every step, andletmetell youIam a lazyguy. 9 Rather than tell you how to do it exactly, I’m going to tell you what you should install, and then tell you to figure it out and get it working. This will be really good for you since it will open a whole world of software you can use that otherpeoplehavereleasedtotheworld. Next,nstallthefollowingpythonpackages: 1. pip from http://pypi.python.org/pypi/pip 2. distribute from http://pypi.python.org/pypi/distribute 3. nose from http://pypi.python.org/pypi/nose/ 4. virtualenv from http://pypi.python.org/pypi/virtualenv Do not just download these packages and install them by hand. Instead see how other people recommend you install these packages and use them for your particular system. The process will be different for most versions of Linux, OSX, and definitely different for Windows. I am warning you, this will be frustrating. In the business we call this "yak shaving". Yak shaving is any activity that is mind numblingly irritatingly boring and tedious that you have to do before you can do something else that’s more fun. You want to create cool Python projects, but you can’t do that until you setup a skeleton directory, but you can’t setup a skeleton directory until you install some packages, but you can’t install pacakages until you install package installers, and you can’t install package installers until you figure out how your system installs software in general, andsoon. Struggle through this anyway. Consider it your trial-by-annoyance to get into the programmer club. Every programmer has todo theseannoying tedioustasksbeforetheycando somethingcool. Testing Your Setup 132 Exercise 46: A Project Skeleton Afteryougetallthatinstalledyoushouldbeabletodothis:
  • 123. Learn Python The Hard Way, Release 1.0 ~/projects/skeleton $ nosetests ---------------------------------------------------------------------- Ran 1 test in 0.007s OK I’ll explain what this nosetests thing is doing in the next exercise, but for now if you do not see that, you probably got something wrong. Make sure you put __init__.py files in your NAME and tests directory and make sure you got tests/NAME_tests.py right. Using The Skeleton Youarenowdone withmostofyouryak shaving.Wheneveryouwanttostartanewproject,justdothis: 1.Makeacopy ofyourskeleton directory.Nameitafteryournew project. 2. Rename (move) the NAME module to be the name of your project or whatever you want to call your root module. 3. Edit yoursetup.pyto haveall the information foryour project. 4. Rename tests/NAME_tests.py to also have your module name. 5. Double check it’s all working using nosetests again. 6. Start coding. Required Quiz Thisexercisedoesn’thaveextracreditbutaquizyoushouldcomplete: 1.Readabouthowtouseallofthethingsyouinstalled. 2. Read about the setup.py file and all it has to offer. Warning, it is not a very well-written piece of software, soitwillbeverystrangetouse. 3. Make aprojectandstart puttingcodeintothe module,then getthe module working. 4. Put a script in the bin directory that you can run. Read about how you can make a Python script that’s runnable Using The Skeleton foryoursystem. 133 5. Mention the bin script you created in your setup.py so that it gets installed.
  • 124. Learn Python The Hard Way, Release 1.0 134 Exercise 46: A Project Skeleton
  • 125. Exercise 47: Automated Testing Having to type commands into your game over and over to make sure it’s workingis annoying. Wouldn’tit be better towrite little pieces of code that test your code? Then when you make a change, or add a new thing to your program, you just "run your tests" and the tests make sure things are still working. These automated tests won’t catch all your bugs, but they will cutdownonthetimeyouspendrepeatedly typing and runningyour code. Every exercise after this one will not have a What You Should See section, but instead it will have a What You Should Test section. You will be writing automated tests for all of your code starting now, and this will hopefully makeyouanevenbetterprogrammer. I won’t try to explain why you should write automated tests. I will only say that, you are trying to be a programmer, and programmers automate boring and tedious tasks. Testing a piece of software is definitely boring and tedious, so you might aswellwritealittlebitofcodetodoitforyou. That should be all the explanation you need because your reason for writing unit tests is to make your brain stronger. You have gone through this book writing code to do things. Now you are going to take the next leap and write code that knows about other code you have written. This process of writing a test that runs some code you have written forces you to understand clearly what you have just written. It solidifies in your brain exactly what it does and why it works and givesyouanewlevelofattentiontodetail. 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 fromyourprojectskeleton. class Room(object): 1 First, make a ex47 project from your project skeleton. Make sure you do it right and rename the module and get that first tests/ex47_tests.py test file going right. Also make sure nose runs this test file. IMPORTANT make sure you also 2 delete tests/skel_tests.pyc if it’s there. def __init__(self, name, description): 3 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 self.name = name wanttotestwiththiscodeinit: 4 self.description = description 5 11 def self.paths = {} 12 add_paths(self, paths): 6 self.paths.update(paths) 7 def go(self, direction): 8 135 return self.paths.get(direction, None) 9 10
  • 126. Learn Python The Hard Way, Release 1.0 Onceyouhavethatfile,changeunittestskeletontothis: from nose.tools import * 1 from ex47.game import Room 2 3 def test_room(): 4 gold = Room("GoldRoom", 5 """This room has gold in it you can grab. There's a 6 door to the north.""") 7 assert_equal(gold.name, "GoldRoom") 8 17 assert_equal(gold.paths, {}) north, 'south': center.add_paths({'north': south}) 18 assert_equal(center.go('north'), north) 9 19 assert_equal(center.go('south'), south) 10 20 11 def test_room_paths(): 21 12 def test_map(): 22 13 center = Room("Center", "Test room in the center.") 23 14 start = Room("Start", "You can go west and down a hole.") 24 15 north = Room("North", "Test room in the north.") 25 16 west = Room("Trees", "There are trees here, you can go east.") 26 start.add_paths({'west': "Test 'down': down}) south = Room("South", west, room in the south.") 27 down = Room("Dungeon", "It's dark down here, you can go up.") west.add_paths({'east': start}) 28 down.add_paths({'up': start}) 29 30 31 32 assert_equal(start.go('west'), west) assert_equal(start.go('west').go('east'), start) assert_equal(start.go('down').go('up'), start) This file imports the Room class you made in the ex47.game module so that you can do tests on it. There are then a set of tests that are functions starting with test_. Inside each test case there’s a bit of code that makes a Room or a set of Rooms, and then makes sure the rooms work the way you expect them to work. It tests out the basic room features,thenthepaths,thentriesoutawholemap. The important functions here are assert_equal which makes sure that variables you have set or paths you have built in a Room are actually what you think they are. If you get the wrong result, then nosetests will print out an errormessagesoyoucangofigureitout. Testing Guidelines Followthesegeneralloosesetofguidelineswhenmakingyourtests: 1. Test files go in tests/ and are named BLAH_tests.py otherwise nosetests won’t run them. This also keepsyourtestsfromclashingwithyourothercode. 136 Exercise 47: Automated Testing 2.Writeonetestfileforeachmoduleyoumake. 3. Keep your test cases (functions) short, but do not worry if they are a bit messy. Test cases are usually kind of
  • 127. Learn Python The Hard Way, Release 1.0 changeyourtests. Duplicatedcode willmakechangingyourtests more difficult. 5. Finally, do not get too attached to your tests. Sometimes, the best way to redesign something is to just delete it, thetests,andstartover. What You Should See ~/projects/simplegame $ nosetests ---------------------------------------------------------------------- Ran 3 tests in 0.007s OK That’s what you should see if everything is working right. Try causing an error to see what that looks like and then fix it. Extra Credit 1.Goreadaboutnosetestsmore,andalsoreadaboutalternatives. 2.LearnaboutPython’s"doctests"andseeifyoulikethembetter. 3. Make your Room more advanced, and then use it to rebuild your game yet again but this time, unit test as you go. What You Should See 137
  • 128. Learn Python The Hard Way, Release 1.0 138 Exercise 47: Automated Testing
  • 129. Exercise 48: Advanced User Input Your game probably was coming along great, but I bet how you handled what the user typed was becoming tedious. Each room needed its own very exact set of phrases that only worked if your player typed them perfectly. What you’d rather have is a device that lets users type phrases in various ways. For example, we’d like to have all of these phrases workthesame: • open door • open the door • go THROUGH the door • punch bear •PunchTheBearintheFACE It should be alright for a user to write something a lot like English for your game, and have your game figure out what it means. To do this, we’re going to write a module that does just that. This module will have a few classes that work together tohandle useinput andconvertitintosomethingyour gamecan work withreliably. InasimpleversionofEnglishthefollowingelements: •Wordsseparatedbyspaces. •Sentencescomposedofthewords. •Grammarthatstructuresthesentencesintomeaning. Thatmeans thebestplacetostartis figuringouthowtogetwordsfromtheuserandwhatkindsofwordsthoseare. Our Game Lexicon InourgamewehavetocreateaLexiconofwords: • Directionwords: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:anystringof0through9characters. When we get to nouns, we have a slight problem since each room could have a different set of Nouns, but let’s just pick thissmallsettoworkwithfornowandimproveitlater. 139
  • 130. Learn Python The Hard Way, Release 1.0 Breaking Up A Sentence Once we have our lexicon of words we need a way to break up sentences so that we can figure out what they are. In our case,we’ve defined asentence as"wordsseparatedbyspaces",sowereally justneed to dothis: stuff = raw_input('> ') words = stuff.split() That’s really all we’ll worry about for now, but this will work really well for quite a while. Lexicon Tuples Once we know how to break upa sentence into words, we justhave togo through the listof words and figure out what "type" they are. To do that we’re goingto use a handy littlePython structure called a"tuple". A tuple is nothing morethan a listthat youcan’tmodify.It’s created by putting datainside two () witha comma,like alist: first_word = ('direction', 'north') second_word = ('verb', 'go') sentence = [first_word, second_word] This creates apair of(TYPE, WORD)thatlets youlook atthe word and dothings withit. This is just an example, but that’s basically the end result. You want to take raw input from the user, carve it into words with split,thenanalyzethosewords toidentify theirtype,andfinallymakeasentenceoutofthem. Scanning Input Now you are ready to write your scanner. This scanner will take a string of raw input from a user and return a sentence that’s composed of a list of tuples with the (TOKEN, WORD) pairings. If a word isn’t part of the lexicon then it should stillreturnthe WORD, butsetthe TOKENtoan errortoken. Theseerrortokens willtellthe userthey messed up. Here’s where it gets fun. I’m not going to tell you how to do this. Instead I’m going to write a unit test und you are goingtowritethescannersothattheunittestworks. Exceptions And Numbers There is one tiny thing I will help you with first, and that’s converting numbers. 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 an error, then you have to handle that exception. For example,ifyoutypethisintopython: ~/projects/simplegame $ python Python 2.6.5 (r265:79063, Apr 16 2010, 13:57:41) [GCC 4.4.3] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> int("hell") 140 Exercise 48: Advanced User Input Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: invalid literal for int() with base 10: 'hell'
  • 131. Learn Python The Hard Way, Release 1.0 You deal with an exception by using the try and except keywords: def convert_number(s): try: return int(s) except ValueError: return None You put the code you want to "try" inside the try block, and then you put the code to run for the error inside the except. In this case, we want to "try" to call int() on something that might be a number. If that has an error, then we "catch"itandreturnNone. In your scanner that you write, you should use this function to test if something is a number. You should also do it as the lastthingyoucheck forbeforedeclaringthatwordanerror word. from nose.tools import * 1 2 from ex48 import lexicon 3 4 def test_directions(): 5 What You Should Test 'north')]) assert_equal(lexicon.scan("north"), [('direction', 6 result = lexicon.scan("north south east") 7 Here are the files tests/lexicon_tests.py that you should use: assert_equal(result, [('direction', 'north'), 8 def test_verbs(): 12 ('direction', 'south'), 'go')]) 13 9 14 assert_equal(lexicon.scan("go"), [('verb', ('direction', 'east')]) 15 10 16 11 result = lexicon.scan("go kill eat") 17 18 assert_equal(result, [('verb', 'go'), 19 20 ('verb', 'kill'), 21 22 ('verb', 'eat')]) 23 24 25 26 27 def test_stops(): 28 def test_nouns(): 'the')]) 29 assert_equal(lexicon.scan("the"), [('stop', 'bear')]) 30 assert_equal(lexicon.scan("bear"), [('noun', 31 result = lexicon.scan("the in of") 32 result = lexicon.scan("bear princess") 33 assert_equal(result, [('stop', 'the'), 34 assert_equal(result, [('noun', 'bear'), 35 ('stop', 'in'), 36 ('noun', 'princess')]) 37 ('stop', 'of')]) 38 def test_numbers(): assert_equal(lexicon.scan("1234"), [('number', 1234)]) 141 result = lexicon.scan("3 91234") assert_equal(result, [('number', 3),
  • 132. Learn Python The Hard Way, Release 1.0 41 def test_errors(): 42 'ASDFADFASDF')]) 43 39 assert_equal(lexicon.scan("ASDFADFASDF"), [('error', 44 40 45 result = lexicon.scan("bear IAS princess") 46 assert_equal(result, [('noun', 'bear'), Rememberthat you will want tomake a new project'IAS'), ('error', withyour skeleton, typeinthis testcase (do notcopy-paste!) and write yourscannersothatthetestruns.Focusonthedetails andmakesureeverythingworksright. ('noun', 'princess')]) Design Hints Focus on getting one test working at a time. Keep this simple and just put all the words in your lexicon in lists that are in your lexicon.py module. Do not modify the input list of words, but instead make your own new list with your lexicon tuples in it. Also, use the in keyword with these lexicon lists to check if a word is in the lexicon. Extra Credit 1.Improvetheunittesttomakesureyoucovermoreofthelexicon. 2.Addtothelexiconandthenupdatetheunittest. 3. Make your scanner handles user input in any capitalization and case. Update the test to make sure this actually works. 4.Findanotherwaytoconvertthenumber. 5.Mysolutionwas 37lineslong.Isyourslonger?Shorter? 142 Exercise 48: Advanced User Input
  • 133. Exercise 49: Making Sentences What weshould be ableto get from ourlittlegamelexiconscanneris alistthatlooks likethis: >>> from ex48 import lexicon >>> print lexicon.scan("go north") [('verb', 'go'), ('direction', 'north')] >>> print lexicon.scan("kill the princess") [('verb', 'kill'), ('stop', 'the'), ('noun', 'princess')] >>> print lexicon.scan("eat the bear") [('verb', 'eat'), ('stop', 'the'), ('noun', 'bear')] >>> print lexicon.scan("open the door and smack the bear in the nose") [('error', 'open'), ('stop', 'the'), ('noun', 'door'), ('error', 'and'), ('error', 'smack'), ('stop', 'the'), ('noun', 'bear'), ('stop', 'in'), ('stop', 'the'), ('error', 'nose')] >>> Now let us turn this into something the game can work with, which would be some kind of Sentence class. If you remembergradeschool,asentencecanbeasimplestructurelike: SubjectVerbObject Obviously it gets more complex than that, and you probably did many days of annoying sentence graphs for English class.WhatwewantistoturntheabovelistsoftuplesintoaniceSentenceobjectthathassubject,verb,andobject. Match And Peek Todothisweneedfourtools: 1.Away toloopthroughthelistoftuples.That’s easy. 2.A way to"match"differenttypes oftuples that weexpectin ourSubject Verb Objectsetup. 3.Awayto"peek"atapotentialtuplesowecanmakesomedecisions. 4. A way to"skip"things we do not care about, like stop words. Weusethepeek functiontosay look atthenextelementinourtuplelist,andthenmatchtotake oneoffandwork withit.Let’s takealookatafirstpeekfunction: def peek(word_list): if word_list: word = word_list[0] return word[0] else: return None Veryeasy.Nowforthematchfunction: 143
  • 134. Learn Python The Hard Way, Release 1.0 def match(word_list, expecting): if word_list: word = word_list.pop(0) if word[0] == expecting: return word else: return None else: return None Again,veryeasy,andfinallyourskipfunction: def skip(word_list, word_type): while peek(word_list) == word_type: match(word_list, word_type) Bynowyoushouldbeabletofigureoutwhatthesedo.Makesureyouunderstandthem. The Sentence Grammar Withourtools wecannowbegintobuildSentenceobjectsfromourlistoftuples.Whatwedois aprocess of: 1. Identify the next word with peek. 2. If that word fits in our grammar, we call a function to handle that part of the grammar, say parse_subject. 3. If it doesn’t, we raise an error, which you will learn about in this lesson. 4.Whenwe’realldone,weshouldhaveaSentenceobjecttowork withinourgame. The best way to demonstrate this is to give you the code to read, but here’s where this exercise is different from the previous one: You will write the test for the parser code I give you. Rather than giving you the test so you can write the code,Iwillgiveyouthecode,andyouhavetowritethetest. Here’s the code that I wrote for parsing simple sentences using the ex48.lexicon module: def class ParserError(Exception): peek(word_list): if word_list: pass word = word_list[0] return word[0] else: class Sentence(object): def match(word_list, expecting): return None 144 def __init__(self, subject, verb, object): Exercise 49: Making Sentences # remember we take ('noun','princess') tuples and convert them self.subject = subject[1]
  • 135. Learn Python The Hard Way, Release 1.0 if word_list: word = word_list.pop(0) if word[0] == expecting: return word else: def parse_verb(word_list): return None skip(word_list, 'stop') else: if peek(word_list) == 'verb': return None return match(word_list, 'verb') next.") else: raise ParseError("Expected a verb def skip(word_list, word_type): while peek(word_list) == word_type: if next == 'noun': word_type) match(word_list, def parse_object(word_list): return match(word_list, 'noun') if skip(word_list, 'stop') next == 'direction': next.") next = peek(word_list) return match(word_list, 'direction') else: raise ParseError("Expected a noun or direction def parse_sentence(word_list): def parse_subject(word_list, subj): skip(word_list, 'stop') verb = parse_verb(word_list) start == parse_object(word_list) obj peek(word_list) if start == 'noun': subj = match(word_list, 'noun') return Sentence(subj, verb, obj) return parse_subject(word_list, subj) elif start == 'verb': verb not: %s" % start) # assume the subject is the player then return parse_subject(word_list, ('noun', 'player')) else: raise ParserError("Must start with subject, object, or 145
  • 136. Learn Python The Hard Way, Release 1.0 A Word On Exceptions You briefly learned about exceptions, but not how to raise them. This code demonstrates how to do that with the ParserException at the top. Notice that it uses classes to give it the type of Exception. Also notice the use of raise keyword to raise the exception. In your tests, youwillwant toworkwith these exceptions, which I’ll showyou howto do. What You Should Test For Exercise 49 is write a complete test that confirms everything in this code is working. That includes making exceptionshappenbygivingitbadsentences. Check for an exception by using the function assert_raises from the nose documentation. Learn how to use this so youcan write a test thatis expected to fail, which is very importantintesting. Learnabout this function (andothers) by reading thenosedocumentation. When you are done, you should know how this bit of code works, and how to write a test for other people’s code even if they donotwantyouto.Trustme,it’saveryhandyskilltohave. Extra Credit 1. Change the parse_ methods and try to put them into a class rather than be just methods. Which design do you likebetter? 2. Make the parser more error resistant so that you can avoid annoying your users if they type words your lexicon doesn’tunderstand. 3.Improvethegrammarbyhandlingmorethingslikenumbers. 4.Think abouthowyoumightusethis Sentenceclassinyourgametodomorefunthings withauser’sinput. 146 Exercise 49: Making Sentences
  • 137. Exercise 50: Your First Work Assignment I’m now going to give you a work assignment, similar to what you might get as a professional programmer. The assignment will be to convert the list of features I give you into a complete little game that I may buy. Your job is to take myvaguedescriptionsofthingsIwantandmakesomethingIcanuse. The purpose of this exercise is to see if you have grasped the concepts you have learned so far. We only have 2 exercisesafterthis,butthis willbeyourlastactualassignedpieceofcoding. Review What You Know At this pointyoushould knowhow to do the following: •Createclassesandstructureroomsfromthem. •Throwandraiseexceptions. •Usefunctions,variables,dictionaries,lists,andtuples. •Turnauser’sinputintoalistoftuplesusingalexiconscanner. •TurnthelistoftuplesintoaSentenceyoucananalyzeusingaparser. Makesureyouknowhowtodothesethings as youwillbeusingthemtocompletethisassignment. Implementing A Feature List Typically when you work on software you will be given a list vague and inconsistent features they want. This sucks, I won’t lie to you. Typically people have no ability to think clearly about the things they want, and even less ability to describethem. As a programmer, it is your job to take the vague things they tell you and work with them to create something they want. Infact,sometimes you willhave aproblem articulating whatyou want. The best way toimplementa feature listlikethis is tofollowthis pattern: 1.Dumpeverything outoftheperson’s headwithoutcriticizing orjudgingtheideas. 2.Asyoudump,writethesedowninaspreadsheetoronindexcards. 3. Take a break, collect all the features and go back through to prioritize them into MUST (have) or NICE (to have). 4.Sortthelistsothatyoucansee whatis MUSTvs. whatis NICE to have. 5. Pick apiece ofthe MUST work,and startworking on it. 147
  • 138. Learn Python The Hard Way, Release 1.0 6. After about a week, show the person who wants the software your, and repeat this process again based on your newfeedback. Thispatterncanbefoundinoneformoranotherindifferent"methodologies"programmersusetoorganizetheirwork. I’m going to give you a list of features that I want in my game, and I’ve already prioritized them so this is just the MUST requirements. Yourjobis tospend one week workingonthelistand gettingitdone. The Feature List • Iwantagamethatissetonanalienspaceship. • The gameshould have ahumanhero who has to escapefrom theclutches ofan alien race who has enslaved him. • The game willbe atextadventuregame,likethat bear and broadswordgameyoudid.Ilike games likethat. • Oh,lasers.Totallygottahavelasers. • Butnottoopowerfullasers.Itshouldbehardtofinishthegame. • But nottoo hard tofinishthe game,just righttokeep players interested. Youknow,likeWorlf of Warcraft.IhearpeoplemaketonsofmoneyoffWoW. • Theshipshould have about10 rooms atfirst,then we wantto expandthem. • I’dliketo be abletochangethe description ofthe rooms withoutchangingthecode. Canyou dothat? • My friendsays farms are big now,sohaveascene wherethere’s afarm andstuff. • The aliens should besomekindof Mafia aliens. Mafia stuffis huge nowtoo. • Ishould be ableto move around with realsentences like"go north", "open door", etc. • It’s alrightifthe way therooms arelaid outis incode,but players willneed aprinted map. Can youkeeptrack ofthemap? • Thereneedstobeastorybehindthis,andmaybealoveinterest. • Probably acouple ofgeek culturereferences. But noStar Trek!Ok,firstseasonis coolbut nothing afterthat. • Iwant to be abletoinstalliton my computer with pythonsocanyou makeitinstallfrom asetup.py? That’ll makeiteasytopackagelater. Tips On Working The List 148 Exercise 50: Your First Work Assignment 1.Makeyourmap,characters,andstoryfirstonpaper.
  • 139. Exercise 51: Reviewing Your Game You worked hard on your Mafia Alien Slave Ship game. You made a great story, filled out rooms, created a nice game engine, and got it working. You are now going to get your game reviewed by a real user and take notes on what they find wrong. This is called "usability testing" and it helps you get good feedback on your game and find new bugs you didn’tanticipate. Whenyou wroteyourgameyou probably only tested thethings youknew about.Theproblem is someoneelsedoesn’tknow how your game is structured, so they’ll try weird things you wouldn’t have thought they’d do. The only way to findthese weirdactionsis toactuallyputyourgamebeforeahumanandletthemtrashit. Find one person, preferably a relative or a friend. You could even get together with a bunch of other people going through this book and have a little sharing session to try out your games. Turn it into a competition even. Anything to get peopletotryyourgamein-person. How To Study A User Studyingauseris easy.Puttheminfrontofyourgameandwatchtwothings: 1.Thescreenwhiletheyuseit. 2. Their face while they use it. Sitataslightanglesoyoucanglanceatbothwhilethey play yourgame. This willhelpyouseehowthey are reacting toyour gameby watchingtheirface. Let them play your game, but have them talk out loud about your game. They will probably not give you feedback if you donottellthem totalk while they play, butifyou getthem totalk andplaythey’lltellyouallsorts ofthings. Once they are playing and talking, take notes on paper and do not judge or argue. Just write down what they say and continue. You want their honest feedback to your game and taking their comments personally will mean you do not get realfeedback. Let them struggle with parts they have a problem with, then help them to move things forward. You should be writing down parts that aretoohard, broken, too difficultto navigate, and anything thatis just plainconfusing. Finally, thank them for helping you out and review what you found with them. They’ll usually want to do it again if you dothat,andit’sjustpolite. Implement The Changes With your list of defects you will make a new list of things you have to change. Spend one week changing them and try to getyourfriend(s)toreviewyour gameonemoretime. 149
  • 140. Learn Python The Hard Way, Release 1.0 Whether they enjoyed your game or not doesn’t matter. What does matter is you have completed a full project with vague specifications and got feedback from a person, then fixed your game to meet their demands. Your game can suck hard,butyouatleastwroteone. Take this lesson seriously. Even though there is no code, it is probably the most important less you can have. It teaches you thatsoftwareis writtenforpeople,socaringabouttheiropinions isimportant. 150 Exercise 51: Reviewing Your Game