├── README.md ├── ex01.py ├── ex02.py ├── ex03.py ├── ex04.py ├── ex05.py ├── ex06.py ├── ex07.py ├── ex08.py ├── ex09.py ├── ex10.py ├── ex11.py ├── ex12.py ├── ex13.py ├── ex14.py ├── ex15.py ├── ex15_sample.txt ├── ex16.py ├── ex17.py ├── ex18.py ├── ex19.py ├── ex20.py ├── ex21.py ├── ex23.py ├── ex24.py ├── ex25.py ├── ex26.py ├── ex29.py ├── ex30.py ├── ex31.py ├── ex32.py ├── ex33.py ├── ex35.py ├── ex38.py ├── ex39.py ├── ex40.py ├── ex41.py ├── ex42.py ├── ex43.py ├── ex44a.py ├── ex44b.py ├── ex44c.py ├── ex44d.py ├── ex44e.py ├── exercise26.txt ├── languages.txt ├── new_file.txt ├── projects ├── gothonweb │ ├── app.py │ ├── gothonweb │ │ ├── __init__.py │ │ └── planisphere.py │ ├── templates │ │ ├── hello.html │ │ ├── hello_form.html │ │ ├── layout.html │ │ ├── show_room.html │ │ └── you_died.html │ └── tests │ │ ├── __init__.py │ │ ├── app_tests.py │ │ └── planisphere_tests.py ├── simplegame │ ├── ex47 │ │ ├── __init__.py │ │ └── game.py │ ├── ex48 │ │ ├── __init__.py │ │ └── lexicon.py │ ├── ex49 │ │ ├── __init__.py │ │ └── parser.py │ ├── setup.py │ └── tests │ │ ├── __init__.py │ │ ├── game_tests.py │ │ ├── lexicon_tests.py │ │ └── parser_tests.py └── skeleton │ ├── NAME │ └── __init__.py │ ├── setup.py │ └── tests │ ├── NAME_tests.py │ └── __init__.py └── test.txt /README.md: -------------------------------------------------------------------------------- 1 | # Learn Python The Hard Way 2 | Welcome to the 1st Edition of Learn Python 3 the Hard Way which teaches Python 3. Apparently this is a new edition and not the 4th edition because it teaches Python 3. You can visit the companion site to the book at [http://learnpythonthehardway.org/](http://learnpythonthehardway.org/) where you can purchase digital downloads and paper versions of the book. The free HTML version of the book is available at [http://learnpythonthehardway.org/python3/](http://learnpythonthehardway.org/python3/). 3 | ## Table Of Contents 4 | * [Preface](https://learnpythonthehardway.org/python3/preface.html) 5 | * [Introduction: The Hard Way Is Easier](https://learnpythonthehardway.org/python3/intro.html) 6 | * [Exercise 0: The Setup](https://learnpythonthehardway.org/python3/ex0.html) 7 | * [Exercise 1: A Good First Program](https://learnpythonthehardway.org/python3/ex1.html) 8 | * [Exercise 2: Comments And Pound Characters](https://learnpythonthehardway.org/python3/ex2.html) 9 | * [Exercise 3: Numbers And Math](https://learnpythonthehardway.org/python3/ex3.html) 10 | * [Exercise 4: Variables And Names](https://learnpythonthehardway.org/python3/ex4.html) 11 | * [Exercise 5: More Variables And Printing](https://learnpythonthehardway.org/python3/ex5.html) 12 | * [Exercise 6: Strings And Text](https://learnpythonthehardway.org/python3/ex6.html) 13 | * [Exercise 7: More Printing](https://learnpythonthehardway.org/python3/ex7.html) 14 | * [Exercise 8: Printing, Printing](https://learnpythonthehardway.org/python3/ex8.html) 15 | * [Exercise 9: Printing, Printing, Printing](https://learnpythonthehardway.org/python3/ex9.html) 16 | * [Exercise 10: What Was That?](https://learnpythonthehardway.org/python3/ex10.html) 17 | * [Exercise 11: Asking Questions](https://learnpythonthehardway.org/python3/ex11.html) 18 | * [Exercise 12: Prompting People](https://learnpythonthehardway.org/python3/ex12.html) 19 | * [Exercise 13: Parameters, Unpacking, Variables](https://learnpythonthehardway.org/python3/ex13.html) 20 | * [Exercise 14: Prompting And Passing](https://learnpythonthehardway.org/python3/ex14.html) 21 | * [Exercise 15: Reading Files](https://learnpythonthehardway.org/python3/ex15.html) 22 | * [Exercise 16: Reading And Writing Files](https://learnpythonthehardway.org/python3/ex16.html) 23 | * [Exercise 17: More Files](https://learnpythonthehardway.org/python3/ex17.html) 24 | * [Exercise 18: Names, Variables, Code, Functions](https://learnpythonthehardway.org/python3/ex18.html) 25 | * [Exercise 19: Functions And Variables](https://learnpythonthehardway.org/python3/ex19.html) 26 | * [Exercise 20: Functions And Files](https://learnpythonthehardway.org/python3/ex20.html) 27 | * [Exercise 21: Functions Can Return Something](https://learnpythonthehardway.org/python3/ex21.html) 28 | * [Exercise 22: What Do You Know So Far?](https://learnpythonthehardway.org/python3/ex22.html) 29 | * [Exercise 23: Read Some Code](https://learnpythonthehardway.org/python3/ex23.html) 30 | * [Exercise 24: More Practice](https://learnpythonthehardway.org/python3/ex24.html) 31 | * [Exercise 25: Even More Practice](https://learnpythonthehardway.org/python3/ex25.html) 32 | * [Exercise 26: Congratulations, Take A Test!](https://learnpythonthehardway.org/python3/ex26.html) 33 | * [Exercise 27: Memorizing Logic](https://learnpythonthehardway.org/python3/ex27.html) 34 | * [Exercise 28: Boolean Practice](https://learnpythonthehardway.org/python3/ex28.html) 35 | * [Exercise 29: What If](https://learnpythonthehardway.org/python3/ex29.html) 36 | * [Exercise 30: Else And If](https://learnpythonthehardway.org/python3/ex30.html) 37 | * [Exercise 31: Making Decisions](https://learnpythonthehardway.org/python3/ex31.html) 38 | * [Exercise 32: Loops And Lists](https://learnpythonthehardway.org/python3/ex32.html) 39 | * [Exercise 33: While Loops](https://learnpythonthehardway.org/python3/ex33.html) 40 | * [Exercise 34: Accessing Elements Of Lists](https://learnpythonthehardway.org/python3/ex34.html) 41 | * [Exercise 35: Branches and Functions](https://learnpythonthehardway.org/python3/ex35.html) 42 | * [Exercise 36: Designing and Debugging](https://learnpythonthehardway.org/python3/ex36.html) 43 | * [Exercise 37: Symbol Review](https://learnpythonthehardway.org/python3/ex37.html) 44 | * [Exercise 38: Doing Things To Lists](https://learnpythonthehardway.org/python3/ex38.html) 45 | * [Exercise 39: Dictionaries, Oh Lovely Dictionaries](https://learnpythonthehardway.org/python3/ex39.html) 46 | * [Exercise 40: Modules, Classes, And Objects](https://learnpythonthehardway.org/python3/ex40.html) 47 | * [Exercise 41: Learning To Speak Object Oriented](https://learnpythonthehardway.org/python3/ex41.html) 48 | * [Exercise 42: Is-A, Has-A, Objects, and Classes](https://learnpythonthehardway.org/python3/ex42.html) 49 | * [Exercise 43: Gothons From Planet Percal #25](https://learnpythonthehardway.org/python3/ex43.html) 50 | * [Exercise 44: Inheritance Vs. Composition](https://learnpythonthehardway.org/python3/ex44.html) 51 | * [Exercise 45: You Make A Game](https://learnpythonthehardway.org/python3/ex45.html) 52 | * [Exercise 46: A Project Skeleton](https://learnpythonthehardway.org/python3/ex46.html) 53 | * [Exercise 47: Automated Testing](https://learnpythonthehardway.org/python3/ex47.html) 54 | * [Exercise 48: Advanced User Input](https://learnpythonthehardway.org/python3/ex48.html) 55 | * [Exercise 49: Making Sentences](https://learnpythonthehardway.org/python3/ex49.html) 56 | * [Exercise 50: Your First Website](https://learnpythonthehardway.org/python3/ex50.html) 57 | * [Exercise 51: Getting Input From A Browser](https://learnpythonthehardway.org/python3/ex51.html) 58 | * [Exercise 52: The Start Of Your Web Game](https://learnpythonthehardway.org/python3/ex52.html) 59 | * [Advice From An Old Programmer](https://learnpythonthehardway.org/python3/advice.html) 60 | * [Next Steps](https://learnpythonthehardway.org/python3/next.html) 61 | * [Appendix A: Command Line Crash Course](https://learnpythonthehardway.org/python3/appendixa.html) -------------------------------------------------------------------------------- /ex01.py: -------------------------------------------------------------------------------- 1 | print("Hello World!") 2 | print("Hello Again") 3 | print("I like typing this.") 4 | print("This is fun.") 5 | print('Yay! Printing.') 6 | print("I'd much rather you 'not'.") 7 | print('I "said" do not touch this.') 8 | -------------------------------------------------------------------------------- /ex02.py: -------------------------------------------------------------------------------- 1 | # A comment, this is so you can read your program later. 2 | # Anything after the # is ignored by pyhton. 3 | 4 | print("I could have code like this.") # and the comment after is ignored 5 | 6 | # You can also use a comment to "disable" or comment out a piece of code: 7 | # print ("This won't run.") 8 | 9 | print("This will run.") 10 | -------------------------------------------------------------------------------- /ex03.py: -------------------------------------------------------------------------------- 1 | print("I will now count my chickens:") 2 | 3 | print("Hens", 25 + 30 / 6) 4 | print("Rosters", 100 - 25 * 3 % 4) 5 | 6 | print("Now I will count the eggs:") 7 | 8 | print(round(3 + 2 + 1 - 5 + 4 % 2 - 1 / 4 + 6)) 9 | 10 | print("Is it true that 3 + 2 < 5 - 7?") 11 | 12 | print(3 + 2 < 5 - 7) 13 | 14 | print("What is 3 + 2?", 3 + 2) 15 | print("What is 5 - 7?", 5 - 7) 16 | 17 | print("Oh, that's why it's False.") 18 | 19 | print("How about some more.") 20 | 21 | print("It is greater?", 5 > -2) 22 | print("It is greater or equal?", 5 >= -2) 23 | print("It is less or equal?", 5 <= -2) 24 | -------------------------------------------------------------------------------- /ex04.py: -------------------------------------------------------------------------------- 1 | cars = 100 2 | space_in_a_car = 4.0 3 | drivers = 30 4 | passengers = 90 5 | cars_not_driven = cars - drivers 6 | cars_driven = drivers 7 | carpool_capacity = cars_driven * space_in_a_car 8 | average_passengers_per_car = passengers / cars_driven 9 | 10 | print("There are", cars, "cars available.") 11 | print("There are only", drivers, "drivers available.") 12 | print("There will be", cars_not_driven, "empty cars today") 13 | print("We can transport", carpool_capacity, "people today.") 14 | print("We have", passengers, "to carpool today.") 15 | print("We need to put about", average_passengers_per_car, "in each car.") 16 | -------------------------------------------------------------------------------- /ex05.py: -------------------------------------------------------------------------------- 1 | my_name = 'Zed A. Shaw' 2 | my_age = 35 # not a lie 3 | my_height = 74 # inches 4 | my_weight = 180 # lbs 5 | my_eyes = 'Blue' 6 | my_teeth = 'White' 7 | my_hair = 'Brown' 8 | 9 | print(f"Let's talk about {my_name}.") 10 | print(f"He's {my_height} inches tall.") 11 | print(f"He's {my_weight} pounds heavy.") 12 | print("Actually that's not too heavy.") 13 | print(f"He's got {my_eyes} eyes and {my_hair} hair.") 14 | print(f"His teeth are usually {my_teeth} depending on the coffee.") 15 | 16 | # this line is tricky, try to get it exactly right 17 | total = my_age + my_height + my_weight 18 | print(f"If I add {my_age}, {my_height}, and {my_weight} I get {total}.") 19 | -------------------------------------------------------------------------------- /ex06.py: -------------------------------------------------------------------------------- 1 | types_of_people = 10 2 | x = f"There are {types_of_people} types of people." 3 | 4 | binary = "binary" 5 | do_not = "don't" 6 | y = f"Those who know {binary} and those who {do_not}." 7 | 8 | print(x) 9 | print(y) 10 | 11 | print(f"I said: {x}") 12 | print(f"I also said : '{y}'.") 13 | 14 | hilarious = False 15 | joke_evaluation = "Isn't that joke so funny?! {}" 16 | 17 | print(joke_evaluation.format(hilarious)) 18 | 19 | w = "This is the left side of..." 20 | e = "a string with a right side." 21 | 22 | print(w + e) 23 | -------------------------------------------------------------------------------- /ex07.py: -------------------------------------------------------------------------------- 1 | print("Mary had a little lamb.") 2 | print("Its fleece was white as {}.".format('snow')) 3 | print("And everywhere that Mary went.") 4 | print("." * 10) # what'd that do? 5 | 6 | end1 = "C" 7 | end2 = "h" 8 | end3 = "e" 9 | end4 = "e" 10 | end5 = "s" 11 | end6 = "e" 12 | end7 = "B" 13 | end8 = "u" 14 | end9 = "r" 15 | end10 = "g" 16 | end11 = "e" 17 | end12 = "r" 18 | 19 | print(end1 + end2 + end3 + end4 + end5 + end6, end=' ') 20 | print(end7 + end8 + end9 + end10 + end11 + end12) 21 | -------------------------------------------------------------------------------- /ex08.py: -------------------------------------------------------------------------------- 1 | formatter = "{} {} {} {}" 2 | 3 | print(formatter.format(1, 2, 3, 4)) 4 | print(formatter.format("one", "two", "three", "four")) 5 | print(formatter.format(True, False, False, True)) 6 | print(formatter.format(formatter, formatter, formatter, formatter)) 7 | print(formatter.format("Try your", 8 | "Own text here", 9 | "Maybe a poem", 10 | "Or a song about fear" 11 | )) 12 | -------------------------------------------------------------------------------- /ex09.py: -------------------------------------------------------------------------------- 1 | # Here's some new strange stuff, remember type it exactly. 2 | 3 | days = "Mon Tue Wed Thu Fri Sat Sun" 4 | months = "Jan\nFeb\nMar\nApr\nMay\nJun\nJul\nAug" 5 | 6 | print("Here are the days:", days) 7 | print("Here are the months: ", months) 8 | 9 | print(""" 10 | There's something going on here. 11 | With the three double-quotes. 12 | We'll be able to type as much as we like. 13 | Even 4 lines if we want, or 5, or 6. 14 | """) 15 | -------------------------------------------------------------------------------- /ex10.py: -------------------------------------------------------------------------------- 1 | tabby_cat = "\tI'm tabbed in." 2 | persian_cat = "I'm split\non a line." 3 | backslash_cat = "I'm \\ a \\ cat." 4 | 5 | fat_cat = """ 6 | I'll do a list: 7 | \t* Cat food 8 | \t* Fishes 9 | \t* Catnip\n\t* Grass 10 | """ 11 | 12 | print(tabby_cat) 13 | print(persian_cat) 14 | print(backslash_cat) 15 | print(fat_cat) 16 | -------------------------------------------------------------------------------- /ex11.py: -------------------------------------------------------------------------------- 1 | print("How old are you?", end=' ') 2 | age = input() 3 | print("How tall are you?", end=' ') 4 | height = input() 5 | print("How much do you weight?", end=' ') 6 | weight = input() 7 | 8 | print(f"So, you're {age} old, {height} tall and {weight} heavy.") 9 | -------------------------------------------------------------------------------- /ex12.py: -------------------------------------------------------------------------------- 1 | age = input("How old are you? ") 2 | height = input("How tall are you? ") 3 | weight = input("How much do you weight? ") 4 | 5 | print(f"So, you're {age} old, {height} tall and {weight} heavy.") 6 | -------------------------------------------------------------------------------- /ex13.py: -------------------------------------------------------------------------------- 1 | from sys import argv 2 | 3 | # read the WYSS section for how to run this 4 | script, first, second, third = argv 5 | 6 | print("The script is called:", script) 7 | print("Your first variable is:", first) 8 | print("Your second variable is:", second) 9 | print("Your third variable is:", third) 10 | -------------------------------------------------------------------------------- /ex14.py: -------------------------------------------------------------------------------- 1 | from sys import argv 2 | 3 | script, user_name = argv 4 | prompt = '> ' 5 | 6 | print(f"Hi {user_name}, I'm the {script} script.") 7 | print("I'd like to ask you a few questions.") 8 | print(f"Do you like me {user_name}?") 9 | likes = input(prompt) 10 | 11 | print(f"Where do you live {user_name}?") 12 | lives = input(prompt) 13 | 14 | print("What kind of computer do you have?") 15 | computer = input(prompt) 16 | 17 | print(f""" 18 | Alright, so you said {likes} about liking me. 19 | You live in {lives}. Not sure where that is. 20 | And you have a {computer} computer. Nice. 21 | """) 22 | -------------------------------------------------------------------------------- /ex15.py: -------------------------------------------------------------------------------- 1 | from sys import argv 2 | 3 | script, filename = argv 4 | 5 | txt = open(filename) 6 | 7 | print(f"Here's your file {filename}:") 8 | print(txt.read()) 9 | 10 | print("Type the filename again:") 11 | file_again = input("> ") 12 | 13 | txt_again = open(file_again) 14 | 15 | print(txt_again.read()) 16 | -------------------------------------------------------------------------------- /ex15_sample.txt: -------------------------------------------------------------------------------- 1 | This is stuff I typed into a file. 2 | It is really cool stuff. 3 | Lots and lots of fun to have in here. -------------------------------------------------------------------------------- /ex16.py: -------------------------------------------------------------------------------- 1 | from sys import argv 2 | 3 | script, filename = argv 4 | 5 | print(f"We're going to erase {filename}.") 6 | print("If you don't want that, hit CTRL-C (^C).") 7 | print("If you do want that, hit RETURN.") 8 | 9 | input("?") 10 | 11 | print("Opening the file...") 12 | target = open(filename, 'w') 13 | 14 | print("Truncating the file. Goodbye!") 15 | target.truncate() 16 | 17 | print("Now I'm going to ask you for three lines.") 18 | 19 | line1 = input("line1: ") 20 | line2 = input("line2: ") 21 | line3 = input("line3: ") 22 | 23 | print("I'm going to write these to the file.") 24 | 25 | target.write(line1) 26 | target.write("\n") 27 | target.write(line2) 28 | target.write("\n") 29 | target.write(line3) 30 | target.write("\n") 31 | 32 | print("And finally, we close it.") 33 | target.close() 34 | -------------------------------------------------------------------------------- /ex17.py: -------------------------------------------------------------------------------- 1 | from os.path import exists 2 | from sys import argv 3 | 4 | script, from_file, to_file = argv 5 | 6 | print(f"Copying from {from_file} to {to_file}") 7 | 8 | # we could do these two on one line too, how? 9 | in_file = open(from_file) 10 | indata = in_file.read() 11 | 12 | print(f"The input file is {len(indata)} bytes long") 13 | 14 | print(f"Does the output file exists? {exists(to_file)}") 15 | print("Ready, hit RETURN to continue, CTRL-C to abort.") 16 | input() 17 | 18 | out_file = open(to_file, 'w') 19 | out_file.write(indata) 20 | 21 | print("Alright, all done.") 22 | 23 | out_file.close() 24 | in_file.close() 25 | -------------------------------------------------------------------------------- /ex18.py: -------------------------------------------------------------------------------- 1 | # this one is like your scripts with argv 2 | def print_two(*args): 3 | arg1, arg2 = args 4 | print(f"arg1: {arg1}, arg2: {arg2}") 5 | 6 | 7 | # ok, that *args is actually pointless, we can just do this 8 | def print_two_again(arg1, arg2): 9 | print(f"arg1: {arg1}, arg2: {arg2}") 10 | 11 | 12 | # this just takes one argument 13 | def print_one(arg1): 14 | print(f"arg1: {arg1}") 15 | 16 | 17 | # this one takes no arguments 18 | def print_none(): 19 | print("I got nothin'.") 20 | 21 | 22 | print_two("Zed", "Shaw") 23 | print_two_again("Zed", "Shaw") 24 | print_one("First!") 25 | print_none() 26 | -------------------------------------------------------------------------------- /ex19.py: -------------------------------------------------------------------------------- 1 | def cheese_and_crackers(cheese_count, boxes_of_crackers): 2 | print(f"You have {cheese_count} cheeses!") 3 | print(f"You have {boxes_of_crackers} boxes of crackers!") 4 | print("Man that's enought for a party!") 5 | print("Get a blanket.\n") 6 | 7 | 8 | print("We can just give the function numbers directly:") 9 | cheese_and_crackers(20, 30) 10 | 11 | print("OR, we can use variables from our script:") 12 | amount_of_cheese = 10 13 | amount_of_crackers = 50 14 | 15 | cheese_and_crackers(amount_of_cheese, amount_of_crackers) 16 | 17 | print("We can even do math inside too:") 18 | cheese_and_crackers(10 + 20, 5 + 6) 19 | 20 | print("And we can combine the two, variables and math:") 21 | cheese_and_crackers(amount_of_cheese + 100, amount_of_crackers + 1000) 22 | -------------------------------------------------------------------------------- /ex20.py: -------------------------------------------------------------------------------- 1 | from sys import argv 2 | 3 | script, input_file = argv 4 | 5 | 6 | def print_all(f): 7 | print(f.read()) 8 | 9 | 10 | def rewind(f): 11 | f.seek(0) 12 | 13 | 14 | def print_a_line(line_count, f): 15 | print(line_count, f.readline()) 16 | 17 | 18 | current_file = open(input_file) 19 | 20 | print("First let's print the whole file:\n") 21 | 22 | print_all(current_file) 23 | 24 | print("Now let's rewind, kind of like a tape.") 25 | 26 | rewind(current_file) 27 | 28 | print("Let's print three lines:") 29 | 30 | current_line = 1 31 | print_a_line(current_line, current_file) 32 | 33 | current_line = current_line + 1 34 | print_a_line(current_line, current_file) 35 | 36 | current_line = current_line + 1 37 | print_a_line(current_line, current_file) 38 | -------------------------------------------------------------------------------- /ex21.py: -------------------------------------------------------------------------------- 1 | def add(a, b): 2 | print(f"ADDING {a} + {b}") 3 | return a + b 4 | 5 | 6 | def subtract(a, b): 7 | print(f"SUBTRACTING {a} - {b}") 8 | return a - b 9 | 10 | 11 | def multiply(a, b): 12 | print(f"MULTIPLYING {a} * {b}") 13 | return a * b 14 | 15 | 16 | def divide(a, b): 17 | print(f"DIVIDING {a} / {b}") 18 | return a / b 19 | 20 | 21 | print("Let's do some math with just functions!") 22 | 23 | age = add(30, 5) 24 | height = subtract(78, 4) 25 | weight = multiply(90, 2) 26 | iq = divide(100, 2) 27 | 28 | print(f"Age: {age}, Height: {height}, Weight: {weight}, IQ: {iq}") 29 | 30 | # A puzzle for the extra credit, type it in anyway. 31 | print("Here is a puzzle.") 32 | 33 | what = add(age, subtract(height, multiply(weight, divide(iq, 2)))) 34 | print("That becomes: ", what, "Can you do it by hand?") 35 | -------------------------------------------------------------------------------- /ex23.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | script, input_encoding, error = sys.argv 4 | 5 | 6 | def main(language_file, encoding, errors): 7 | line = language_file.readline() 8 | 9 | if line: 10 | print_line(line, encoding, errors) 11 | return main(language_file, encoding, errors) 12 | 13 | 14 | def print_line(line, encoding, errors): 15 | next_lang = line.strip() 16 | raw_bytes = next_lang.encode(encoding, errors=errors) 17 | cooked_string = raw_bytes.decode(encoding, errors=errors) 18 | 19 | print(raw_bytes, "<==>", cooked_string) 20 | 21 | 22 | languages = open("languages.txt", encoding="utf-8") 23 | 24 | main(languages, input_encoding, error) 25 | -------------------------------------------------------------------------------- /ex24.py: -------------------------------------------------------------------------------- 1 | print("Let's practice everything.") 2 | print('You\'d need to know \'bout escapes with \\ that do:') 3 | print('\n newlines and \t tabs.') 4 | 5 | poem = """ 6 | \tThe lovely world 7 | with logic so firmly planted 8 | cannot discern \n the needs of love 9 | nor comprehend passion from intuition 10 | and requires an explanation 11 | \n\t\twhere there is none. 12 | """ 13 | 14 | print("--------------") 15 | print(poem) 16 | print("--------------") 17 | 18 | five = 10 - 2 + 3 - 6 19 | print(f"This should be five: {five}") 20 | 21 | 22 | def secret_formula(started): 23 | jelly_beans = started * 500 24 | jars = jelly_beans / 1000 25 | crates = jars / 100 26 | return jelly_beans, jars, crates 27 | 28 | 29 | start_point = 10000 30 | beans, jars, crates = secret_formula(start_point) 31 | 32 | # remember that this is another way to format string 33 | print("With a starting point of: {}".format(start_point)) 34 | # it's just like with an f"" string 35 | print(f"We'd have {beans} beans, {jars} jars, and {crates} crates.") 36 | 37 | start_point = start_point / 10 38 | 39 | print("We can also do that this way:") 40 | formula = secret_formula(start_point) 41 | # this is an easy way to apply a list to a format string 42 | print("We'd have {} beans, {} jars, and {} crates.".format(*formula)) 43 | -------------------------------------------------------------------------------- /ex25.py: -------------------------------------------------------------------------------- 1 | def break_words(stuff): 2 | """This function will break up words for us.""" 3 | words = stuff.split(' ') 4 | return words 5 | 6 | 7 | def sort_words(words): 8 | """Sorts the words.""" 9 | return sorted(words) 10 | 11 | 12 | def print_first_word(words): 13 | """Prints the first word after popping it off.""" 14 | word = words.pop(0) 15 | print(word) 16 | 17 | 18 | def print_last_word(words): 19 | """Prints the last word after popping it of.""" 20 | word = words.pop(-1) 21 | print(word) 22 | 23 | 24 | def sort_sentence(sentence): 25 | """Takes in a full sentence and returns the sorted words.""" 26 | words = break_words(sentence) 27 | return (sort_words(words)) 28 | 29 | 30 | def print_first_and_last(sentence): 31 | """Prints the first and last words of a sentence.""" 32 | words = break_words(sentence) 33 | print_first_word(words) 34 | print_last_word(words) 35 | 36 | 37 | def print_first_and_last_sorted(sentence): 38 | """Sorts the words then prints the first and last one.""" 39 | words = sort_sentence(sentence) 40 | print_first_word(words) 41 | print_last_word(words) 42 | -------------------------------------------------------------------------------- /ex26.py: -------------------------------------------------------------------------------- 1 | from sys import argv 2 | 3 | print("How old are you?", end=' ') 4 | age = input() 5 | print("How tall are you?", end=' ') 6 | height = input() 7 | print("How much do you weigh?", end=' ') 8 | weight = input() 9 | 10 | print(f"So, you're {age} old, {height} tall and {weight} heavy.") 11 | 12 | script, filename = argv 13 | 14 | txt = open(filename) 15 | 16 | print(f"Here's your file {filename}:") 17 | print(txt.read()) 18 | 19 | print("Type the filename again:") 20 | file_again = input("> ") 21 | 22 | txt_again = open(file_again) 23 | 24 | print(txt_again.read()) 25 | 26 | print("Let's practice everything.") 27 | print('You\'d need to know \'bout escapes with \\ that do:') 28 | print('\n newlines and \t tabs.') 29 | 30 | poem = """ 31 | \tThe lovely world 32 | with logic so firmly planted 33 | cannot discern \n the needs of love 34 | nor comprehend passion from intuition 35 | and requires an explanation 36 | \n\t\twhere there is none. 37 | """ 38 | 39 | print("--------------") 40 | print(poem) 41 | print("--------------") 42 | 43 | five = 10 - 2 + 3 - 6 44 | print(f"This should be five: {five}") 45 | 46 | 47 | def secret_formula(started): 48 | jelly_beans = started * 500 49 | jars = jelly_beans / 1000 50 | crates = jars / 100 51 | return jelly_beans, jars, crates 52 | 53 | 54 | start_point = 10000 55 | beans, jars, crates = secret_formula(start_point) 56 | 57 | # remember that this is another way to format a string 58 | print("With a starting point of: {}".format(start_point)) 59 | # it's just like with an f"" string 60 | print(f"We'd have {beans} beans, {jars} jars, and {crates} crates.") 61 | 62 | start_point = start_point / 10 63 | 64 | print("We can also do that this way:") 65 | formula = secret_formula(start_point) 66 | # this is an easy way to apply a list to a format string 67 | print("We'd have {} beans, {} jars, and {} crates.".format(*formula)) 68 | 69 | people = 20 70 | cats = 30 71 | dogs = 15 72 | 73 | if people < cats: 74 | print("Too many cats! The world is doomed!") 75 | 76 | if people > cats: 77 | print("Not many cats! The world is saved!") 78 | 79 | if people < dogs: 80 | print("The world is drooled on!") 81 | 82 | if people > dogs: 83 | print("The world is dry!") 84 | 85 | dogs += 5 86 | 87 | if people >= dogs: 88 | print("People are greater than or equal to dogs.") 89 | 90 | if people <= dogs: 91 | print("People are less than or equal to dogs.") 92 | 93 | if people == dogs: 94 | print("People are dogs.") 95 | -------------------------------------------------------------------------------- /ex29.py: -------------------------------------------------------------------------------- 1 | people = 20 2 | cats = 30 3 | dogs = 15 4 | 5 | if people < cats: 6 | print("Too many cats! The world is doomed!") 7 | 8 | if people > cats: 9 | print("Not many cats! The world is saved!") 10 | 11 | if people < dogs: 12 | print("The world is drooled on!") 13 | 14 | if people > dogs: 15 | print("The world is dry!") 16 | 17 | dogs += 5 18 | 19 | if people >= dogs: 20 | print("People are greater than or equal to dogs.") 21 | 22 | if people <= dogs: 23 | print("People are less than or equal to dogs.") 24 | 25 | if people == dogs: 26 | print("People are dogs.") 27 | -------------------------------------------------------------------------------- /ex30.py: -------------------------------------------------------------------------------- 1 | people = 30 2 | cars = 40 3 | trucks = 15 4 | 5 | if cars > people: 6 | print("We should take the cars.") 7 | elif cars < people: 8 | print("We should not take the cars.") 9 | else: 10 | print("We can't decide.") 11 | 12 | if trucks > cars: 13 | print("That's too many trucks.") 14 | elif trucks < cars: 15 | print("Maybe we could take the trucks.") 16 | else: 17 | print("We still can't decide.") 18 | 19 | if people > trucks: 20 | print("Alright, let's just take the trucks.") 21 | else: 22 | print("Fine, let's stay home then.") 23 | -------------------------------------------------------------------------------- /ex31.py: -------------------------------------------------------------------------------- 1 | print("You enter a dark room with two doors.") 2 | print("Do you go through door #1 or door #2?") 3 | 4 | door = input("> ") 5 | 6 | if door == "1": 7 | print("There's a giant bear here eating a cheese cake.") 8 | print("What do you do?") 9 | print("1. Take the cake.") 10 | print("2. Scream at the bear.") 11 | 12 | bear = input("> ") 13 | 14 | if bear == "1": 15 | print("The bear eats your face off. Good job!") 16 | elif bear == "2": 17 | print("The bear eats your legs off. Good job!") 18 | else: 19 | print(f"Well, doing {bear} is probably better.") 20 | print("Bear runs away.") 21 | 22 | elif door == "2": 23 | print("You stare into the endless abyss at Cthulhu's retina.") 24 | print("1. Blueberries.") 25 | print("2. Yellow jacket clothespins.") 26 | print("3. Understanding revolvers yelling melodies.") 27 | 28 | insanity = input("> ") 29 | 30 | if insanity == "1" or insanity == "2": 31 | print("Your body survives powered by a mind of jello.") 32 | print("Good job!") 33 | else: 34 | print("The insanity rots your eyes into a pool of muck.") 35 | print("Good job!") 36 | 37 | else: 38 | print("You stumble around and fall on knife and die. Good job!") 39 | -------------------------------------------------------------------------------- /ex32.py: -------------------------------------------------------------------------------- 1 | the_count = [1, 2, 3, 4, 5] 2 | fruits = ['apples', 'oranges', 'pears', 'apricots'] 3 | change = [1, 'pennies', 2, 'dimes', 3, 'quarters'] 4 | 5 | # this first kind of for-loop goes through a list 6 | for number in the_count: 7 | print(f"This is count {number}") 8 | 9 | # same as above 10 | for fruit in fruits: 11 | print(f"A fruit of type: {fruit}") 12 | 13 | # also we can go through mixed lists too 14 | # notice we have to use %r since we don't know what's in items 15 | for i in change: 16 | print(f"I got {i}") 17 | 18 | # we can also build lists, first start with an empty one 19 | elements = [] 20 | 21 | # then use the range function to do 0 to 5 counts 22 | for i in range(0, 6): 23 | print(f"Adding {i} to the list.") 24 | # append is a function that lists understand 25 | elements.append(i) 26 | 27 | # now we can print them out too 28 | for i in elements: 29 | print(f"Element was: {i}") 30 | -------------------------------------------------------------------------------- /ex33.py: -------------------------------------------------------------------------------- 1 | i = 0 2 | numbers = [] 3 | 4 | while i < 6: 5 | print(f"At the top i is {i}") 6 | numbers.append(i) 7 | 8 | i = i + 1 9 | print("Numbers now: ", numbers) 10 | print(f"At the bottom i is {i}") 11 | 12 | print("The numbers: ") 13 | 14 | for num in numbers: 15 | print(num) 16 | -------------------------------------------------------------------------------- /ex35.py: -------------------------------------------------------------------------------- 1 | from sys import exit 2 | 3 | 4 | def gold_room(): 5 | print("This room is full of gold. How much do you take?") 6 | 7 | choice = input("> ") 8 | if "0" in choice or "1" in choice: 9 | how_much = int(choice) 10 | else: 11 | dead("Man, learn to type a number.") 12 | 13 | if how_much < 50: 14 | print("Nice, you're not greedy, you win!") 15 | exit(0) 16 | else: 17 | dead("You greedy bastard!") 18 | 19 | 20 | def bear_room(): 21 | print("There is bear here.") 22 | print("The bear has a bunch of honey.") 23 | print("The fat bear is in front of another door.") 24 | print("How are you going to move the bear?") 25 | bear_moved = False 26 | 27 | while True: 28 | choice = input("> ") 29 | 30 | if choice == "take honey": 31 | dead("The bear looks at you then slaps your face off.") 32 | elif choice == "taunt bear" and not bear_moved: 33 | print("The bear has moved from the door.") 34 | print("You can go through it now.") 35 | bear_moved = True 36 | elif choice == "taunt bear" and bear_moved: 37 | dead("The bear gets pissed off and chews your leg off.") 38 | elif choice == "open door" and bear_moved: 39 | gold_room() 40 | else: 41 | print("I got no idea what that means.") 42 | 43 | 44 | def cthulhu_room(): 45 | print("Here you see the great evil Cthulhu.") 46 | print("He, it, whatever stares at you and you go insane.") 47 | print("Do you flee for your life or eat your head?") 48 | 49 | choice = input("> ") 50 | 51 | if "flee" in choice: 52 | start() 53 | elif "head" in choice: 54 | dead("Well that was tasty!") 55 | else: 56 | cthulhu_room() 57 | 58 | 59 | def dead(why): 60 | print(why, "Good job!") 61 | exit(0) 62 | 63 | 64 | def start(): 65 | print("You are in a dark room.") 66 | print("There is a door to your right and left.") 67 | print("Which one do you take?") 68 | 69 | choice = input("> ") 70 | 71 | if choice == "left": 72 | bear_room() 73 | elif choice == "right": 74 | cthulhu_room() 75 | else: 76 | dead("You stumble around the room until you starve.") 77 | 78 | 79 | start() 80 | -------------------------------------------------------------------------------- /ex38.py: -------------------------------------------------------------------------------- 1 | ten_things = "Apples Oranges Crows Telephone Light Sugar" 2 | 3 | print("Wait there's not 10 things in that list, let's fix that.") 4 | 5 | stuff = ten_things.split(' ') 6 | more_stuff = ["Day", "Night", "Song", "Frisbee", 7 | "Corn", "Banana", "Girl", "Boy"] 8 | 9 | while len(stuff) != 10: 10 | next_one = more_stuff.pop() 11 | print("Adding: ", next_one) 12 | stuff.append(next_one) 13 | print(f"There's {len(stuff)} items now.") 14 | 15 | print("There we go: ", stuff) 16 | 17 | print("Let's do some things with stuff.") 18 | 19 | print(stuff[1]) 20 | print(stuff[-1]) # whoa! fancy 21 | print(stuff.pop()) 22 | print(' '.join(stuff)) # what= cool! 23 | print('#'.join(stuff[3:5])) # super stellar! 24 | -------------------------------------------------------------------------------- /ex39.py: -------------------------------------------------------------------------------- 1 | # create a mapping of state to abbreviation 2 | states = { 3 | 'Oregon': 'OR', 4 | 'Florida': 'FL', 5 | 'California': 'CA', 6 | 'New York': 'NY', 7 | 'Michigan': 'MI' 8 | } 9 | 10 | # create a basic set of states and some cities in them 11 | cities = {'CA': 'San Francisco', 12 | 'MI': 'Detroit', 13 | 'FL': 'Jacksonville'} 14 | 15 | # add some more cities 16 | cities['NY'] = 'New York' 17 | cities['OR'] = 'Portland' 18 | 19 | # print out some cities 20 | print('-' * 10) 21 | print("NY State has: ", cities['NY']) 22 | print("OR State has: ", cities['OR']) 23 | 24 | # print some states 25 | print('-' * 10) 26 | print("Michigan's abbreviation is: ", states["Michigan"]) 27 | print("Florida's abbreviation is: ", states['Florida']) 28 | 29 | # do it by using the state then cities dict 30 | print('-' * 10) 31 | print("Michigan has: ", cities[states['Michigan']]) 32 | print("Florida has: ", cities[states['Florida']]) 33 | 34 | # print every state abbreviation 35 | print('-' * 10) 36 | for state, abbrev in states.items(): 37 | print(f"{state} is abbreviated {abbrev}") 38 | 39 | # print every city in state 40 | print('-' * 10) 41 | for abbrev, city in cities.items(): 42 | print(f"{abbrev} has the city {city}") 43 | 44 | # now do both at the same time 45 | print('-' * 10) 46 | for state, abbrev in states.items(): 47 | print(f"{state} state is abbreviated {abbrev}") 48 | print(f"and has city {cities[abbrev]}") 49 | 50 | print('-' * 10) 51 | # safely get an abbreviation by state that might not be there 52 | state = states.get('Texas') 53 | 54 | if not state: 55 | print("Sorry, no Texas.") 56 | 57 | # get a city with a default values 58 | city = cities.get('TX', 'Does not Exist') 59 | print(f"The city for the state 'TX' is: {city}") 60 | -------------------------------------------------------------------------------- /ex40.py: -------------------------------------------------------------------------------- 1 | class Song(object): 2 | def __init__(self, lyrics): 3 | self.lyrics = lyrics 4 | 5 | def sing_me_a_song(self): 6 | for line in self.lyrics: 7 | print(line) 8 | 9 | 10 | happy_bday = Song(["Happy birthday to you", 11 | "I don't want to get sued", 12 | "So I'll stop right there"]) 13 | 14 | bulls_on_parade = Song(["They rally around the family", 15 | "With pockets full of shells"]) 16 | 17 | happy_bday.sing_me_a_song() 18 | 19 | bulls_on_parade.sing_me_a_song() 20 | -------------------------------------------------------------------------------- /ex41.py: -------------------------------------------------------------------------------- 1 | import random 2 | import sys 3 | from urllib.request import urlopen 4 | 5 | WORD_URL = "http://learncodethehardway.org/words.txt" 6 | WORDS = [] 7 | 8 | PHRASES = { 9 | "class %%%(%%%):": 10 | "Make a class named %%% that is-a %%%.", 11 | "class %%%(object):\n\tdef __init__(self, ***)": 12 | "class %%% has-a __init__ that takes self and *** params.", 13 | "class %%%(object):\n\tdef ***(self, @@@)": 14 | "class %%% has-a function *** that takes self and @@@ params.", 15 | "*** = %%%()": 16 | "Set *** to an instance of class %%%.", 17 | "***.***(@@@)": 18 | "From *** get the *** function, and call it with params self, @@@.", 19 | "***.*** = '***'": 20 | "From *** get the *** attribute and set it to '***'." 21 | } 22 | 23 | # do they want to drill phrases first 24 | if len(sys.argv) == 2 and sys.argv[1] == "english": 25 | PHRASE_FIRST = True 26 | else: 27 | PHRASE_FIRST = False 28 | 29 | # load up the words from the website 30 | for word in urlopen(WORD_URL).readlines(): 31 | WORDS.append(str(word.strip(), encoding="utf-8")) 32 | 33 | 34 | def convert(snippet, phrase): 35 | class_names = [w.capitalize() for w in 36 | random.sample(WORDS, snippet.count("%%%"))] 37 | other_names = random.sample(WORDS, snippet.count("***")) 38 | results = [] 39 | param_names = [] 40 | 41 | for i in range(0, snippet.count("@@@")): 42 | param_count = random.randint(1, 3) 43 | param_names.append(', '.join( 44 | random.sample(WORDS, param_count))) 45 | 46 | for sentence in snippet, phrase: 47 | result = sentence[:] 48 | 49 | # fake class names 50 | for word in class_names: 51 | result = result.replace("%%%", word, 1) 52 | 53 | # fake other names 54 | for word in other_names: 55 | result = result.replace("***", word, 1) 56 | 57 | # fake parameter lists 58 | for word in param_names: 59 | result = result.replace("@@@", word, 1) 60 | 61 | results.append(result) 62 | 63 | return results 64 | 65 | 66 | # keep going until they hit CTRL-D 67 | try: 68 | while True: 69 | snippets = list(PHRASES.keys()) 70 | random.shuffle(snippets) 71 | 72 | for snippet in snippets: 73 | phrase = PHRASES[snippet] 74 | question, answer = convert(snippet, phrase) 75 | if PHRASE_FIRST: 76 | question, answer = answer, question 77 | 78 | print(question) 79 | 80 | input("> ") 81 | print(f"ANSWER: {answer}\n\n") 82 | except EOFError: 83 | print("\nBye") 84 | -------------------------------------------------------------------------------- /ex42.py: -------------------------------------------------------------------------------- 1 | ## Animal is-a object (yes, sort of confusing) look at the extra credit 2 | class Animal(object): 3 | pass 4 | 5 | 6 | ## Dog is-a Animal 7 | class Dog(Animal): 8 | def __init__(self, name): 9 | ## Dog has-a name 10 | self.name = name 11 | 12 | 13 | ## Cat is-a Animal 14 | class Cat(Animal): 15 | def __init__(self, name): 16 | ## Cat has a name 17 | self.name = name 18 | 19 | 20 | ## Person is-a object 21 | class Person(object): 22 | def __init__(self, name): 23 | ## Person has-a name 24 | self.name = name 25 | 26 | ## Person has-a pet of some kind 27 | self.pet = None 28 | 29 | 30 | ## Employee is-a Person 31 | class Employee(Person): 32 | def __init__(self, name, salary): 33 | ## Employee has-a name 34 | super(Employee, self).__init__(name) 35 | ## Employee has-a salary 36 | self.salary = salary 37 | 38 | 39 | ## Fish is-a object 40 | class Fish(object): 41 | pass 42 | 43 | 44 | ## Salmon is-a Fish 45 | class Salmon(Fish): 46 | pass 47 | 48 | 49 | ## Halibut is a Fish 50 | class Halibut(Fish): 51 | pass 52 | 53 | 54 | ## rover is-a Dog 55 | rover = Dog("Rover") 56 | 57 | ## satan is-a Cat 58 | satan = Cat("Satan") 59 | 60 | ## mary is-a Person 61 | mary = Person("Mary") 62 | 63 | ## mary has-a pet 64 | mary.pet = satan 65 | 66 | ## frank is-a Employee 67 | frank = Employee("Frank", 120000) 68 | 69 | ## frank has-a pet 70 | frank.pet = rover 71 | 72 | ## flipper is-a Fish 73 | flipper = Fish() 74 | 75 | ## crouse is-a Salmon 76 | crouse = Salmon() 77 | 78 | ## harry is-a Halibut 79 | harry = Halibut() 80 | -------------------------------------------------------------------------------- /ex43.py: -------------------------------------------------------------------------------- 1 | from random import randint 2 | from sys import exit 3 | from textwrap import dedent 4 | 5 | 6 | class Scene(object): 7 | def enter(self): 8 | print("This scene is not yet configured.") 9 | print("Subclass it and implement enter().") 10 | exit(1) 11 | 12 | 13 | class Engine(object): 14 | def __init__(self, scene_map): 15 | self.scene_map = scene_map 16 | 17 | def play(self): 18 | current_scene = self.scene_map.opening_scene() 19 | last_scene = self.scene_map.next_scene('finished') 20 | 21 | while current_scene != last_scene: 22 | next_scene_name = current_scene.enter() 23 | current_scene = self.scene_map.next_scene(next_scene_name) 24 | 25 | # be sure to print out the last scene 26 | current_scene.enter() 27 | 28 | 29 | class Death(Scene): 30 | quips = [ 31 | "You died. You kinda suck at this.", 32 | "Your mom would be proud...if she were smarter.", 33 | "Such a luser.", 34 | "I have a small puppy that's better at this.", 35 | "You're worse than yor Dad's jokes" 36 | ] 37 | 38 | def enter(self): 39 | print(Death.quips[randint(0, len(self.quips) - 1)]) 40 | exit(1) 41 | 42 | 43 | class CentralCorridor(Scene): 44 | def enter(self): 45 | print(dedent(""" 46 | The Gothons of Planet Percal #25 have invaded your ship and 47 | destroyed your entire crew. You are the last surviving 48 | member and your last mission is to get the neutron destruct 49 | bomb from the Weapons Armory, put it in the bridge, and 50 | blow the ship up after getting into an escape pod. 51 | 52 | You're running down the central corridor to the Weapons 53 | Armory when a Gothon jumps out, red scaly skin, dark grimy 54 | teeth, and evil clown costume flowing around his hate 55 | filled body. He's blocking the door to the Armory and 56 | about to pull a weapon to blast you. 57 | """)) 58 | 59 | action = input("> ") 60 | 61 | if action == "shoot!": 62 | print(dedent(""" 63 | Quick on the draw you yank out your blaster and fire 64 | it at the Gothon. His clown costume is flowing and 65 | moving around his body, which throws off your aim. 66 | Your laser hits his costume but misses him entirely. 67 | This completely ruins his brand new costume his mother 68 | bought him, which makes him fly into an insane rage 69 | and blast you repeatedly in the face until you are 70 | dead. Then he eats you. 71 | """)) 72 | return 'death' 73 | 74 | elif action == "dodge!": 75 | print(dedent(""" 76 | Like a world class boxer you dodge, weave, slip and 77 | slide right as the Gothon's blaster cranks a laser 78 | past your head. In the middle of your artful dodge 79 | your foot slips and you bang your head on the metal 80 | wall and pass out. You wake up shortly after only to 81 | die as the Gothon stomps on your head and eats you. 82 | """)) 83 | return 'death' 84 | 85 | elif action == "tell a joke": 86 | print(dedent(""" 87 | Lucky for you they made you learn Gothon insults in 88 | the academy. You tell the one Gothon joke you know: 89 | Lbhe zbgure vf fb sng, jura fur fvgf nebhaq gur ubhfr, 90 | fur fvgf nebhaq gur ubhfr. The Gothon stops, tries 91 | not to laugh, then busts out laughing and can't move. 92 | While he's laughing you run up and shoot him square in 93 | the head putting him down, then jump through the 94 | Weapon Armory door. 95 | """)) 96 | return 'laser_weapon_armory' 97 | 98 | else: 99 | print("DOES NOT COMPUTE!") 100 | return 'central_corridor' 101 | 102 | 103 | class LaserWeaponArmory(Scene): 104 | def enter(self): 105 | print(dedent(""" 106 | You do a dive roll into the Weapon Armory, crouch and scan 107 | the room for more Gothons that might be hiding. It's dead 108 | quiet, too quiet. You stand up and run to the far side of 109 | the room and find the neutron bomb in its container. 110 | There's a keypad lock on the box and you need the code to 111 | get the bomb out. If you get the code wrong 10 times then 112 | the lock closes forever and you can't get the bomb. The 113 | code is 3 digits. 114 | """)) 115 | 116 | code = f"{randint(1,9)}{randint(1,9)}{randint(1,9)}" 117 | guess = input("[keypad]> ") 118 | guesses = 0 119 | 120 | while guess != code and guesses < 10: 121 | print("BZZZZEDDD!") 122 | guesses += 1 123 | guess = input("[keypad]> ") 124 | 125 | if guess == code: 126 | print(dedent(""" 127 | The container clicks open and the seal breaks, letting 128 | gas out. You grab the neutron bomb and run as fast as 129 | you can to the bridge where you must place it in the 130 | right spot. 131 | """)) 132 | return 'the_bridge' 133 | else: 134 | print(dedent(""" 135 | The lock buzzes one last time and then you hear a 136 | sickening melting sound as the mechanism is fused 137 | together. You decide to sit there, and finally the 138 | Gothons blow up the ship from their ship and you die. 139 | """)) 140 | return 'death' 141 | 142 | 143 | class TheBridge(Scene): 144 | def enter(self): 145 | print(dedent(""" 146 | You burst onto the Bridge with the netron destruct bomb 147 | under your arm and surprise 5 Gothons who are trying to 148 | take control of the ship. Each of them has an even uglier 149 | clown costume than the last. They haven't pulled their 150 | weapons out yet, as they see the active bomb under your 151 | arm and don't want to set it off. 152 | """)) 153 | 154 | action = input("> ") 155 | 156 | if action == "throw the bomb": 157 | print(dedent(""" 158 | In a panic you throw the bomb at the group of Gothons 159 | and make a leap for the door. Right as you drop it a 160 | Gothon shoots you right in the back killing you. As 161 | you die you see another Gothon frantically try to 162 | disarm the bomb. You die knowing they will probably 163 | blow up when it goes off. 164 | """)) 165 | return 'death' 166 | 167 | elif action == "slowly place the bomb": 168 | print(dedent(""" 169 | You point your blaster at the bomb under your arm and 170 | the Gothons put their hands up and start to sweat. 171 | You inch backward to the door, open it, and then 172 | carefully place the bomb on the floor, pointing your 173 | blaster at it. You then jump back through the door, 174 | punch the close button and blast the lock so the 175 | Gothons can't get out. Now that the bomb is placed 176 | you run to the escape pod to get off this tin can. 177 | """)) 178 | 179 | return 'escape_pod' 180 | else: 181 | print("DOES NOT COMPUTE!") 182 | return 'the_bridge' 183 | 184 | 185 | class EscapePod(Scene): 186 | def enter(self): 187 | print(dedent(""" 188 | You rush through the ship desperately trying to make it to 189 | the escape pod before the whole ship explodes. It seems 190 | like hardly any Gothons are on the ship, so your run is 191 | clear of interference. You get to the chamber with the 192 | escape pods, and now need to pick one to take. Some of 193 | them could be damaged but you don't have time to look. 194 | There's 5 pods, which one do you take? 195 | """)) 196 | 197 | good_pod = randint(1, 5) 198 | guess = input("[pod #]> ") 199 | 200 | if int(guess) != good_pod: 201 | print(dedent(f""" 202 | You jump into pod {guess} and hit the eject button. 203 | The pod escapes out into the void of space, then 204 | implodes as the hull ruptures, crushing your body into 205 | jam jelly. 206 | """)) 207 | 208 | return 'death' 209 | else: 210 | print(dedent(f""" 211 | You jump into pod {guess} and hit the eject button. 212 | The pod easily slides out into space heading to the 213 | planet below. As it flies to the planet, you look 214 | back and see your ship implode then explode like a 215 | bright star, taking out the Gothon ship at the same 216 | time. You won! 217 | """)) 218 | 219 | return 'finished' 220 | 221 | 222 | class Finished(Scene): 223 | def enter(self): 224 | print("You won! Good job.") 225 | return 'finished' 226 | 227 | 228 | class Map(object): 229 | scenes = { 230 | 'central_corridor': CentralCorridor(), 231 | 'laser_weapon_armory': LaserWeaponArmory(), 232 | 'the_bridge': TheBridge(), 233 | 'escape_pod': EscapePod(), 234 | 'death': Death(), 235 | 'finished': Finished() 236 | } 237 | 238 | def __init__(self, start_scene): 239 | self.start_scene = start_scene 240 | 241 | def next_scene(self, scene_name): 242 | val = Map.scenes.get(scene_name) 243 | return val 244 | 245 | def opening_scene(self): 246 | return self.next_scene(self.start_scene) 247 | 248 | 249 | a_map = Map('central_corridor') 250 | a_game = Engine(a_map) 251 | a_game.play() 252 | -------------------------------------------------------------------------------- /ex44a.py: -------------------------------------------------------------------------------- 1 | class Parent(object): 2 | def implicit(self): 3 | print("PARENT implicit()") 4 | 5 | 6 | class Child(Parent): 7 | pass 8 | 9 | 10 | dad = Parent() 11 | son = Child() 12 | 13 | dad.implicit() 14 | son.implicit() 15 | -------------------------------------------------------------------------------- /ex44b.py: -------------------------------------------------------------------------------- 1 | class Parent(object): 2 | def override(self): 3 | print("PARENT override()") 4 | 5 | 6 | class Child(Parent): 7 | def override(self): 8 | print("CHILD override()") 9 | 10 | 11 | dad = Parent() 12 | son = Child() 13 | 14 | dad.override() 15 | son.override() 16 | -------------------------------------------------------------------------------- /ex44c.py: -------------------------------------------------------------------------------- 1 | class Parent(object): 2 | def altered(self): 3 | print("PARENT altered()") 4 | 5 | 6 | class Child(Parent): 7 | def altered(self): 8 | print("CHILD, BEFORE PARENT altered()") 9 | super(Child, self).altered() 10 | print("CHILD, AFTER PARENT altered()") 11 | 12 | 13 | dad = Parent() 14 | son = Child() 15 | 16 | dad.altered() 17 | son.altered() 18 | -------------------------------------------------------------------------------- /ex44d.py: -------------------------------------------------------------------------------- 1 | class Parent(object): 2 | def override(self): 3 | print("PARENT override()") 4 | 5 | def implicit(self): 6 | print("PARENT implicit()") 7 | 8 | def altered(self): 9 | print("PARENT altered()") 10 | 11 | 12 | class Child(Parent): 13 | def override(self): 14 | print("CHILD override()") 15 | 16 | def altered(self): 17 | print("CHILD, BEFORE PARENT altered()") 18 | super(Child, self).altered() 19 | print("CHILD, AFTER PARENT altered()") 20 | 21 | 22 | dad = Parent() 23 | son = Child() 24 | 25 | dad.implicit() 26 | son.implicit() 27 | 28 | dad.override() 29 | son.override() 30 | 31 | dad.altered() 32 | son.altered() 33 | -------------------------------------------------------------------------------- /ex44e.py: -------------------------------------------------------------------------------- 1 | class Other(object): 2 | def override(self): 3 | print("OTHER override()") 4 | 5 | def implicit(self): 6 | print("OTHER implicit()") 7 | 8 | def altered(self): 9 | print("OTHER altered()") 10 | 11 | 12 | class Child(object): 13 | def __init__(self): 14 | self.other = Other() 15 | 16 | def implicit(self): 17 | self.other.implicit() 18 | 19 | def override(self): 20 | print("CHILD override()") 21 | 22 | def altered(self): 23 | print("CHILD, BEFORE OTHER altered()") 24 | self.other.altered() 25 | print("CHILD, AFTER OTHER altered()") 26 | 27 | 28 | son = Child() 29 | 30 | son.implicit() 31 | son.override() 32 | son.altered() 33 | -------------------------------------------------------------------------------- /exercise26.txt: -------------------------------------------------------------------------------- 1 | print("How old are you?", end=' ') 2 | age = input() 3 | print("How tall are you?", end=' ') 4 | print("How much do you weigh?", end=' ' 5 | weight = input() 6 | 7 | print(f"So, you're {age} old, {height} tall and {weight} heavy.") 8 | 9 | script, filename = argv 10 | 11 | txt = open(filenme) 12 | 13 | print("Here's your file {filename}:") 14 | print(tx.read()) 15 | 16 | print("Type the filename again:") 17 | file_again = input("> ") 18 | 19 | txt_again = open(file_again) 20 | 21 | print(txt_again_read()) 22 | 23 | 24 | print('Let's practice everything.') 25 | print('You\'d need to know \'bout escapes 26 | with \\ that do \n newlines and \t tabs.') 27 | 28 | poem = """ 29 | \tThe lovely world 30 | with logic so firmly planted 31 | cannot discern \n the needs of love 32 | nor comprehend passion from intuition 33 | and requires an explanation 34 | \n\t\twhere there is none. 35 | """ 36 | 37 | print("--------------) 38 | print(poem) 39 | print(--------------") 40 | 41 | 42 | five = 10 - 2 + 3 - 43 | print(f"This should be five: {five}" 44 | 45 | def secret_formula(started) 46 | jelly_beans = started * 500 47 | jars = jelly_beans / 1000 48 | crates = jars 100 49 | return jelly_beans, jars, crates 50 | 51 | 52 | start_point = 10000 53 | beans, jars = secret_formula(start_point) 54 | 55 | # remember that this is another way to format a string 56 | print("With a starting point of: {}".format(start_point)) 57 | # it's just like with an f"" string 58 | print(f"We'd have {beans} beans, {jars} jars, and {crates} crates.") 59 | 60 | start_point = start_point / 10 61 | 62 | print("We can also do that this way:") 63 | formula = secret_formula(startpoint) 64 | # this is an easy way to apply a list to a format string 65 | print("We'd have {} beans, {} jars, and {} crates.".format(*formula)) 66 | 67 | 68 | 69 | people = 20 70 | cates = 30 71 | dogs = 15 72 | 73 | 74 | if people < cats: 75 | print "Too many cats! The world is doomed!" 76 | 77 | if people < cats: 78 | print("Not many cats! The world is saved!") 79 | 80 | if people < dogs: 81 | print("The world is drooled on!") 82 | 83 | if people > dogs 84 | print("The world is dry!") 85 | 86 | 87 | dogs += 5 88 | 89 | if people >= dogs: 90 | print("People are greater than or equal to dogs.") 91 | 92 | if people <= dogs 93 | print("People are less than or equal to dogs.) 94 | 95 | 96 | if people = dogs: 97 | print("People are dogs.") -------------------------------------------------------------------------------- /languages.txt: -------------------------------------------------------------------------------- 1 | Afrikaans 2 | አማርኛ 3 | Аҧсшәа 4 | العربية 5 | Aragonés 6 | Arpetan 7 | Azərbaycanca 8 | Bamanankan 9 | বাংলা 10 | Bân-lâm-gú 11 | Беларуская 12 | Български 13 | Boarisch 14 | Bosanski 15 | Буряад 16 | Català 17 | Чӑвашла 18 | Čeština 19 | Cymraeg 20 | Dansk 21 | Deutsch 22 | Eesti 23 | Ελληνικά 24 | Español 25 | Esperanto 26 | فارسی 27 | Français 28 | Frysk 29 | Gaelg 30 | Gàidhlig 31 | Galego 32 | 한국어 33 | Հայերեն 34 | हिन्दी 35 | Hrvatski 36 | Ido 37 | Interlingua 38 | Italiano 39 | עברית 40 | ಕನ್ನಡ 41 | Kapampangan 42 | ქართული 43 | Қазақша 44 | Kreyòl ayisyen 45 | Latgaļu 46 | Latina 47 | Latviešu 48 | Lëtzebuergesch 49 | Lietuvių 50 | Magyar 51 | Македонски 52 | Malti 53 | मराठी 54 | მარგალური 55 | مازِرونی 56 | Bahasa Melayu 57 | Монгол 58 | Nederlands 59 | नेपाल भाषा 60 | 日本語 61 | Norsk bokmål 62 | Nouormand 63 | Occitan 64 | Oʻzbekcha/ўзбекча 65 | ਪੰਜਾਬੀ 66 | پنجابی 67 | پښتو 68 | Plattdüütsch 69 | Polski 70 | Português 71 | Română 72 | Romani 73 | Русский 74 | Seeltersk 75 | Shqip 76 | Simple English 77 | Slovenčina 78 | کوردیی ناوەندی 79 | Српски / srpski 80 | Suomi 81 | Svenska 82 | Tagalog 83 | தமிழ் 84 | ภาษาไทย 85 | Taqbaylit 86 | Татарча/tatarça 87 | తెలుగు 88 | Тоҷикӣ 89 | Türkçe 90 | Українська 91 | اردو 92 | Tiếng Việt 93 | Võro 94 | 文言 95 | 吴语 96 | ייִדיש 97 | 中文 98 | -------------------------------------------------------------------------------- /new_file.txt: -------------------------------------------------------------------------------- 1 | Mary had a little lamb 2 | Its fleece was white as snow 3 | It was also tasty -------------------------------------------------------------------------------- /projects/gothonweb/app.py: -------------------------------------------------------------------------------- 1 | from flask import Flask, session, redirect, url_for, request 2 | from flask import render_template 3 | from gothonweb import planisphere 4 | 5 | app = Flask(__name__) 6 | 7 | 8 | @app.route("/") 9 | def index(): 10 | # this is used to "setup" the session with starting values 11 | session['room_name'] = planisphere.START 12 | return redirect(url_for("game")) 13 | 14 | 15 | @app.route("/game", methods=['GET', 'POST']) 16 | def game(): 17 | room_name = session.get('room_name') 18 | 19 | if request.method == "GET": 20 | if room_name: 21 | room = planisphere.load_room(room_name) 22 | return render_template("show_room.html", room=room) 23 | else: 24 | # why is this here? do you need it? 25 | return render_template("you_died.html") 26 | else: 27 | action = request.form.get('action') 28 | 29 | if room_name and action: 30 | room = planisphere.load_room(room_name) 31 | next_room = room.go(action) 32 | 33 | if not next_room: 34 | session['room_name'] = planisphere.name_room(room) 35 | else: 36 | session['room_name'] = planisphere.name_room(next_room) 37 | 38 | return redirect(url_for("game")) 39 | 40 | 41 | # YOU SHOULD CHANGE THIS IF YOU PUT ON THE INTERNET 42 | app.secret_key = 'ASDf323rFF%$t2gfwgw74' 43 | 44 | 45 | @app.route("/hello", methods=['POST', 'GET']) 46 | def hello(): 47 | greeting = "Hello World" 48 | 49 | if request.method == "POST": 50 | name = request.form['name'] 51 | greet = request.form['greet'] 52 | greeting = f"{greet}, {name}" 53 | return render_template("hello.html", greeting=greeting) 54 | else: 55 | return render_template("hello_form.html") 56 | 57 | 58 | if __name__ == "__main__": 59 | app.run() 60 | -------------------------------------------------------------------------------- /projects/gothonweb/gothonweb/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ubarredo/LearnPythonTheHardWay/bce36594853ffba54b442619d6c2f636324717c3/projects/gothonweb/gothonweb/__init__.py -------------------------------------------------------------------------------- /projects/gothonweb/gothonweb/planisphere.py: -------------------------------------------------------------------------------- 1 | class Room(object): 2 | 3 | def __init__(self, name, description): 4 | self.name = name 5 | self.description = description 6 | self.paths = {} 7 | 8 | def go(self, direction): 9 | return self.paths.get(direction, None) 10 | 11 | def add_paths(self, paths): 12 | self.paths.update(paths) 13 | 14 | 15 | central_corridor = Room("Central Corridor", 16 | """ 17 | The Gothons of Planet Percal #25 have invaded your ship and destroyed 18 | your entire crew. You are the last surviving member and your last 19 | mission is to get the neutron destruct bomb from the Weapons Armory, put 20 | it in the bridge, and blow the ship up after getting into an escape pod. 21 | 22 | You're running down the central corridor to the Weapons Armory when a 23 | Gothon jumps out, red scaly skin, dark grimy teeth, and evil clown 24 | costume flowing around his hate filled body. He's blocking the door to 25 | the Armory and about to pull a weapon to blast you. 26 | """) 27 | 28 | 29 | laser_weapon_armory = Room("Laser Weapon Armory", 30 | """ 31 | Lucky for you they made you learn Gothon insults in the academy. You 32 | tell the one Gothon joke you know: Lbhe zbgure vf fb sng, jura fur fvgf 33 | nebhaq gur ubhfr, fur fvgf nebhaq gur ubhfr. The Gothon stops, tries 34 | not to laugh, then busts out laughing and can't move. While he's 35 | laughing you run up and shoot him square in the head putting him down, 36 | then jump through the Weapon Armory door. 37 | 38 | You do a dive roll into the Weapon Armory, crouch and scan the room for 39 | more Gothons that might be hiding. It's dead quiet, too quiet. You 40 | stand up and run to the far side of the room and find the neutron bomb 41 | in its container. There's a keypad lock on the box and you need the 42 | code to get the bomb out. If you get the code wrong 10 times then the 43 | lock closes forever and you can't get the bomb. The code is 3 digits. 44 | """) 45 | 46 | 47 | the_bridge = Room("The Bridge", 48 | """ 49 | The container clicks open and the seal breaks, letting gas out. You 50 | grab the neutron bomb and run as fast as you can to the bridge where you 51 | must place it in the right spot. 52 | 53 | You burst onto the Bridge with the netron destruct bomb under your arm 54 | and surprise 5 Gothons who are trying to take control of the ship. Each 55 | of them has an even uglier clown costume than the last. They haven't 56 | pulled their weapons out yet, as they see the active bomb under your arm 57 | and don't want to set it off. 58 | """) 59 | 60 | 61 | escape_pod = Room("Escape Pod", 62 | """ 63 | You point your blaster at the bomb under your arm and the Gothons put 64 | their hands up and start to sweat. You inch backward to the door, open 65 | it, and then carefully place the bomb on the floor, pointing your 66 | blaster at it. You then jump back through the door, punch the close 67 | button and blast the lock so the Gothons can't get out. Now that the 68 | bomb is placed you run to the escape pod to get off this tin can. 69 | 70 | You rush through the ship desperately trying to make it to the escape 71 | pod before the whole ship explodes. It seems like hardly any Gothons 72 | are on the ship, so your run is clear of interference. You get to the 73 | chamber with the escape pods, and now need to pick one to take. Some of 74 | them could be damaged but you don't have time to look. There's 5 pods, 75 | which one do you take? 76 | """) 77 | 78 | 79 | the_end_winner = Room("The End", 80 | """ 81 | You jump into pod 2 and hit the eject button. The pod easily slides out 82 | into space heading to the planet below. As it flies to the planet, you 83 | look back and see your ship implode then explode like a bright star, 84 | taking out the Gothon ship at the same time. You won! 85 | """) 86 | 87 | 88 | the_end_loser = Room("The End", 89 | """ 90 | You jump into a random pod and hit the eject button. The pod escapes 91 | out into the void of space, then implodes as the hull ruptures, crushing 92 | your body into jam jelly. 93 | """) 94 | 95 | escape_pod.add_paths({ 96 | '2': the_end_winner, 97 | '*': the_end_loser 98 | }) 99 | 100 | generic_death = Room("death", "You died.") 101 | 102 | the_bridge.add_paths({ 103 | 'throw the bomb': generic_death, 104 | 'slowly place the bomb': escape_pod 105 | }) 106 | 107 | laser_weapon_armory.add_paths({ 108 | '0132': the_bridge, 109 | '*': generic_death 110 | }) 111 | 112 | central_corridor.add_paths({ 113 | 'shoot!': generic_death, 114 | 'dodge!': generic_death, 115 | 'tell a joke': laser_weapon_armory 116 | }) 117 | 118 | START = 'central_corridor' 119 | 120 | 121 | def load_room(name): 122 | """ 123 | There is a potential security problem here. 124 | Who gets to set name? Can that expose a variable? 125 | """ 126 | return globals().get(name) 127 | 128 | 129 | def name_room(room): 130 | """ 131 | Same possible security problem. Can you trust room? 132 | What's a better solution than this globals lookup? 133 | """ 134 | for key, value in globals().items(): 135 | if value == room: 136 | return key 137 | -------------------------------------------------------------------------------- /projects/gothonweb/templates/hello.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | 3 | {% block content %} 4 | 5 | {% if greeting %} 6 | i just wanted to say 7 | {{ greeting }}. 8 | {% else %} 9 | Hello, world! 10 | {% endif %} 11 | 12 | {% endblock %} -------------------------------------------------------------------------------- /projects/gothonweb/templates/hello_form.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | 3 | {% block content %} 4 | 5 |

