23 |
24 |
25 | # ------------------------------------------------------------------------------- #
26 |
27 | # dict keys are generally strings
28 | # dict values can be ANY datatype, including other dictionaries
29 |
30 | example_dict = {'a': 11, 'b': 22, 'c': 33}
31 |
32 | example_dict = {
33 | # key: value,
34 | 'a': 11,
35 | 'b': 22,
36 | 'c': 33
37 | }
38 |
39 | # print(example_dict) # {'a': 11, 'b': 22, 'c': 33}
40 |
41 | # ------------------------------------------------------------------------------- #
42 |
43 | # dictionary values are retrieved by placing their keys
44 | # in SQUARE brackets after the dictionary's name
45 |
46 | # print(example_dict['a']) # 11
47 | # print(example_dict['b']) # 22
48 | # print(example_dict['c']) # 33
49 |
50 | # ---------------------------------------------------------------------------- #
51 |
52 | # dictionaries are usually used to group related data
53 |
54 | address = {
55 | "street": "123 Faux St.",
56 | "city": "Portland",
57 | "state": "Oregon",
58 | "zipcode": 123456
59 | }
60 |
61 | # print(address['street'])
62 | # print(f"{address['city']}, {address['state']} {address['zipcode']}")
63 |
64 | # ------------------------------------------------------------------------------------------ #
65 |
66 | book = {
67 | 'title': 'The Hobbit',
68 | 'author': 'JRR Tolkien',
69 | 'pages': 200
70 | }
71 |
72 | # print(f"The book {book['title']} has {book['pages']} pages and was written by {book['author']}")
73 |
74 | # ----------------------------------------------------------------------------------------- #
75 |
76 | # cannot retrieve values at non-existent keys
77 | # book['characters'] # KeyError: 'characters'
78 |
79 | # add a value at the key of 'characters'
80 | book['characters'] = ['Bilbo', 'Gandalf', 'Smaug']
81 | # print(book['characters']) # ['Bilbo', 'Gandalf', 'Smaug']
82 |
83 | # add a character to the list
84 | book['characters'].append('Balin')
85 | # print(book['characters']) # ['Bilbo', 'Gandalf', 'Smaug', 'Balin']
86 |
87 | # ---------------------------------------------------------------------------------------- #
88 |
89 | # change the value at a key
90 | book['pages'] = 199
91 | # print(book)
92 |
93 | # ------------------------------------------------------------------------------------------ #
94 |
95 | # deleting a key:value pair
96 | # keyword 'del'
97 | # del book['pages']
98 | # print(book)
99 |
100 | # ------------------------------------------------------------------------------------------- #
101 |
102 | # dictionary methods
103 |
104 | # .pop(key) - remove the key:value pair at the key and return the value
105 | pages = book.pop('pages')
106 | # print(pages, book)
107 |
108 | # --------------------------------------------------------------------------------------------- #
109 |
110 | # .update(new_dict) - add the items from the new_dict to the original dictionary
111 | new_items = {
112 | 'pages': 200,
113 | 'isbn_number': 3456789876598765
114 | }
115 |
116 | # book.update(new_items)
117 | # print(book)
118 |
119 | # ----------------------------------------------------------------------------------------------- #
120 |
121 | # as of Python 3.9, we can use the 'merge' operator
122 |
123 | book = book | new_items
124 |
125 | # print(book)
126 |
127 | # ------------------------------------------------------------------------------------------------ #
128 |
129 | # Fruit Stand
130 |
131 | fruit_prices = {
132 | 'apple': 2.33,
133 | 'banana': 1.76,
134 | 'peaches': 2.99
135 | }
136 |
137 | while True:
138 | # ask the user which fruit they want to buy
139 | fruit_name = input("\nPlease enter the name of the fruit you want to buy or 'done' to quit: ")
140 |
141 | # exit if 'done'
142 | if fruit_name == 'done':
143 | print("\nThanks for shopping!")
144 | break # end the loop
145 |
146 | # get the price of the user's fruit_name
147 | price_per = fruit_prices[fruit_name]
148 |
149 | # ask the use how many they want
150 | quantity = input("Enter the quantity: ")
151 |
152 | # convert the quantity to integer
153 | quantity = int(quantity)
154 |
155 | # calculate the total
156 | total = quantity * price_per
157 |
158 | print(f'{quantity} {fruit_name} @ ${price_per} each - ${round(total, 2)}')
--------------------------------------------------------------------------------
/practice/unit_3/solutions/exercise_2_solution.md:
--------------------------------------------------------------------------------
1 | # Unit 3 Practice Solutions
2 |
3 | ## **Exercise 1 Solution**
4 |
5 | ### **1.1**
6 |
7 | ```python
8 | def main():
9 | # dictionary of tile scores
10 | scrabble = {
11 | 'BLANK': 0,
12 | 'A': 1,
13 | 'B': 3,
14 | 'C': 3,
15 | 'D': 2,
16 | 'E': 1,
17 | 'F': 4,
18 | 'G': 2,
19 | 'H': 4,
20 | 'I': 1,
21 | 'J': 8,
22 | 'K': 5,
23 | 'L': 1,
24 | 'M': 3,
25 | 'N': 1,
26 | 'O': 1,
27 | 'P': 3,
28 | 'Q': 10,
29 | 'R': 1,
30 | 'S': 1,
31 | 'T': 1,
32 | 'U': 1,
33 | 'V': 4,
34 | 'W': 4,
35 | 'X': 8,
36 | 'Y': 4,
37 | 'Z': 10,
38 | }
39 |
40 |
41 | # get the tiles from the user and uppercase them
42 | tiles = input('Please enter the letters on your tiles, separated by commas: ')
43 |
44 | # replace spaces with blank strings
45 | # convert all to uppercase
46 | tiles = tiles.replace(' ', '').upper()
47 |
48 | # split into a list at the commas
49 | tiles = tiles.split(',')
50 |
51 | # loop through the tiles and add up the point values
52 | total = 0
53 | for tile in tiles:
54 | # get the point value for the current tile
55 | point_value = scrabble[tile]
56 | # add the point value to the total
57 | total += point_value
58 |
59 | # place a comma and a space between each element in tiles and print the result
60 | result = f"With the letters {', '.join(tiles)} the maximum possible score is {total} if all the tiles are played."
61 |
62 | print(result)
63 |
64 |
65 | main()
66 | ```
67 |
68 | Output:
69 |
70 | Please enter the letters on your tiles, separated by commas: blank,g,h,q,z,j,x
71 |
72 | With the letters BLANK, G, H, Q, Z, J, X the maximum possible score is 42 if all the tiles are played.
73 |
74 | ### **1.2**
75 |
76 | ```python
77 | def main():
78 | # dictionary of tile scores
79 | scrabble = {
80 | 'BLANK': 0,
81 | 'A': 1,
82 | 'B': 3,
83 | 'C': 3,
84 | 'D': 2,
85 | 'E': 1,
86 | 'F': 4,
87 | 'G': 2,
88 | 'H': 4,
89 | 'I': 1,
90 | 'J': 8,
91 | 'K': 5,
92 | 'L': 1,
93 | 'M': 3,
94 | 'N': 1,
95 | 'O': 1,
96 | 'P': 3,
97 | 'Q': 10,
98 | 'R': 1,
99 | 'S': 1,
100 | 'T': 1,
101 | 'U': 1,
102 | 'V': 4,
103 | 'W': 4,
104 | 'X': 8,
105 | 'Y': 4,
106 | 'Z': 10,
107 | }
108 |
109 | tile_quantities = {
110 | 'A': 9,
111 | 'B': 2,
112 | 'C': 2,
113 | 'D': 4,
114 | 'E': 12,
115 | 'F': 2,
116 | 'G': 3,
117 | 'H': 2,
118 | 'I': 9,
119 | 'J': 1,
120 | 'K': 1,
121 | 'L': 4,
122 | 'M': 2,
123 | 'N': 6,
124 | 'O': 8,
125 | 'P': 2,
126 | 'Q': 1,
127 | 'R': 6,
128 | 'S': 4,
129 | 'T': 6,
130 | 'U': 4,
131 | 'V': 2,
132 | 'W': 2,
133 | 'X': 1,
134 | 'Y': 2,
135 | 'Z': 1,
136 | 'BLANK': 2,
137 | }
138 |
139 | # get the tiles from the user and uppercase them
140 | tiles = input(
141 | 'Please enter the letters on your tiles, separated by commas: ')
142 |
143 | # replace spaces with blank strings
144 | # convert all to uppercase
145 | tiles = tiles.replace(' ', '').upper()
146 |
147 | # split into a list at the commas
148 | tiles = tiles.split(',')
149 |
150 | # loop through the tiles and add up the point values
151 | total = 0
152 | for tile in tiles:
153 |
154 | # if the user's entry contains more of a tile than exist in Scrabble, tell the user.
155 | number_in_hand = tiles.count(tile)
156 | number_available = tile_quantities[tile]
157 | if number_in_hand > number_available:
158 | print(f'There is/are only {number_available} "{tile}" tile(s) in Scrabble. You entered {number_in_hand}.')
159 |
160 | # exit the main() function
161 | return
162 |
163 | # get the point value for the current tile
164 | point_value = scrabble[tile]
165 | # add the point value to the total
166 | total += point_value
167 |
168 | # place a comma and a space between each element in tiles and print the result
169 | result = f"With the letters {', '.join(tiles)} the maximum possible score is {total} if all the tiles are played."
170 |
171 | print(result)
172 |
173 |
174 | main()
175 |
176 | ```
177 |
178 | **Output:**
179 |
180 | ```
181 | Please enter the letters on your tiles, separated by commas: z,z,z,z,z,z,z
182 |
183 | There is/are only 1 "Z" tile(s) in Scrabble. You entered 7.
184 | ```
185 |
186 | Keep in mind that this is just one potential solution.
187 |
188 | ## [< Exercise 2](../exercise_2.md)| [Exercise 3 >](../exercise_3.md)
189 |
190 | ---
191 |
192 | ### [<< Back to Unit 3 Practice](/practice/unit_3/)
193 |
--------------------------------------------------------------------------------
/units/unit3.md:
--------------------------------------------------------------------------------
1 | # Unit 3 - Dictionaries
2 |
3 | ---
4 |
5 | [Back to Syllabus](https://github.com/PdxCodeGuild/Programming102#top)
6 |
7 | ### Table of Contents
8 |
9 | - [Dictionaries](#dictionaries)
10 | - [Dictionary Methods](#methods)
11 | - [Looping with Dictionaries](#loops)
12 | - [Exercises](https://github.com/PdxCodeGuild/Programming102/blob/master/practice/unit_3/)
13 | - [Lab 3](https://github.com/PdxCodeGuild/Programming102/blob/master/labs/lab3.md)
14 |
15 | ---
16 |
17 | ## Dictionaries
18 |
19 | - Dictionaries are one of the most powerful datatypes in Python.
20 | - They can be used to store large amounts of data and make working with data easy.
21 | - Dictionaries are a collection of `key: value` pairs
22 | - We can start with an empty dictionary:
23 |
24 | ```python
25 | employee_availability = {}
26 | ```
27 |
28 | - Or we can start with some pre defined data:
29 |
30 | ```python
31 | employee_availability = {
32 | "lisa": "Mon", # string
33 | "al": ["Tues", "Wed", "Thurs"], # list
34 | "anthony": ["Mon", "Tues", "Wed", "Thurs", "Fri"] # list
35 | }
36 | ```
37 |
38 | - The keys in our employee_availability dictionary are `lisa, al, and anthony`
39 | - The values in our employee_availability dictionary are `"Mon", ["Tues", "Wed", "Thurs"], ["Mon", "Tues", "Wed", "Thurs", "Fri"]`
40 |
41 | - To access a value in our dictionary we just need to use the key
42 |
43 | ```python
44 | schedule = employee_availability["al"]
45 | print(schedule)
46 | ```
47 |
48 | > ["Tues", "Wed", "Thurs"]
49 |
50 | - We can change a value by also using a key:
51 |
52 | ```python
53 | employee_availability["al"] = ["Mon", "Wed", "Fri"]
54 | schedule = employee_availability["al"]
55 | print(schedule)
56 | ```
57 |
58 | > ["Mon", "Wed", "Fri"]
59 |
60 | - To add a new value, we just need to give our dictionary a new key, then assign it a value:
61 |
62 | ```python
63 | employee_availability["bill"] = ["Mon", "Wed", "Fri"]
64 | print(employee_availability)
65 | ```
66 |
67 | > {"lisa": "Mon", "al": ["Mon", "Wed", "Fri"], "anthony": ["Mon", "Tues", "Wed", "Thurs", "Fri"], "bill": ["Mon", "Wed", "Fri"]}
68 |
69 | - To remove a key value pair from a dictionary we use the `del` keyword
70 |
71 | ```python
72 | del employee_availability["bill"]
73 | print(employee_availability)
74 | ```
75 |
76 | > {"lisa": "Mon", "al": ["Mon", "Wed", "Fri"], "anthony": ["Mon", "Tues", "Wed", "Thurs", "Fri"]}
77 |
78 | ---
79 |
80 | ## Dictionary Methods
81 |
82 | Methods give datatypes more functionality, and just like [string methods](https://www.w3schools.com/python/python_ref_string.asp) and [list methods](https://www.w3schools.com/python/python_ref_list.asp), we also have [dictionary methods](https://www.w3schools.com/python/python_ref_dictionary.asp).
83 |
84 | | method | description | example |
85 | | -------- | ------------------------------------------------------------------------- | -------------------------------------------- |
86 | | clear() | Removes all elements from a dictionary | dictionary_name.clear() |
87 | | copy() | Returns a copy of the dictionary | new_dictionary = dictionary_name.copy() |
88 | | get() | Returns the value of a specified key, or a default value if key not found | data = dictionary_name.get("key", False) |
89 | | items() | Returns a list containing key: value pairs | data = dictionary_name.items() |
90 | | keys() | Returns a list contianing a list of keys | keys = dictionary_name.keys() |
91 | | pop() | Removes the element with the specified key | dictionary_name.pop("key") |
92 | | update() | Updates the dictionary with the specified key: value pairs | dictionary_name.update({"key": "new value"}) |
93 | | values() | Returns a list of all the values | values = dictionary_name.values() |
94 |
95 | ---
96 |
97 | ## Looping with Dictionaries
98 |
99 | Since dictinaries can become quite large, Python allows us to loop over them.
100 | There are two was to loop over a dictionary:
101 |
102 | - The first is to loop over the keys
103 |
104 | ```python
105 | for key in employee_availability:
106 | print(key)
107 | ```
108 |
109 | ```python
110 | > "lisa"
111 | > "al"
112 | > "anthony"
113 | ```
114 |
115 | - The second is to loop over both the keys and values using the .items() method
116 |
117 | ```python
118 | for key, value in employee_availability.items():
119 | print(key, value)
120 | ```
121 |
122 | ```python
123 | > "lisa" "Mon"
124 | > "al" ["Mon", "Wed", "Fri"]
125 | > "anthony" ["Mon", "Tues", "Wed", "Thurs", "Fri"]
126 | ```
127 |
128 | ### [Exercises](https://github.com/PdxCodeGuild/Programming102/blob/master/practice/unit_3/)
129 |
130 | ### [Lab 3](https://github.com/PdxCodeGuild/Programming102/blob/master/labs/lab3.md)
131 |
132 | [Back to top](#top)
133 |
--------------------------------------------------------------------------------
/units/unit2.md:
--------------------------------------------------------------------------------
1 | # Unit 2 - Functions
2 |
3 | ---
4 |
5 | [Back to Syllabus](https://github.com/PdxCodeGuild/Programming102#top)
6 |
7 | ### Table of Contents
8 |
9 | - [REPL](#repl)
10 | - [What is a Function](#whatis)
11 | - [Defining a Function](#define)
12 | - [Passing Arguments to Functions](#arguments)
13 | - [Return](#return)
14 | - [main( )](#main)
15 | - [Exercises](https://github.com/PdxCodeGuild/Programming102/blob/master/practice/unit_2/)
16 | - [Lab 2](https://github.com/PdxCodeGuild/Programming102/blob/master/labs/lab2.md)
17 |
18 | ---
19 |
20 | ## REPL
21 |
22 | - **Read:** take user input
23 | - **Evaluate:** evaluate the input
24 | - **Print:** shows the output to user
25 | - **Loop:** repeat
26 |
27 | ```python
28 | play_again = "yes"
29 | while play_again == "yes":
30 | # Do some stuff
31 | play_again = input("Would you like to play again? ")
32 | ```
33 |
34 | ---
35 |
36 | ## What is a function?
37 |
38 | - A function is a named block of code that runs only when called.
39 | - They are typically designed to do one specific job.
40 | - Once defined, you can call a function as many times as needed.
41 | - You can think of them as a variable, but for a whole block of code!
42 |
43 | ---
44 |
45 | ## Defining a function
46 |
47 | - Functions are defined (or created) by using the `def` keyword.
48 |
49 | ```python
50 | def my_func():
51 | "This is where the body of the function goes"
52 | ```
53 |
54 | - As we see above, we use the `def` keyword followed by our functions name `my_func`.
55 | - Notice how the function body is indented. Python uses indentation instead of `{ }` or `( )` like other languages.
56 | - The body is how we tell the computer what `my_func` does.
57 | - It is good practice to use docstrings to tell the user what the function does. Docstrings start and end with triple quotes.
58 |
59 | ```python
60 | def my_func():
61 | '''This is a docstring, use this to tell other users what this function does'''
62 |
63 | print("The function body goes below the docstring")
64 | ```
65 |
66 | - Now that we have defined a function, in order to use it we need to call that function.
67 |
68 | ```python
69 | my_func()
70 | ```
71 |
72 | ---
73 |
74 | ## Passing Arguments to Functions
75 |
76 | - We can pass information into our function and have it do something with that data.
77 | - This requires us to change our function definition slightly.
78 |
79 | ```python
80 | def my_func(message):
81 | '''This function will print a message'''
82 | print(message)
83 | ```
84 |
85 | - Now that we have told our function to expect some data, we just pass in the data when we call the function.
86 |
87 | ```python
88 | my_func("Hello World")
89 | ```
90 |
91 | - The data `"Hello World"` is being passed in to our function call.
92 | - That data is then stored in the variable `message`.
93 | - If we run this function, our output would be: `Hello World`.
94 | - You can declare as many arguments in your function defintion as you want.
95 |
96 | - You can even declare default values to the variables we create.
97 | - Using defaults is a good way to avoid errors in your code.
98 |
99 | ```python
100 | def my_func(message="Hello"):
101 | '''This function will print a message'''
102 | print(message)
103 | ```
104 |
105 | - Now we can see what the output would look like if we do not pass in any data:
106 |
107 | ```python
108 | my_func()
109 | ```
110 |
111 | > "Hello"
112 |
113 | - And if we do pass in data:
114 |
115 | ```python
116 | my_func("Nice day today!")
117 | ```
118 |
119 | > "Nice day today!"
120 |
121 | ---
122 |
123 | ## Return
124 |
125 | - Variables and data used inside a function are unique to that function.
126 | - If I declare a variable inside a function, it will only exist inside that function.
127 | - So how do we get the data back out? We use the `return` keyword
128 |
129 | ```python
130 | def add(num1, num2):
131 | '''This function will add two numbers together and return the result'''
132 | num = num1 + num2
133 | return num
134 |
135 | added_nums = add(3, 4)
136 | print(added_nums)
137 | ```
138 |
139 | In this case our output would be:
140 |
141 | > 7
142 |
143 | ---
144 |
145 | ## main( )
146 |
147 | - It is good practice to use a main function. This is where the core functionality of your code will live.
148 | - Using a main function also helps us keep code clean and helps us avoid using global variables
149 | - Using a main function is similar to using any other function
150 | - First we define the function:
151 |
152 | ```python
153 | def main():
154 | '''This is our main function'''
155 |
156 | # All of our code goes here
157 |
158 | ```
159 |
160 | - Then we just need to call that main function
161 |
162 | ```python
163 | main()
164 | ```
165 |
166 | - Just keep in mind if you define other functions, you define them before your main function.
167 |
168 | ---
169 |
170 | ### [Exercises](https://github.com/PdxCodeGuild/Programming102/blob/master/practice/unit_2)
171 |
172 | ### [Lab 2](https://github.com/PdxCodeGuild/Programming102/blob/master/labs/lab2.md)
173 |
174 | [Back to top](#top)
175 |
--------------------------------------------------------------------------------
/resources/countwords.txt:
--------------------------------------------------------------------------------
1 | Alice was beginning to get very tired of sitting by her sister on the
2 | bank, and of having nothing to do. Once or twice she had peeped into the
3 | book her sister was reading, but it had no pictures or conversations in
4 | it, "and what is the use of a book," thought Alice, "without pictures or
5 | conversations?"
6 |
7 | So she was considering in her own mind (as well as she could, for the
8 | day made her feel very sleepy and stupid), whether the pleasure of
9 | making a daisy-chain would be worth the trouble of getting up and
10 | picking the daisies, when suddenly a White Rabbit with pink eyes ran
11 | close by her.
12 |
13 | There was nothing so very remarkable in that, nor did Alice think it so
14 | very much out of the way to hear the Rabbit say to itself, "Oh dear! Oh
15 | dear! I shall be too late!" But when the Rabbit actually took a watch
16 | out of its waistcoat-pocket and looked at it and then hurried on, Alice
17 | started to her feet, for it flashed across her mind that she had never
18 | before seen a rabbit with either a waistcoat-pocket, or a watch to take
19 | out of it, and, burning with curiosity, she ran across the field after
20 | it and was just in time to see it pop down a large rabbit-hole, under
21 | the hedge. In another moment, down went Alice after it!
22 |
23 | The rabbit-hole went straight on like a tunnel for some way and then
24 | dipped suddenly down, so suddenly that Alice had not a moment to think
25 | about stopping herself before she found herself falling down what seemed
26 | to be a very deep well.
27 |
28 | Either the well was very deep, or she fell very slowly, for she had
29 | plenty of time, as she went down, to look about her. First, she tried to
30 | make out what she was coming to, but it was too dark to see anything;
31 | then she looked at the sides of the well and noticed that they were
32 | filled with cupboards and book-shelves; here and there she saw maps and
33 | pictures hung upon pegs. She took down a jar from one of the shelves as
34 | she passed. It was labeled "ORANGE MARMALADE," but, to her great
35 | disappointment, it was empty; she did not like to drop the jar, so
36 | managed to put it into one of the cupboards as she fell past it.
37 |
38 | Down, down, down! Would the fall never come to an end? There was nothing
39 | else to do, so Alice soon began talking to herself. "Dinah'll miss me
40 | very much to-night, I should think!" (Dinah was the cat.) "I hope
41 | they'll remember her saucer of milk at tea-time. Dinah, my dear, I wish
42 | you were down here with me!" Alice felt that she was dozing off, when
43 | suddenly, thump! thump! down she came upon a heap of sticks and dry
44 | leaves, and the fall was over.
45 |
46 | Alice was not a bit hurt, and she jumped up in a moment. She looked up,
47 | but it was all dark overhead; before her was another long passage and
48 | the White Rabbit was still in sight, hurrying down it. There was not a
49 | moment to be lost. Away went Alice like the wind and was just in time to
50 | hear it say, as it turned a corner, "Oh, my ears and whiskers, how late
51 | it's getting!" She was close behind it when she turned the corner, but
52 | the Rabbit was no longer to be seen.
53 |
54 | She found herself in a long, low hall, which was lit up by a row of
55 | lamps hanging from the roof. There were doors all 'round the hall, but
56 | they were all locked; and when Alice had been all the way down one side
57 | and up the other, trying every door, she walked sadly down the middle,
58 | wondering how she was ever to get out again.
59 |
60 | Suddenly she came upon a little table, all made of solid glass. There
61 | was nothing on it but a tiny golden key, and Alice's first idea was that
62 | this might belong to one of the doors of the hall; but, alas! either the
63 | locks were too large, or the key was too small, but, at any rate, it
64 | would not open any of them. However, on the second time 'round, she came
65 | upon a low curtain she had not noticed before, and behind it was a
66 | little door about fifteen inches high. She tried the little golden key
67 | in the lock, and to her great delight, it fitted!
68 |
69 | Alice opened the door and found that it led into a small passage, not
70 | much larger than a rat-hole; she knelt down and looked along the passage
71 | into the loveliest garden you ever saw. How she longed to get out of
72 | that dark hall and wander about among those beds of bright flowers and
73 | those cool fountains, but she could not even get her head through the
74 | doorway. "Oh," said Alice, "how I wish I could shut up like a telescope!
75 | I think I could, if I only knew how to begin."
76 |
77 | Alice went back to the table, half hoping she might find another key on
78 | it, or at any rate, a book of rules for shutting people up like
79 | telescopes. This time she found a little bottle on it ("which certainly
80 | was not here before," said Alice), and tied 'round the neck of the
81 | bottle was a paper label, with the words "DRINK ME" beautifully printed
82 | on it in large letters.
83 |
84 | "No, I'll look first," she said, "and see whether it's marked '_poison_'
85 | or not," for she had never forgotten that, if you drink from a bottle
86 | marked "poison," it is almost certain to disagree with you, sooner or
87 | later. However, this bottle was _not_ marked "poison," so Alice ventured
88 | to taste it, and, finding it very nice (it had a sort of mixed flavor of
89 | cherry-tart, custard, pineapple, roast turkey, toffy and hot buttered
90 | toast), she very soon finished it off.
--------------------------------------------------------------------------------
/resources/example_lessons/unit_5/alice.txt:
--------------------------------------------------------------------------------
1 | Alice was beginning to get very tired of sitting by her sister on the
2 | bank, and of having nothing to do. Once or twice she had peeped into the
3 | book her sister was reading, but it had no pictures or conversations in
4 | it, "and what is the use of a book," thought Alice, "without pictures or
5 | conversations?"
6 |
7 | So she was considering in her own mind (as well as she could, for the
8 | day made her feel very sleepy and stupid), whether the pleasure of
9 | making a daisy-chain would be worth the trouble of getting up and
10 | picking the daisies, when suddenly a White Rabbit with pink eyes ran
11 | close by her.
12 |
13 | There was nothing so very remarkable in that, nor did Alice think it so
14 | very much out of the way to hear the Rabbit say to itself, "Oh dear! Oh
15 | dear! I shall be too late!" But when the Rabbit actually took a watch
16 | out of its waistcoat-pocket and looked at it and then hurried on, Alice
17 | started to her feet, for it flashed across her mind that she had never
18 | before seen a rabbit with either a waistcoat-pocket, or a watch to take
19 | out of it, and, burning with curiosity, she ran across the field after
20 | it and was just in time to see it pop down a large rabbit-hole, under
21 | the hedge. In another moment, down went Alice after it!
22 |
23 | The rabbit-hole went straight on like a tunnel for some way and then
24 | dipped suddenly down, so suddenly that Alice had not a moment to think
25 | about stopping herself before she found herself falling down what seemed
26 | to be a very deep well.
27 |
28 | Either the well was very deep, or she fell very slowly, for she had
29 | plenty of time, as she went down, to look about her. First, she tried to
30 | make out what she was coming to, but it was too dark to see anything;
31 | then she looked at the sides of the well and noticed that they were
32 | filled with cupboards and book-shelves; here and there she saw maps and
33 | pictures hung upon pegs. She took down a jar from one of the shelves as
34 | she passed. It was labeled "ORANGE MARMALADE," but, to her great
35 | disappointment, it was empty; she did not like to drop the jar, so
36 | managed to put it into one of the cupboards as she fell past it.
37 |
38 | Down, down, down! Would the fall never come to an end? There was nothing
39 | else to do, so Alice soon began talking to herself. "Dinah'll miss me
40 | very much to-night, I should think!" (Dinah was the cat.) "I hope
41 | they'll remember her saucer of milk at tea-time. Dinah, my dear, I wish
42 | you were down here with me!" Alice felt that she was dozing off, when
43 | suddenly, thump! thump! down she came upon a heap of sticks and dry
44 | leaves, and the fall was over.
45 |
46 | Alice was not a bit hurt, and she jumped up in a moment. She looked up,
47 | but it was all dark overhead; before her was another long passage and
48 | the White Rabbit was still in sight, hurrying down it. There was not a
49 | moment to be lost. Away went Alice like the wind and was just in time to
50 | hear it say, as it turned a corner, "Oh, my ears and whiskers, how late
51 | it's getting!" She was close behind it when she turned the corner, but
52 | the Rabbit was no longer to be seen.
53 |
54 | She found herself in a long, low hall, which was lit up by a row of
55 | lamps hanging from the roof. There were doors all 'round the hall, but
56 | they were all locked; and when Alice had been all the way down one side
57 | and up the other, trying every door, she walked sadly down the middle,
58 | wondering how she was ever to get out again.
59 |
60 | Suddenly she came upon a little table, all made of solid glass. There
61 | was nothing on it but a tiny golden key, and Alice's first idea was that
62 | this might belong to one of the doors of the hall; but, alas! either the
63 | locks were too large, or the key was too small, but, at any rate, it
64 | would not open any of them. However, on the second time 'round, she came
65 | upon a low curtain she had not noticed before, and behind it was a
66 | little door about fifteen inches high. She tried the little golden key
67 | in the lock, and to her great delight, it fitted!
68 |
69 | Alice opened the door and found that it led into a small passage, not
70 | much larger than a rat-hole; she knelt down and looked along the passage
71 | into the loveliest garden you ever saw. How she longed to get out of
72 | that dark hall and wander about among those beds of bright flowers and
73 | those cool fountains, but she could not even get her head through the
74 | doorway. "Oh," said Alice, "how I wish I could shut up like a telescope!
75 | I think I could, if I only knew how to begin."
76 |
77 | Alice went back to the table, half hoping she might find another key on
78 | it, or at any rate, a book of rules for shutting people up like
79 | telescopes. This time she found a little bottle on it ("which certainly
80 | was not here before," said Alice), and tied 'round the neck of the
81 | bottle was a paper label, with the words "DRINK ME" beautifully printed
82 | on it in large letters.
83 |
84 | "No, I'll look first," she said, "and see whether it's marked '_poison_'
85 | or not," for she had never forgotten that, if you drink from a bottle
86 | marked "poison," it is almost certain to disagree with you, sooner or
87 | later. However, this bottle was _not_ marked "poison," so Alice ventured
88 | to taste it, and, finding it very nice (it had a sort of mixed flavor of
89 | cherry-tart, custard, pineapple, roast turkey, toffy and hot buttered
90 | toast), she very soon finished it off.
--------------------------------------------------------------------------------
/resources/lessons/lesson_2:
--------------------------------------------------------------------------------
1 | '''
2 | Programming 102
3 | Unit 2
4 | '''
5 |
6 | import random
7 |
8 | '''
9 | R ead
10 | E valuate
11 | P rint
12 | L oop
13 | '''
14 |
15 |
16 | '''
17 | play_again = 'yes'
18 |
19 | # this loop will only loop if the user enters exactly 'yes'
20 | while play_again == 'yes':
21 | # loop this code block
22 |
23 | print('\nWelcome to the game!')
24 |
25 | # ...
26 | # ... other code ..
27 | # ...
28 |
29 | # ask the user if they want to play again
30 | play_again = input('Do you want to play again? yes/no:')
31 | else:
32 | print('\nThanks for playing!')
33 | '''
34 | # ------------------------------------------------------------------------------- #
35 | '''
36 | while True: # infinite loop, requiring 'break' to end the loop
37 | # ask the user for a color and give them the option to quit
38 | color = input("\nEnter a color or 'done' to quit: ")
39 |
40 | # check if the user wants to quit
41 | if color == 'done':
42 | print('Goodbye!')
43 | break # end the loop
44 |
45 | print(f'\nThanks for entering "{color}"')
46 | '''
47 |
48 | # ------------------------------------------------------------------------------- #
49 |
50 | # Functions!
51 |
52 | # built-in functions
53 | # print(), type(), input(), len(), str(), int(), float(), list(), bool(), range()
54 |
55 | '''
56 | Functions
57 |
58 | - named code blocks
59 | - run only when called upon with parentheses after their name
60 | - typically designed to perform a single task
61 | - once defined, a function can be called as many times as needed with different data
62 | - receive data & return data after it's been manipulated
63 | '''
64 | # ------------------------------------------------------------------------------- #
65 |
66 | '''
67 | # parameters are empty variables in a function's defintion which await data from the function call
68 | def function_name(parameter_1, parameter_2, ...):
69 | # this code block will be run
70 | # when the function is 'called'
71 |
72 | # manipulate the parameters somehow
73 |
74 | # send the result back to where the function was called
75 | # with the keyword 'return'
76 | # if no return value is specified, a function will return 'None' by default
77 | return manipulated_parameters
78 |
79 | # call the function and save the return value in a variable
80 | data_returned_from_function = function_name(argument_1, argument_2, ...)
81 | '''
82 | # ------------------------------------------------------------------------------- #
83 |
84 | # increment(number) - add one to the number and return the result
85 |
86 | def increment(number):
87 | result = number + 1
88 | return result
89 |
90 | # call the function with a value for 'number'
91 | result = increment(9)
92 | # print(result) # 10
93 |
94 | result = increment(result)
95 | # print(result) # 11
96 |
97 |
98 | # use the function in a loop
99 |
100 | x = 0
101 |
102 | while x < 10:
103 | # print(x)
104 |
105 | # use the function to increment x
106 | x = increment(x)
107 |
108 | # -------------------------------------------------------------------------------------- #
109 |
110 | # arguments MUST be passed to fill parameters (unless default values are provided)
111 | # increment() # TypeError: increment() missing 1 required positional argument: 'number'
112 |
113 |
114 | # -------------------------------------------------------------------------------------- #
115 |
116 | # add(a, b) - return the sum of two numbers, 'a' and 'b'
117 |
118 | def add(a=1, b=1):
119 | return a + b
120 |
121 | # if NO default values are provided for parameters:
122 | # add() # TypeError: add() missing 2 required positional arguments: 'a' and 'b'
123 | # add(9) # TypeError: add() missing 1 required positional argument: 'b'
124 | # print(add(9, 1)) # 10 - a=9, b=1
125 |
126 | # if default values ARE provided for parameters
127 | # print(add(10)) # 11 - (a=10, b=default)
128 | # print(add()) # 2 - (a=default, b=default)
129 | # print(add(5, 2)) # 7 - (a=5, b=2)
130 | # print(add(b=7)) # 8 - (a=default, b=7)
131 | # print(add(b=7, a=5)) # 12 (a=5, b=7)
132 |
133 | # -------------------------------------------------------------------------------------- #
134 |
135 | # 'shred' a string and return a randomized list of its characters
136 |
137 | def shred_string(string):
138 | # convert the string to a list of its characters
139 | characters = list(string)
140 |
141 | # random the list
142 | random.shuffle(characters)
143 |
144 | return characters
145 |
146 |
147 | shredded = shred_string('hello world')
148 | # print(shredded)
149 |
150 | shredded = shred_string('ABCDEFG')
151 | # print(shredded)
152 |
153 | # -------------------------------------------------------------------------------------- #
154 |
155 | # generate a list of 'k' integers between 'low' and 'high'
156 |
157 | def generate_random_numbers(k, low=0, high=100):
158 | # create a blank list to store the numbers
159 | numbers = []
160 |
161 | # loop 'k' times
162 | for x in range(k):
163 | # generate a random number between 'low' and 'high'
164 | random_number = random.randint(low, high)
165 |
166 | # add the number to the list
167 | numbers.append(random_number)
168 |
169 | return numbers
170 |
171 | random_numbers = generate_random_numbers(10)
172 | # print(random_numbers) # [93, 62, 25, 98, 76, 75, 42, 20, 25, 37]
173 |
174 | random_numbers = generate_random_numbers(3, 10, 20)
175 | # print(random_numbers) # [13, 11, 15]
176 |
177 | random_numbers = generate_random_numbers(10000, -100, 100)
178 | # print(random_numbers)
179 |
--------------------------------------------------------------------------------
/docs/vocab.md:
--------------------------------------------------------------------------------
1 | # Programming Vocab
2 |
3 |
4 |
5 | ## Argument
6 |
7 | - An object passed to a function to fill one of its parameters
8 |
9 | - When a function is called, arguments are passed to fill the functions parameters
10 |
11 | ## Class
12 |
13 | - A data structure which acts as a blueprint for creating objects.
14 |
15 | - All Python datatypes are created with classes.
16 |
17 | - When we create an object, we're creating an 'instance' of a pre-defined class which shares all the attributes of the class but can have properties unique to each instance
18 |
19 | - Classes have attributes which can be functions or variables
20 |
21 | ## Code Block
22 |
23 | - A section of code that executes together
24 |
25 | - In Python, code blocks are defined using horizontal indentation.
26 |
27 | - The first line of code in a code block determines its indentation and all subsequent lines in that block must match that indentation.
28 |
29 | ## Concatenation
30 | - Adding two strings together with a plus sign (`+`) to form a single string
31 |
32 | ## Docstring
33 |
34 | - A multi-line string at the beginning of a function's code block that provides documentation about the function, its parameters and its return value
35 |
36 | ## Function
37 |
38 | - A named code block that performs a specific task.
39 |
40 | - Functions reduce repetition in our code by allowing us to write code in a generic way and use it with multiple values.
41 |
42 | - Functions are executed with parentheses after their name. (e.g. `print()`)
43 |
44 | ## Immutable (Unchangeable)
45 | If an object is immutable, it cannot be given a new value directly. Instead, a new copy of the object will need to be created with the desired changes applied.
46 |
47 | See "Mutable"
48 |
49 | ## Index
50 |
51 | - An item's position in a sequence (list, string, etc.)
52 |
53 | - Indices are always integers and must correspond to an existing item in the sequence, otherwise an `IndexError` will be raised.
54 | ## Iteration
55 | A single pass through a loop's code block. A loop is made of one or more iterations.
56 |
57 | ## Loop
58 |
59 | - A code block that repeats until a certain condition is met.
60 |
61 | - With a `for` loop, the condition is that there are more items left in the `sequence`
62 |
63 | - With a `while` loop, we define the condition directly.
64 |
65 | ## Method
66 |
67 | - A function that only manipulates the object to which it belongs
68 |
69 | ## Module
70 | A Python file containing code that can be imported into another Python file to be used.
71 |
72 | All the code in the global scope of a module is run when that module is
73 |
74 | ## Mutable (Changeable)
75 | If an object is mutable, it has the ability to be given a new value without needing to create a new instance of the object.
76 |
77 | See "Immutable"
78 |
79 | ## Object
80 |
81 | - A collection of variables and methods that act on those variables.
82 |
83 | - A class is a blueprint for an object. Multiple objects can be created from the same class.
84 |
85 | - The variables and methods contained in an object are called its 'attributes'
86 |
87 | - An object's attributes are accessed with dot notation (e.g. `'abc'.upper()`)
88 |
89 | ## Operand
90 |
91 | - A piece of data being used to perform an operation
92 |
93 | ## Operation
94 |
95 | - Any process that manipulates data (operands)
96 |
97 | ## Operator
98 |
99 | - A symbol or word that performs an operation on one or more pieces of data (operands)
100 |
101 | ## Ordered Sequence
102 |
103 | - A sequence whose items can be retrieved using their position in the sequence
104 |
105 | - An item's position in a sequence is called its 'index'.
106 |
107 | - Lists (`list`) and Strings (`str`) are examples of ordered sequences.
108 |
109 | - Python Sets (`set`) are an example of an *un*-ordered sequence.
110 |
111 | ## Parameter
112 | An empty variable in the definition of a function which will hold the values which are to be used in the function.
113 |
114 | When a function is called, values are passed through the parentheses in the function call and those values are assigned to the parameters and then passed into the function's code block.
115 |
116 | Parameters can also be given default values that will be used if no value is passed for that parameter.
117 |
118 | ```python
119 | # 'a' and 'b' are parameters
120 | # 'b' has a default value of 1
121 | def add(a, b=1):
122 | '''return the sum of two numbers, 'a' and 'b''''
123 | return a + b
124 | ```
125 |
126 |
127 | ## Return Value
128 | The value that is sent back from a function to the location where the function was called.
129 |
130 | The return value takes the place of the function call as the code is evaluated.
131 |
132 | ## Scope
133 | Four levels in which variables exist in any Python file. Data in outer scopes are available to inner scopes, but data in inner scopes isn't available to outer scopes.
134 |
135 | Data can be returned from functions to make it available to outer scopes.
136 |
137 | ### Levels of scope
138 | **Built-in** - Everything included behind-the-scenes in a Python file
139 |
140 | **Global** - Everything created in the Python file
141 |
142 | **Enclosed** - Everything defined within the code block of a global function
143 |
144 | **Local** - Everything within the code block of an enclosed function
145 |
146 | ## Sequence
147 | A collection of items. Sequences can be ordered (e.g. lists and strings) or unordered (e.g. sets and dictionaries)
148 |
149 | If a sequence is ordered, its items can be retrieved using their positions in the list.
150 |
151 | ## Subscriptable
152 | The quality of being able to use an index or key to retrieve a value from an object.
153 |
154 |
155 | ## Typecasting
156 | The process of converting one type of data to another.
157 | ## Variable
158 | - A named storage space for data.
159 |
160 | - Variables can store objects of any datatype and can be used in operations involving that datatype.
161 |
162 | - Variables can be re-defined with new values at any time.
163 |
164 |
165 |
166 |
167 |
168 |
169 |
--------------------------------------------------------------------------------
/labs/lab5.md:
--------------------------------------------------------------------------------
1 | # Lab 5 - User Login
2 |
3 | [Back to Syllabus](https://github.com/PdxCodeGuild/Programming102#top)
4 |
5 | Create a REPL which allows a user to 'log in'.
6 |
7 | Please complete the sections **in order**. Create a working version of 5.1 before attempting 5.2, etc. This will make your life easier. You may also want to consider creating separate `.py` files for each version, so you can refer back to previous working versions.
8 |
9 | ### **5.1**
10 |
11 | Create a dictionary called `profile`
12 |
13 | The `profile` should contain **two** **key : value** pairs with keys of `username` and `password` and values of your choosing. They will represent a `username` and `password` for a **single** user.
14 |
15 | username - gandalfTheGrey
16 | password - noneShallPass!
17 |
18 | **Do not** create your profile with the user's username as the key and their password as the value as below:
19 |
20 | 'gandalfTheGrey':'noneShallPass'
21 |
22 | Define a function called `login()` which will have three parameters for:
23 |
24 | - `username_attempt`
25 | - `password_attempt`
26 | - `profile`
27 |
28 | If the values passed to the function for `username_attempt` and `password_attempt` match the values at the keys of `username` and `password` found in the `profile`, The `login()` function will `return True`.
29 |
30 | If the credentials don't match those in the `profile`, the `login()` function will `return False`
31 |
32 | - Create variables for a `username_attempt` and `password_attempt` which will emulate a user's login attempt.
33 |
34 | - Pass the `profile` dictionary, `username_attempt` and `password_attempt` to `login()`. Use the boolean that is returned to tell the user whether or not their login attempt was successful.
35 |
36 | Output:
37 | ```
38 | # successful login
39 | username: gandalfTheGrey
40 | password: noneShallPass!
41 |
42 | Welcome, gandalfTheGrey!
43 |
44 | # unsuccessful login
45 | username: gandalfTheGrey
46 | password: myPrecious?
47 |
48 | Error! Your username or password was incorrect!
49 | ```
50 | ### **5.2**
51 |
52 | Create a REPL that asks the user for their `username_attempt` and `password_attempt` and attempts to log them in.
53 |
54 | If their login is **successful**, print a welcome message and end the program.
55 |
56 | If their login is **unsuccessful**, ask if they'd like to try again.
57 |
58 | ### **5.3 - Extra Challenge**
59 |
60 | Allow the user **three attempts** to login. If they exceed three attempts without a successful login, tell the user and end the program
61 |
62 | Output:
63 |
64 | username: gandalfTheGrey
65 | password: myPrecious?
66 |
67 | Error! Your username or password was incorrect!
68 |
69 | Enter 'y' to try again, 'n' to quit: y
70 |
71 | You have 2 login attempt(s) remaining...
72 |
73 | username: gandalfTheGrey
74 | password: foolOfATook!
75 |
76 | Error! Your username or password was incorrect!
77 |
78 | Enter 'y' to try again, 'n' to quit: y
79 |
80 | You have 1 login attempt(s) remaining...
81 |
82 | username: gandalfTheGrey
83 | password: bilboBaggins!
84 |
85 | Error! Your username or password was incorrect!
86 |
87 | Your login has been unsuccessful three times! Try again later. Goodbye!
88 |
89 | ### **5.4 - Extra Challenge**
90 |
91 | Add support for **multiple** users.
92 |
93 | A few things will need to change:
94 |
95 | - Instead of one `profile`, you will need a **_list_** of `profiles`. Each `profile` will be a dictionary containing **key : value** pairs with the keys of `username` and `password`.
96 |
97 | - When the user enters their username and password attempts, loop through the list of `profiles`, pass each `profile` one at time into the `login()` function along with the `username_attempt` and `password_attempt`.
98 |
99 | - If the `username_attempt` and `password_attempt` match the values at the keys of `username` and `password` current `profile`, the `login()` function will return that `True` and that user will be logged in. Otherwise, it will return `False`.
100 |
101 | ### **5.5 - Extra Challenge**
102 |
103 | - Define a function called `user_exists()` which will:
104 |
105 | - loop through each `profile` in the `profiles` list
106 | - check to see if the `username` the user entered already exists within one of the `profile` dictionaries.
107 |
108 | If a user with that `username` already exists, `return True`, otherwise `return False`
109 |
110 | - Define a function called `create_user()` which:
111 |
112 | - prompts the user for a `username` and `password`.
113 | - checks to see if the `username` already exists in the `profiles` list using the `user_exists()` function
114 | - If the `username` is unique and doesn't appear in the `profiles` list, `.append()` it to the `profiles` list.
115 |
116 |
117 | - Integrate the `create_user()` function into your REPL to allow the user to create a new username.
118 |
119 | ---
120 |
121 | Profiles list:
122 |
123 | username: gandalfTheGrey
124 | password: noneShallPass!
125 |
126 | username: bilboBaggins
127 | password: theShire123
128 |
129 | username: iAmSmeagol
130 | password: myPrecious!
131 |
132 | Output:
133 |
134 | Welcome!
135 |
136 | Please select from the following options:
137 |
138 | 1. Create user
139 | 2. Login
140 |
141 | Enter the number of your choice: 1
142 |
143 | Create User
144 | -----------
145 | Enter your new username: gandalfTheGrey
146 |
147 | That username already exists!
148 |
149 | Enter your new username:
150 | mrSamwise
151 |
152 | Enter your password:
153 | frodoIsMyFriend
154 |
155 | Thanks for signing up, mrSamwise!
156 |
157 | Please select from the following options:
158 |
159 | 1. Create user
160 | 2. Login
161 |
162 | Enter the number of your choice: 2
163 |
164 | Login:
165 | ------
166 |
167 | username: smaugTheDragon
168 | password: gimmeYerGold!
169 |
170 | Error! Your username or password was incorrect!
171 |
172 | Enter 'y' to try again, 'n' to quit: y
173 |
174 | You have 2 login attempt(s) remaining...
175 |
176 | username: iAmSmeagol
177 | password: myPrecious!
178 |
179 | Welcome, iAmSmeagol!
180 |
181 | ---
182 |
183 | [Back to Syllabus](https://github.com/PdxCodeGuild/Programming102#top)
184 |
--------------------------------------------------------------------------------
/practice/unit_4/exercise_2.md:
--------------------------------------------------------------------------------
1 | ## Unit 4 Practice
2 |
3 | ## **Exercise 2 - Hero Battle**
4 |
5 | ## 2.1
6 | ---
7 | Create two dictionaries, `hero` and `villain`. The items in each dictionary will represent each characters stats.
8 |
9 |
10 |
11 | |Stat|Datatype|Values|
12 | |-|-|-|
13 | |`name`| string| any|
14 | |`hp`| integer | 0 - 100|
15 | |`attack` | integer |1 - 10|
16 |
17 |
18 |
19 |
20 |
21 | ## `is_defeated()`
22 | The `is_defeated()` function will determine if a player's `hp` is at or below zero, meaning they're been defeated. Here's the function's definition:
23 |
24 | ```python
25 | def is_defeated(character):
26 | '''
27 | Returns False if the character's hp is greater than zero
28 | Returns True if the character's hp is less than or equal to
29 | '''
30 | # ... your code here ...
31 |
32 | pass # replace 'pass' with a return statement
33 | ```
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 | Write a REPL which allows the two characters to do battle. Each character will attack during every loop.
42 |
43 | Each attack will subtract the character's `attack` strength from its opponents `hp`. Since the `attack` stat has a range from 1 - 10, **feel free to multiply it by *5* or *10* to speed up the battle.**
44 |
45 | Use the `is_defeated()` function to determine if the opponent has lost the battle, announce who won and end the loop.
46 |
47 | An `input()` function can be used to slow the battle down a bit and allow the user to decide when the next round of the battle will be executed. This way the battle will be more interactive and won't happen instantaneously.
48 |
49 |
50 |
51 | ### [Exercise 2.1 Solution](./solutions/exercise_2/exercise_2_1_solution.md)
52 |
53 |
54 |
55 |
56 | ## 2.2
57 | ---
58 |
59 |
60 | Chances are that there is a fair amount of reptition in the logic which performs each character's turn in the battle, since the same steps will need to be executed by each character during their turn.
61 |
62 | Create a function `attack()` to handle each round of the battle.
63 |
64 | ```python
65 | def attack(attacker, opponent):
66 | '''
67 | Apply battle damage to the opponent using the attacker's attack stat
68 | If the opponent is defeated, return True, signifying the battle is over
69 | Otherwise return False, signifying the battle will continue for another round
70 | '''
71 | # ... your code here ...
72 |
73 | return # use is_defeated() to return True/False if the battle is over
74 | ```
75 |
76 | Subtract the value of the attacker's `attack` stat from the opponents `hp` stat. Return `True` if the opponent is defeated, otherwise return `False`. This boolean will be used to determine if the battle is over or if it will continue for another round.
77 |
78 |
79 |
80 | ### [Exercise 2.2 Solution](./solutions/exercise_2/exercise_2_2_solution.md)
81 |
82 |
83 |
84 |
85 |
86 | ## 2.3
87 | ---
88 |
89 |
90 | Add additional stats `defense` and `stance` and add allow each the characters to choose their `stance` each round.
91 |
92 |
93 |
94 |
95 | |Stat|Datatype|Values|
96 | |-|-|-|
97 | |`name`| string| any|
98 | |`hp`| integer | 0 - 100|
99 | |`attack` | integer |1 - 10|
100 | |`defense` |integer |1 - 10|
101 | |`stance`| string |`'attack'` / `'defend'`|
102 |
103 |
104 |
105 |
106 |
107 | If a character chooses to defend, they will not attack this turn.
108 |
109 | If the character's stance is set to `'defend'` when their opponent attacks, the damage they receive is reduced. If the character's stance is set to `'attack'`, no change is made to the incoming damage.
110 |
111 | Two additional functions could be added to handle these modifications:
112 |
113 |
114 |
115 | ## `set_stance()`
116 |
117 | This function will take in a character dictionary and allow them to choose whether they want to set their `stance` stat to`attack` or `defend` this round using a REPL.
118 |
119 | ```python
120 | def set_stance(character):
121 | '''
122 | Ask the user which stance they would like to take this round.
123 | Change the value at the key of 'stance' to match the user's choice.
124 | Stance options: 'attack', 'defend'
125 | '''
126 |
127 | # ... your code here ...
128 |
129 | # return the character dictionary with adjusted stance stat
130 | return character
131 |
132 | ```
133 |
134 |
135 |
136 | ## `defend()`
137 |
138 | The function `defend()` will be used to adjust the incoming damage to a character when it's their opponent's turn to attack.
139 |
140 | Below are the damage reduction rates for different `'defense'` stat levels:
141 |
142 |
143 |
144 |
145 |
146 | |Defense Level|Damage Reduction|
147 | |-|-|
148 | |0 - 4|10%|
149 | |5 - 7|33%|
150 | |8 - 10|66%|
151 |
152 |
153 |
154 |
155 |
156 | ```python
157 | def defend(character, incoming_damage):
158 | '''
159 | Calculate the amount the incoming_damage will be reduced
160 | based on the character's 'defense' stat.
161 |
162 | Return the amount the incoming_damage will be reduced
163 | in a variable called 'damage_reduction'
164 |
165 | 0 - 4 = 10%, 5 - 7 = 33%, 8 - 10 = 66%
166 | '''
167 |
168 | # return the reduction amount, rounded to the nearest integer
169 | return round(damage_reduction)
170 | ```
171 |
172 |
173 |
174 | ### [Exercise 2.3 Solution](./solutions/exercise_2/exercise_2_3_solution.md)
175 |
176 |
177 |
178 |
179 |
180 | ---
181 |
182 | ###
183 |
184 | Add some more fun features. Pull from your favorite games or stories and get creative! Some ideas might include:
185 |
186 | - Special, stronger attacks. These could even require a few rounds to build up power before they're able to be used.
187 | - randomized stats
188 | - randomize which character attacks first
189 | - add `'heal'` as a possible `stance` option and increase the character's `hp` that round if chosen based on a `healing` stat
190 | - have the opponent's choices be made by code, rather than user input
191 | - add a third character
192 | - More than one `villain` (list of dictionaries). The `hero` could `level_up()` with each opponent it defeats.
193 |
194 |
195 | ---
196 |
197 | ### [<< Back to Unit 4 Practice](/practice/unit_4/)
198 |
--------------------------------------------------------------------------------
/resources/example_lessons/unit_2/unit_2_lesson.py:
--------------------------------------------------------------------------------
1 | '''
2 | Programming 102
3 | Unit 2
4 | '''
5 |
6 | import random
7 |
8 | '''
9 | R ead
10 | E valuate
11 | P rint
12 | L oop
13 | '''
14 |
15 | ### INTRODUCE THE TERMINAL AS A REPL
16 |
17 | '''
18 | play_again = 'yes'
19 |
20 | # this loop will only loop if the user enters exactly 'yes'
21 | while play_again == 'yes':
22 | # loop this code block
23 |
24 | print('\nWelcome to the game!')
25 |
26 | # ...
27 | # ... other code ...
28 | # ...
29 |
30 | # ask the user if they want to play again
31 | play_again = input("Do you want to play again? yes/no: ")
32 |
33 | else:
34 | print("\nThanks for playing!")
35 | '''
36 | # ------------------------------------------------------------------------------- #
37 |
38 | '''
39 | while True: # infinite loop, requiring 'break' to end the loop
40 | # ask the user for a color and give them the option to quit
41 | color = input("\nEnter a color or 'done' to quit: ")
42 |
43 | # check if the user wants to quit
44 | if color == 'done':
45 | print('Goodbye!')
46 | break # end the loop
47 |
48 |
49 | print(f"\nThanks for entering '{color}'")
50 |
51 | '''
52 |
53 | # ------------------------------------------------------------------------------------------ #
54 |
55 | # Functions!
56 |
57 | # built-in functions
58 | # print(), type(), input(), len(), str(), int(), float(), list(), bool(), range()
59 |
60 | '''
61 | Functions
62 |
63 | - named code blocks
64 | - run only when called upon with parentheses after their name
65 | - typically designed to perform a single task
66 | - once defined, a function can be called as many times as needed with different data
67 | - receive data & return data after it's been manipulated
68 | '''
69 |
70 | # ---------------------------------------------------------------------------------- #
71 |
72 | ### INTRODUCE INCREMENTALLY
73 | ### 1. KEYWORD def
74 | ### 2. function_name, PARENTHESES, AND COLON
75 | ### 3. EXPLAIN THAT THE CODE BLOCK WILL BE CALLED WHEN THE FUNCTION IS RUN
76 | ### 4. DEFINE PARAMETERS TO ALLOW DATA TO BE PASSED INTO THE FUNCTION
77 | ### 5. EXPLAIN THAT THE DATA THAT IS PASSED TO THE PARAMETERS IS MANIPULATED IN THE FUNCTION
78 | ### 6. EXPLAIN return, THE VALUE THAT'S RETURNED AS WELL AS TO WHERE IT'S RETURNED
79 | ### 7. CALL THE FUNCTION, PASS ARGUMENTS, DEFINE VARIABLE WITH RETURN VALUE
80 |
81 | ### 8. THIS FORMAT CAN BE USED TO DEFINE ALL THE OTHER FUNCTIONS TOO
82 |
83 | # keyword 'def' to define a function
84 | '''
85 | # parameters are empty variables in a function's definition which await data from the function call
86 | def function_name(parameter_1, parameter_2, ...):
87 | # this code block will be run
88 | # when the function is 'called'
89 |
90 | # manipulate the parameters somehow
91 |
92 | # send the result back to where the function was called
93 | # with the keyword 'return'
94 | # if no return value is specified, a function will return 'None' by default
95 | return manipulate_parameters
96 |
97 | # call the function and save the return value in a variable
98 | data_returned_from_function = function_name(argument_1, argument_2, ...)
99 | # data passed to functions to fill parameters are called 'arguments'
100 | '''
101 | # ----------------------------------------------------------------------------------- #
102 |
103 | # increment(number) - add one to the number and return the result
104 |
105 | def increment(number):
106 | result = number + 1
107 | return result
108 |
109 | # call the function with a value for 'number'
110 | result = increment(9)
111 | # print(result)
112 |
113 | result = increment(result)
114 | # print(result)
115 |
116 | # use the function in a loop
117 | x = 0
118 |
119 | while x < 10:
120 | # print(x)
121 |
122 | # use the function to increment x
123 | x = increment(x)
124 |
125 | # -------------------------------------------------------------------------------------- #
126 |
127 | # arguments MUST be passed to fill parameters (unless default values are provided)
128 | # increment() # TypeError: increment() missing 1 required positional argument: 'number'
129 |
130 | # ---------------------------------------------------------------------------------------- #
131 |
132 | # add(a, b) - return the sum of two numbers, 'a' and 'b'
133 |
134 | def add(a=1, b=1):
135 | return a + b
136 |
137 | # if NO default values are provided for parameters:
138 | # add() # TypeError: add() missing 2 required positional arguments: 'a' and 'b'
139 | # add(9) # TypeError: add() missing 1 required positional argument: 'b'
140 | # print(add(9, 1)) # 10 - a=9, b=1
141 |
142 | # if default values ARE provided for parameters
143 | # print(add(10)) # 11 - (a=10, b=default)
144 | # print(add()) # 2 - (a=default, b=default)
145 | # print(add(5, 2)) # 7 - (a=5, b=2)
146 | # print(add(b=7)) # 8 - (a=default, b=7)
147 | # print(add(b=7, a=5)) # 12 - (a=5, b=7)
148 |
149 | # ------------------------------------------------------------------------------------- #
150 |
151 | # 'shred' a string and return a randomized list of its characters
152 |
153 | def shred_string(string):
154 | # convert the string to a list of its characters
155 | characters = list(string)
156 |
157 | # randomize the list
158 | random.shuffle(characters)
159 |
160 | return characters
161 |
162 |
163 |
164 | shredded = shred_string('hello world')
165 | # print(shredded)
166 |
167 | shredded = shred_string('ABCDEFG')
168 | # print(shredded)
169 |
170 | # -------------------------------------------------------------------------------------- #
171 |
172 | # generate a list of 'k' integers between 'low' and 'high'
173 |
174 | def generate_random_numbers(k, low=0, high=100):
175 | # create a blank list to store the numbers
176 | numbers = []
177 |
178 | # loop 'k' times
179 | for x in range(k):
180 | # generate a random number between 'low' and 'high'
181 | random_number = random.randint(low, high)
182 |
183 | # add the number to the list
184 | numbers.append(random_number)
185 |
186 | return numbers
187 |
188 |
189 | random_numbers = generate_random_numbers(10)
190 | # print(random_numbers) # [80, 94, 71, 99, 3, 48, 74, 29, 41, 12]
191 |
192 | random_numbers = generate_random_numbers(3, 10, 20)
193 | # print(random_numbers) # [15, 17, 17]
194 |
195 | random_numbers = generate_random_numbers(1000, -100, 100)
196 | # print(random_numbers)
197 |
198 |
--------------------------------------------------------------------------------
/practice/unit_2/solutions/exercise_4_solution.md:
--------------------------------------------------------------------------------
1 | # Unit 2 Practice Solutions
2 |
3 | ## **Exercise 4 - Calculator**
4 |
5 | ### **4.1**
6 |
7 | ```python
8 | def add(a, b):
9 | '''return the sum of two numbers, a and b'''
10 | return a + b
11 |
12 | def subtract(a, b):
13 | '''return the difference of two numbers, a and b'''
14 | return a - b
15 |
16 |
17 | while True:
18 | # ask the user for the operation
19 | operation = input("Enter the operation you would like to perform or 'done' to quit: ")
20 |
21 | # check if the user would like to quit
22 | if operation == 'done':
23 | print('Goodbye!')
24 | break # end the REPL
25 |
26 | # get the operands from the user
27 | operand_1 = input('Enter the first operand: ')
28 | operand_2 = input('Enter the second operand: ')
29 |
30 | # convert strings to floats
31 | operand_1 = float(operand_1)
32 | operand_2 = float(operand_2)
33 |
34 | # check the operation and call appropriate function
35 | if operation == '+':
36 | result = add(operand_1, operand_2)
37 | elif operation == '-':
38 | result = subtract(operand_1, operand_2)
39 |
40 | # display the result
41 | print(f'{operand_1} {operation} {operand_2} = {result}')
42 | ```
43 | ---
44 |
45 | ### **2.2**
46 |
47 | ```python
48 |
49 | # add these two functions
50 | def multiply(a, b):
51 | '''return the product of two numbers, a and b'''
52 | return a * b
53 |
54 | def divide(a, b):
55 | '''return the quotient of two numbers, a and b'''
56 | return a / b
57 |
58 | # ---------------------------------------------------- #
59 |
60 | # add checks for multiplication and division
61 | if operation == '+':
62 | result = add(operand_1, operand_2)
63 | elif operation == '-':
64 | result = subtract(operand_1, operand_2)
65 | elif operation == '*':
66 | result = multiply(operand_1, operand_2)
67 | elif operation == '/':
68 | result = divide(operand_1, operand_2)
69 |
70 | ```
71 |
72 | ---
73 | ### **2.3**
74 | ```python
75 | def add(a, b):
76 | '''return the sum of two numbers, a and b'''
77 | return a + b
78 |
79 | def subtract(a, b):
80 | '''return the difference of two numbers, a and b'''
81 | return a - b
82 |
83 | def multiply(a, b):
84 | '''return the product of two numbers, a and b'''
85 | return a * b
86 |
87 | def divide(a, b):
88 | '''return the quotient of two numbers, a and b'''
89 | return a / b
90 |
91 | # initialize the running total to None
92 | total = None
93 |
94 | while True:
95 | # ask the user for the operation
96 | operation = input("\n\nEnter the operation you would like to perform or 'done' to quit: ")
97 |
98 | # check if the user would like to quit
99 | if operation == 'done':
100 | # print final total
101 | print(f'\nYour final total was: {total}')
102 |
103 | print('\nGoodbye!')
104 | break # end the REPL
105 |
106 | # if total still contains the value None, get both operands from the user
107 | # note: this will only be True on the first loop
108 | if not total:
109 | # get the operands from the user
110 | operand_1 = input('Enter the first operand: ')
111 | operand_2 = input('Enter the second operand: ')
112 |
113 | else:
114 | # if the total is already defined, set it as the first operand and get the other operand from the user
115 | operand_1 = total
116 | operand_2 = input(f'\n{total} {operation} x:\n\nEnter x: ')
117 |
118 | # convert strings to floats
119 | operand_1 = float(operand_1)
120 | operand_2 = float(operand_2)
121 |
122 | # check the operation and call appropriate function
123 | if operation == '+':
124 | total = add(operand_1, operand_2)
125 |
126 | elif operation == '-':
127 | total = subtract(operand_1, operand_2)
128 |
129 | elif operation == '*':
130 | total = multiply(operand_1, operand_2)
131 |
132 | elif operation == '/':
133 | total = divide(operand_1, operand_2)
134 |
135 | # display the result
136 | print(f'\n{operand_1} {operation} {operand_2} = {total}')
137 | ```
138 |
139 | ---
140 | ### **2.4**
141 | ```python
142 | def add(a, b):
143 | '''return the sum of two numbers, a and b'''
144 | return a + b
145 |
146 | def subtract(a, b):
147 | '''return the difference of two numbers, a and b'''
148 | return a - b
149 |
150 | def multiply(a, b):
151 | '''return the product of two numbers, a and b'''
152 | return a * b
153 |
154 | def divide(a, b):
155 | '''return the quotient of two numbers, a and b'''
156 | return a / b
157 |
158 | # dictionary of operators as keys and their respective functions as values
159 | operations = {
160 | '+': add,
161 | '-': subtract,
162 | '*': multiply,
163 | '/': divide
164 | }
165 |
166 | # begin running total
167 | total = None
168 |
169 | while True:
170 | # ask the user for the operation
171 | operator = input("\nEnter the operation you would like to perform or 'done' to quit: ")
172 |
173 | # check if the user would like to quit
174 | if operator == 'done':
175 | # print final total
176 | print(f'\nYour final total was: {total}')
177 |
178 | print('\nGoodbye!')
179 | break # end the REPL
180 |
181 | # if total still contains the value None
182 | # note: this will only be True on the first loop
183 | if not total:
184 | # get the operands from the user
185 | operand_1 = input('Enter the first operand: ')
186 | operand_2 = input('Enter the second operand: ')
187 |
188 | else:
189 | # if the total is already defined, set it as the first operand
190 | operand_1 = total
191 | operand_2 = input(f'\n{total} {operator} x:\n\nEnter x: ')
192 |
193 | # convert strings to floats
194 | operand_1 = float(operand_1)
195 | operand_2 = float(operand_2)
196 |
197 | # retrieve the function at the key of the chosen operator
198 | operation = operations[operator]
199 |
200 | # perform the calculation on the total
201 | total = operation(operand_1, operand_2)
202 |
203 |
204 | # display the result
205 | print(f'{operand_1} {operator} {operand_2} = {total}')
206 | ```
207 | ---
208 | Keep in mind that this is just one potential solution.
209 |
210 | ---
211 |
212 | ## [< Exercise 3](../exercise_3.md)
213 |
214 | ### [<< Back to Unit 2 Practice](/practice/unit_2/)
215 |
--------------------------------------------------------------------------------
/resources/example_lessons/unit_4/unit_3_review.py:
--------------------------------------------------------------------------------
1 | '''
2 | Unit 3 Review
3 | '''
4 |
5 | # dictionaries are defined using curly brackets
6 | # key:value pairs are separated with commas
7 |
8 | blank_dictionary = {}
9 |
10 | todo = {
11 | # key: value,
12 | 'title': 'Go grocery shopping',
13 | 'completed': False
14 | }
15 |
16 | # dict keys are usually strings
17 | # dict values can be ANY datatype, including other dicts
18 |
19 | # ---------------------------------------------------------------------------------- #
20 |
21 | # when accessing values with keys,
22 | # the keys go in SQUARE brackets
23 | title = todo['title']
24 | # print(title) # Go grocery shopping
25 |
26 | # integers in square brackets generally mean lists
27 | # string in square brackets generally mean dictionaries
28 |
29 | # --------------------------------------------------------------------------------- #
30 |
31 | # cannot access a value at a non-existant key
32 | # todo['id'] # KeyError: 'id'
33 |
34 | # values can be added to keys that don't yet exist
35 | todo['id'] = 1
36 | # print(todo) # 'title': 'Go grocery shopping', 'completed': False, 'id': 1}
37 |
38 | # change the value at a key
39 | # the to do has been finished
40 | todo['completed'] = True
41 | # print(todo) # {'title': 'Go grocery shopping', 'completed': True, 'id': 1}
42 |
43 | # ----------------------------------------------------------------------------- #
44 |
45 | # .pop(key) delete the key:value pair at the key and return it
46 | todo_id = todo.pop('id')
47 | # print(todo_id, todo) # 1 {'title': 'Go grocery shopping', 'completed': True}
48 |
49 |
50 | # alternative to the .get() method:
51 | key = 'title'
52 | default = f"'{key}' is not a valid key in the dictionary."
53 |
54 | # check if the key is in the dictionary before using it
55 | if key in todo.keys():
56 | value = todo[key]
57 |
58 | else:
59 | value = default
60 |
61 | # print(value)
62 |
63 | # .get(key, default) - return the value at the key if it exists or the default if it doesn't
64 |
65 | key = 'id'
66 | default = f"'{key}' is not a valid key in the dictionary."
67 |
68 | value = todo.get(key, default)
69 | # print(value) # 'id' is not a valid key in the dictionary.
70 |
71 | # --------------------------------------------------------- #
72 |
73 | key = 'title'
74 | default = f"'{key}' is not a valid key in the dictionary."
75 |
76 | value = todo.get(key, default)
77 | # print(value) # Go grocery shopping
78 |
79 | # ------------------------------------------------------------------------- #
80 |
81 | #.update(new_dictionary) add the new_dictionary to the original
82 |
83 | todo.update({
84 | 'id': 1,
85 | 'user': 'KG'
86 | })
87 | # print(todo) # {'title': 'Go grocery shopping', 'completed': True, 'id': 1, 'user': 'KG'}
88 |
89 | # ------------------------------------- #
90 |
91 | # Display the todo item
92 | todo_display = f"""
93 | {todo['id']}. {todo['title']}
94 | Created by: {todo['user']}
95 | Completed: {todo['completed']}"""
96 |
97 | # print(todo_display)
98 |
99 | # ---------------------------------------- #
100 |
101 | # looping dictionaries
102 | # .keys(), .values(), .items() - access different parts of the a dictionary
103 |
104 | # print(todo.keys()) # dict_keys(['title', 'completed', 'id', 'user'])
105 |
106 | # loop through keys
107 | for key in todo.keys():
108 | # get the value at the current key
109 | value = todo[key]
110 | # print(f"{key}: {value}")
111 |
112 |
113 | # -------------------------------------------------------------------------- #
114 |
115 | # .values()
116 | # print(todo.values()) # dict_values(['Go grocery shopping', True, 1, 'KG'])
117 | '''
118 | for value in todo.values():
119 | print(value)
120 | '''
121 |
122 | # ----------------------------------------------------------------------- #
123 | # loop through the key:value pairs (items)
124 |
125 | # tuple - unchangeable list, uses indices but cannot accept new values
126 | # print(todo.items()) # dict_items([('title', 'Go grocery shopping'), ('completed', True), ('id', 1), ('user', 'KG')])
127 | '''
128 | for item in todo.items():
129 | key = item[0]
130 | value = item[1]
131 | print(f"{key}: {value}")
132 |
133 | '''
134 | # -------------------------------------------------------- #
135 |
136 | # 'in' to check if a key is in the dictionary
137 | # print('title' in todo.keys())
138 | # print('completed' in todo) # .keys() is optional
139 |
140 | # -------------------------------------------------------- #
141 |
142 | # instead of multiple, individual todo item dictionaries, create a list of dictionaries instead
143 | todo_1 = {'title': 'Go grocery shopping', 'completed': False, 'id': 1}
144 | todo_2 = {'title': 'Water the garden', 'completed': True, 'id': 2}
145 | todo_3 = {'title': 'Master Python dictionaries', 'completed': False, 'id': 3}
146 |
147 |
148 | # list of dictionaries
149 | todo_list = [
150 | {'title': 'Go grocery shopping', 'completed': False, 'id': 1},
151 | {'title': 'Water the garden', 'completed': True, 'id': 2},
152 | {'title': 'Master Python dictionaries', 'completed': False, 'id': 3}
153 | ]
154 |
155 | # list of dictionaries organized vertically
156 | todo_list = [
157 | {
158 | 'title': 'Go grocery shopping',
159 | 'completed': False,
160 | 'id': 1
161 | },
162 | {
163 | 'title': 'Water the garden',
164 | 'completed': True,
165 | 'id': 2
166 | },
167 | {
168 | 'title': 'Master Python dictionaries',
169 | 'completed': False,
170 | 'id': 3
171 | }
172 | ]
173 |
174 | # pull out one dictionary at a time from the list
175 | # print(todo_list[0]) # {'title': 'Go grocery shopping', 'completed': False, 'id': 1}
176 | # print(todo_list[0]['title']) # Go grocery shopping
177 |
178 | # loop through the todo_list
179 | for todo in todo_list:
180 | # if todo['completed'] == False:
181 | if not todo['completed']: # same as line 168
182 | todo_display = f"""
183 | {todo['id']}. {todo['title']}
184 | Completed: {todo['completed']}"""
185 |
186 | # print(todo_display)
187 |
188 | # ------------------------------------------------------------ #
189 |
190 | # nested dictionaries
191 |
192 | fruit_prices = {
193 | 'apple': {
194 | 'green': 2.12,
195 | 'yellow': 3.13,
196 | 'red': {
197 | 'price': 4.14,
198 | 'inventory': 100
199 | }
200 | },
201 | 'grape': 3.13
202 | }
203 |
204 | # print(fruit_prices['apple']) # {'green': 2.12, 'yellow': 3.13, 'red': 4.14}
205 |
206 | apple_prices = fruit_prices['apple']
207 | # print(apple_prices['green']) # 2.12
208 |
209 | # print(fruit_prices['apple']['green']) # 2.12
210 |
211 | # print(fruit_prices['apple']['red']) # {'price': 4.14, 'inventory': 100}
212 | # print(fruit_prices['apple']['red']['price']) # 4.14
213 |
--------------------------------------------------------------------------------
/practice/unit_4/solutions/exercise_2/exercise_2_3_solution.md:
--------------------------------------------------------------------------------
1 | # Unit 4 Practice Solutions
2 |
3 | ## **Exercise 2 Solution**
4 |
5 | ### **2.3**
6 |
7 |
8 |

9 |
10 |
11 |
12 |
13 | In this version, we're going to allow the active player to choose if they want to attack or defend each round. If they choose to defend, the next damage they receive will be reduced based on their `defense` stat.
14 |
15 | We'll be introducing two more functions, `set_stance()` and `defend()`.
16 |
17 | ### `set_stance()`
18 |
19 | This function will contain a REPL which will allow the user to choose which stance the active character should take this round. The function will take in the user's input, set the active character's stance stat and return the updated character dictionary.
20 |
21 | ### `defend()`
22 |
23 | This function will take in the opponent's stat dictionary and the amount of incoming damage from the active player's `attack` stat, reduce the incoming damage based on the opponent's `defense` stat and return the reduced damage amount.
24 |
25 | ```python
26 |
27 | # ----------------------------------------------------------- #
28 | # Setup
29 | # ----------------------------------------------------------- #
30 | hero = {
31 | "name": "Andromeda",
32 | "hp": 100,
33 | "attack": 7,
34 | "defense": 6,
35 | "stance": "" # 'attack' or 'defend'
36 | }
37 |
38 | villain = {
39 | "name": "Helios",
40 | "hp": 100,
41 | "attack": 5,
42 | "defense": 5,
43 | "stance": "" # 'attack' or 'defend'
44 | }
45 |
46 |
47 | def is_defeated(character):
48 | '''
49 | Returns False if the character's hp is greater than zero
50 | Returns True if the character's hp is less than or equal to
51 | '''
52 | return character['hp'] <= 0
53 |
54 |
55 | def set_stance(character):
56 | '''
57 | Set the character's stance stat with user
58 | input and return the updated dictionary
59 | '''
60 |
61 | stance_options = {
62 | '1': 'attack',
63 | '2': 'defend'
64 | }
65 |
66 | prompt = f"""
67 | {character['name']}, how would you like to proceed?
68 |
69 | 1. Attack
70 | 2. Defend
71 |
72 | Enter the number of the option
73 | > """
74 |
75 | stance_number = input(prompt)
76 |
77 | # make sure the user entered a valid selection
78 | while stance_number not in stance_options.keys():
79 | print('\n!***! Invalid selection !***!')
80 | stance_number = input(prompt)
81 |
82 | # Once the user has entered a valid selection, set the dictionary-
83 | character['stance'] = stance_options[stance_number]
84 |
85 | return character
86 |
87 |
88 | def defend(character, incoming_damage):
89 | '''
90 | Calculate the amount the incoming_damage will be reduced
91 | based on the character's 'defense' stat.
92 |
93 | Return the amount the incoming_damage will be reduced
94 | in a variable called 'damage_reduction'
95 |
96 | 0 - 4 = 10%, 5 - 7 = 33%, 8 - 10 = 66%
97 | '''
98 | defense = character['defense']
99 | if defense < 5:
100 | damage_reduction = incoming_damage * .1
101 | elif defense < 8:
102 | damage_reduction = incoming_damage * .33
103 | else:
104 | damage_reduction = incoming_damage * .66
105 |
106 | # return the reduction amount, rounded to the nearest integer
107 | return round(damage_reduction)
108 |
109 |
110 | def attack(active, opponent):
111 | '''
112 | Apply battle damage to the opponent using the attacker's attack stat
113 | If the opponent is defeated, return True, signifying the battle is over
114 | Otherwise return False, signifying the battle will continue for another round
115 | '''
116 | battle_over = False
117 |
118 | print("\n" + ("-" * 50)) # print a divider
119 |
120 | # display hp
121 | print(f"\n{active['name']} has {active['hp']} hp!")
122 | print(f"{opponent['name']} has {opponent['hp']} hp!")
123 |
124 | input("\nPress enter to battle!")
125 |
126 |
127 | # active character chooses stance
128 | active = set_stance(active)
129 |
130 | print("\n" + ("-" * 50)) # print a divider
131 |
132 | if active['stance'] == 'attack':
133 | # active character attacks
134 | print(f"\n{active['name']} attacks!")
135 |
136 | # damage to be dealt to the opponent
137 | damage = active['attack'] * 5 # multiply damage to speed up the game
138 |
139 | # if the opponent chose to defend last turn
140 | if opponent['stance'] == 'defend':
141 | # calculate the damage reduction
142 | damage_reduction = defend(opponent, damage)
143 |
144 | # reduce damage
145 | damage -= damage_reduction
146 |
147 | print(f"\n{opponent['name']} defends! Damage reduced by {damage_reduction}!")
148 |
149 | # subtract attackers's attack strength from the opponents's hp
150 | opponent['hp'] -= damage
151 |
152 | print(f"{opponent['name']} takes {damage} damage!")
153 |
154 | elif active['stance'] == 'defend':
155 | print(f"\n{active['name']}, the next damage you receive will be reduced!")
156 |
157 | # return True if the opponent is defeated, otherwise False
158 | return is_defeated(opponent)
159 |
160 |
161 |
162 |
163 | # ----------------------------------------------------------- #
164 | # Battle!
165 | # ----------------------------------------------------------- #
166 |
167 | # this will alternate between 0 and 1 to decide whose turn it is
168 | turn_counter = 0
169 |
170 | while True:
171 |
172 | # stat dictionaries stored at matching keys
173 | all_stats = {
174 | 'hero': hero,
175 | 'villain': villain
176 | }
177 |
178 | # keys for the all_stats dictionary
179 | # the turn_counter will alternate between 0 and 1 to decide whose turn it is
180 | stat_keys = list(all_stats.keys()) # ['hero', 'villain']
181 |
182 | # get the key of the active player
183 | active_key = stat_keys[turn_counter]
184 | # get the stat dictionary of the active player
185 | active = all_stats[active_key]
186 |
187 |
188 | # get the key of the current opponent
189 | # index -1 if turn_counter is 0
190 | # index 0 if the turn_counter is 1
191 | opponent_key = stat_keys[turn_counter - 1]
192 | # get the stat dictionary of the opponent
193 | opponent = all_stats[opponent_key]
194 |
195 | # execute current round of battle
196 | # receive True if opponent is defeated, otherwise False
197 | victorious = attack(active, opponent)
198 |
199 | # check the outcome of the battle.
200 | # if the opponent was defeated, end the loop
201 | if victorious:
202 | print(f"\n{opponent['name']} has been defeated! {active['name']} is victorious!")
203 | break # end the loop
204 |
205 | ```
206 |
207 |
208 |
209 |
210 | Keep in mind that this is just one potential solution.
211 |
212 | ## [< 2.2 Solution](./exercise_2_2_solution.md)
213 | ---
214 |
215 | ### [<< Back to Unit 4 Practice](/practice/unit_4/)
216 |
--------------------------------------------------------------------------------
/resources/lessons/lesson_3_review:
--------------------------------------------------------------------------------
1 | '''
2 | Unit 3 Review
3 | '''
4 |
5 | # dictionaries are defined using curly brackets
6 | # key:value pairs are separated with commas
7 |
8 | blank_dictionary = {}
9 |
10 |
11 | todo = {
12 | # key:value
13 | 'title':'Go grocery shopping',
14 | 'completed': False
15 | }
16 |
17 |
18 | # dict keys are usually strings
19 | # dict values can be ANY datatype, including other dicts
20 |
21 | # ---------------------------------------------------------------------------------- #
22 |
23 | # when accessing values with keys,
24 | # the keys go in SQUARE brackets
25 |
26 | title = todo['title']
27 | # print(title) # Go grocery shopping
28 |
29 | # integers in square brackets generally mean lists
30 | # string in square brackets generally mean dictionaries
31 |
32 | # --------------------------------------------------------------------------------- #
33 |
34 | # cannot access a value at a non-existant key
35 |
36 | # todo['id'] # KeyError: 'id'
37 |
38 | # values can be added to keys that don't yet exist
39 |
40 | todo['id'] = 1
41 |
42 | # print(todo) # {'title': 'Go grocery shopping', 'completed': False, 'id': 1}
43 |
44 | # change the value at a key
45 | # the todo has been finished
46 |
47 | todo['completed'] = True
48 | # print(todo) {'title': 'Go grocery shopping', 'completed': True, 'id': 1}
49 |
50 | # ----------------------------------------------------------------------------- #
51 | '''Dictionary Methods'''
52 |
53 | # .pop(key) delete the key:value pair at the key and return the value
54 |
55 | todo_id = todo.pop('id')
56 | # print(todo_id, todo) # 1 {'title': 'Go grocery shopping', 'completed': True}
57 |
58 | # ----------------------------------------------------------------------------- #
59 |
60 | # alternative to the .get() method:
61 |
62 | key = 'title'
63 |
64 | default = f"'{key}' is not a valid key in the dictionary."
65 |
66 | # check if the key is in the dictionary before using it
67 |
68 | if key in todo.keys():
69 | value = todo[key]
70 |
71 | else:
72 | value = default
73 |
74 | # print(value)
75 |
76 | # .get(key, default) - return the value at the key if it exists or the default if it doesn't
77 |
78 | key = 'id'
79 | default = f"'{key} is not a valid key in the dictionary."
80 |
81 | value = todo.get(key, default)
82 | # print(value) # 'id' is not a valid key in the dictionary.
83 |
84 | # ------------------------------------------------------------------------- #
85 |
86 | # .update(new_dictionary) add the new_dictionary to the original
87 |
88 |
89 | todo.update({
90 | 'id':1,
91 | 'user': 'JJ'
92 | })
93 |
94 | # print(todo) {'title': 'Go grocery shopping', 'completed': True, 'id': 1, 'user': 'JJ'}
95 | # ------------------------------------- #
96 |
97 | # Display the todo item
98 |
99 | todo_display = f"""
100 | {todo['id']}. {todo['title']}
101 | Created by: {todo['user']}
102 | Completed: {todo['completed']}"""
103 |
104 | # print(todo_display)
105 | # ---------------------------------------- #
106 | # looping dictionaries
107 | # .keys(), .values(), .items() - access different parts of the a dictionary
108 |
109 | # print(todo.keys()) dict_keys(['title', 'completed', 'id', 'user'])
110 |
111 |
112 | # -------------------------------------------------------------------------- #
113 |
114 | # .keys() - access a dictionary's values
115 |
116 | # loop through keys
117 |
118 | for key in todo.keys():
119 | # get the value at the current key
120 | value = todo[key]
121 |
122 | # print(f'{key}: {value}')
123 |
124 | # -------------------------------------------------------------------------- #
125 |
126 | # .values() - access a dictionary's values
127 | # print(todo.values()) # dict_values(['Go grocery shopping', True, 1, 'JJ'])
128 |
129 | '''
130 | for value in todo.values():
131 | print(value)
132 | '''
133 | # ----------------------------------------------------------------------- #
134 | # loop through the key:value pairs (items)
135 |
136 | # tuple - unchangeable list, uses indices but cannot accept new values
137 |
138 | # print(todo.items()) # dict_items([('title', 'Go grocery shopping'), ('completed', True), ('id', 1), ('user', 'JJ')])
139 | '''
140 | for item in todo.items():
141 | key = item[0]
142 | value = item[1]
143 | print(f'{key}: {value}')
144 | '''
145 |
146 |
147 | # -------------------------------------------------------- #
148 |
149 | # 'in' to check if a key is in the dictionary
150 |
151 | # print('title' in todo.keys())
152 | # print('completed' in todo) # .keys() is optional
153 |
154 | # -------------------------------------------------------- #
155 |
156 | # instead of multiple, individual todo item dictionaries, create a list of dictionaries instead
157 |
158 | todo_1 = {'title': 'Go grocery shopping', 'completed': False, 'id': 1}
159 | todo_2 = {'title': 'Water the garden', 'completed': True, 'id': 2}
160 | todo_3 = {'title': 'Master Python dictionaries', 'completed': False, 'id': 3}
161 |
162 | # list of dictionaries. List is organized vertically, dictionaries organized horizontally.
163 |
164 | todo_list = [
165 |
166 | {'title': 'Go grocery shopping', 'completed': False, 'id': 1},
167 | {'title': 'Water the garden', 'completed': True, 'id': 2},
168 | {'title': 'Master Python dictionaries', 'completed': False, 'id': 3},
169 |
170 | ]
171 |
172 | # list of dictionaries organized vertically
173 | todo_list = [
174 |
175 | {
176 | 'title': 'Go grocery shopping',
177 | 'completed': False,
178 | 'id': 1
179 | },
180 | {
181 | 'title': 'Water the garden',
182 | 'completed': True,
183 | 'id': 2
184 | },
185 | {
186 | 'title': 'Master Python dictionaries',
187 | 'completed': False,
188 | 'id': 3
189 | }
190 |
191 | ]
192 |
193 | # pull out a single dictionary from the list using an index
194 | # print(todo_list[0]) # {'title': 'Go grocery shopping', 'completed': False, 'id': 1}
195 |
196 | # print(todo_list[0]['title']) # Go grocery shopping
197 |
198 | # loop through the todo_list
199 |
200 | for todo in todo_list:
201 | # if todo['completed'] == False
202 | if not todo['completed']: # same as line 201
203 |
204 | todo_display = f"""
205 | {todo['id']}. {todo['title']}
206 | Completed: {todo['completed']}"""
207 |
208 | # print(todo_display)
209 |
210 |
211 | # ------------------------------------------------------------ #
212 |
213 | # nested dictionaries
214 |
215 | fruit_prices = {
216 |
217 | 'apple': {
218 | 'green': 2.12,
219 | 'yellow': 3.13,
220 | 'red': {
221 | 'price': 4.14,
222 | 'inventory': 100
223 | }
224 | },
225 | 'grape': 3.13
226 | }
227 |
228 | # print(fruit_prices['apple']) # {'green': 2.12, 'yellow': 3.13, 'red': {'price': 4.14, 'inventory': 100}}
229 |
230 |
231 | apple_prices = fruit_prices['apple']
232 |
233 | # print(apple_prices['green']) # 2.12
234 |
235 | # print(fruit_prices['apple']['green']) # 2.12
236 |
237 | # print(fruit_prices['apple']['red']) # {'price': 4.14, 'inventory': 100}
238 | # print(fruit_prices['apple']['red']['price']) # 4.14
239 |
--------------------------------------------------------------------------------
/units/unit1.md:
--------------------------------------------------------------------------------
1 | # Unit 1 - Review
2 |
3 | ---
4 |
5 | [Back to Syllabus](https://github.com/PdxCodeGuild/Programming102#top)
6 |
7 | ### Table of Contents
8 |
9 | - [Unit 1 - Review](#unit-1---review)
10 | - [Table of Contents](#table-of-contents)
11 | - [ Variables](#-variables)
12 | - [ DataTypes](#-datatypes)
13 | - [ Conditional Statements](#-conditional-statements)
14 | - [ For / While Loops](#-for--while-loops)
15 | - [while loops](#while-loops)
16 | - [for loops](#for-loops)
17 | - [ Troubleshooting](#-troubleshooting)
18 | - [ Common Error Messages](#-common-error-messages)
19 | - [Exercises](#exercises)
20 | - [Lab 1](#lab-1)
21 |
22 | ---
23 |
24 | ### Variables
25 |
26 | - Variables in python are used to reference data. They make our code more readable if used correctly.
27 | - Variables are declared when you give them a name and assign them a value `name = "Anthony"`
28 | - Keep in mind there are a few rules when choosing your variable name:
29 | - Variables names are case sensitive (name and NAME are different variables)
30 | - Must start with a letter or underscore
31 | - Can have numbers but can not start with one
32 |
33 | ---
34 |
35 | ### DataTypes
36 |
37 | | DataType | Description | Example |
38 | | -------- | ---------------------- | --------------------------------------------- |
39 | | String | Text Surrounded By "" | `string1 = "hello"` |
40 | | Integer | Whole Number | `int1 = 4` |
41 | | Float | Decimal Number | `float1 = 2.4` |
42 | | Boolean | True/False | `bool1 = True` |
43 | | List | Collection of Elements | `list1 = ["hello", "goodbye", 4, 2.4, False]` |
44 |
45 | ---
46 |
47 | ### Conditional Statements
48 |
49 | We can decide `if` we want code to run based on a true or false condtion.
50 |
51 | ```python
52 | num = 4
53 | if num > 0:
54 | print("Number is greater than zero")
55 | ```
56 |
57 | We can also choose to run code if the previous condition was false, but the current condion is true.
58 | To do this we use `elif`:
59 |
60 | ```python
61 | num = 4
62 | if num > 0:
63 | print("Number is greater than zero")
64 | elif num == 0:
65 | print("The number is zero)
66 | ```
67 |
68 | Finally we can use `else` to catch anything that was not caught by the previous condtions:
69 |
70 | ```python
71 | num = 4
72 | if num > 0:
73 | print("Number is greater than zero")
74 | elif num == 0:
75 | print("The number is zero")
76 | else:
77 | print("The number is less than zero")
78 | ```
79 |
80 | ---
81 |
82 | ### For / While Loops
83 |
84 | Loops can be used to run a block of code more than once. Python has two kinds of loops, the `while` loop and the `for` loop.
85 |
86 | #### while loops
87 |
88 | `while` loops are similar to `if` statements. They run as long as the condition remains true.
89 |
90 | ```python
91 | num = 0
92 | while num < 5:
93 | print(num)
94 | num += 1 # Be sure to increment our counter, otherwise the condition would remain True forever
95 | ```
96 |
97 | #### for loops
98 |
99 | `for` loops are slightly different. They are useful when iterating over a list:
100 |
101 | ```python
102 | colors = ["red", "blue", "green", "yello", "purple"]
103 | for color in colors: # color is a temporary variable name holding an element from colors
104 | print(color)
105 | ```
106 |
107 | ### Troubleshooting
108 |
109 | 
110 |
111 | ### Common Error Messages
112 |
113 | | Error | Cause | Example |
114 | | ------------------- | ------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------- |
115 | | AttributeError | Attribute reference or assignment fails | [AttributeError](https://repl.it/@dirtTastesGood/pythonattributeerrorexample) |
116 | | ImportError | `import` statement has troubles trying to load a module | [ImportError](https://repl.it/@dirtTastesGood/pythonimporterrorexample) |
117 | | ModuleNotFoundError | `import` statement has troubles trying to load a module | [ModuleNotFoundError](https://repl.it/@dirtTastesGood/pythonmodulenotfounderrorexample) |
118 | | IndexError | sequence index is out of range | [IndexError](https://repl.it/@dirtTastesGood/pythonindexerrorexample) |
119 | | KeyError | Referenced key is not in a dictionary | [KeyError](https://repl.it/@dirtTastesGood/pythonkeyerrorexample) |
120 | | KeyboardInterrupt | Using `ctrl + c` to exit Python program | [KeyboardInterrupt](https://repl.it/@dirtTastesGood/pythonkeyboardinterruptexample) |
121 | | NameError | Variable or function name doesn't exist | [NameError](https://repl.it/@dirtTastesGood/pythonnameerrorexample) |
122 | | SyntaxError | Many causes. Incorrect Python syntax. | [SyntaxError](https://repl.it/@dirtTastesGood/pythonsyntaxerrorexample) |
123 | | IndentationError | Indendation too far left or right | [IndentationError](https://repl.it/@dirtTastesGood/pythonindentationerrorexample) |
124 | | TypeError | operation or function is applied to an object of inappropriate type. | [TypeError](https://repl.it/@dirtTastesGood/pythontypeerrorexample) |
125 | | UnboundLocalError | Variable isn't defined within the function | [UnboundLocalError](https://repl.it/@dirtTastesGood/pythonunboundlocalerrorexample) |
126 | | ValueError | an operation or function receives an argument that has the right type but an inappropriate value | [ValueError](https://repl.it/@dirtTastesGood/pythonvalueerrorexample) |
127 | | ZeroDivisionError | Dividing by zero | [ZeroDivisionError](https://repl.it/@dirtTastesGood/pythonzerodivisionerrorexample) |
128 |
129 | ---
130 |
131 | ### [Exercises](https://github.com/PdxCodeGuild/Programming102/blob/master/practice/unit_1/)
132 |
133 | ### [Lab 1](https://github.com/PdxCodeGuild/Programming102/blob/master/labs/lab1.md)
134 |
135 | [Back to top](#top)
136 |
--------------------------------------------------------------------------------