Fill Out This Form

6 | 7 |
8 | A Greeting: 9 |
10 | Your Name: 11 |
12 | 13 |
14 | 15 | {% endblock %} -------------------------------------------------------------------------------- /projects/gothonweb/templates/layout.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Gothons From PLanet Percal #25 4 | 5 | 6 | 7 | {% block content %} 8 | 9 | {% endblock %} 10 | 11 | 12 | -------------------------------------------------------------------------------- /projects/gothonweb/templates/show_room.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | 3 | {% block content %} 4 | 5 |

{{ room.name }}

6 | 7 | 8 |
 9 |     {{ room.decription }}
10 | 
11 | 12 | {% if room.name in ["death", "The End"] %} 13 |

Play Again?

14 | {% else %} 15 |

16 |

17 | - 18 |
19 |

20 | {% endif %} 21 | 22 | {% endblock %} -------------------------------------------------------------------------------- /projects/gothonweb/templates/you_died.html: -------------------------------------------------------------------------------- 1 |

You Died!

2 | 3 |

Looks like you bit the dust.

4 |

Play Again

-------------------------------------------------------------------------------- /projects/gothonweb/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ubarredo/LearnPythonTheHardWay/bce36594853ffba54b442619d6c2f636324717c3/projects/gothonweb/tests/__init__.py -------------------------------------------------------------------------------- /projects/gothonweb/tests/app_tests.py: -------------------------------------------------------------------------------- 1 | from nose.tools import * 2 | from app import app 3 | 4 | app.config['TESTING'] = True 5 | web = app.test_client() 6 | 7 | 8 | def test_hello(): 9 | rv = web.get('/hello', follow_redirects=True) 10 | assert_equal(rv.status_code, 200) 11 | assert_in(b"Fill Out This Form", rv.data) 12 | 13 | data = {'name': 'Zed', 'greet': 'Hola'} 14 | rv = web.post('/hello', follow_redirects=True, data=data) 15 | assert_in(b"Zed", rv.data) 16 | assert_in(b"Hola", rv.data) 17 | -------------------------------------------------------------------------------- /projects/gothonweb/tests/planisphere_tests.py: -------------------------------------------------------------------------------- 1 | from nose.tools import * 2 | from gothonweb.planisphere import * 3 | 4 | 5 | def test_room(): 6 | gold = Room("GoldRoom", 7 | """This room has gold in it you can grab. There's a 8 | door to the north.""") 9 | assert_equal(gold.name, "GoldRoom") 10 | assert_equal(gold.paths, {}) 11 | 12 | 13 | def test_room_paths(): 14 | center = Room("Center", "Test room in the center.") 15 | north = Room("North", "Test room in the north.") 16 | south = Room("South", "Test room in the south.") 17 | 18 | center.add_paths({'north': north, 'south': south}) 19 | assert_equal(center.go('north'), north) 20 | assert_equal(center.go('south'), south) 21 | 22 | 23 | def test_map(): 24 | start = Room("Start", "You can go west and down a hole.") 25 | west = Room("Trees", "There are trees here, you can go east.") 26 | down = Room("Dungeon", "It's dark here, you can go up.") 27 | 28 | start.add_paths({'west': west, 'down': down}) 29 | west.add_paths({'east': start}) 30 | down.add_paths({'up': start}) 31 | 32 | assert_equal(start.go('west'), west) 33 | assert_equal(start.go('west').go('east'), start) 34 | assert_equal(start.go('down').go('up'), start) 35 | 36 | 37 | def test_gothon_game_map(): 38 | start_room = load_room(START) 39 | assert_equal(start_room.go('shoot!'), generic_death) 40 | assert_equal(start_room.go('dodge!'), generic_death) 41 | 42 | room = start_room.go('tell a joke') 43 | assert_equal(room, laser_weapon_armory) 44 | -------------------------------------------------------------------------------- /projects/simplegame/ex47/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ubarredo/LearnPythonTheHardWay/bce36594853ffba54b442619d6c2f636324717c3/projects/simplegame/ex47/__init__.py -------------------------------------------------------------------------------- /projects/simplegame/ex47/game.py: -------------------------------------------------------------------------------- 1 | class Room(object): 2 | def __init__(self, name, description): 3 | self.name = name 4 | self.description = description 5 | self.paths = {} 6 | 7 | def go(self, direction): 8 | return self.paths.get(direction, None) 9 | 10 | def add_paths(self, paths): 11 | self.paths.update(paths) 12 | -------------------------------------------------------------------------------- /projects/simplegame/ex48/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ubarredo/LearnPythonTheHardWay/bce36594853ffba54b442619d6c2f636324717c3/projects/simplegame/ex48/__init__.py -------------------------------------------------------------------------------- /projects/simplegame/ex48/lexicon.py: -------------------------------------------------------------------------------- 1 | class Lexicon(object): 2 | def __init__(self): 3 | self.pairs = {} 4 | directions = ['north', 'south', 'east', 'west', 5 | 'down', 'up', 'left', 'right', 'back'] 6 | verbs = ['go', 'stop', 'kill', 'eat'] 7 | stops = ['the', 'in', 'of', 'from', 'at', 'it'] 8 | nouns = ['door', 'bear', 'princess', 'cabinet'] 9 | groups = {'direction': directions, 'verb': verbs, 10 | 'stop': stops, 'noun': nouns} 11 | for group_name, group_list in groups.items(): 12 | for list_element in group_list: 13 | self.pairs.update({list_element: group_name}) 14 | 15 | def scan(self, sentence): 16 | scan_list = [] 17 | for word in sentence.split(): 18 | if word.lower() in self.pairs.keys(): 19 | scan_list.append((self.pairs[word.lower()], word)) 20 | else: 21 | try: 22 | scan_list.append(('number', int(word))) 23 | except ValueError: 24 | scan_list.append(('error', word)) 25 | return scan_list 26 | 27 | 28 | lexicon = Lexicon() 29 | -------------------------------------------------------------------------------- /projects/simplegame/ex49/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ubarredo/LearnPythonTheHardWay/bce36594853ffba54b442619d6c2f636324717c3/projects/simplegame/ex49/__init__.py -------------------------------------------------------------------------------- /projects/simplegame/ex49/parser.py: -------------------------------------------------------------------------------- 1 | class ParserError(Exception): 2 | pass 3 | 4 | 5 | class Sentence(object): 6 | def __init__(self, subject, verb, object): 7 | # remember we take ('noun', 'princess') tuples and convert them 8 | self.subject = subject[1] 9 | self.verb = verb[1] 10 | self.object = object[1] 11 | 12 | 13 | def peek(word_list): 14 | if word_list: 15 | word = word_list[0] 16 | return word[0] 17 | else: 18 | return None 19 | 20 | 21 | def match(word_list, expecting): 22 | if word_list: 23 | word = word_list.pop(0) 24 | 25 | if word[0] == expecting: 26 | return word 27 | else: 28 | return None 29 | else: 30 | return None 31 | 32 | 33 | def skip(word_list, word_type): 34 | while peek(word_list) == word_type: 35 | match(word_list, word_type) 36 | 37 | 38 | def parse_verb(word_list): 39 | skip(word_list, 'stop') 40 | 41 | if peek(word_list) == 'verb': 42 | return match(word_list, 'verb') 43 | else: 44 | raise ParserError("Expected a verb next.") 45 | 46 | 47 | def parse_object(word_list): 48 | skip(word_list, 'stop') 49 | next_word = peek(word_list) 50 | 51 | if next_word == 'noun': 52 | return match(word_list, 'noun') 53 | if next_word == 'direction': 54 | return match(word_list, 'direction') 55 | else: 56 | raise ParserError("Expected a noun or direction next.") 57 | 58 | 59 | def parse_subject(word_list): 60 | skip(word_list, 'stop') 61 | next_word = peek(word_list) 62 | 63 | if next_word == 'noun': 64 | return match(word_list, 'noun') 65 | elif next_word == 'verb': 66 | return ('noun', 'player') 67 | else: 68 | raise ParserError("Expected a verb next.") 69 | 70 | 71 | def parse_sentence(word_list): 72 | subj = parse_subject(word_list) 73 | verb = parse_verb(word_list) 74 | obj = parse_object(word_list) 75 | 76 | return Sentence(subj, verb, obj) 77 | -------------------------------------------------------------------------------- /projects/simplegame/setup.py: -------------------------------------------------------------------------------- 1 | try: 2 | from setuptools import setup 3 | except ImportError: 4 | from distutils.core import setup 5 | 6 | config = { 7 | 'description': 'My Project', 8 | 'author': 'My Name', 9 | 'url': 'URL to get it at.', 10 | 'download_url': 'Where to download it.', 11 | 'author_email': 'My email', 12 | 'version': '0.1', 13 | 'install_requires': ['nose'], 14 | 'packages': ['NAME'], 15 | 'scripts': [], 16 | 'name': 'projectname' 17 | } 18 | 19 | setup(**config) 20 | -------------------------------------------------------------------------------- /projects/simplegame/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ubarredo/LearnPythonTheHardWay/bce36594853ffba54b442619d6c2f636324717c3/projects/simplegame/tests/__init__.py -------------------------------------------------------------------------------- /projects/simplegame/tests/game_tests.py: -------------------------------------------------------------------------------- 1 | from nose.tools import * 2 | from ex47.game import Room 3 | 4 | 5 | def test_room(): 6 | gold = Room("GoldRoom", 7 | """This room has gold in it you can grab. There's a 8 | door to the north.""") 9 | assert_equal(gold.name, "GoldRoom") 10 | assert_equal(gold.paths, {}) 11 | 12 | 13 | def test_room_paths(): 14 | center = Room("Center", "Test room in the center.") 15 | north = Room("North", "Test room in the north.") 16 | south = Room("South", "Test room in the south.") 17 | 18 | center.add_paths({'north': north, 'south': south}) 19 | assert_equal(center.go('north'), north) 20 | assert_equal(center.go('south'), south) 21 | 22 | 23 | def test_map(): 24 | start = Room("Start", "You can go west and down a hole.") 25 | west = Room("Trees", "There are trees here, you can go east.") 26 | down = Room("Dungeon", "It's dark here, you can go up.") 27 | 28 | start.add_paths({'west': west, 'down': down}) 29 | west.add_paths({'east': start}) 30 | down.add_paths({'up': start}) 31 | 32 | assert_equal(start.go('west'), west) 33 | assert_equal(start.go('west').go('east'), start) 34 | assert_equal(start.go('down').go('up'), start) 35 | -------------------------------------------------------------------------------- /projects/simplegame/tests/lexicon_tests.py: -------------------------------------------------------------------------------- 1 | from nose.tools import * 2 | from ex48.lexicon import lexicon 3 | 4 | 5 | def test_directions(): 6 | assert_equal(lexicon.scan("north"), [('direction', 'north')]) 7 | result = lexicon.scan("north south east") 8 | assert_equal(result, [('direction', 'north'), 9 | ('direction', 'south'), 10 | ('direction', 'east')]) 11 | 12 | 13 | def test_verbs(): 14 | assert_equal(lexicon.scan("go"), [('verb', 'go')]) 15 | result = lexicon.scan("go kill eat") 16 | assert_equal(result, [('verb', 'go'), 17 | ('verb', 'kill'), 18 | ('verb', 'eat')]) 19 | 20 | 21 | def test_stops(): 22 | assert_equal(lexicon.scan("the"), [('stop', 'the')]) 23 | result = lexicon.scan("the in of") 24 | assert_equal(result, [('stop', 'the'), 25 | ('stop', 'in'), 26 | ('stop', 'of')]) 27 | 28 | 29 | def test_nouns(): 30 | assert_equal(lexicon.scan("bear"), [('noun', 'bear')]) 31 | result = lexicon.scan("bear princess") 32 | assert_equal(result, [('noun', 'bear'), 33 | ('noun', 'princess')]) 34 | 35 | 36 | def test_numbers(): 37 | assert_equal(lexicon.scan("1234"), [('number', 1234)]) 38 | result = lexicon.scan("3 91234") 39 | assert_equal(result, [('number', 3), 40 | ('number', 91234)]) 41 | 42 | 43 | def test_errors(): 44 | assert_equal(lexicon.scan("ASDFADFASDF"), 45 | [('error', 'ASDFADFASDF')]) 46 | result = lexicon.scan("bear IAS princess") 47 | assert_equal(result, [('noun', 'bear'), 48 | ('error', 'IAS'), 49 | ('noun', 'princess')]) 50 | -------------------------------------------------------------------------------- /projects/simplegame/tests/parser_tests.py: -------------------------------------------------------------------------------- 1 | from nose.tools import * 2 | from ex49.parser import * 3 | 4 | 5 | def test_peek(): 6 | result = peek([('verb', 'run'), ('direction', 'north')]) 7 | assert_equal(result, 'verb') 8 | 9 | 10 | def test_match(): 11 | result = match([('verb', 'run'), ('direction', 'north')], 'verb') 12 | assert_equal(result, ('verb', 'run')) 13 | 14 | 15 | def test_skip(): 16 | result = [('stop', 'at'), ('stop', 'the'), ('direction', 'north')] 17 | skip(result, 'stop') 18 | assert_equal(result, [('direction', 'north')]) 19 | 20 | 21 | def test_parse_verb(): 22 | result = parse_verb([('verb', 'eat'), ('stop', 'the'), ('noun', 'honey')]) 23 | assert_equal(result, ('verb', 'eat')) 24 | 25 | 26 | def test_parse_object(): 27 | result = parse_object([('stop', 'the'), ('noun', 'honey')]) 28 | assert_equal(result, ('noun', 'honey')) 29 | 30 | 31 | def test_parse_subject(): 32 | result = parse_subject([('verb', 'run'), ('direction', 'south')]) 33 | assert_equal(result, ('noun', 'player')) 34 | 35 | 36 | def test_parse_sentence(): 37 | result = parse_sentence([('noun', 'bear'), ('verb', 'eat'), 38 | ('stop', 'the'), ('noun', 'honey')]) 39 | 40 | assert_equal(result.subject, 'bear') 41 | assert_equal(result.verb, 'eat') 42 | assert_equal(result.object, 'honey') 43 | 44 | 45 | def test_fails(): 46 | assert_raises(Exception, parse_verb, [('stop', 'the'), ('noun', 'honey')]) 47 | assert_raises(Exception, parse_object, [('stop', 'the'), ('verb', 'run')]) 48 | assert_raises(Exception, parse_subject, [('stop', 'the'), 49 | ('direction', 'north')]) 50 | -------------------------------------------------------------------------------- /projects/skeleton/NAME/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ubarredo/LearnPythonTheHardWay/bce36594853ffba54b442619d6c2f636324717c3/projects/skeleton/NAME/__init__.py -------------------------------------------------------------------------------- /projects/skeleton/setup.py: -------------------------------------------------------------------------------- 1 | try: 2 | from setuptools import setup 3 | except ImportError: 4 | from distutils.core import setup 5 | 6 | config = { 7 | 'description': 'My Project', 8 | 'author': 'My Name', 9 | 'url': 'URL to get it at.', 10 | 'download_url': 'Where to download it.', 11 | 'author_email': 'My email', 12 | 'version': '0.1', 13 | 'install_requires': ['nose'], 14 | 'packages': ['NAME'], 15 | 'scripts': [], 16 | 'name': 'projectname' 17 | } 18 | 19 | setup(**config) 20 | -------------------------------------------------------------------------------- /projects/skeleton/tests/NAME_tests.py: -------------------------------------------------------------------------------- 1 | from nose.tools import * 2 | import NAME 3 | 4 | 5 | def setup(): 6 | print("SETUP!") 7 | 8 | 9 | def teardown(): 10 | print("TEAR DOWN!") 11 | 12 | 13 | def test_basic(): 14 | print("I RAN!", end='') 15 | -------------------------------------------------------------------------------- /projects/skeleton/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ubarredo/LearnPythonTheHardWay/bce36594853ffba54b442619d6c2f636324717c3/projects/skeleton/tests/__init__.py -------------------------------------------------------------------------------- /test.txt: -------------------------------------------------------------------------------- 1 | Mary had a little lamb 2 | Its fleece was white as snow 3 | It was also tasty --------------------------------------------------------------------------------