The Art of Doing Computer Science Through Python Application By Michael Eramo Copyright © 2020 by Michael P. Eramo All rights reserved. www.theartofdoingcs.com Deadications To my beautiful son Lucas. You are a constant reminder that human beings grow and improve each and every day. You are my motivation to continually improve, little by little, to be a better human being and a better father. I’ll always remember watching my father tinkering away, wondering, and learning; trying to create something out of nothing. I hope you can remember the same in me. To baby Eramo. I can’t wait to meet you. To my beautiful wife Alyssa. We are a team. Thank you for your unending support. I love you. 2 The Art of Doing Computer Science Through Python Application Hello, my name is Michael Eramo. I am an experienced educator, lifelong learner, and a self-taught programmer. I hold official Bachelor's Degrees in Music Industry, Education, and Physics, a Master's Degree in Mathematical Science, and a certificate in Software Development from Microsoft. While I owe extensive my knowledge base in Music, Physics, Mathematics, and Education to the many great educators I have worked with, my understanding of Computer Science is all my own. I have never taken an "official" computer science course; I am completely self-taught. However, do not let that deter you from taking this course! Instead, let it motivate you that you too can learn anything you want to. Not only have I done it, but I've come to realize what works best for the self-taught programmer, and I have perfected the process! See, I had this deep fear right after my son was born that I was done growing as an individual; that the person I was at 30 was going to be the same person I was at 55. I felt that there was literally ZERO time in the day to do anything other than go to work and be a dad. That is, until I bought a book on Computer Science, and a sense of wonder was woken. I've read countless books, watched hundreds of videos, and put in thousands of hours exploring and writing code. I would routinely wake up at 3:00 AM to learn for a few hours before I had to go to my full time job, teaching high school, before I went to my part time job of teaching college. Days were long, but getting up at 3:00 AM to read, to learn, or to code benefited me more than a few extra hours of sleep. It helped me realize that I was never done learning; never done growing. To me, that is what defines a lifelong learner. I have years of classroom experience as a high school Physics teacher, Computer Science teacher, and college Mathematics professor. I am part of the New York State Master Teacher Program; a network of more than 800 outstanding public school teachers throughout the state who share a passion for their own STEM learning and for collaborating with colleagues to inspire the next generation of STEM leaders. Most importantly, I know what motivates people to learn on their own; to find a way to create time to learn, when there is no time to be had. I understand that time is valuable and that all learning should be engaging, meaningful, and have purpose. Combining my expertise as an educator and my own personal interest in self-taught computer science led me to a telling realization; most educational material for the self-taught programmer is NOT EDUCATIONAL AT ALL. Instead, it falls into one of two categories: Page 1 1. Writing small "snippets" of programs that when taken out of context, seem to serve no purpose at all and frankly, are beneath the user. Prime examples include using a for loop to print out all the even numbers from 1 to 100 or using if statements to respond to generic user input. Here, users are bored and aren't challenged to create anything with meaning. There is little purpose other than gaining what is essentially factual level knowledge. It is a waste of your time. 2. Watching others code whole "applications" without a true understanding of what is going on. These are programs whose scope is beyond the user in which there is no clear guide to walk the user through the thought process without just giving them the answers. Here, without proper support and guidance, the user just defaults to letting someone else unfold the solution for them. There is little engagement in watching someone else's work and rarely a thought is generated on one's own. It is a waste of time. Yes, I will admit that some learning does take place in doing simple tasks or watching others complete complicated tasks. In fact, much of how I learned was done this way. However, I'm telling you it pales in comparison to the learning that takes place by DOING meaningful and appropriately challenging work. This is the art of doing. The art of doing is the art form of transforming oneself from a passive learner who watches, to one who sees the process of learning for what it truly is; a mechanism to better oneself. In "The Art of Doing", I have worked very hard to put together 40 meaningful, engaging, and purposeful "Challenge Problems" for you to solve. Each challenge problem is differentiated for 3 levels of learning. First, you are given a description of the program you are to create and example output. This allows users an opportunity to solve well defined problems that are meaningful and appropriate in scope. Here, all of the solution is user generated. It is engaged learning. Second, you are given a comprehensive guide that will assist you in thought process needed to successfully code your program. This allows users appropriate assistance that tests their knowledge and forces them to generate the thoughts needed to solve the given problem. It is meaningful learning. Third, you are given completed code, with comments, to highlight how to accomplish the end goal. This allows users to reference a working version of the program if they are stuck and cannot solve a portion of the problem without assistance. Rather than grow frustrated, the user can quickly reference this code to gain intellectual footing, and work back to solving the problem on their own. It is purposeful learning. Engaging, meaningful, and with purpose. These challenge problems are vehicles that not only teach computer science, but teach you the art of doing. I guarantee that after completing them all you will consider yourself a lifelong learner and be proud to call yourself a self-taught programmer. I hope you learn something and enjoy the process. Page 2 The Art of Doing Computer Science Through Python Application Chapter 1: Basic Data Types ● Letter Counter App ● Miles Per Hour Conversion App ● Temperature Conversion App ● Right Triangle Solver App ● Multiplication Exponent Table Program Chapter 2: Lists ● Grade Sorter App ● Different Types of Lists Program ● Grocery List App ● Basketball Roster Program ● Favorite Teachers Program Chapter 3: For Loops ● Binary Hexadecimal Conversion App ● Quadratic Equation Solver App ● Factorial Calculator App ● Fibonacci Calculator App ● Grade Point Average Calculator App Chapter 4: Conditionals ● Shipping Accounts Program ● Coin Toss App ● Voter Registration App ● Guess My Number App ● Rock, Paper, Scissors App Chapter 5: Dictionaries ● Thesaurus App ● Database Admin Program ● Yes No Polling App ● Frequency Analysis App ● Code Breakers App Chapter 6: While Loops ● Factor Generator App ● Even Odd Number Sorter App ● Prime Number App ● Guess the Word App ● PowerBall Simulation App Chapter 7: Functions ● Python Dice App ● Python Calculator App ● Bank Deposit and Withdrawal Program ● Head to Head Tic-Tac-Toe App ● Loan Calculator App Chapter 8: Classes ● Pythonagachi Simulator App ● Casino Blackjack App ● Pykemon Simulator App ● Epidemic Outbreak Terminal App ● Epidemic Outbreak GUI App Page 3 Throughout the scope of this book and its 40 challenge problems, you will get exposed to numerous ideas, theories, and fundamental computer science concepts. By working through all 40 challenge problems, you will gain a mastery level understanding of the following topics: Data Types: ● Strings: A series of characters ● Integers: Whole numbers ● Floats: Decimal numbers ● Lists: A mutable collection ● Tuples: An immutable collection ● Ranges: A sequence of integers ● Booleans: A True or False value ● Dictionaries: A collection of associated key-value pairs Control Flow: ● For Loops ● If Statements ● If/Else Statements ● If/Elif/Else Statements ● Break ● Pass ● Continue ● While Loops ● Def ● Return Assignment, Algebraic, Logical, Members, and Comparison Operators ● = Assignment ● += Compound Assignment ● -= Compound Assignment ● + Concatenation (strings) ● + Addition (ints and floats) ● - Subtraction ● * Multiplication ● / Division ● ** Exponentiation ● % Modulo Division ● And ● Or ● Not ● In ● Not in ● == Equal to ● != Not Equal to ● < Less than ● > Greater Than ● <= Less Than or Equal ● >= Greater Than or Equal Over 20 Built In Python Functions: ● print() ● type() ● str() ● int() ● float() Page 4 ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● input() round() sorted() len() range() list() min() max() sum() zip() bin() hex() set() bool() super() String Methods: ● .upper() ● .lower() ● .title() ● .strip() ● .count() ● .join() ● .startswith() ● .replace() ● .split() Lists Methods: ● .append() ● .insert() ● .pop() ● .remove() ● .sort() ● .reverse() ● .copy() ● .index() Dictionary Methods: ● .items() ● .keys() ● .values() ● .most_common() And External Libraries: ● math ● datetime ● cmath ● random ● collections ● time ● matplotlib ● tkinter Page 5 Basic Data Types Challenge 1: Letter Counter App Description: You are responsible for writing a program that will get a message and a specific letter from a user and then count the number of occurrences of that letter in the given message. You program should count “H” and “h” as an occurence of h. Your program will then display a message to the user stating the occurrences of the given letter. Step By Step Guide: ● Print a welcome message ● Get user input for their name. ○ Take proper precautions to always display the name capitalized. ● ● ● ● Print a message saying hello to the user using the user’s name. Print a message stating the goal of the program. Get user input for the message they would like to use. Get user input for the letter they would like to count. ○ Standardize both the message and letter such that “H” and “h” both count as an occurrence of the letter h. ● Create a variable called letter_count and set it equal to the number of occurrences of the given letter in the given message. ○ Use the .count() method. ● Print a message stating the number of occurrences of the given letter in the given message. ● ● ● ● Use at least 2 comments to describe sections of your code. “Chunk” your code so that is readable. Use appropriate and informative variable names. Format your output as below. Example Output: Welcome to the Letter Counter App What is your name: mike Hello Mike! I will count the number of times that a specific letter occurs in a message. Please enter a message: Hello, how are you doing today? I hope that you have a happy holiday! Which letter would you like to count the occurrences of: h Mike, your message has 7 h's in it. Page 6 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #Basic Data Types Challenge 1: Letter Counter App print("Welcome to the Letter Counter App") #Get user input. name = input("\nWhat is your name: ").title().strip() print("Hello, " + name + "!") print("I will count the number of times that a specific letter occurs in a message.") message = input("\nPlease enter a message: ") letter = input("Which letter would you like to count the occurrences of: ") #Standardize to lower case. message = message.lower() letter = letter.lower() #Get the count and display results. letter_count = message.count(letter) print("\n" + name + ", your message has " + str(letter_count) + " " + letter + "'s in it.") Return to index Page 7 Basic Data Types Challenge 2: Miles Per Hour Conversion App Description: You are responsible for writing a program that will convert any given speed in miles per hour to a more metric friendly unit of meters per second. All calculations should be rounded to a set decimal precision of 2 decimal places. Step By Step Guide: ● Print a welcome message. ● Get user input for their speed in miles per hour. ○ Allow for a decimal speed. ● Convert the speed in miles per hour to meters per second. ○ Use a conversion ratio of 1 mph = 0.4474 mps. ○ Use the round() function to round this speed to 2 decimal places. ○ Check the python documentation for information on how to use the round() function. ● Print a message to the user that informs them of their speed in meters per second. ● ● ● ● Use at least 2 comments to describe sections of your code. “Chunk” your code so that is readable. Use appropriate and informative variable names. Format your output as below. Example Output: Welcome to the Miles Per Hour Conversion App What is your speed in miles per hour: 55.8 Your speed in meters per second is 24.96. Page 8 1 2 3 4 5 6 7 8 9 10 11 12 #Basic Data Types Challenge 2: MPH to MPS Conversion App print("Welcome to the MPH to MPS Conversion App") #Gather user input mph = float(input("\nWhat is your speed in miles per hour: ")) #Convert to mps mps = mph*0.4474 mps = round(mps, 2) print("Your speed in meters per second is " + str(mps) + ".") Return to index Page 9 Basic Data Types Challenge 3: Temperature Conversion App Description: You are responsible for writing a program that will convert a given temperature in degrees Fahrenheit to degrees Celsius and degrees Kelvin. Your program will round all conversions to a precision of four decimal places. Lastly, your program will display the results in a convenient table style format. Step By Step Guide: ● Print a welcome message. ● Get user input for their given temperature in degrees Fahrenheit. ○ Allow for a decimal temperature. ● Convert the temperature into both Celsius and Kelvin. ○ If you are unsure of the conversion ratios, google is your friend. ○ Round all values to 4 decimal places. ● Display all three temperatures such that the temperature values are aligned when printing. ● ● ● ● Use at least 2 comments to describe sections of your code. “Chunk” your code so that is readable. Use appropriate and informative variable names. Format your output as below. Example Output: Welcome to the Temperature Conversion App What is the given temperature in degrees Fahrenheit: 212.52 Degrees Fahrenheit: Degrees Celsius: Degrees Kelvin: 212.52 100.2889 373.4389 Page 10 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 #Basic Data Types Challenge 3: Temperature Conversion App print("Welcome to the Temperature Conversion App") #Gather user input temp_f = float(input("\nWhat is the given temperature in degrees Fahrenheit: ")) #Convert temps temp_c = (5/9)*(temp_f - 32) temp_k = temp_c + 273.15 #Round temp_f temp_c temp_k temps = round(temp_f, 4) = round(temp_c, 4) = round(temp_k, 4) #Summary table print("\nDegrees Fahrenheit:\t" + str(temp_f)) print("Degrees Celsius:\t" + str(temp_c)) print("Degrees Kelvin:\t\t" + str(temp_k)) Return to index Page 11 Basic Data Types Challenge 4: Right Triangle Solver App Description: You are responsible for writing a program that will calculate the hypotenuse and area of a right triangle given its two bases. Your program will round all calculations to a precision of three decimal places and provide a summary of the mathematical results. Step By Step Guide: ● Print a welcome message. ● Get user input for the first leg of the right triangle. ● Get user input for the second leg of the right triangle. ● ● ● Calculate the hypotenuse of the right triangle using the Pythagorean theorem. ○ We can't actually take a square root with basic Python. In order to take a square root, we will need to import a library of extra code. ○ Type import math as the first line of code in your program. ○ This allows us to access higher level mathematical functions such as the square root function sqrt(). ○ Google how to take a square root using the math library. Calculate the area of the right triangle. Round each value to 3 decimal places. ● Print a message to the user informing them of both the hypotenuse and area of the given triangle. ● ● ● ● Use at least 2 comments to describe sections of your code. “Chunk” your code so that is readable. Use appropriate and informative variable names. Format your output as below. Example Output: Welcome to the Right Triangle Solver App What is the first leg of the triangle: 20 What is the second leg of the triangle: 40.5 For a triangle with legs of 20 and 40.5 the hypotenuse is 45.169. For a triangle with legs of 20 and 40.5 the area is 405.0. Page 12 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #Basic Data Types Challenge 4: import math Right Triangle Solver App print("Welcome to the Right Triangle Solver App") #Get user input side_a = float(input("\nWhat is the first leg of the triangle: ")) side_b = float(input("What is the second leg of the triangle: ")) #Calculations side_c = math.sqrt(side_a**2 + side_b**2) side_c = round(side_c, 3) area = 0.5*side_a*side_b area = round(area, 3) #Summary print("\nFor a triangle with legs of " + str(side_a) + " and " + str(side_b) + " the hypotenuse is " + str(side_c) + ".") print("For a triangle with legs of " + str(side_a) + " and " + str(side_b) + " the area is " + str(area) + ".") Return to index Page 13 Basic Data Types Challenge 5: Multiplication/Exponent Table App Description: You are responsible for writing a program that displays a multiplication table and exponentiation table for any given number. Each table should show mathematical results for operations performed with the given number and integers from 1 to 9. The program will then print a series of messages to the user describing how cool mathematics truly is. Step By Step Guide: ● Print a welcome message. ● Get user input for their name. ● Get user input for their number. ● Define a variable called message that will hold the following string: ○ name.title() + ", Math is cool!" ● ● ● Create a multiplication table that calculates the product of the number entered and the numbers 1 through 9. Create an exponent table that calculates the exponential power of the number entered raised to the power 1 through 9. Each result should be rounded to 4 decimals. Each line in your table can be created in a single print statement. ○ I would recommend getting one line to work correctly. ○ Copy and paste the line the correct number of times, changing values accordingly for each subsequent line. ○ We will later learn a more efficient way to accomplish this task. ● ● Each table should have its own heading as below. Each mathematical result should be formatted as below. ● Lastly, print a series of statements using the various string methods introduced. ○ Print msg ○ Print msg in lower case ○ Print msg in title case ○ Print msg in upper case ● ● ● ● Use at least 2 comments to describe sections of your code. “Chunk” your code so that is readable. Use appropriate and informative variable names. Format your output as below. ● Example Output Welcome to the Multiplication/Exponent Table App Page 14 What is your name: mike What number would you like to work with: 2.35 Multiplication Table For 2.35 1.0 * 2.35 = 2.35 2.0 * 2.35 = 4.7 3.0 * 2.35 = 7.05 4.0 * 2.35 = 9.4 5.0 * 2.35 = 11.75 6.0 * 2.35 = 14.1 7.0 * 2.35 = 16.45 8.0 * 2.35 = 18.8 9.0 * 2.35 = 21.15 Exponent Table For 2.35 2.35 ** 1 = 2.35 2.35 ** 2 = 5.5225 2.35 ** 3 = 12.9779 2.35 ** 4 = 30.498 2.35 ** 5 = 71.6703 2.35 ** 6 = 168.4252 2.35 ** 7 = 395.7993 2.35 ** 8 = 930.1284 2.35 ** 9 = 2185.8017 Mike Math is cool! mike math is cool! Mike Math Is Cool! MIKE MATH IS COOL! Page 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 #Basic Data Types Challenge 5: Multiplication/Exponent Table Program print("Welcome to the Multiplication/Exponent Table Program") #Gather user input name = input("\nHello, what is your name: ").title().strip() num = float(input("What number would you like to work with: ")) message = name + ", Math is cool!" #Multiplication table print("\nMultiplication Table For " + str(num)) print("\n\t 1.0 * " + str(num) + " = " + str(round(1*num, 4))) print("\t 2.0 * " + str(num) + " = " + str(round(2*num, 4))) print("\t 3.0 * " + str(num) + " = " + str(round(3*num, 4))) print("\t 4.0 * " + str(num) + " = " + str(round(4*num, 4))) print("\t 5.0 * " + str(num) + " = " + str(round(5*num, 4))) print("\t 6.0 * " + str(num) + " = " + str(round(6*num, 4))) print("\t 7.0 * " + str(num) + " = " + str(round(7*num, 4))) print("\t 8.0 * " + str(num) + " = " + str(round(8*num, 4))) print("\t 9.0 * " + str(num) + " = " + str(round(9*num, 4))) #Exponent table print("\nExponent Table print("\n\t" + str(num) print("\t" + str(num) + print("\t" + str(num) + print("\t" + str(num) + print("\t" + str(num) + print("\t" + str(num) + print("\t" + str(num) + print("\t" + str(num) + print("\t" + str(num) + For " + str(num)) + " ** 1 = " + str(round(num**1, 4))) " ** 2 = " + str(round(num**2, 4))) " ** 3 = " + str(round(num**3, 4))) " ** 4 = " + str(round(num**4, 4))) " ** 5 = " + str(round(num**5, 4))) " ** 6 = " + str(round(num**6, 4))) " ** 7 = " + str(round(num**7, 4))) " ** 8 = " + str(round(num**8, 4))) " ** 9 = " + str(round(num**9, 4))) #Math is cool! print("\n" + message) print("\t" + message.lower()) print("\t\t" + message.title()) print("\t\t\t" + message.upper()) Return to index Page 16 Lists Challenge 6: Grade Sorter App Description: You are responsible for writing a program that will collect four grades from a user. Your program will then sort these grades from highest to lowest. Then, your program will simulate dropping the lowest two grades the user entered. Lastly, it will comment on the users highest grade. Step By Step Guide: ● Print a welcome message. ● Create a blank list called grades. ● Get user input to add 4 grades to the list. ○ Be aware of the data type you are using. ● Print the list as formatted below. ○ You may have to cast the list to a string. ● ● Permanently sort the list from highest to lowest. Print the list as formatted below. ● ● ● Inform the user that their lowest two grades are being dropped. Remove the lowest two grades from the list. Print a message informing the user that the grades were dropped. ● ● Print the remaining grades. Print the users highest grade with a message. ● ● ● ● Use at least 2 comments to describe sections of your code. “Chunk” your code so that is readable. Use appropriate and informative variable names. Format your output as below. Example Output: Welcome to the Grade Sorter App What is your first grade (0-100): 82 What is your second grade (0-100): 95 What is your third grade (0-100): 100 What is your fourth grade (0-100): 61 Your grades are: [82, 95, 100, 61] Your grades from highest to lowest are: [100, 95, 82, 61] Page 17 The lowest two grades will now be dropped. Removed grade: 61 Removed grade: 82 Your remaining grades are: [100, 95] Nice work! Your highest grade is a 100. Page 18 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 #Lists Challenge 6: Grade Sorter App print("Welcome to the Grade Sorter App") #Initialize list and get user input grades = [] grade = int(input("\nWhat is your first grade (0-100): ")) grades.append(grade) grade = int(input("What is your second grade (0-100): ")) grades.append(grade) grade = int(input("What is your third grade (0-100): ")) grades.append(grade) grade = int(input("What is your fourth grade (0-100): ")) grades.append(grade) print("\nYour grades are: " + str(grades)) #Sort the list from highest to lowest grades.sort(reverse=True) print("\nYour grades from highest to lowest are: " + str(grades)) #Removing the lowest two grades. print("\nThe lowest two grades will now be dropped.") removed_grade = grades.pop() print("Removed grade: " + str(removed_grade)) removed_grade = grades.pop() print("Removed grade: " + str(removed_grade)) #Recap remaining grades print("\nYour remaining grades are: " + str(grades)) print("Nice work! Your highest grade is " + str(grades[0]) + ".") Return to index Page 19 Lists Challenge 7: Different Types of Lists Program Description: You are responsible for writing a program that will highlight the similarities and differences between four different types of lists: a list of strings, a list of integers, a list of floats, and a list of lists. For each list, your program will describe the data type of the list, the elements of the list, and the data type of the first element in the list. Your program will then highlight the similarities and differences between sorting a list numerically and alphabetically. Step By Step Guide: ● Define a list using a variable num_strings and "hard code" the following four numerical strings: "15", "100", "55", "42". ● Define a list using a variable num_ints and hard code the following four numerical integers: 15, 100, 55, 42. ● Define a list using a variable num_floats and hard code any four floats you want. ● Define a list using a variable num_lists. This is going to be a lists of lists or a nested list! Use the following syntax: num_lists = [[1,2,3], [4,5,6], [7,8,9]] ● Print a summary of each variable (or list). The summary should contain: ○ A statement about the variable's type. ○ A statement about the elements of the variable. ○ A statement about the first element and its type. ○ Use formatting below. ● ● ● Permanently sort num_strings and num_ints. Print each list. Print a statement about what you discover when sorting these two lists. ● ● ● ● Use at least 2 comments to describe sections of your code. “Chunk” your code so that is readable. Use appropriate and informative variable names. Format your output as below. Example Output: Summary Table The variable num_strings is a <class 'list'>. It contains the elements: ['15', '100', '55', '42'] The element 15 is a <class 'str'>. The variable num_ints is a <class 'list'>. It contains the elements: [15, 100, 55, 42] The element 15 is a <class 'int'>. Page 20 The variable num_floats is a <class 'list'>. It contains the elements: [2.2, 5.0, 1.245, 0.142857] The element 2.2 is a <class 'float'>. The variable num_lists is a <class 'list'>. It contains the elements: [[1, 2, 3], [4, 5, 6], [7, 8, 9]] The element [1, 2, 3] is a <class 'list'>. Now sorting num_strings and num_ints... Sorted num_strings: ['100', '15', '42', '55'] Sorted num_ints: [15, 42, 55, 100] Strings are sorted alphabetically while integers are sorted numerically! Page 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 #Lists Challenge 7: Different Types of Lists Program #Defining my lists num_strings = ['15', '100', '55', '42'] num_ints = [15, 100, 55, 42] num_floats = [2.2, 5.0, 1.245, 0.142857] num_lists = [[1,2,3], [4,5,6], [7,8,9]] #Summary of each list print("\t\tSummary Table") print("\nThe variable num_strings is a " + str(type(num_strings)) + ".") print("It contains the elements: " + str(num_strings)) print("The element " + num_strings[0] + " is a " + str(type(num_strings[0])) + ".") print("\nThe variable num_ints is a " + str(type(num_ints)) + ".") print("It contains the elements: " + str(num_ints)) print("The element " + str(num_ints[0]) + " is a " + str(type(num_ints[0])) + ".") print("\nThe variable num_floats is a " + str(type(num_floats)) + ".") print("It contains the elements: " + str(num_floats)) print("The element " + str(num_floats[0]) + " is a " + str(type(num_floats[0])) + ".") print("\nThe variable num_lists is a " + str(type(num_lists)) + ".") print("It contains the elements: " + str(num_lists)) print("The element " + str(num_lists[0]) + " is a " + str(type(num_lists[0])) + ".") #Sorting the lists num_strings.sort() num_ints.sort() print("\nNow sorting num_strings and num_ints...") print("Sorted num_strings: " + str(num_strings)) print("Sorted num_ints: " + str(num_ints)) print("\nStrings are sorted alphabetically while integers are sorted numerically!!!") Return to index Page 22 Lists Challenge 8: Grocery List App Description: You are responsible for writing a program that will simulate a grocery shopping list. Your program will start with two items on the shopping list, meat and cheese, and then allow a user to add three new items to the list. To simulate shopping, your program will ask the user what item they just purchased and then remove the item from the shopping list. Upon having only two items in the shopping list, your program will inform the user that the store is out of a particular item and prompt the user to replace the item with a new item. You will use the datetime library to display the current date and time the shopping is taking place in mm/dd hh:mm format. Step By Step Guide: ● Define a list that will hold the foods you need to get at the grocery store. ○ Start by populating the list with two foods, Meat and Cheese. ● ● Print a welcome message. Print the current date and time. ○ This functionality is outside the scope of basic Python. We will have to import the datetime library to gain access to code that can perform this function. ○ Type import datetime as the first line of code in your program. ○ Create a datetime object using the datetime library and store the pertinent information in appropriately named variables using the following code: ■ time = datetime.datetime.now() ■ month = str(time.month) ■ day = str(time.day) ■ hour = str(time.hour) ■ minute = str(time.minute) ● ● ○ Use these new variables to print the current date and time. Print a message informing the user of the two foods in their grocery list. Get user input and append three new foods to the grocery list. ○ Make sure to title case any user input. ● ● ● Print the grocery list. Permanently sort the grocery list. Print the sorted grocery list. ● Simulate shopping by doing the following: ○ Print the current list length. ○ Print the current list. ○ Get user input for the food purchased. ■ The input should be case insensitive. The program should recognize Meat, meat, and MEAT all the same. ○ Remove the appropriate food from the list. Page 23 ○ ● Do this three times. ● When there is only 2 foods left in the list, print the list and inform the user that the store is out of the last item in the list, making sure to remove this item from the list. Ask user what food they would like instead and insert this food at the beginning of the list. Print a final version of the grocery list. ● ● ● ● Use at least 2 comments to describe sections of your code. “Chunk” your code so that is readable. Use appropriate and informative variable names. Format your output as below. ● Example Output: Welcome to the Grocery List App. Current Date and Time: 11/3 2:31 You currently have Meat and Cheese in your list. Type of food to add to the grocery list: bananas Type of food to add to the grocery list: apples Type of food to add to the grocery list: soup Here is your grocery list: ['Meat', 'Cheese', 'Bananas', 'Apples', 'Soup'] Here is your grocery list sorted: ['Apples', 'Bananas', 'Cheese', 'Meat', 'Soup'] Simulating grocery shopping... Current grocery list: 5 items ['Apples', 'Bananas', 'Cheese', 'Meat', 'Soup'] What food did you just buy: apples Removing Apples from list... Current grocery list: 4 items ['Bananas', 'Cheese', 'Meat', 'Soup'] What food did you just buy: Cheese Removing Cheese from list... Current grocery list: 3 items ['Bananas', 'Meat', 'Soup'] What food did you just buy: soup Removing Soup from list... Current grocery list: 2 items Page 24 ['Bananas', 'Meat'] Sorry, the store is out of Meat. What food would you like instead: fish Here is what remains on your grocery list: ['Fish', 'Bananas'] Page 25 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 #Lists Challenge 8: import datetime Grocery List App #Create the datetime object and store the current date and time time = datetime.datetime.now() month = str(time.month) day = str(time.day) hour = str(time.hour) minute = str(time.minute) #Welcome message foods = ["Meat", "Cheese"] print("Welcome to the Grocery List App") print("Current Date and Time: " + month + "/" + day + "\t" + hour + ":" + minute) print("You currently have " + foods[0] + " and " + foods[1] + " in your list.") #Get user input food = input("\nType of food to add to the grocery list: ") foods.append(food.title()) food = input("Type of food to add to the grocery list: ") foods.append(food.title()) food = input("Type of food to add to the grocery list: ") foods.append(food.title()) #Print and sort the list print("\nHere is your grocery list: ") print(foods) foods.sort() print("Here is your grocery list sorted: ") print(foods) #Simulate Shopping print("\nSimulating grocery shopping...") print("\nCurrent grocery list: " + str(len(foods)) + " items") print(foods) buy_food = input("What food did you just buy: ").title() foods.remove(buy_food) print("Removing " + buy_food + " from the list...") print("\nCurrent grocery list: " + str(len(foods)) + " items") print(foods) buy_food = input("What food did you just buy: ").title() foods.remove(buy_food) print("Removing " + buy_food + " from the list...") print("\nCurrent grocery list: " + str(len(foods)) + " items") print(foods) buy_food = input("What food did you just buy: ").title() foods.remove(buy_food) print("Removing " + buy_food + " from the list...") #The store is out of an item... print("\nCurrent grocery list: " + str(len(foods)) + " items") print(foods) no_item = foods.pop() print("\nSorry, the store is out of " + no_item + ".") new_food = input("What food would you like instead: ").title() foods.insert(0, new_food) print("\nHere is what remains on your grocery list: ") print(foods) Return to index Page 26 Lists Challenge 9: Basketball Roster Program Description: You are responsible for writing a program that will build and display a basketball roster based off user input. Your program will then simulate an injury to a specific player in the roster and prompt the user to update the roster. Upon updating the roster, your program will display the final roster and wish the newly add player good luck. Step By Step Guide: ● Print a welcome message. ● Create a blank list called roster. ● Get user input for the names of the starting roster for a basketball team. ○ The starting roster includes a point guard, shooting guard, small forward, power forward, and center. Use an input statement for each position. ○ Make sure to always display the name capitalized. ○ Add each position to your list roster. ○ Your point guard should be index 0, shooting guard at index 1, ect... ● Print the starting 5 as formatted below. ● ● ● ● Remove the small forward from the list and store it in a variable called injured_player. Print a message to the user informing them that this player is injured. Get the length of the current roster. Print a message to the user informing them of the length of the current roster. ● ● Get user input for who will take the injured players spot and store this in a variable called added_player. Add this player to the roster at the correct position. ● ● ● ● Print the updated starting 5 as formatted below. Print a good luck message to the new player. Get the length of the current roster. Print a message to the user informing them of the length of the current roster. ● ● ● ● Use at least 2 comments to describe sections of your code. “Chunk” your code so that is readable. Use appropriate and informative variable names. Format your output as below. Example Output: Welcome to the Basketball Roster Program Who is your point guard: mike eramo Who is your shooting guard: Klay Thompson Who is your small forward: LEBRON JAMES Page 27 Who is your power forward: Anthony DaVis Who is your center: kevin getman Your starting 5 for the upcoming basketball season Point Guard: Mike Eramo Shooting Guard: Klay Thompson Small Forward: Lebron James Power Forward: Anthony Davis Center: Kevin Getman Oh no, Lebron James is injured. Your roster only has 4 players. Who will take Lebron James's spot: lucas eramo Your starting 5 for the upcoming basketball season Point Guard: Mike Eramo Shooting Guard: Klay Thompson Small Forward: Lucas Eramo Power Forward: Anthony Davis Center: Kevin Getman Good luck Lucas Eramo you will do great! Your roster now has 5 players. Page 28 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 #Lists Challenge 9: Basketball Roster Program print("Welcome to the Basketball Roster Program") #Get user input and define our roster roster = [] player = input("\nWho is your point guard: ").title() roster.append(player) player = input("Who is your shooting guard: ").title() roster.append(player) player = input("Who is your small forward: ").title() roster.append(player) player = input("Who is your power forward: ").title() roster.append(player) player = input("Who is your center: ").title() roster.append(player) #Display roster print("\n\tYour starting 5 for the upcoming basketball season") print("\t\tPoint Guard:\t\t" + roster[0]) print("\t\tShooting Guard:\t\t" + roster[1]) print("\t\tSmall Forward:\t\t" + roster[2]) print("\t\tPower Forward:\t\t" + roster[3]) print("\t\tCenter:\t\t\t" + roster[4]) #Remove an injured player injured_player = roster.pop(2) print("\nOh no, " + injured_player + " is injured.") roster_length = len(roster) print("Your roster only has " + str(roster_length) + " players.") #Add a new player added_player = input("Who will take " + injured_player + "'s spot: ").title() roster.insert(2, added_player) #Display roster print("\n\tYour starting 5 for the upcoming basketball season") print("\t\tPoint Guard:\t\t" + roster[0]) print("\t\tShooting Guard:\t\t" + roster[1]) print("\t\tSmall Forward:\t\t" + roster[2]) print("\t\tPower Forward:\t\t" + roster[3]) print("\t\tCenter:\t\t\t" + roster[4]) print("\nGood luck " + roster[2] + " you will do great!") roster_length = len(roster) print("Your roster now has " + str(roster_length) + " players.") Return to index Page 29 Lists Challenge 10: Favorite Teachers Program Description: You are responsible for writing a program that will create a list of a user’s favorite teachers. It will display these teachers ranked (assuming the first teacher entered is the favorite, the second teacher entered is the next favorite, ect…), alphabetically, in reverse alphabetical order, the top two teachers, the next two teachers, the last favorite teacher, and the total number of favorite teachers in the list. Your program will then add and remove teachers from this list, each time displaying a similar summary. Step By Step Guide: ● Print a welcome message. ● Create a blank list called fav_teachers. ● Prompt the user to enter in their four favorite teachers. ○ The user should only enter the last name of the teacher. ○ Make sure to title case all user input for sorting purposes. ● Add each of these teachers to the list fav_teachers. ● ● ● ● ● ● ● ● Print the favorite teachers ranked. Print the favorite teachers alphabetically. Print the favorite teachers in reverse alphabetical order. Print the top two teachers. Print the next two teachers. Print the last favorite teacher. Print the total number of favorite teachers. Follow the formatting below. ● ● Print a message to the user informing them that first favorite teacher is no longer their favorite teacher. Prompt the user to enter their new favorite teacher. ○ Store the name of this teacher in the first index of the list ○ Shift all other teachers down one index. ● ● ● ● ● ● ● ● Print the favorite teachers ranked. Print the favorite teachers alphabetically. Print the favorite teachers in reverse alphabetical order. Print the top two teachers. Print the next two teachers. Print the last favorite teacher. Print the total number of favorite teachers. Follow the formatting below. ● ● Print a message to the user informing them that they no longer like a teacher. Prompt the user to pick a teacher to remove from the list. Page 30 ● Remove this teacher. ● ● ● ● ● ● ● ● Print the favorite teachers ranked. Print the favorite teachers alphabetically. Print the favorite teachers in reverse alphabetical order. Print the top two teachers. Print the next two teachers. Print the last favorite teacher. Print the total number of favorite teachers. Follow the formatting below. ● ● ● ● Use at least 2 comments to describe sections of your code “Chunk” your so that it is readable. Use appropriate and informative variable names. Format your output as below. Example Output: Welcome to the Favorite Teachers Program Who is your first favorite teacher: Eramo Who is your second favorite teacher: ricco Who is your third favorite teacher: gates Who is your fourth favorite teacher: foote Your favorite teachers ranked are: ['Eramo', 'Ricco', 'Gates', 'Foote'] Your favorite teachers alphabetically are: ['Eramo', 'Foote', 'Gates', 'Ricco'] Your favorite teachers in reverse alphabetical order are: ['Ricco', 'Gates', 'Foote', 'Eramo'] Your top two teachers are: Eramo and Ricco. Your next two favorite teachers are: Gates and Foote. Your last favorite teacher is: Foote. You have a total of 4 favorite teachers. Oops, Eramo is no longer your first favorite teacher. Who is your new FAVORITE teacher: marley Your favorite teachers ranked are: ['Marley', 'Eramo', 'Ricco', 'Gates', 'Foote'] Your favorite teachers alphabetically are: ['Eramo', 'Foote', 'Gates', 'Marley', 'Ricco'] Your favorite teachers in reverse alphabetical order are: ['Ricco', 'Marley', 'Gates', 'Foote', 'Eramo'] Your top two teachers are: Marley and Eramo. Your next two favorite teachers are: Ricco and Gates. Your last favorite teacher is: Foote. You have a total of 5 favorite teachers. Page 31 You've decided you no longer like a teacher. Which teacher would you like to remove from you list: eramo Your favorite teachers ranked are: ['Marley', 'Ricco', 'Gates', 'Foote'] Your favorite teachers alphabetically are: ['Foote', 'Gates', 'Marley', 'Ricco'] Your favorite teachers in reverse alphabetical order are: ['Ricco', 'Marley', 'Gates', 'Foote'] Your top two teachers are: Marley and Ricco. Your next two favorite teachers are: Gates and Foote. Your last favorite teacher is: Foote. You have a total of 4 favorite teachers. Page 32 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 #Lists Challenge 10: Favorite Teachers Program print("Welcome to the Favorite Teachers Program") fav_teachers = [] #Get user input fav_teachers.append(input("\nWho is your first favorite teacher: ").title()) fav_teachers.append(input("Who is your second favorite teacher: ").title()) fav_teachers.append(input("Who is your third favorite teacher: ").title()) fav_teachers.append(input("Who is your fourth favorite teacher: ").title()) #Summary of list print("\nYour favorite teachers ranked are: " + str(fav_teachers)) print("Your favorite teachers alphabetically are: " + str(sorted(fav_teachers))) print("Your favorite teachers in reverse alphabetical order are: " + str(sorted(fav_teachers, reverse=True))) print("\nYour top two teachers are: " + fav_teachers[0] + " and " + fav_teachers[1] + ".") print("Your next two favorite teachers are: " + fav_teachers[2] + " and " + fav_teachers[3] + ".") print("Your last favorite teacher is: " + fav_teachers[-1] + ".") print("You have a total of " + str(len(fav_teachers)) + " favorite teachers.") #Insert a new favorite teacher fav_teachers.insert(0, input("\nOops, " + fav_teachers[0] + " is no longer your first favorite teacher. Who is your new FAVORITE teacher: ").title()) #Summary of list print("\nYour favorite teachers ranked are: " + str(fav_teachers)) print("Your favorite teachers alphabetically are: " + str(sorted(fav_teachers))) print("Your favorite teachers in reverse alphabetical order are: " + str(sorted(fav_teachers, reverse=True))) print("\nYour top two teachers are: " + fav_teachers[0] + " and " + fav_teachers[1] + ".") print("Your next two favorite teachers are: " + fav_teachers[2] + " and " + fav_teachers[3] + ".") print("Your last favorite teacher is: " + fav_teachers[-1] + ".") print("You have a total of " + str(len(fav_teachers)) + " favorite teachers.") #Remove a specific teacher fav_teachers.remove(input("\nYou've decided you no longer like a teacher. teacher would you like to remove from your list: ").title()) Which #Summary of list print("\nYour favorite teachers ranked are: " + str(fav_teachers)) print("Your favorite teachers alphabetically are: " + str(sorted(fav_teachers))) print("Your favorite teachers in reverse alphabetical order are: " + str(sorted(fav_teachers, reverse=True))) print("\nYour top two teachers are: " + fav_teachers[0] + " and " + fav_teachers[1] + ".") print("Your next two favorite teachers are: " + fav_teachers[2] + " and " + fav_teachers[3] + ".") print("Your last favorite teacher is: " + fav_teachers[-1] + ".") print("You have a total of " + str(len(fav_teachers)) + " favorite teachers.") Return to index Page 33 For Loops Challenge 11: Binary Hexadecimal Converter App Description: You are responsible for writing a program that will generate binary and hexadecimal values from 1 up to a specified user value. Recall that decimal is a base 10 number system, binary is a base 2 number system, and hexadecimal is a base 16 number system. Your program will use list slicing to first only show a portion of these values. Your program will then loop through the entire lists of decimal, binary, and hexadecimal values to show the relationship between numbers of different bases. Step By Step Guide: ● Print a welcome message. ● Get user input for how many values they would like to convert to binary and hexadecimal. ● ● ● ● ● Using the range function, generate a list of numbers holding the decimal values from 1 up to the users maximum value. Create a blank list for the binary values. Create a blank list for the hexadecimal values. Use a for loop to loop through the decimal values. During each iteration: ○ Determine the binary representation and hexadecimal representation of the decimal value and add each value to the appropriate list. ■ To accomplish this use the built in bin() and hex() functions. ■ Google or check the python documentation on how to use these functions. Print a message informing the user that the lists are complete. ● Rather than print the whole list initially, use slicing to only show a portion of each list. ○ Get user input for the decimal number to start and stop at. ○ Be careful and think as to how these numbers relate to the indices of a list slice. ● ● Print a message for each list slice. Use a for loop to loop through the portion of the list specified and print each element. ● Prompt the user to press Enter to see the entire list generated. ○ To pause a program you can use an input statement. ● ● Print a table header. Using only one for loop, print the decimal, binary, and hexadecimal values for each element in each list. ○ This can be accomplished using the zip() function or proper list indexing. Page 34 ● ● ● ● Use at least 2 comments to describe sections of your code. “Chunk” your code so that is readable. Use appropriate and informative variable names. Format your output as below. Example Output: Welcome to the Binary/Hexadecimal Converter App Compute binary and hexadecimal values up to the following decimal number: 12 Generating lists....complete! Using slices, we will now show a portion of each list. What decimal number would you like to start at: 4 What decimal number would you like to stop at: 7 Decimal values from 4 to 7: 4 5 6 7 Binary values from 4 to 7: 0b100 0b101 0b110 0b111 Hexadecimal values from 4 to 7: 0x4 0x5 0x6 0x7 Press Enter to see all values from 1 to 12. Decimal----Binary----Hexadecimal ---------------------------------------------------------1----0b1----0x1 2----0b10----0x2 3----0b11----0x3 4----0b100----0x4 5----0b101----0x5 6----0b110----0x6 7----0b111----0x7 8----0b1000----0x8 9----0b1001----0x9 Page 35 10----0b1010----0xa 11----0b1011----0xb 12----0b1100----0xc Page 36 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 #For Loops Challenge 11: Binary Hexadecimal Converter App print("Welcome to the Binary/Hexadecimal Converter App") #Get user input and generate lists. max_value = int(input("\nCompute binary and hexadecimal values up to the following decimal number: ")) decimal = list(range(1, max_value+1)) binary = [] hexadecimal = [] for num in decimal: binary.append(bin(num)) hexadecimal.append(hex(num)) print("Generating lists...Complete!") #Get slicing index from user. print("\nUsing slices, we will now show a portion of each list.") lower_range = int(input("What decimal number would you like to start at: ")) upper_range = int(input("What decimal number would you like to stop at: ")) #Slice through each list individually print("\nDecimal values from " + str(lower_range) + " to " + str(upper_range) + ":") for num in decimal[lower_range-1:upper_range]: print(num) print("\nBinary values from " + str(lower_range) + " to " + str(upper_range) + ":") for num in binary[lower_range-1:upper_range]: print(num) print("\nHexadecimal values from " + str(lower_range) + " to " + str(upper_range) + ":") for num in hexadecimal[lower_range-1:upper_range]: print(num) #Output the whole list to the screen input("\nPress Enter to see all values from 1 to " + str(max_value) + ".") print("Decimal----Binary----Hexadecimal") print("----------------------------------------------") for d, b, h in zip(decimal, binary, hexadecimal): print(str(d) + "----" + str(b) + "----" + str(h)) Return to index Page 37 For Loops Challenge 12: Quadratic Equation Solver App Description: You are responsible for writing a program that will display the solutions to any number of quadratic equations. Your program will ask the user how many quadratic equations they would like to solve, ask for the coefficients of the equation in the standard form of ax2 + bx + c = 0 , solve for x, and then display the solutions. Your program will allow for both real and complex solutions. Step By Step Guide: ● Print a welcome summary to the user. ○ This summary should describe a quadratic equation and complex numbers. ● Get user input for how many quadratic equations they would like to solve. ● ● Loop through the number of equations. Each iteration, you should: ○ Print a message header stating the equation number you are solving. ○ Get user input for the values of the coefficients a, b, and c. ○ Solve for the roots of the quadratic x1 and x2. ■ In order to solve a quadratic equation, you may be required to take the square root of a negative value which would result in an imaginary number. The resulting solution is a complex number as it has both real and imaginary parts. ■ The previously introduced math library’s sqrt() function works well for real numbers but not for imaginary numbers. To work with imaginary values and complex numbers we will need to import a library of extra code. ■ Type import cmath as the first line of code in your program. ○ Print a summary of the solutions to the equation. Once the loop is complete, print a message thanking the user for using the program. ● ● ● ● Use at least 2 comments to describe sections of your code. “Chunk” your code so that is readable. Use appropriate and informative variable names. Format your output as below. Example Output: Welcome to the Quadratic Equation Solver App. A quadratic equation is of the form ax^2 + bx + c = 0 Your solutions can be real or complex numbers. A complex number has two parts: a + bj Where a is the real portion and bj is the imaginary portion. Page 38 How many equations would you like to solve today: 2 Solving equation #1 --------------------------------------------------------------Please enter your value of a (coefficient of x^2): 1 Please enter your value of b (coefficient of x): 6 Please enter your value of c (coefficient): 9 The solutions to 1.0x^2 + 6.0x + 9.0 = 0 are: x1 = (-3+0j) x2 = (-3+0j) Solving equation #2 --------------------------------------------------------------Please enter your value of a (coefficient of x^2): 1 Please enter your value of b (coefficient of x): -5 Please enter your value of c (coefficient): 14.2 The solutions to 1.0x^2 + -5.0x + 14.2 = 0 are: x1 = (2.5+2.819574435974337j) x2 = (2.5-2.819574435974337j) Thank you for using the Quadratic Equation Solver App. Goodbye. Page 39 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 #For Loops Challenge 12: import cmath Quadratic Equation Solver App #Print Welcome Information print("Welcome to the Quadratic Equation Solver App") print("\nA quadratic equation is of the form ax^2 + bx + c = 0") print("Your solutions can be real or complex numbers.") print("A complex number has two parts: a + bj") print("Where a is the real portion and bj is the imaginary portion.") #Get user input eq_number = int(input("\nHow many equations would you like to solve today: ")) #Loop through and solve each equation for i in range(eq_number): print("\nSolving equation #" + str(i+1)) print("--------------------------------------------------") a = float(input("\nPlease enter your value of a (coefficient of x^2): ")) b = float(input("Please enter your value of b (coefficient of x): ")) c = float(input("Please enter your value of c (coefficient): ")) #Solving the quadratic formula x1 = (-b + cmath.sqrt(b**2 - 4*a*c))/(2*a) x2 = (-b - cmath.sqrt(b**2 - 4*a*c))/(2*a) print("\nThe solutions to " + str(a) + "x^2 + " + str(b) + "x + " + str(c) + " = 0 are: ") print("\n\tx1 = " + str(x1)) print("\tx2 = " + str(x2)) print("\nThank you for using the Quadratic Equation Solver App. Return to index Goodbye.") Page 40 For Loops Challenge 13: Factorial Calculator App Description: You are responsible for writing a program that will calculate the factorial of any given number. Your program will display the mathematical relationship of the factorial. It will then use the math library to compute the value of the given factorial. Lastly, your program will use its own algorithm to compute the value of the given factorial and compare the results. Step By Step Guide: ● Print a welcome message. ● Get user input for a number to compute the factorial of. ● Print a mathematical representation of the factorial you are about to compute. ○ To accomplish this you will want to use a single print statement that prints the number chosen and "! = ". ○ Then you will want to use the optional argument end=" " to override the default \n end of a print statement. ○ Setting end=" " will end the print statement with a space and keep the prompt on the same line. ○ Next, use a for loop to print through the sequence of numbers needed for your factorial and use an appropriate value for the end argument. ○ Lastly, outside of the for loop print your last number with the default end argument of \n to put your prompt on a new line. ● Use the math library to compute the factorial of your given number and print the result. ○ Type import math as the first line of code in your program. ○ The math library has a built in function to compute a factorial you can use. ● Write your own algorithm to compute the factorial of your given number and print the results. ○ Recall that a factorial is just repeated multiplication. ○ To perform this repeated multiplication, use a for loop with a numerical range. ● Print a summary of the results to show that math library and your algorithm were in agreement. ● ● ● ● Use at least 2 comments to describe sections of your code. “Chunk” your code so that is readable. Use appropriate and informative variable names. Format your output as below. Example Output: Welcome to the Factorial Calculator App Page 41 What number would you like to compute the factorial of? 10 10! = 1*2*3*4*5*6*7*8*9*10 Here is the result from the math library: The factorial of 10 is 3628800! Here is the result from my own algorithm: The factorial of 10 is 3628800! It is shown twice that 10! = 3628800 (with excitement) Page 42 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 #For Loops Challenge 13: import math Factorial Calculator App print("Welcome to the Factorial Calculator App") #Get user input number = int(input("\nWhat number would you like to compute the factorial of: ")) #Display the mathematical relationship of a factorial print(str(number) + "! = ", end="") for i in range(1, number): print(str(i), end="*") print(str(number)) #Using the math library fact = math.factorial(number) print("\nHere is the result from the math library: ") print("The factorial of " + str(number) + " is " + str(fact) + "!") #Using my own algorithm fact = 1 for i in range(1, number+1): fact = fact*i print("\nHere is the result from my own algorithm: ") print("The factorial of " + str(number) + " is " + str(fact) + "!") #Summary print("\nIt is shown twice that " + str(number) + "! = " + str(fact) + " (with excitement!)") Return to index Page 43 For Loops Challenge 14: Fibonacci Calculator App Description: You are responsible for writing a program that will compute the first n terms of the Fibonacci Sequence. Your program will then display these terms. Next, your program will calculate the ratios of consecutive Fibonacci numbers to prove that these ratios approach the irrational mathematical constant of Phi; 1.618…. Step By Step Guide: ● Print a welcome message. ● Get user input for how many digits of the Fibonacci Sequence they would like to compute. ● ● Define a list which holds two integers, 1 and 1. ○ This is the start of your Fibonacci Sequence. Using a for loop, write an algorithm that will compute the next term of the Fibonacci Sequence and append it to your list. ○ The nth term of the Fibonacci Sequence can be found by adding the n-1 and n-2 terms together. ○ You essentially take the previous two terms in the sequence and add them together to get the current term. Iterate over this loop until you reach the desired number of terms. ● Display the results of your algorithm. ● Define an empty list that will hold the ratios of consecutive terms from your Fibonacci Sequence. ○ These ratios will approach a value of Phi; 1.618.... ● ● Using a for loop, write an algorithm that will compute these ratios. ○ To compute this ratio, you will divide the 2nd term in your list by the first. ○ The next iteration, you will divide the 3rd term by the 2nd. ○ The next iteration, the 4th term by the 3rd, and so forth. Each time you compute this ratio, append it to your list. ● Display the results of your algorithm. ● Print a statement about the Golden Ratio and Fibonacci. ● ● ● ● Use at least 2 comments to describe sections of your code. “Chunk” your code so that is readable. Use appropriate and informative variable names. Format your output as below. ● Page 44 Example Output: Welcome to the Fibonacci Calculator App How many digits of the Fibonacci Sequence would you like to compute: 15 The first 15 numbers of the Fibonacci sequence are: 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 The corresponding Golden Ratio values are: 1.0 2.0 1.5 1.6666666666666667 1.6 1.625 1.6153846153846154 1.619047619047619 1.6176470588235294 1.6181818181818182 1.6179775280898876 1.6180555555555556 1.6180257510729614 1.6180371352785146 The ratio of consecutive Fibonacci terms approaches Phi; 1.618... Page 45 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 #For Loops Challenge 14: Fibonacci Calculator App print("Welcome to the Fibonacci Calculator App") #Get user input num = int(input("\nHow many digits of the Fibonacci Sequence would you like to compute: ")) #Compute the values of the fib fib = [1,1] for i in range(num-2): new_fib = fib[i] + fib[i+1] fib.append(new_fib) #Display the fib values print("\nThe first " + str(num) + " numbers of the Fibonacci Sequence are: ") for number in fib: print(number) #Compute the golden ratio golden = [] for i in range(len(fib)-1): ratio = fib[i+1]/fib[i] golden.append(ratio) #Display the golden ratio values print("\nThe corresponding Golden Ratio values are: ") for ratio in golden: print(ratio) print("\nThe ratio of consecutive Fibonacci terms approaches Phi; 1.618...") Return to index Page 46 For Loops Challenge 15: Grade Point Average Calculator App Description: You are responsible for writing a program that will collect any number of grades from a user. Your program will sort these grades numerically from highest to lowest and calculate the grade point average of the user. Your program will then ask for the average the user desires and calculate what the user must get on their next assignment to achieve this average. Lastly, your program will make a copy of the users grades and allow them to alter one of their previous grades to see how doing worse or better on an assignment would have changed their overall average. Step By Step Guide: ● Print a welcome message. ● Get user input for their name. ● Get user input for the number of grades they would like to enter. ● ● Create an empty list that will hold the user's grades. Get user input for each individual grade and add it to the list. ● Sort the grades from highest to lowest and print each grade individually as formatted below. ● ● ● Calculate the average grade for the student as a float. Round this average to two decimal places. Display the students grade summary as formatted below. ○ This summary should include the user's name, the total number of grades, the highest grade, the lowest grade, and the average. ● ● ● ● Prompt the user for their desired average. Calculate what grade they need to get on their next assignment to achieve this average. Round this grade to two decimal places. Wish the user luck and inform them of the needed grade to get their desired average. ● ● ● ● Make a copy of your original list of grades. Get user input for a grade value that they would like to change. Get user input for the new grade value they would like the old grade changed to. Make the appropriate changes in the copy of the original list. ○ Please keep the original grades list in tact. ● Sort the new grades from highest to lowest and print each grade individually as formatted below. ● Calculate the new average grade for the student as a float. Page 47 ● ● Round this average to two decimal places. Display the students grade summary as formatted below. ○ ● ● ● ● ● ● ● This summary should include the user's name, the total number of grades, the highest grade, the lowest grade, and the average. Print a comparison of the users old average and updated average. Print a statement regarding how many points, rounded to two decimal places, their average changed by. Inform them that their original grades however are still the same and print the original grades as a list. Use at least 2 comments to describe sections of your code. “Chunk” your code so that is readable. Use appropriate and informative variable names. Format your output as below. Example Output: Welcome to the Average Calculator App What is your name: mike How many grades would you like to enter: 5 Enter grade: 72 Enter grade: 64 Enter grade: 80 Enter grade: 83 Enter grade: 77 Grades Highest to Lowest: 83 80 77 72 64 Mike's Grade Summary: Total Number of Grades: 5 Highest Grade: 83 Lowest Grade: 64 Average: 75.2 What is your desired average: 79 Good luck Mike! You will need to get a 98.0 on your next assignment to earn a 79.0 average. Page 48 Lets see what your average could have been if you did better/worse on an assignment. What grade would you like to change: 64 What grade would you like to change 64 to: 80 New Grades Highest to Lowest: 83 80 80 77 72 Mike's New Grade Summary: Total Number of Grades: 5 Highest Grade: 83 Lowest Grade: 72 Average: 78.4 Your new average would be a 78.4 compared to your real average of 75.2! That is a change of 3.2 points! Too bad your original grades are still the same! [83, 80, 77, 72, 64] You should go ask for extra credit! Page 49 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 #For Loops Challenge 15: Grade Point Average Calculator App print("Welcome to the Grade Point Average Calculator App") #Get user input name = input("What is your name: ").title().strip() grade_num = int(input("How many grades would you like to enter: ")) #Get the user's grades grades = [] for i in range(grade_num): grades.append(int(input("Enter grade: "))) #Sort the grades and print them to the screen grades.sort(reverse=True) print("\nGrades Highest to Lowest:") for grade in grades: print("\t" + str(grade)) #Calculate the average average = sum(grades)/len(grades) average = round(average, 2) #Print a grade summary print("\n" + name + "'s Grade Summary:") print("\tTotal Number of Grades: " + str(len(grades))) print("\tHighest Grade: " + str(max(grades))) print("\tLowest Grade: " + str(min(grades))) print("\tAverage: " + str(average)) #Get the user's desired average and calculate what they need to get on the next assignment desired_avg = float(input("\nWhat is your desired average: ")) grade_req = desired_avg*(len(grades)+1) - sum(grades) grade_req = round(grade_req, 2) #Print a summary print("\nGood luck " + name + "!") print("You will need to get a " + str(grade_req) + " on your next assignment to earn a " + str(desired_avg) + " average.") #Make a copy of the original grades and swap out one of the grades new_grades = grades[:] print("\nLets see what you average could have been if you did better/worse on an assignment.") grade_change = int(input("What grade would you like to change: ")) new_grades.remove(grade_change) new_grade = int(input("What grade would you like to change " + str(grade_change) + " to: ")) new_grades.append(new_grade) #Sort the new grades and print them to the screen new_grades.sort(reverse=True) print("\nNew Grades Highest to Lowest:") for grade in new_grades: print("\t" + str(grade)) #Calculate the new average new_average = sum(new_grades)/len(new_grades) new_average = round(new_average, 2) #Print a new grade summary print("\n" + name + "'s New Grade Summary:") print("\tTotal Number of Grades: " + str(len(new_grades))) Page 50 61 62 63 64 65 66 67 68 69 70 71 72 73 74 print("\tHighest Grade: " + str(max(new_grades))) print("\tLowest Grade: " + str(min(new_grades))) print("\tAverage: " + str(new_average)) #Print a summary on how the average changed print("\nYour new average would be a " + str(new_average) + " compared to your real average of " + str(average) + "!") average_change = new_average - average average_change = round(average_change, 2) print("That is a change of " + str(average_change) + " points!") #Too bad the original grades are still intact! print("\nToo bad your original grades are still the same!") print(grades) print("You should go ask for extra credit!") Return to index Page 51 Conditionals Challenge 16: Shipping Accounts Program Description: You are responsible for writing a program that will simulate logging into a business’s shipping accounts software. Once logged in your program will display the current costs of shipping x amount of items. Based on the number of items shipped, the cost to ship each item will vary. Once the cost to ship an item is set, your program will calculate the cost of shipping the entire order. Upon confirmation of the order, your program will place the order and prepare the shipment. Step By Step Guide: ● Begin by creating a list that will hold 5 user names of your choice. ○ For example: users = ['eramom', 'footea', 'davisv', 'papinukt', 'allenj'] ● ● Print a welcome message to the user. Get user input for their specific username. ○ Usernames should not be case sensitive. For example, eramom == Eramom. ● If the username is in the list of usernames: ○ Welcome the user. ○ Print the shipping price summary as formatted below. ○ Get user input for how many items they would like to ship. ○ Use an if, elif, else chain to determine the cost of shipping each item. ○ Calculate the users bill based on the number of items to ship and the cost of shipping each item. ■ Round this bill to two decimal places. ○ Print the results as formatted below. ○ ○ ○ Ask the user if they would like to place their order. If the users answer starts with y: ■ Print a message confirming that their order has been placed. Else: ■ Inform the user that no order has been placed. ● Else, the user does not have an account: ○ Inform the user and say goodbye. ● ● ● ● Use at least 2 comments to describe sections of your code. “Chunk” your code so that is readable. Use appropriate and informative variable names. Format your output as below. Example Output 1: Page 52 Welcome to the Shipping Accounts Program Hello, what is your username: EramoM Hello eramom. Welcome back to your account. Current shipping prices are as follows: Shipping orders 0 to 100: Shipping orders 100 to 500: Shipping orders 500 to 1000: Shipping orders over 1000: $5.10 each $5.00 each $4.95 each $4.80 each How many items would you like to ship: 867 To ship 867 items it will cost you $4291.65 at $4.95 per item. Would you like to place this order (y/n): y Okay. Shipping your 867 items. Example Output 2: Welcome to the Shipping Accounts Program Hello, what is your username: allenj Hello allenj. Welcome back to your account. Current shipping prices are as follows: Shipping orders 0 to 100: Shipping orders 100 to 500: Shipping orders 500 to 1000: Shipping orders over 1000: $5.10 each $5.00 each $4.95 each $4.80 each How many items would you like to ship: 235 To ship 235 items it will cost you $1175.0 at $5.0 per item. Would you like to place this order (y/n): n Okay, no order is being placed at this time. Example Output 3: Welcome to the Shipping Accounts Program Hello, what is your username: smtihJ Sorry, you do not have an account with us. Goodbye. Page 53 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 #Conditionals Challenge 16: Shipping Accounts Program #Define our list of users users = ['eramom', 'footea', 'davisv', 'papinukt', 'allenj'] print("Welcome to the Shipping Accounts Program") #Get user input username = input("\nHello, what is your username: ").lower().strip() #Our user is in our list.... if username in users: #Print a price summary print("\nHello " + username + ". Welcome back to your account.") print("Current shipping prices are as follows:") print("\nShipping orders 0 to 100: \t\t$5.10 each") print("Shipping orders 100 to 500: \t\t$5.00 each") print("Shipping orders 500 to 1000: \t\t$4.95 each") print("Shipping orders over 1000: \t\t$4.80 each") #Determine price based on how many items are shipped quantity = int(input("\nHow many items would you like to ship: ")) if quantity < 100: cost = 5.10 elif quantity < 500: cost = 5.00 elif quantity < 1000: cost = 4.95 else: cost = 4.80 #Display final cost bill = quantity*cost bill = round(bill, 2) print("To ship " + str(quantity) + " items it will cost you $" + str(bill) + " at $" + str(cost) + " per item.") #Place the order if the user desires choice = input("\nWould you like to place this order (y/n): ").lower() if choice.startswith('y'): print("Okay. Shipping your " + str(quantity) + " items.") else: print("Okay, no order is being placed at this time.") #Our user is not in the list else: print("Sorry, you do not have an account with us. Return to index Goodbye.") Page 54 Conditionals Challenge 17: Coin Toss App Description: You are responsible for writing a program that will simulate flipping a coin n number of times. Your program will present the user an option to see the result of each individual flip. Your program will also inform the user any time the number of heads flipped is equal to the number of tails flipped. Upon completion of all flips, your program will provide a summary table that shows the number and percentage of each flip. Step By Step Guide: ● Print a welcome message. ● Get user input for how many times the user would like to flip the coin. ● Get user input for whether they would like to see the result of each individual coin flip or not. ○ This response should be case insensitive. ○ Any response that starts with y should be taken as a yes. ● ● Create a variable to store the number of times heads is flipped and set it equal to zero. Create a variable to store the number of times tails is flipped and set it equal to zero. ● ● Flip a coin for the correct number of times. For each flip; do the following: ○ To simulate a coin flip we will randomly pick a number from two possible states. ■ The random generation of numbers is outside the scope of basic python. In order to generate random numbers we will need to import a library of extra code. ■ Type import random as the first line of code in your program. ○ Create a coin flip using the random library to generate a random integer; 0 or 1. ■ Let one of these values imply that a heads was flipped while the other implies that tails was flipped. ○ Use an if/else statement to increase the number of heads or tails flipped depending on the outcome of the coin flip. ○ If the user indicated that they want to see the individual results: ■ Display what was flipped. ○ If the number of heads and tails are equal: ■ Inform the user each time this occurred. ● ● ● ● Calculate the percentage of heads flipped. Calculate the percent of tails flipped. Round these values to two decimal places. Print out the results of the total trials as formatted below. ● ● Use at least 2 comments to describe sections of your code. “Chunk” your code so that is readable. Page 55 ● ● Use appropriate and informative variable names. Format your output as below. Example Output 1: Welcome to the Coin Toss App I will flip a coin a set number of times. How many times would you like me to flip the coin: 97 Would you like to see the result of each flip (y/n): n Flipping!!! At 2 flips, the number of heads and tails were equal at 1 each. At 8 flips, the number of heads and tails were equal at 4 each. At 10 flips, the number of heads and tails were equal at 5 each. At 12 flips, the number of heads and tails were equal at 6 each. At 14 flips, the number of heads and tails were equal at 7 each. At 20 flips, the number of heads and tails were equal at 10 each. Results Of Flipping A Coin 97 Times: Side Heads Tails Count 42/97 55/97 Percentage 43.3% 56.7% Example Output 2: Welcome to the Coin Toss App I will flip a coin a set number of times. How many times would you like me to flip the coin: 10 Would you like to see the result of each flip (y/n): YEAH Flipping!!! TAILS HEADS At 2 flips, the number of heads and tails were equal at 1 each. TAILS TAILS HEADS HEADS At 6 flips, the number of heads and tails were equal at 3 each. TAILS HEADS At 8 flips, the number of heads and tails were equal at 4 each. Page 56 HEADS TAILS At 10 flips, the number of heads and tails were equal at 5 each. Results Of Flipping A Coin 10 Times: Side Heads Tails Count 5/10 5/10 Percentage 50.0% 50.0% Page 57 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 #Conditionals Challenge 17: import random Coin Toss App print("Welcome to the Coin Toss App") print("\nI will flip a coin a set number of times.") #Get user input flip_number = int(input("How many times would you like me to flip the coin: ")) choice = input("Would you like to see the result of each flip (y/n): ").lower() print("\nFlipping!!!\n") #Initialize variables heads = 0 tails = 0 #The main loop for flips in range(flip_number): #Create the coin object coin = random.randint(0,1) if coin == 1: heads += 1 if choice.startswith('y'): print("HEADS") else: tails += 1 if choice.startswith('y'): print("TAILS") if heads == tails: print("At " + str(flips + 1) + " flips, the number of heads and tails were equal at " + str(heads) + " each.") #Calculate percentages heads_percentage = round(100*heads/flip_number, 2) tails_percentage = round(100*tails/flip_number, 2) #Print the results print("\nResults of Flipping a Coin " + str(flip_number) + " Times: ") print("\nSide\t\tCount\t\tPercentage") print("Heads\t\t" + str(heads) + "/" + str(flip_number) + "\t\t" + str(heads_percentage) + "%") print("Tails\t\t" + str(tails) + "/" + str(flip_number) + "\t\t" + str(tails_percentage) + "%") Return to index Page 58 Conditionals Challenge 18: Voter Registration App Description: You are responsible for writing a program that will simulate registering to vote. If a user is 18 or older, your program will present them with a list of potential political parties to register for. Upon choosing a party, your program will confirm that the user has registered and print a specific message depending on the party joined. Step By Step Guide: ● Print a welcome message. ● Get user input for their name. ● Get user input for their age. ● Create the following list that holds the following political parties: ○ Republican, Democratic, Independent, Libertarian, Green] ● ● If the user is old enough to vote print a message informing the user they are old enough to vote. ○ List all the possible political parties to join as formatted below. ○ Get user input for the party they wish to join. ○ If the chosen party is in the list of voting parties print a message they have joined. ■ If the party is republican or democratic inform the user that it is a major party. ■ Elif the party is independent inform the user that they are an independent person. ■ Else inform the user that their party is not a major party. ○ Else inform the user that the party they chose is not a given party. Else inform the user they are not old enough to vote. ● ● ● ● Use at least 2 comments to describe sections of your code. “Chunk” your code so that is readable. Use appropriate and informative variable names. Format your output as below. Example Output 1: Welcome to the Voter Registration App Please enter your name: mike Please enter your age: 16 You are not old enough to register to vote. Example Output 2: Page 59 Welcome to the Voter Registration App Please enter your name: mike Please enter your age: 21 Congratulations Mike! You are old enough to register to vote. Here is a list of political parties to join. - Republican - Democratic - Independent - Libertarian - Green What party would you like to join: republican Congratulations Mike! You have joined the Republican party! That is a major party! Example Output 3: Welcome to the Voter Registration App Please enter your name: mike Please enter your age: 33 Congratulations Mike! You are old enough to register to vote. Here is a list of political parties to join. - Republican - Democratic - Independent - Libertarian - Green What party would you like to join: INDEPENDENT Congratulations Mike! You have joined the Independent party! You are an independent person! Page 60 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 #Conditionals Challenge 18: Voter Registration App print("Welcome to the Voter Registration App") #Get user input name = input("\nPlease enter your name: ").title().strip() age = int(input("Please enter your age: ")) #Define our list of political parties parties = ["Republican", "Democratic", "Independent", "Libertarian", "Green"] #If the user is 18 or older, they can register to vote if age > 17: print("\nCongratulations " + name + "! You are old enough to register to vote.") print("\nHere is a list of political parties to join.") #Display our political parties for party in parties: print("\t- " + party) #Get user input for the party they wish to join chosen_party = input("\nWhat party would you like to join: ").title().strip() #Print a message specific to the party chosen if chosen_party in parties: print("\nCongratulations " + name + "! You have joined the " + chosen_party + " party!") if chosen_party == "Republican" or chosen_party == "Democratic": print("That is a major party!") elif chosen_party == "Independent": print("You are an independent person!") else: print("That is not a major party.") else: print("That is not a given party.") #Else the user is younger than 18 years old else: print("\nYou are not old enough to register to vote.") Return to index Page 61 Conditionals Challenge 19: Guess My Number App Description: You are responsible for writing a program that will play the classic “Hi Low” game. Your program will randomly pick a number between 1 and 20. Users will then guess the number. With each guess, your program will respond that the user’s guess is either too high or too low. When the user guesses correct, or after 5 guesses, your program will end the game and summarize the results. Step By Step Guide: ● Print a welcome message. ● Get user input for their name. ● Inform the user that you are thinking of a number between 1 and 20. ● Use the random library to generate a random integer between 1 and 20. ○ Type import random as the first line of code in your program. ● Allow the user to guess 5 times. Each time do the following: ○ Get the users guess. ○ If the guess is too low inform them. ○ Elif the guess is too high inform them. ○ Else the guess is the number use the break command to exit the for loop. ■ Google or reference the python documentation on how the break command works. ● ● If the user got the number correct, inform them and tell them how many guesses it took. If the user did not get the number correct after the 5th guess, let them know they lost. ● ● ● ● Use at least 2 comments to describe sections of your code. “Chunk” your code so that is readable. Use appropriate and informative variable names. Format your output as below. Example Output 1: Welcome to the Guess My Number App Hello! What is your name: mike Well Mike, I am thinking of a number between 1 and 20. Take a guess: 15 Your guess is too low. Take a guess: 20 Your guess is too high. Page 62 Take a guess: 19 Good job, Mike! You guessed my number in 3 guesses! Example Output 2: Welcome to the Guess My Number App Hello! What is your name: MIKE Well Mike, I am thinking of a number between 1 and 20. Take a guess: 1 Your guess is too low. Take a guess: 20 Your guess is too high. Take a guess: 2 Your guess is too low. Take a guess: 19 Your guess is too high. Take a guess: 3 Your guess is too low. Game Over. The number I was thinking of was 10. Page 63 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 #Conditionals Challenge 19: import random Guess My Number App print("Welcome to the Guess My Number App") #Get user input name = input("\nHello! What is your name: ").title().strip() #Pick a random integer from 1 to 20 print("Well " + name + ", I am thinking of a number between 1 and 20.") number = random.randint(1,20) #Guess the number 5 times for guess_num in range(5): guess = int(input("\nTake a guess: ")) if guess < number: print("Your guess is too low.") elif guess > number: print("Your guess is too high.") else: break #The game is done, recap winning or loosing if guess == number: print("\nGood job, " + name + "! You guessed my number in " + str(guess_num + 1) + " guesses!") else: print("\nGame Over. The number I was thinking of was " + str(number) + ".") Return to index Page 64 Conditionals Challenge 20: Rock, Paper, Scissors App Description: You are responsible for writing a program that will simulate playing the classic game Rock, Paper, Scissors against computer AI. Your program will ask the user how many rounds of the game they would like to play, simulate each round, keep score, and determine an overall winner. Your program will also print the classic phrases such as “Paper covers rock” or “Scissors cut paper”. Step By Step Guide: ● Print a welcome message. ● Get user input for how many rounds they would like to play. ● ● ● Create a list called moves that holds three strings: 'rock', 'paper', and 'scissors'. Create a variable to hold the players score and set it to zero. Create a variable to hold the computer score and set it to zero. ● ● Play the game for the correct number of rounds using a for loop. Each round should do the following: ○ Print information for the current round. ■ This includes round number, player score, and computer score. ○ Have the computer randomly pick an element from the list moves. ■ Type import random as the first line of code in your program. ■ Randomly generate an integer from 0 to 2 which corresponds to an index in the list moves (0 = rock, 1 = paper, 2 = scissors). ■ Assign the computer a move based off this random index. Get the players choice of rock, paper, or scissors. ○ Make sure to make it case insensitive. ● ● If the player has made a valid move: ○ Print both moves. ○ Program the "logic" behind a game of rock, paper, scissors and play the round. ■ Rock beats scissors, scissors beats paper, paper beats rock. ■ For each outcome make sure you: ● Set a round winner (player or computer). ● Adjust the score. ● Set a phrase (rock smashes scissors!) to be displayed. ● Else the player has not made a valid move: ○ Let the computer win the round. ● After all rounds have been played, print out the final game statistics and print a statement indicating who won the game. Page 65 ● ● ● ● Use at least 2 comments to describe sections of your code. “Chunk” your code so that is readable. Use appropriate and informative variable names. Format your output as below. Example Output 1: Welcome to a game of Rock, Paper, Scissors How many rounds would you like to play: 3 Round 1 Player: 0 Computer: 0 Time to pick...rock, paper, scissors: scissors Computer: paper Player: scissors Scissors cut paper! You win round 1. Round 2 Player: 1 Computer: 0 Time to pick...rock, paper, scissors: PAPER Computer: rock Player: paper Paper covers rock! You win round 2. Round 3 Player: 2 Computer: 0 Time to pick...rock, paper, scissors: Rock Computer: rock Player: rock It is a tie, how boring! This round was a tie. Final Game Results Rounds Played: 3 Player Score: 2 Computer Score: 0 Winner: PLAYER!!! Example Output 2: Welcome to a game of Rock, Paper, Scissors How many rounds would you like to play: 3 Page 66 Round 1 Player: 0 Computer: 0 Time to pick...rock, paper, scissors: pizza That is not a valid game option! Computer gets the point! Round 2 Player: 0 Computer: 1 Time to pick...rock, paper, scissors: paper Computer: paper Player: paper It is a tie, how boring! This round was a tie. Round 3 Player: 0 Computer: 1 Time to pick...rock, paper, scissors: Rock Computer: rock Player: rock It is a tie, how boring! This round was a tie. Final Game Results Rounds Played: 3 Player Score: 0 Computer Score: 1 Winner: Computer :-( Page 67 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 #Conditionals Challenge 20: import random Rock, Paper, Scissors App print("Welcome to a game of Rock, Paper, Scissors") #Get user input rounds = int(input("\nHow many rounds would you like to play: ")) #Initialize variables moves = ['rock', 'paper', 'scissors'] p_score = 0 c_score = 0 #The main game loop for game_round in range(rounds): #Print the main game screen and get user input print("\nRound " + str(game_round + 1)) print("Player: " + str(p_score) + "\tComputer: " + str(c_score)) #Get the computers move c_index = random.randint(0,2) c_choice = moves[c_index] #Get the players move p_choice = input("Time to pick...rock, paper, scissors: ").lower().strip() #If the player makes a valid move if p_choice in moves: print("\tComputer: " + c_choice) print("\tPlayer: " + p_choice) #Computer chooses rock if p_choice == 'rock' and c_choice == 'rock': winner = 'tie' phrase = 'It is a tie, how boring!' elif p_choice == 'paper' and c_choice == 'rock': winner = 'player' phrase = 'Paper covers rock!' elif p_choice == 'scissors' and c_choice == 'rock': winner = 'computer' phrase = 'Rock smashes scissors!' #Computer chooses paper elif p_choice == 'rock' and c_choice == 'paper': winner = 'computer' phrase = 'Paper covers rock!' elif p_choice == 'paper' and c_choice == 'paper': winner = 'tie' phrase = 'It is a tie, how boring!' elif p_choice == 'scissors' and c_choice == 'paper': winner = 'player' phrase = 'Scissors cut paper!' #Computer chooses scissors elif p_choice == 'rock' and c_choice == 'scissors': winner = 'player' phrase = 'Rock smashes scissors!' elif p_choice == 'paper' and c_choice == 'scissors': winner = 'computer' phrase = 'Scissors cut paper!' elif p_choice == 'scissors' and c_choice == 'scissors': winner = 'tie' phrase = 'It is a tie, how boring!' #Catch for any other conditions else: print("Round winner not calculated.") winner = 'tie' Page 68 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 phrase = 'It is a tie, how boring!' #Display round results print("\t" + phrase) if winner == 'player': print("\tYou win round " + str(game_round + 1) + ".") p_score += 1 elif winner == 'computer': print("\tComputer wins round " + str(game_round + 1) + ".") c_score += 1 else: print("\tThis round was a tie.") #Else the player did not make a valid move else: print("That is not a valid game option!") print("Computer gets the point!") c_score += 1 #Game has ended, print results print("\nFinal Game Results") print("\tRounds Played: " + str(rounds)) print("\tPlayer Score: " + str(p_score)) print("\tComputer Score: " + str(c_score)) if p_score > c_score: print("\tWinner: PLAYER!!!") elif c_score > p_score: print("\tWinner: Computer :-(") else: print("\tThe game was a tie.") Return to index Page 69 Dictionaries Challenge 21: Thesaurus App Description: You are responsible for writing a program that simulates a thesaurus. Your program will present a user with a list of words that your thesaurus contains. Based on the users choice, you will randomly present them with a synonym for their chosen word. Lastly, your program will display all of the potential synonyms for each word in the thesaurus. Step By Step Guide: ● Create a dictionary called "thesaurus". ○ You must have a minimum of four keys in the dictionary. ○ Each key should be a string of a word of your choice. ○ The associated values for each key should be a list containing five synonyms for the key. ● For example, my dictionary includes: "hot":['balmy', 'summery', 'tropical', 'boiling', 'scorching'], "cold":['chilly', 'cool', 'freezing', 'frigid', 'polar'], "happy":['content', 'cheery', 'merry', 'jovial', 'jocular'], "sad":['unhappy', 'downcast', 'miserable', 'glum', 'melancholy'], ● ● Print a welcome message. Print what words are in your thesaurus. ○ This is represented by the keys of your dictionary ● ● Ask the user what word they would like to get a synonym for. If the users choice is in the thesaurus: ○ Chose a random synonym from the list containing the synonyms for the word. ■ Type import random as the first line of your program. ○ Display the information. Else, the word is not in the dictionary: ○ Inform the user. ● ● ● ● ● ● ● ● Ask the user if they would like to see the whole thesaurus. ○ This is represented by both the keys and values. If yes: ○ Display the whole dictionary following the format below. Else: ○ Print a goodbye message Use at least 2 comments to describe sections of your code. “Chunk” your code so that is readable. Use appropriate and informative variable names. Format your output as below. Page 70 Example Output 1: Welcome to the Thesaurus App! Choose a word from the thesaurus and I will give you a synonym. Here are the words in the thesaurus: -hot -cold -happy -sad What word would you like a synonym for: Hot A synonym for hot is boiling. Would you like to see the whole thesaurus (yes/no): yes Hot synonyms are: - balmy - summery - tropical - boiling - scorching Cold synonyms are: - chilly - cool - freezing - frigid - polar Happy synonyms are: - content - cheery - merry - jovial - jocular Sad synonyms are: - unhappy - downcast - miserable - glum - melancholy Page 71 Example Output 2: Welcome to the Thesaurus App! Choose a word from the thesaurus and I will give you a synonym. Here are the words in the thesaurus: -hot -cold -happy -sad What word would you like a synonym for: mad I'm sorry, that word is not currently in the thesaurus. Would you like to see the whole thesaurus (yes/no): no I hope you enjoyed the program. Thank you! Page 72 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 #Dictionaries Challenge 21: import random Thesaurus App #Define the thesaurus thesaurus = { "hot":['balmy', 'summery', 'tropical', 'boiling', 'scorching'], "cold":['chilly', 'cool', 'freezing', 'frigid', 'polar'], "happy":['content', 'cheery', 'merry', 'jovial', 'jocular'], "sad":['unhappy', 'downcast', 'miserable', 'glum', 'melancholy'], } #Print welcome information print("Welcome to the Thesaurus App!") print("\nChoose a word from the thesaurus and I will give you a synonym.") print("\nHere are the words in the thesaurus: ") for key in thesaurus.keys(): print("\t-" + key) #Get user input choice = input("\nWhat word would you like a synonym for: ").lower().strip() #Provide a random synonym if choice in thesaurus.keys(): index = random.randint(0,4) print("A synonym for " + choice + " is " + thesaurus[choice][index] + ".") else: print("I'm sorry, that word is not currently in the thesaurus.") #Get user input to see the whole thesaurus choice = input("\nWould you like to see the whole thesaurus (yes/no): ").lower().strip() #Show all values in the thesaurus if choice == 'yes': for key, values in thesaurus.items(): print("\n" + key.title() + " synonyms are: ") for value in values: print("\t-" + value) else: print("\nI hope you enjoyed the program. Thank you!") Return to index Page 73 Dictionaries Challenge 22: Database Admin Program Description: You are responsible for writing a program that will simulate logging into a database and prompting a user to change their password. All usernames and passwords to the database will be stored in a dictionary. Upon entering the correct credentials, your program will prompt the user to enter a new password that is a minimum of eight characters long. If the new password meets the criteria, it will be accepted, otherwise the new password will be rejected. If the user who logged in is the admin, a list of all usernames and passwords will be displayed. Step By Step Guide: ● Print a welcome message. ● Create a dictionary called "log_on_information". ○ The key-value pairs in this dictionary will be username:password. ○ Store 5 keys. ■ Each key should be a string representing a username. ■ One username must be "admin00". ○ Store 5 values. ■ Each value should be a string representing a password at least 8 characters long. ● Get user input for their username. ● ● ● Follow the following conditional logic to control user interaction. If the username is in the database, get user input for their password. ○ If they enter the password correct, greet them with a message. ■ If the user that logged in is the admin00, display the whole dictionary. ■ Else, if the user who logged in is not the admin, ask the user if they would like to change their password. ● If the user wants to change their password, ask them for their new password and inform them that the password must be 8 characters long. ○ If the password is not 8 characters long, do not accept. ○ Else, If the password is 8 characters long or more, accept and display the username and new password. ● Else, if the user does not want to change their password, print a goodbye message. ○ Else, if the user enters their password incorrectly, inform the user. Else, If the username is not in the database, inform the user. ● ● ● ● Use at least 2 comments to describe sections of your code. “Chunk” your code so that is readable. Use appropriate and informative variable names. Format your output as below. Page 74 Example Output 1: Welcome to the Database Admin Program Enter your username: admin00 Enter your password: admin1234 Hello admin00! You are logged in! Here is the current user database: Username: mooman74 Username: meramo1986 Username: nickyD Username: george2 Username: admin00 Password: alskes145 Password: kehns010101 Password: world1star Password: booo3oha Password: admin1234 Example Output 2: Welcome to the Database Admin Program Enter your username: mooman74 Enter your password: alskes145 Hello mooman74! You are logged in! Would you like to change your password: yes What would you like your new password to be: 123456789 mooman74 your password is 123456789 Example Output 3: Welcome to the Database Admin Program Enter your username: nickyD Enter your password: world1star Hello nickyD! You are logged in! Would you like to change your password: yes What would you like your new password to be: helpme helpme not the minimum eight characters. nickyD your password is world1star Example Output 4: Welcome to the Database Admin Program Page 75 Enter your username: george2 Enter your password: happy Password incorrect! Example Output 5: Welcome to the Database Admin Program Enter your username: billbobagins Username not in database, goodbye. Page 76 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 #Dictionaries Challenge 22: Database Admin Program print("Welcome to the Database Admin Program") #Create a dictionary to hold all username:password key-value pairs log_on_information = { 'mooman74':'alskes145', 'meramo1986':'kehns010101', 'nickyD':'world1star', 'george2':'booo3oha', 'admin00':'admin1234', } #Get user input username = input("Enter your username: ") #Simulate logging on... #Get user password if username in log_on_information.keys(): password = input("Enter your password: ") if password == log_on_information[username]: print("\nHello " + username + "! You are logged in!") if username == 'admin00': #Show the whole database to the admin account print("\nHere is the current user database:") for key, value in log_on_information.items(): print("Username: " + key + "\t\tPassword: " + value) else: #Allow standard user to change their password password_change = input("Would you like to change your password (yes/ no): ").lower().strip() if password_change == 'yes': new_password = input("What would you like your new password to be (min 8 chars): ") if len(new_password) >= 8: log_on_information[username] = new_password else: print(new_password + " is not the minimum eight characters.") print("\n" + username + " your password is " + log_on_information[username] + ".") else: print("\nThank you, goodbye.") #User did not enter their password correctly else: print("Password incorrect!") #User not in database else: print("Username not in database. Goodbye.") Return to index Page 77 Dictionaries Challenge 23: Yes or No Polling App Description: You are responsible for writing a program that will conduct a poll on a yes or no issue. Upon starting the program a user will be prompted for an issue to vote on, the number of voters, and a password to view the poll results. You program will then conduct the poll. Each time a user votes, your program will ask for the voters full name to verify that they have not yet voted. If the voter has not yet voted, they will be presented with the issue and can vote yes or no. The vote will be recorded. Once the number of voters specified by the user has been reached, the poll will close and a summary will be displayed. If the user enters the correct password a result of each voters name and how they voted will be displayed. Step By Step Guide: ● Print a welcome message. ● Get user input for the issue that the voters will be voting on. ● Get user input for the number of voters that will be allowed to vote. ● Get user input for a password to be used to view the polling results. ● ● ● Define a variable to count the number of yes votes and initialize it to zero. Define a variable to count the number of no votes and initialize it to zero. Define a blank dictionary that will hold the results of the poll. ○ Each key in the dictionary will be a person's full name ○ The associated value will be their vote. ● ● Simulate the polling process by using a for loop the appropriate number of times. Each iteration of the loop: ○ Ask the user to enter their full name. ○ If the user's name has already been registered: ■ Print a message that informs them they cannot vote again. ○ Else, they haven't yet voted: ■ Print a message describing the issue that is to be voted on. ■ Get user input for their choice, yes or no. ● You should allow users to type 'yes', 'YES', 'Yes', 'y' or 'Y' for yes and similar for no. ● Depending on the user input, increment the number of yes or no votes by one. ● If they user entered in another option; record their vote but inform them that their vote was not yes or no and will not influence the poll. ■ Add a new element to your dictionary. ● The key of this element should be the user's name. ● The value of this element should be their choice; which regardless of how they entered it should be 'yes', 'no', or their invalid vote. ■ Print a message thanking the user and confirming their vote. Page 78 ● ● Once the voting is finished, print a summary that shows the total number of voters. List the full names of all the voters. ● ● ● Give a final voting result. Reprint the issue that was being voted on. Use an if/elif/else chain to print an appropriate message if yes won, if no won, and if it was a tie. ● ● Get user input for a password to see the voting results, vote by vote. If the user enters the password correct: ○ Print all full names and their corresponding votes. Else: ○ Let the user know the password was not correct. ● ● Print a message thanking the user for using the program. ● ● ● ● Use at least 2 comments to describe sections of your code. “Chunk” your code so that is readable. Use appropriate and informative variable names. Format your output as below. Example Output 1: Welcome to the Yes or No Issue Polling App What is the yes or no issue you will be voting on today: Should soda be banned for young children? What is the number of voters you will allow on the issue: 4 Enter a password for polling results: admin1234 Enter your full name: john smith Here is our issue: Should soda be banned for young children? What do you think...yes or no: yes Thank you John Smith! Your vote of yes has been recorded. Enter your full name: madison jones Here is our issue: Should soda be banned for young children? What do you think...yes or no: YES Thank you Madison Jones! Your vote of yes has been recorded. Enter your full name: bryce leaf Here is our issue: Should soda be banned for young children? What do you think...yes or no: N Thank you Bryce Leaf! Your vote of no has been recorded. Page 79 Enter your full name: madison jones Sorry, it seems that someone with that name has already voted. The following 3 people voted: John Smith Madison Jones Bryce Leaf On the following issue: Should soda be banned for young children? Yes wins! 2 votes to 1. To see the voting results enter the admin password: admin1234 Voter: John Smith Vote: yes Voter: Madison Jones Vote: yes Voter: Bryce Leaf Vote: no Thank you for using the Yes or No Issue Polling App. Example Output 2: Welcome to the Yes or No Issue Polling App What is the yes or no issue you will be voting on today: Should college tuition be free? What is the number of voters you will allow on the issue: 3 Enter a password for polling results: freecollege Enter your full name: rob alman Here is our issue: Should college tuition be free? What do you think...yes or no: y Thank you Rob Alman! Your vote of yes has been recorded. Enter your full name: tim rean Here is our issue: Should college tuition be free? What do you think...yes or no: Who cares...I dont. That is not a yes or no answer, but okay... Thank you Tim Rean! Your vote of who cares...i dont. has been recorded. Enter your full name: mary smith Here is our issue: Should college tuition be free? What do you think...yes or no: n Thank you Mary Smith! Your vote of no has been recorded. The following 3 people voted: Rob Alman Tim Rean Mary Smith Page 80 On the following issue: Should college institution be free? It was a tie! 1 votes to 1. To see the voting results enter the admin password: payme Sorry, that is not the correct password. Goodbye... Thank you for using the Yes or No Issue Polling App. Page 81 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 #Dictionaries Challenge 23: Yes or No Polling App print("Welcome to the Yes or No Issue Polling App") #Get user input issue = input("What is the yes or no issue you will be voting on today: ") vote_number = int(input("what is the number of voters you will allow on the issue: ")) password = input("Enter a password for the polling results: ") #Initialize our variables yes = 0 no = 0 results = {} #Simulate voting for i in range(vote_number): name = input("\nEnter your full name: ").title().strip() if name in results.keys(): print("Sorry, it seems that someone with that name has already voted.") else: print("Here is our issue: " + issue) choice = input("What do you think...yes or no: ").lower().strip() if choice == 'yes' or choice == 'y': choice = 'yes' yes += 1 elif choice == 'no' or choice == 'n': choice = 'no' no += 1 else: print("That is not a yes or no answer, but okay...") #Add vote to the dictionary results results[name] = choice print("Thank you " + name + "! Your vote of " + results[name] + " has been recorded.") #Show who actually voted total_votes = len(results.keys()) print("\nThe following " + str(total_votes) + " people voted: ") for key in results.keys(): print(key) #Summarize the voting results print("\nOn the following issue: " + issue) if yes > no: print("Yes wins! " + str(yes) + " votes to " + str(no) + ".") elif no > yes: print("No wins! " + str(no) + " votes to " + str(yes) + ".") else: print("It was a tie! " + str(no) + " votes to " + str(yes) + ".") #Allow the admin to see the actual votes guess = input("\nTo see the voting results enter the admin password: ") if guess == password: for key, value in results.items(): print("Voter: " + key + "\t\t\tVote: " + value) else: print("Sorry, that is not the correct password. Goodbye...") print("\nThank you for using the Yes or No Issue Polling App.") Return to index Page 82 Dictionaries Challenge 24: Frequency Analysis App Description: You are responsible for writing a program that will analyse the letter distribution of a given text. Your program will take any text, remove all non-alpha characters, count the frequency of each letter within the text, calculate the percentage of occurrence for each letter, and create a list of letters ordered from highest occurrence to lowest occurrence. Your program will perform these operations for two different bodies of text. Step By Step Guide: ● Print a welcome message. ● Create a list called non_letters. ○ This will hold all non letter characters that may appear in a phrase the user enters. ○ Make sure to include all punctuation marks, numbers, a blank space, the newline character, and the tab character. ● Get user input for a phrase to be analyzed. ○ Store this phrase in a variable called key_phrase_1. ○ Take proper precautions to standardize the user input such that it will always be lower case. ● ● Remove all non letters from the phrase entered by the user. To do this use a for loop to loop through your list of non letters. ○ Each iteration, use the .replace() method for strings to replace the current non_letter with ''; or nothing. ○ This will remove any non letters from your phrase and replace them with an empty character. ○ I would suggest looking up how to use this new method. ○ After this step is done a previously entered string such as "Hello! How are you doing today? 32 years old I'm today." would appear as, "hellohowareyoudoingtodayyearsoldimtoday" ● Store the total length of the new "cleaned up" phrase entered by the user in a variable called total_occurrences. ● Create a Counter object called letter_count. ○ A Counter is a collection where elements are stored as dictionary keys and their counts are stored as dictionary values. Counts are allowed to be any integer value including zero or negative counts. ○ For our purpose, each letter in our phrase will be a key to this dictionary and the number of occurrences will be the value. ○ Counters are outside the scope of basic Python so we will need to import an extra library of code. Page 83 ○ ○ ● ● Type “from collections import Counter” as your first line of code in your program. This will import the Counter dictionary subclass. To create the Counter type the following: ○ letter_count = Counter(key_phrase_1) letter_count will be a dictionary that has every letter as a key and the associated number of occurrences of that letter as the value. ● Print a frequency analysis of the letters used in the phrase entered by the user. ○ This should show the letter, the total number of occurrences, and the percentage that it occurred in the phrase. ○ Sort the results such that they are in alphabetical order. ○ Round the percentage to two decimal places. ● After you display the frequency analysis for key_phrase_1, order the letters from highest to lowest occurrence. ○ In order to do this create a variable called ordered_letter_count. ○ Set the value of ordered_letter_count equal to your Counter you created from part 1, letter_count and use the .most_common() method. ○ I would highly suggest looking up "python counter most common" and see how this method works. ○ I would also suggest experimenting with this method and see what kind of data type it returns and what each piece of information represents. ● ● Create a blank list called key_phrase_1_ordered_letters. Your goal is to append all of the letters from key_phrase_1 to this list in order from most occurrences to least occurrences. Once you have done this, print all the letters in key_phrase_1_ordered_letters on one line. ○ If you can't remember how to do this look into the end= argument of the print function. ● ● ● ● ● Expand your code to allow the user to enter in a second message after the first. Display all the same statistics for the second message. Choose your variable names wisely! Don't overwrite any information from the first message when you run the code a second time. ● ● ● ● Use at least 2 comments to describe sections of your code. “Chunk” your code so that is readable. Use appropriate and informative variable names. Format your output as below. Example Output Welcome to the Frequency Analysis App Page 84 Enter a word or phrase to count the occurrence of each letter: Hello! How are you doing today? 32 years old I'm today. Here is the frequency analysis from key phrase 1: Letter a d e g h i l m n o r s t u w y Occurrence 4 4 3 1 2 2 3 1 1 7 2 1 2 1 1 4 Percentage 10.26% 10.26% 7.69% 2.56% 5.13% 5.13% 7.69% 2.56% 2.56% 17.95% 5.13% 2.56% 5.13% 2.56% 2.56% 10.26% Letters ordered from highest occurrence to lowest: oaydelhritwungsm Enter a word or phrase to count the occurrence of each letter: This is prety interesting. I feel like i'm learning something new! Here is the frequency analysis from key phrase 2: Letter a e f g h i k l m n o p Occurrence 1 9 1 3 2 9 1 3 2 6 1 1 Percentage 1.89% 16.98% 1.89% 5.66% 3.77% 16.98% 1.89% 5.66% 3.77% 11.32% 1.89% 1.89% Page 85 r s t w y 3 4 5 1 1 5.66% 7.55% 9.43% 1.89% 1.89% Letters ordered from highest occurrence to lowest: ientsrglhmpyfkaow Page 86 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 #Dictionaries Challenge 24: Frequency Analysis App from collections import Counter print("Welcome to the Frequency Analysis App") #List of elements to remove from all text for analysis non_letters = ['1','2','3','4','5','6','7','8','9','0',' ', '.','?','!',',','"',"'",':',';','(',')','%','$','&','#','\n','\t'] #Information for the first key key_phrase_1 key_phrase_1 = input("Enter a word or phrase to count the occurrence of each letter: ").lower().strip() #Removing all non letters from key_phrase_1 for non_letter in non_letters: key_phrase_1 = key_phrase_1.replace(non_letter, '') total_occurrences = len(key_phrase_1) #Create a counter object to tally the number of each letter letter_count = Counter(key_phrase_1) #Determine the frequency analysis for the message print("\nHere is the frequency analysis from key phrase 1: ") print("\n\tLetter\t\tOccurrence\tPercentage") for key, value in sorted(letter_count.items()): percentage = 100*value/total_occurrences percentage = round(percentage, 2) print("\t" + key + "\t\t" + str(value) + "\t\t" + str(percentage) + "%") #Make a list of letters from highest occurrence to lowest ordered_letter_count = letter_count.most_common() key_phrase_1_ordered_letters = [] for pair in ordered_letter_count: key_phrase_1_ordered_letters.append(pair[0]) #Print the list print("\nLetters ordered from highest occurrence to lowest: ") for letter in key_phrase_1_ordered_letters: print(letter, end='') #Information for the second key key_phrase_2 key_phrase_2 = input("\n\nEnter a word or phrase to count the occurrence of each letter: ").lower().strip() #Removing all non letters from key_phrase_2 for non_letter in non_letters: key_phrase_2 = key_phrase_2.replace(non_letter, '') total_occurrences = len(key_phrase_2) #Create a counter object to tally the number of each letter letter_count = Counter(key_phrase_2) #Determine the frequency analysis for the message print("\nHere is the frequency analysis from key phrase 2: ") print("\n\tLetter\t\tOccurrence\tPercentage") for key, value in sorted(letter_count.items()): percentage = 100*value/total_occurrences percentage = round(percentage, 2) print("\t" + key + "\t\t" + str(value) + "\t\t" + str(percentage) + "%") #Make a list of letters from highest occurrence to lowest ordered_letter_count = letter_count.most_common() Page 87 62 63 64 65 66 67 68 69 key_phrase_2_ordered_letters = [] for pair in ordered_letter_count: key_phrase_2_ordered_letters.append(pair[0]) #Print the list print("\nLetters ordered from highest occurrence to lowest: ") for letter in key_phrase_2_ordered_letters: print(letter, end='') Return to index Page 88 Dictionaries Challenge 25: Code Breaker App Description: You are responsible for writing a program that will encode or decode a message based off the letter distribution of a predetermined key text. Your program will determine a frequency analysis for two texts and use these letter distributions to create a cipher to either encode or decode a message based off user input. This program is an extension of the Frequency Analysis App. Step by Step Guide: ● ● ● ● Begin by copying your code from the Frequency Analysis App Print a new welcome message. Comment out the user input for getting key_phrase_1 Hard code a predetermined phrase between you and the person you are communicating with for key_phase_1. I am using excerpts from Sherlock Holmes, but anything will do. key_phrase_1 = """ To Sherlock Holmes she is always the woman. I have seldom heard him mention her under any other name. In his eyes she eclipses and predominates the whole of her sex. It was not that he felt any emotion akin to love for Irene Adler. All emotions, and that one particularly, were abhorrent to his cold, precise but admirably balanced mind. He was, I take it, the most perfect reasoning and observing machine that the world has seen, but as a lover he would have placed himself in a false position. He never spoke of the softer passions, save with a gibe and a sneer. They were admirable things for the observer excellent for drawing the veil from men's motives and actions. But for the trained reasoner to admit such intrusions into his own delicate and finely adjusted temperament was to introduce a distracting factor which might throw a doubt upon all his mental results. Grit in a sensitive instrument, or a crack in one of his own highpower lenses, would not be more disturbing than a strong emotion in a nature such as his. And yet there was but one woman to him, and that woman was the late Irene Adler, of dubious and questionable memory. I had seen little of Holmes lately. My marriage had drifted us away from each other. My own complete happiness, and the homecentred interests which rise up around the man who first finds himself master of his own establishment, were sufficient to absorb all my attention, while Holmes, who loathed every form of society with his whole Bohemian soul, remained in our lodgings in Baker Street, buried among his old books, and alternating from week to week between cocaine and ambition, the drowsiness of the drug, and the fierce energy of his own keen nature. He was still, as ever, deeply attracted by the study of crime, Page 89 and occupied his immense faculties and extraordinary powers of observation in following out those clues, and clearing up those mysteries which had been abandoned as hopeless by the official police. From time to time I heard some vague account of his doings: of his summons to Odessa in the case of the Trepoff murder, of his clearing up of the singular tragedy of the Atkinson brothers at Trincomalee, and finally of the mission which he had accomplished so delicately and successfully for the reigning family of Holland. Beyond these signs of his activity, however, which I merely shared with all the readers of the daily press, I knew little of my former friend and companion. """ ● ● Comment out the user input for getting key_phrase_2 Hard code a predetermined phrase between you and the person you are communicating with for key_phase_2. I am using excerpts from Sherlock Holmes, but anything will do. key_phrase_2 = """ Quite so! You have not observed. And yet you have seen. That is just my point. Now, I know that there are seventeen steps, because I have both seen and observed. By the way, since you are interested in these little problems, and since you are good enough to chronicle one or two of my trifling experiences, you may be interested in this. He threw over a sheet of thick, pink tinted notepaper which had been lying open upon the table. It came by the last post, said he. Read it aloud. The note was undated, and without either signature or address. There will call upon you tonight, at a quarter to eight o'clock, it said, "a gentleman who desires to consult you upon a matter of the very deepest moment. Your recent services to one of the royal houses of Europe have shown that you are one who may safely be trusted with matters which are of an importance which can hardly be exaggerated. This account of you we have from all quarters received. Be in your chamber then at that hour, and do not take it amiss if your visitor wear a mask. This is indeed a mystery, I remarked. What do you imagine that it means? I have no data yet. It is a capital mistake to theorise before one has data. Insensibly one begins to twist facts to suit theories, instead of theories to suit facts. But the note itself. What do you deduce from it? I carefully examined the writing, and the paper upon which it was written. The man who wrote it was presumably well to do, I remarked, endeavouring to imitate my companion's processes. Such paper could not be bought under half a crown a packet. It is peculiarly strong and stiff. """ Page 90 ● ● ● ● ● ● ● ● You should be able to encode or decode a message regardless of the key phrases chosen. To In order to accomplish this, you must look at the frequency analysis of the two key phrases. Given a character in the secret message that is to be encoded, you must find its index in the frequency analysis of the first message. Then find the letter that appears at the same index in the frequency analysis of the second message. This is your encoding rule to encode one character as another. For example, the letter "o" appears at index 1 in the first frequency analysis. The letter "t" appears at index 1 in the second frequency analysis. Therefore the letter “o” would be encoded to the letter “t”. The letter “h” appears at index 7 in the first frequency analysis. The letter “r” appears at index 7 in the second frequency analysis. Therefore the letter “h” would be encoded to the letter “r”. Similarly, the word “oh” would be encoded to “tr” using the given key phrases. NEW CODE TO ADD ● ● ● ● Ask the user if they would like to encode or decode a message. Ask the user for the message. ○ You should take proper precautions to make the message all lower case. ○ You should take proper precautions to remove all non-letters from their message. If the user chose to encode the message, run an algorithm to encode and print the message. ○ Create a blank list called encoded_phrase. ○ For each letter that is in the phrase: ■ Create a variable called index and set it equal to the index of the current letter in key_phrase_1_ordered_letters. ● To accomplish this you can use the .index() method. ● Google or check Python documentation on the .index() method. ■ Create a variable called letter and set it equal to the letter that appears in key_phrase_2_ordered_letters at the specified index. ■ Append letter to the list encoded_phrase. ○ Print the encoded message. ■ There are multiple ways to do this. You may use the end= argument of the print function or the .join() method for strings. Elif the user chose to decode the message, run an algorithm to decode and print the message. ○ Create a blank list called decoded_phrase. ○ For each letter that is in the phrase: ■ Create a variable called index and set it equal to the index of the current letter in key_phrase_2_ordered_letters. ● To accomplish this you can use the .index() method. ● Google or check Python documentation on the .index() method. Page 91 ■ ● Create a variable called letter and set it equal to the letter that appears in key_phrase_1_ordered_letters at the specified index. ■ Append letter to the list encoded_phrase. ○ Print the decoded message. ■ There are multiple ways to do this. You may use the end= argument of the print function or the .join() method for strings. Else, the user chose an invalid option and inform them. ● ● ● ● Use at least 2 comments to describe sections of your code. “Chunk” your code so that is readable. Use appropriate and informative variable names. Format your output as below. Example Output 1: Welcome to the Code Breakers App Here is the frequency analysis from key phrase 1: Letter a b c d e f g h i j k l m n o p q r s t u v w x Occurrence 153 32 53 81 249 57 28 117 150 1 12 85 69 142 157 27 1 116 139 154 45 17 46 3 Percentage 7.77% 1.63% 2.69% 4.12% 12.65% 2.9% 1.42% 5.95% 7.62% 0.05% 0.61% 4.32% 3.51% 7.22% 7.98% 1.37% 0.05% 5.89% 7.06% 7.83% 2.29% 0.86% 2.34% 0.15% Page 92 y 34 1.73% Letters ordered from highest occurrence to lowest: eotainshrldmfcwuybgpvkxjq Here is the frequency analysis from key phrase 2: Letter a b c d e f g h i j k l m n o p q r s t u v w x y Occurrence 103 21 36 45 169 21 16 67 88 1 10 33 29 78 103 26 3 72 77 135 46 15 29 3 35 Percentage 8.17% 1.67% 2.85% 3.57% 13.4% 1.67% 1.27% 5.31% 6.98% 0.08% 0.79% 2.62% 2.3% 6.19% 8.17% 2.06% 0.24% 5.71% 6.11% 10.71% 3.65% 1.19% 2.3% 0.24% 2.78% Letters ordered from highest occurrence to lowest: etoainsrhudcylmwpbfgvkqxj Would you like to encode or decode a message: encode What is the phrase: Wow, this is awesome! The encoded message is: mtmorisisamestce Example Output 2: Welcome to the Code Breakers App Page 93 Here is the frequency analysis from key phrase 1: Letter a b c d e f g h i j k l m n o p q r s t u v w x y Occurrence 153 32 53 81 249 57 28 117 150 1 12 85 69 142 157 27 1 116 139 154 45 17 46 3 34 Percentage 7.77% 1.63% 2.69% 4.12% 12.65% 2.9% 1.42% 5.95% 7.62% 0.05% 0.61% 4.32% 3.51% 7.22% 7.98% 1.37% 0.05% 5.89% 7.06% 7.83% 2.29% 0.86% 2.34% 0.15% 1.73% Letters ordered from highest occurrence to lowest: eotainshrldmfcwuybgpvkxjq Here is the frequency analysis from key phrase 2: Letter a b c d e f g h i Occurrence 103 21 36 45 169 21 16 67 88 Percentage 8.17% 1.67% 2.85% 3.57% 13.4% 1.67% 1.27% 5.31% 6.98% Page 94 j k l m n o p q r s t u v w x y 1 10 33 29 78 103 26 3 72 77 135 46 15 29 3 35 0.08% 0.79% 2.62% 2.3% 6.19% 8.17% 2.06% 0.24% 5.71% 6.11% 10.71% 3.65% 1.19% 2.3% 0.24% 2.78% Letters ordered from highest occurrence to lowest: etoainsrhudcylmwpbfgvkqxj Would you like to encode or decode a message: decode What is the phrase: mtmorisisamestce The decoded message is: wowthisisawesome Page 95 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 #Dictionaries Challenge 25: Code Breakers App from collections import Counter print("Welcome to the Code Breakers App") #List of elements to remove from all text for analysis non_letters = ['1','2','3','4','5','6','7','8','9','0',' ', '.','?','!',',','"',"'",':',';','(',')','%','$','&','#','\n','\t'] #Comment out user input for key phrase 1 #Information for the first key key_phrase_1 #key_phrase_1 = input("Enter a word or phrase to count the occurrence of each letter: ").lower().strip() #Hard code a pre-determined key_phrase_1 for communication purposes key_phrase_1 = """ To Sherlock Holmes she is always the woman. I have seldom heard him mention her under any other name. In his eyes she eclipses and predominates the whole of her sex. It was not that he felt any emotion akin to love for Irene Adler. All emotions, and that one particularly, were abhorrent to his cold, precise but admirably balanced mind. He was, I take it, the most perfect reasoning and observing machine that the world has seen, but as a lover he would have placed himself in a false position. He never spoke of the softer passions, save with a gibe and a sneer. They were admirable things for the observer excellent for drawing the veil from men's motives and actions. But for the trained reasoner to admit such intrusions into his own delicate and finely adjusted temperament was to introduce a distracting factor which might throw a doubt upon all his mental results. Grit in a sensitive instrument, or a crack in one of his own highpower lenses, would not be more disturbing than a strong emotion in a nature such as his. And yet there was but one woman to him, and that woman was the late Irene Adler, of dubious and questionable memory. I had seen little of Holmes lately. My marriage had drifted us away from each other. My own complete happiness, and the homecentred interests which rise up around the man who first finds himself master of his own establishment, were sufficient to absorb all my attention, while Holmes, who loathed every form of society with his whole Bohemian soul, remained in our lodgings in Baker Street, buried among his old books, and alternating from week to week between cocaine and ambition, the drowsiness of the drug, and the fierce energy of his own keen nature. He was still, as ever, deeply attracted by the study of crime, and occupied his immense faculties and extraordinary powers of observation in following out those clues, and clearing up those mysteries which had been abandoned as hopeless by the official police. From time to time I heard some vague account of his doings: of his summons to Odessa in the case of the Trepoff murder, of his clearing up of the singular tragedy of the Atkinson brothers at Trincomalee, and finally of the mission which he had accomplished so delicately and successfully for the reigning family of Holland. Beyond these signs of his activity, however, which I merely shared with all the readers of the daily press, I knew little of my former friend and companion. """ key_phrase_1 = key_phrase_1.lower() #Removing all non letters from key_phrase_1 for non_letter in non_letters: Page 96 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 key_phrase_1 = key_phrase_1.replace(non_letter, '') total_occurrences = len(key_phrase_1) #Create a counter object to tally the number of each letter letter_count = Counter(key_phrase_1) #Determine the frequency analysis for the message print("\nHere is the frequency analysis from key phrase 1: ") print("\n\tLetter\t\tOccurrence\tPercentage") for key, value in sorted(letter_count.items()): percentage = 100*value/total_occurrences percentage = round(percentage, 2) print("\t" + key + "\t\t" + str(value) + "\t\t" + str(percentage) + "%") #Make a list of letters from highest occurrence to lowest ordered_letter_count = letter_count.most_common() key_phrase_1_ordered_letters = [] for pair in ordered_letter_count: key_phrase_1_ordered_letters.append(pair[0]) #Print the list print("\nLetters ordered from highest occurrence to lowest: ") for letter in key_phrase_1_ordered_letters: print(letter, end='') #Comment out user input for key_phrase_2 #Information for the second key key_phrase_2 #key_phrase_2 = input("\n\nEnter a word or phrase to count the occurrence of each letter: ").lower().strip() #Hard code a pre-determined key_phrase_2 for communication purposes. key_phrase_2 = """ Quite so! You have not observed. And yet you have seen. That is just my point. Now, I know that there are seventeen steps, because I have both seen and observed. By the way, since you are interested in these little problems, and since you are good enough to chronicle one or two of my trifling experiences, you may be interested in this. He threw over a sheet of thick, pink tinted notepaper which had been lying open upon the table. It came by the last post, said he. Read it aloud. The note was undated, and without either signature or address. There will call upon you tonight, at a quarter to eight o'clock, it said, "a gentleman who desires to consult you upon a matter of the very deepest moment. Your recent services to one of the royal houses of Europe have shown that you are one who may safely be trusted with matters which are of an importance which can hardly be exaggerated. This account of you we have from all quarters received. Be in your chamber then at that hour, and do not take it amiss if your visitor wear a mask. This is indeed a mystery, I remarked. What do you imagine that it means? I have no data yet. It is a capital mistake to theorise before one has data. Insensibly one begins to twist facts to suit theories, instead of theories to suit facts. But the note itself. What do you deduce from it? I carefully examined the writing, and the paper upon which it was written. The man who wrote it was presumably well to do, I remarked, endeavouring to imitate my companion's processes. Such paper could not be bought under half a crown a packet. It is peculiarly strong and stiff. """ key_phrase_2 = key_phrase_2.lower() Page 97 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 #Removing all non letters from key_phrase_2 for non_letter in non_letters: key_phrase_2 = key_phrase_2.replace(non_letter, '') total_occurrences = len(key_phrase_2) #Create a counter object to tally the number of each letter letter_count = Counter(key_phrase_2) #Determine the frequency analysis for the message print("\n\nHere is the frequency analysis from key phrase 2: ") print("\n\tLetter\t\tOccurrence\tPercentage") for key, value in sorted(letter_count.items()): percentage = 100*value/total_occurrences percentage = round(percentage, 2) print("\t" + key + "\t\t" + str(value) + "\t\t" + str(percentage) + "%") #Make a list of letters from highest occurrence to lowest ordered_letter_count = letter_count.most_common() key_phrase_2_ordered_letters = [] for pair in ordered_letter_count: key_phrase_2_ordered_letters.append(pair[0]) #Print the list print("\nLetters ordered from highest occurrence to lowest: ") for letter in key_phrase_2_ordered_letters: print(letter, end='') #Encode/Decode a given message using key_phrase_1 and key_phrase_2 choice = input("\n\nWould you like to encode or decode a message: ").lower() phrase = input("What is the phrase: ").lower() #Removing all non letters from the users phrase for non_letter in non_letters: phrase = phrase.replace(non_letter, '') #User wants to encode a message if choice == 'encode': encoded_phrase = [] for letter in phrase: index = key_phrase_1_ordered_letters.index(letter) letter = key_phrase_2_ordered_letters[index] encoded_phrase.append(letter) print("\nThe encoded message is: ") for letter in encoded_phrase: print(letter, end='') #User wants to decode a message elif choice == 'decode': decoded_phrase = [] for letter in phrase: index = key_phrase_2_ordered_letters.index(letter) letter = key_phrase_1_ordered_letters[index] decoded_phrase.append(letter) print("\nThe decoded message is: ") for letter in decoded_phrase: print(letter, end='') #User entered an invalid option else: print("Please type 'encode' or 'decode'. Return to index Try again.") Page 98 While Loops Challenge 26: Factor Generator App Description: You are responsible for writing a program that generates all factors of a given number. Your program will display the factors individually and give a mathematically summary of how different pairs of factors can be multiplied together to get the given number. Step By Step Guide: ● Print a welcome message. ● Create an active flag variable to control a while loop and set it to True. ● ● ● Use this flag to run a while loop: ○ Get user input for a number to determine the factors of. ○ Write an algorithm to determine the factors of the given number. ■ Create a blank list called factors. ■ Use a for loop to loop through the numbers 1 up to and including the given number: ● If the given number is divisible by the current number in the loop, the current number is a factor: ○ Add the current number to the list factors. ○ Modulo division will help you here. ○ Print all factors of the number as formatted below. ○ Print a summary which shows how the factors multiply together to get the users number using a for loop. ■ The first element in your list will pair with the last element. ● factors[0] an factors[-1] ■ The second element will pair with the second to last element. ● factors[1] and factors[-2] ■ The third element will pair with the third to last element. ● factors[2] and factors[-3] ■ Try to generalize this pattern using an iterable variable i. ■ You only need to loop through half of your list to accomplish this. ● for i in range(int(len(factors)/2)) ○ ○ Get user input for if they would like to continue the program. If the user does not want to continue: ■ Set your flag variable to False ■ Print a goodbye message thanking the user. Use at least 2 comments to describe sections of your code. “Chunk” your code so that is readable. Page 99 ● ● Use appropriate and informative variable names. Format your output as below. Example Output 1: Welcome to the Factor Generator App Enter a number to determine all factors of that number: 44 Factors of 44 are: 1 2 4 11 22 44 In summary: 1 * 44 = 44 2 * 22 = 44 4 * 11 = 44 Run again (y/n): n Thank you for using the program. Have a great day. Example Output 2: Welcome to the Factor Generator App Enter a number to determine all factors of that number: 100 Factors of 100 are: 1 2 4 5 10 20 25 50 100 In summary: 1 * 100 = 100 2 * 50 = 100 4 * 25 = 100 5 * 20 = 100 Page 100 Run again (y/n): y Enter a number to determine all factors of that number: 33 Factors of 33 are: 1 3 11 33 In summary: 1 * 33 = 33 3 * 11 = 33 Run again (y/n): n Thank you for using the program. Have a great day. Page 101 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 #While Loops Challenge 26: Factor Generator App print("Welcome to the Factor Generator App") running = True #Run the program until the user quits while running: #Get user input number = int(input("\nEnter a number to determine all factors of that number: ")) #Find the factors of the user's given number factors = [] for i in range(1, number+1): if number % i == 0: factors.append(i) #Print out the factors print("\nFactors of " + str(number) + " are: ") for factor in factors: print(factor) #Print a summary of the factors mathematically print("\nIn summary: ") for i in range(int(len(factors)/2)): print(str(factors[i]) + " * " + str(factors[-i-1]) + " = " + str(number)) #Ask the user if they would like to quit choice = input("\nRun again (y/n): ").lower() if choice != 'y': running = False print("Thank you for using the program. Have a great day.") Return to index Page 102 While Loops Challenge 27: Even Odd Number Sorter App Description: You are responsible for writing a program that sorts a list of comma separated numbers as either even or odd. Upon sorting the numbers into two groups, your program will then sort each group numerically and display the results. Step By Step Guide: ● Print a welcome message. ● Create an active flag variable that will control a while loop and set it to True. ● Use this flag to run a while loop: ○ Get user input for a series of numbers separated by a comma. ■ This series of numbers will be a string, don’t change this for now. ■ Take precaution to remove any spaces the user may have put into the number using the .replace() method for strings. ■ Replace “ “ a space with “” a blank string. ■ The user may enter "1, 2, 3, 4," or they may enter "1,2,3,4". ■ You want to have the results of the program be the same regardless. ○ Turn the string into a list using the .split() method for strings. ■ Each element in our list should be a number. ■ The string should be split using a comma. ■ For example, if i have a list values = [‘1,2,3,4,5’] calling values.split(“,”) would return a list [‘1’, ‘2’, ‘3’, ‘4’, ‘5’]. ■ Store this return value in a variable called num_list. ○ ○ Create a blank list called evens. Create a blank list called odds. ○ For every number in your list of numbers: ■ Cast the number to an integer. ■ Recall a number is even if it is divisible by 2. ■ If the number is even: ● Append the number to the evens lists. ● Print a statement that the number is even. ■ Else: ● Append the number to the odds lists. ● Print a statement that the number is odd. ○ ○ Permanently sort your even numbers in numerical order. Permanently sort your odd numbers in numerical order. Page 103 ● ● ● ● ○ ○ Display all the even numbers in numerical order as formatted below. Display all odd numbers in numerical order as formatted below. ○ ○ Get user input for if they would like to continue the program. If the user does not want to continue: ■ Set your flag variable to False ■ Print a goodbye message thanking the user. Use at least 2 comments to describe sections of your code. “Chunk” your code so that is readable. Use appropriate and informative variable names. Format your output as below. Example Output: Welcome to the Even Odd Number Sorter App Enter in a string of numbers separated by a comma (,) : 1, 2, 3, 6, 18, 9, 4, 13, 22 ---- Result Summary ---1 is odd! 2 is even! 3 is odd! 6 is even! 18 is even! 9 is odd! 4 is even! 13 is odd! 22 is even! The following 5 numbers are even: 2 4 6 18 22 The following 4 numbers are odd: 1 3 9 13 Would you like to run the program again (y/n): y Enter in a string of numbers separated by a comma (,) : 1, 2, 3, 4 Page 104 ---- Result Summary ---1 is odd! 2 is even! 3 is odd! 4 is even! The following 2 numbers are even: 2 4 The following 2 numbers are odd: 1 3 Would you like to run the program again (y/n): n Thank you for using the program. Goodbye. Page 105 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 #While Loops Challenge 27: Even Odd Number Sorter App print("Welcome to the Even Odd Number Sorter App") running = True #Run the program as longs as the user wants while running: #Get user input num_string = input("\nEnter in a string of numbers separated by a comma (,) : ") num_string = num_string.replace(' ', '') num_list = num_string.split(",") #Initialize lists to hold even/odd values evens = [] odds = [] #Calculate whether the number is even or odd print("\n---- Result Summary ----") for number in num_list: number = int(number) if number % 2 == 0: evens.append(number) print("\t" + str(number) + " is even!") else: odds.append(number) print("\t" + str(number) + " is odd!") #Sort the lists evens and odds evens.sort() odds.sort() #Show the even numbers print("\nThe following " + str(len(evens)) + " numbers are even: ") for even in evens: print("\t" + str(even)) #Show the odd numbers print("\nThe following " + str(len(odds)) + " numbers are odd: ") for odd in odds: print("\t" + str(odd)) #Quit the program if the user does not enter in 'y' choice = input("\nWould you like to run the program again (y/n): ").lower() if choice != 'y': running = False print("Thank you for using the program. Goodbye.") Return to index Page 106 While Loops Challenge 28: Prime Number App Description: You are responsible for writing a program that will either determine if a given number is prime or display all prime numbers within a given range of values. When determining all prime numbers within a given range, your program will time the process and report how long the calculations took to the user. It is important to time certain processes within our programs so we can so how efficient our code is. Step By Step Guide: ● Print a welcome message. ● Create an active flag variable to control a while loop and set it to True. ● Use this flag to run a while loop: ○ Display the users options for the program formatted as below. ○ Get user input for which option the program should run. ■ The program has 3 possibilities. ■ First, the user entered 1 and wants to calculate if a number is prime. ■ Second, the user entered 2 and wants all prime numbers within a set range of numbers. ■ Third, the user entered some foolish input other than 1 or 2. ○ If the user entered 1: ■ Get user input for their number to check. ■ Run an algorithm to determine if the number is prime or not. ● A number is prime if it is only divisible by 1 and itself. Another way to think of this is a number is prime if it is not divisible by any number from 2 to itself minus 1. ● Begin your algorithm by assuming the given number is prime. ● Create a variable prime_status and set it equal to True ● Using a for loop, loop through the numbers from 2 up to but not including the given number. Each iteration you should: ○ Check if the given number is divisible by the current number in the loop. If the given number is divisible by the current number in the loop: ■ Set prime_status to False ■ Break out of the for loop as there is no need to check other numbers. ■ You can check divisibility using the modulus operator. ● If, after the for loop is done prime_status is True: ○ Print a message stating the number is prime. ● Else: ○ Print a message stating the number is not prime. Page 107 ○ ○ Elif the user entered 2: ■ Get user input for the lower bound of the numerical range. ■ Get user input for the upper bound of the numerical range. ■ Create a variable primes and set it equal to a blank list. This will hold all prime numbers between the lower bound and upper bound. ■ Time how long the upcoming calculations are going to take. ● Timing processes is outside the scope of basic Python. To perform this action we will have to import an extra library of code. ● Type import time as the first line of code in your program. ● We want to use the time library to measure how long the upcoming calculations take. ● Prior to running the upcoming loop, call the time library to capture the current time and store it in a variable start_time. ● Reference google of python documentation on how to use the time library. ■ For every number in between the lower bound and upper bound determine run an algorithm to determine if the number is prime. ● Use a for loop to loop through a range of numbers between lower bound and upper bound. Each iteration you should: ○ Check if the current number is greater than 1. If it is: ■ Run your previous prime checking algorithm. ○ Else: ■ Set prime_status equal to False as 1 is not prime. ○ If prime_status is True: ■ Add the current prime candidate number to the list primes. ■ Once the algorithm is finished for every number between the lower bound and upper bound, call the time library again to capture the current time and store it in a variable end_time. ■ Create a variable delta_time and set it equal to the difference of end_time and start_time. ● This is how long your calculation took. ● Round this value to 4 decimal places. ■ ■ ■ Print a summary of the amount of time the calculations took. Prompt the user to press enter to continue Print all of the found prime numbers. Else: ■ ■ The user entered a value other than 1 or 2. Print a message letting them know their choice was not a valid option. Page 108 ○ ○ ● ● ● ● Get user input for if they would like to continue the program. If the user does not want to continue: ■ Set your flag variable to False ■ Print a goodbye message thanking the user. Use at least 2 comments to describe sections of your code. “Chunk” your code so that is readable. Use appropriate and informative variable names. Format your output as below. Example Output: Welcome to the Prime Number App Enter 1 to determine if a specific number is prime. Enter 2 to determine all prime numbers within a set range. Enter your choice 1 or 2: 1 Enter a number to determine if it is prime or not: 55 55 is not prime! Would you like to run the program again (y/n): y Enter 1 to determine if a specific number is prime. Enter 2 to determine all prime numbers within a set range. Enter your choice 1 or 2: 1 Enter a number to determine if it is prime or not: 11 11 is prime! Would you like to run the program again (y/n): y Enter 1 to determine if a specific number is prime. Enter 2 to determine all prime numbers within a set range. Enter your choice 1 or 2: 2 Enter the lower bound of your range: 1 Enter the upper bound of your range: 100 Calculations took a total of 0.0003 seconds. The following numbers between 1 and 100 are prime: Press enter to continue. 2 3 5 7 11 13 Page 109 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 Would you like to run the program again (y/n): y Enter 1 to determine if a specific number is prime. Enter 2 to determine all prime numbers within a set range. Enter your choice 1 or 2: 51 That is not a valid option. Would you like to run the program again (y/n): n Thank you for using the program. Have a nice day. Page 110 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #While Loops Challenge 28: import time Prime Number App print("Welcome to the Prime Number App") running = True #Run the program as long as the user wants while running: #Get user input print("\nEnter 1 to determine if a specific number is prime.") print("Enter 2 to determine all prime numbers within a set range.") option = input("Enter your choice 1 or 2: ") #Determine if a single number is prime if option == '1': number = int(input("\nEnter a number to determine if it is prime or not: ")) 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 #Prime status check prime_status = True for i in range(2, number): if number % i == 0: prime_status = False break #Print summary if prime_status: print(str(number) + " is prime!") else: print(str(number) + " is not prime!") #Determine primes within a range of values and time the calculations elif option == '2': l_bound = int(input("\nEnter the lower bound of your range: ")) u_bound = int(input("Enter the upper bound of your range: ")) primes = [] #Get the current time start_time = time.time() #Check prime status of all numbers within l_bound and u_bound for prime_candidate in range(l_bound, u_bound + 1): #1 is not prime if prime_candidate > 1: prime_status = True for i in range(2, prime_candidate): if prime_candidate % i == 0: prime_status = False break else: prime_status = False #Prime candidate is in fact prime! if prime_status: primes.append(prime_candidate) #Get the current time end_time = time.time() #Determine the time the calculations took delta_time = round(end_time - start_time, 4) print("\nCalculations took a total of " + str(delta_time) + " seconds.") Page 111 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 print("The following numbers between " + str(l_bound) + " and " + str(u_bound) + " are prime: ") input("Press enter to continue.") for prime in primes: print(prime) #Not a valid choice entered by the user else: print("\nThat is not a valid option.") #Quit the program if the user does not enter in y choice = input("Would you like to run the program again (y/n): ").lower() if choice != 'y': running = False print("\nThank you for using the program. Have a nice day.") Return to index Page 112 While Loops Challenge 29: Guess My Word App Description: You are responsible for writing a program that plays a word guessing game with a user. Your program will provide a category of words to the user and a string of dashes “-----” that represent the length of the word. The user will guess the word and with each incorrect guess, your program will reveal a letter at random, “-a---”. Upon guessing the word correctly, your program will then inform the user how many guesses they took. Step By Step Guide: ● Print a welcome message. ● Create a dictionary called game_dict that has a minimum of four keys. ○ Each key should be a category such as "sports", "colors", or "fruits". ○ Each subsequent value should be a list. ○ In the list you should have a minimum of 6 strings that are in that category. ○ For instance if the key is sports, the subsequent value should be a list containing the words "basketball", "baseball", "tennis", etc... ● ● Create a blank list called game_keys. Use a for loop to loop through the keys of game_dict: ○ Append the current key in the dictionary to the list game_keys. ● Create an active flag variable to control a while loop and set it to True. ● Use this flag to run a while loop: ○ To implement the randomness of the game, extra code will be needed that is outside the scope of basic Python. ■ Type import random as the first line of code in your program. ○ ○ ○ ○ Randomly pick a key from the list game_keys and store it in a variable named game_category. ■ Generate a random integer that correspond to the indices of the list game_keys. ■ game_category = game_keys[?????] Randomly pick a value from the dictionary that corresponds to that key and store it in a variable named game_word. ■ Generate a random integer that corresponds to the indices of the list associated as the value to the chosen key from above. ■ game_word = game_dict[game_category][?????] Create an empty list called blank_word. For every letter that appears in game_word: ■ Append a dash ‘-’ to blank_word Page 113 ■ For instance if the game_category was fruits and the game_word was apple, you should append five "-"to the list. ○ Print a clue statement informing the user what category of words they are to guess from and how many letters there are in the word as formatted below. ○ ○ Create an empty string called guess that will eventually hold the users guess. Create a variable guess_count and set it equal to zero. ○ Use a second while loop nested inside the first to allow the user to continue guessing as long as their guess is not equal to the word they are trying to guess, which would imply they won the game. This second loop will simulate playing a single round of the game while the first loop will control playing the game or quitting. ■ Print blank_word, which is a list, as a string using the .join() method. ■ Get user input for their guess and update the value of the variable guess. ■ Increment guess_count by 1. ■ ■ ○ ○ If the guess is correct: ● Inform the user they won the game and in how many tries. ● End the game by breaking out of the second while loop. Else: ● The guess is not correct. ● Inform the user and reveal a letter at random to the user. ○ Make sure to reveal a different letter each time. ○ You should check that the letter you are choosing to reveal is currently represented by a "-" in the blank_word list. ○ If it is, to reveal it, replace the “-” with the corresponding letter such that when you print blank_word it will be a combination of “-” and letters. ○ If it is not, continue to pick a random letter until you find one that is. ○ To do this, create an active flag variable to control a while loop and set it to True. ○ Use this flag to run a while loop: ■ Create a variable letter_index and set it equal to a random integer that corresponds with a random index of your list blank_word. ■ If blank_word[letter_index] is equal to a “-”: ● Set blank_word[letter_index] equal to the actual letter of the game_word. ● Set your flag variable to False. Once a game round is over, get user input for if they would like to play again. If the user does not want to play again: Page 114 ○ ○ ● ● ● ● Set your flag variable to False Print a goodbye message thanking the user. Use at least 2 comments to describe sections of your code. “Chunk” your code so that is readable. Use appropriate and informative variable names. Format your output as below. Example Output: Welcome to the Guess My Word App Guess a 7 letter word from the following category: Classes ------Enter your guess: history That is not correct. Let us reveal a letter to help you! ---l--Enter your guess: science That is not correct. Let us reveal a letter to help you! ---li-Enter your guess: english Correct! You guessed the word in 3 guesses. Would you like to play again (y/n): y Guess a 6 letter word from the following category: Fruits -----Enter your guess: apples That is not correct. Let us reveal a letter to help you! ---a-Enter your guess: orange That is not correct. Let us reveal a letter to help you! ---a-a Enter your guess: bananas That is not correct. Let us reveal a letter to help you! -a-a-a Enter your guess: banana Page 115 Correct! You guessed the word in 4 guesses. Would you like to play again (y/n): n Thank you for playing our game. Page 116 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 #While Loops Challenge 29: Guess the Word App import random print("Welcome to the Guess My Word App") #Create the dict to hold our words game_dict = { "sports":['basketball', 'baseball', 'soccer', 'football', 'tennis', 'curling'], "colors":['orange', 'yellow', 'purple', 'aquamarine', 'violet', 'gold'], "fruits":['apple', 'banana', 'watermelon', 'peach', 'mango', 'strawberry'], "classes":['english', 'history', 'science', 'mathematics', 'art', 'health'], } #Create a list of keys game_keys = [] for key in game_dict.keys(): game_keys.append(key) #The main game loop playing = True while playing: #Randomly pick the game category and the game word from the game dictionary game_category = game_keys[random.randint(0,len(game_keys)-1)] game_word = game_dict[game_category][random.randint(0, len(game_dict[game_category])-1)] #Build a dashed "-" word to represent the game word blank_word = [] for letter in game_word: blank_word.append("-") print("Guess a " + str(len(game_word)) + " letter word from the following category: " + game_category.title()) guess = "" guess_count = 0 #A single round loop while guess != game_word: #Get a single guess from the user print("".join(blank_word)) guess = input("\nEnter your guess: ").lower() guess_count += 1 #Guess is correct, user won the game if guess == game_word: print("\nCorrect! You guessed the word in " + str(guess_count) + " guesses.") break #Guess is incorrect, user must keep guessing else: print("That is not correct. let us reveal a letter to help you!") #Loop to replace "-" in blank_word to reveal a letter to help user swapping = True while swapping: letter_index = random.randint(0, len(game_word)-1) if blank_word[letter_index] == "-": blank_word[letter_index] = game_word[letter_index] swapping = False #Ask the user to play again choice = input("\nWould you like to play again (y/n): ").lower() Page 117 61 62 63 if choice != 'y': playing = False print("Thank you for playing the game.") Return to index Page 118 While Loops Challenge 30: Power Ball Simulator App Description: You are responsible for writing a program that simulates the Power Ball Lottery. The traditional power ball is played by randomly choosing 5 white balls numbered 1 through 69 then randomly choosing 1 red ball numbered 1 through 26. The traditional power ball has astronomically low odds of winning. Therefore, your program will allow users to adjust the odds by setting how many balls the lottery will choose from. Your program will then calculate the odds the user has of winning. The user will purchase tickets in a set interval, without purchasing repeated losing tickets, until they either win the lottery or choose to give up. Step By Step Guide: ● Print a welcome message as formatted below. ● ● ● ● The normal Power Ball Lottery chooses 5 random white balls numbered 1 through 69. Once a ball is chosen, it cannot be chosen again. Using all 69 balls will make winning the lottery nearly impossible. Therefore, we want to give the user the option to set how many white balls they will pick from. Get user input for the number of white balls to use. ○ Store this user input in a variable called white_balls. ● If the user entered a number less than 5, set the value of white_balls to five. ○ This ensures that we have enough numbers to choose from. ● ● ● Similarly, the red Power Ball is normally chosen from red balls numbered 1 through 26. We want to give the user the option to set how many red balls they will pick from. Get user input for the number of red balls to use. ○ Store this input in a variable called red_balls. ● If the user entered a number less than 1, set the value of red_balls to one. ○ This ensures we have at least one power ball. ● ● Generate the odds the user will win this specific lottery. Create a variable called odds and set it equal to 1. ○ You will use this variable to perform repeated multiplication. Use a for loop to loop an appropriate number of times to perform the correct multiplication. Your for loop should be a numerical for loop such as for i in range(5): ○ For example, if the user wanted 69 white balls and 26 red balls the odds would be calculated as follows: (69*68*67*66*65)*26/120. ○ For example, if the user wanted 20 white balls and 4 red balls the odds would be calculated as follows: (20*19*18*17*16)*4/120. ○ Try to determine the relationship between the number of white balls used, the value of i in the for loop, and the terms being multiplied together to get the odds. Determine the odds for any specific lottery given and print the odds to the user. ● ● Page 119 ● ● We will allow users to purchase tickets in a set interval. Get user input for how many tickets they would like to purchase in each interval. ○ Store this input in a variable called ticket_interval. ● ● Next, we need to simulate creating the winning lotto numbers. Each lottery ball will be represented by a random integer. ○ Type import random as the first line of code in your program. Create a blank list called winning_numbers. ● ● Generate the numbers to represent the white balls. ○ While there are less than 5 values in winning_numbers: ■ Generate a random integer from 1 up to the users value of white_balls. ■ If the integer does not already appear in the list winning_numbers: ● Append the integer to the list winning_numbers. We cannot have repeated values. ● Permanently sort the list winning_numbers. ● Generate the number to represent the red power ball. ○ Generate a random integer from 1 up to the users value of red_balls. ○ Append this to the end of the list winning_numbers. ○ Do not sort the list as the red power ball is always at the end of the winning numbers. ● You now have a list of numbers, winning_numbers that represent the winning Power Ball numbers; 5 numbers that are ordered and then one final Power Ball number added at the end. ○ For example [10, 22, 24, 54, 67, 3] ● ● ● Now, simulate the actual Power Ball drawing. Print a welcome message as formatted below. Display the winning power ball numbers all on one line as formatted below. ○ Use the end= argument. Prompt the user to press enter to being purchasing tickets. ● ● ● ● Create a variable called tickets_purchased and set it equal to 0. ○ This will keep track of how many tickets have been created. ○ Every time your while loop runs you should increment this by 1. Create a flag variable called active and set it to True. ○ This variable will stay True as long as the user wants to continue to purchase tickets. After, the number of tickets stored in ticket_interval have been created, ask the user if they want to purchase more. If they do not, set this variable to False. Create a blank list called tickets_sold. ○ This will keep track of every ticket that has been sold. Page 120 ○ ● Use a while loop that will continue to run until a winning ticket is picked or user wants to stop wasting their money. This loop needs to check two conditions: The winning ticket has not been sold and the user still wants to play. ○ Create a blank list called lottery_numbers which will hold the current lottery numbers of a ticket that is being purchased. ■ Once the ticket is created and determined to be a loser, you can use this same variable for the next ticket. ○ Simulate picking a lottery ticket. ■ You should do this in a similar manner to picking the actual power ball numbers. Pick 5 numbers, sort them, and then add a 6th. ○ If this current ticket is not in your list of tickets sold: ■ Increase the number of purchased tickets by 1. ■ Add it to the list of tickets sold, ■ Print the ticket as a list. ○ Else: ■ Print a message that a losing ticket was generated that has already been purchased and that the ticket is being disregarded. ○ ● ● ● ● ● ● ● We will use this list to make sure that we don't purchase a losing ticket more than once. After picking the number of tickets in ticket_interval, which can be checked using modulo division: ■ Print the total number of tickets purchased. ■ Get user input for if they would like to continue purchasing tickets. ■ If the user does not want to continue: ● Set your flag variable to False The while loop will end either by purchasing the winning ticket or by giving up. If the current lottery ticket is equal to the winning ticket: ○ You won the lottery! ○ Print the winning ticket numbers. ○ Print the total number of tickets purchased. Else: ○ You didn’t win the lottery. ○ Print how many tickets were purchased. Use at least 2 comments to describe sections of your code. “Chunk” your code so that is readable. Use appropriate and informative variable names. Format your output as below. Example Output 1: --------------------Power-Ball Simulator-------------------- Page 121 How many white-balls to draw from for the 5 winning numbers (Normally 69): 7 How many red-balls to draw from for the Power-Ball (Normally 26): 1 You have a 1 in 21.0 chance of winning this lottery. Purchase tickets in what interval: 5 ---------Welcome to the Power-Ball----------Tonight's winning numbers are: 1 2 3 5 7 1 Press 'Enter' to begin purchasing tickets!!! [2, 3, 5, 6, 7, 1] [1, 3, 4, 5, 6, 1] [1, 2, 4, 5, 6, 1] [1, 3, 4, 5, 7, 1] Losing ticket generated; disregard... [1, 2, 5, 6, 7, 1] 5 tickets purchased so far with no winners... Keep purchasing tickets (y/n): y [1, 4, 5, 6, 7, 1] [1, 3, 5, 6, 7, 1] [1, 2, 3, 5, 7, 1] Winning ticket numbers: 1 2 3 5 7 1 Purchased a total of 8 tickets. Example Output 2: --------------------Power-Ball Simulator-------------------How many white-balls to draw from for the 5 winning numbers (Normally 69): 69 How many red-balls to draw from for the Power-Ball (Normally 26): 26 You have a 1 in 292201338.0 chance of winning this lottery. Purchase tickets in what interval: 20 ---------Welcome to the Power-Ball----------Tonight's winning numbers are: 31 37 55 57 61 12 Press 'Enter' to begin purchasing tickets!!! [11, 36, 40, 50, 52, 10] [8, 20, 45, 49, 51, 14] [35, 42, 57, 60, 67, 3] [19, 21, 28, 53, 67, 12] [5, 17, 22, 59, 67, 18] Page 122 [1, 3, 12, 15, 50, 17] [18, 44, 45, 54, 66, 24] [6, 33, 47, 55, 61, 16] [28, 35, 36, 47, 52, 5] [7, 9, 37, 42, 57, 24] [12, 14, 21, 56, 60, 18] [20, 52, 55, 62, 69, 16] [11, 38, 41, 61, 63, 17] [5, 24, 25, 33, 37, 7] [36, 38, 44, 51, 62, 15] [20, 23, 59, 60, 66, 20] [4, 9, 23, 29, 33, 21] [11, 14, 35, 36, 60, 3] [7, 19, 48, 50, 68, 26] [6, 24, 27, 37, 58, 18] 20 tickets purchased so far with no winners... Keep purchasing tickets (y/n): y [4, 8, 14, 22, 68, 16] [3, 24, 34, 41, 57, 12] [30, 36, 39, 40, 59, 16] [6, 23, 33, 34, 50, 26] [1, 19, 54, 60, 61, 23] [1, 35, 43, 52, 54, 13] [3, 6, 7, 37, 50, 13] [2, 6, 22, 28, 47, 25] [6, 19, 46, 55, 60, 5] [8, 44, 50, 52, 61, 2] [39, 44, 52, 54, 64, 17] [16, 19, 24, 27, 49, 13] [18, 24, 27, 34, 68, 12] [15, 19, 27, 44, 57, 23] [40, 42, 47, 55, 65, 10] [13, 30, 36, 45, 59, 17] [4, 16, 22, 28, 57, 2] [17, 27, 51, 65, 66, 14] [7, 15, 22, 43, 53, 4] [11, 18, 20, 30, 53, 21] 40 tickets purchased so far with no winners... Keep purchasing tickets (y/n): n You bought 40 tickets and still lost! Better luck next time! Page 123 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 #While Loops Challenge 30: import random Power Ball Simulator App print("---------------------Power Ball Simulator---------------------") #Determine the size of the lottery #Get the number of white-balls white_balls = int(input("How many white-balls to draw from for the 5 winning numbers (Normally 69): ")) if white_balls < 5: white_balls = 5 #Get the number of red-balls red_balls = int(input("How many red-balls to draw from for the Power Ball (Normally 26): ")) if red_balls < 1: red_balls = 1 #Calculate the odds of winning this specific lottery odds = 1 for i in range(5): #Example multiplication for generating odds to win #(69*68*67*66*65)*26/120 normal power ball #(20*19*18*17*16)*4/120 20 white balls, 4 red balls odds *= white_balls - i odds *= red_balls/120 print("You have a 1 in " + str(odds) + " chance of winning this lottery.") #Get ticket interval ticket_interval = int(input("Purchase tickets in what interval: ")) #Generate the winning lottery numbers #Get the white-balls for the ticket winning_numbers = [] while len(winning_numbers) < 5: number = random.randint(1, white_balls) if number not in winning_numbers: winning_numbers.append(number) winning_numbers.sort() #Get the red-ball for the ticket number = random.randint(1, red_balls) winning_numbers.append(number) #Simulate the power ball drawing print("\n----------Welcome to the Power Ball----------") print("\nTonight's winning numbers are: ", end="") for number in winning_numbers: print(str(number), end=' ') input("\nPress 'Enter' to begin purchasing tickets!!!") #initialize variables to aid in the selling of tickets tickets_purchased = 0 active = True tickets_sold = [] #Run the lottery if we haven't purchased the winning ticket and we still want to play while winning_numbers not in tickets_sold and active == True: #Make a new lottery ticket for the user to buy lottery_numbers = [] #Get the white-balls for the ticket while len(lottery_numbers) < 5: Page 124 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 number = random.randint(1, white_balls) if number not in lottery_numbers: lottery_numbers.append(number) lottery_numbers.sort() #Get the red-ball for the ticket number = random.randint(1, red_balls) lottery_numbers.append(number) #This current ticket has not yet been sold if lottery_numbers not in tickets_sold: tickets_purchased += 1 tickets_sold.append(lottery_numbers) print(lottery_numbers) #The ticket has already been sold and is a loser; don't sell again else: print("Losing ticket generated; disregard...") #Check if the user wants to continue buying tickets at the indicated interval if tickets_purchased % ticket_interval == 0: print(str(tickets_purchased) + " tickets purchased so far with no winners...") choice = input("\nKeep purchasing tickets (y/n): ") if choice != 'y': active = False #The lottery is now over #We purchased the winning ticket and we won the lottery if lottery_numbers == winning_numbers: print("\nWinning ticket numbers: ", end='') for number in lottery_numbers: print(str(number), end=' ') print("\nPurchased a total of " + str(tickets_purchased) + " tickets.") #We didn't purchase the winning ticket and we gave up else: print("\nYou bought " + str(tickets_purchased) + " tickets and still lost!") print("Better luck next time!") Return to index Page 125 Functions Challenge 31: The Python Dice App Description: You are responsible for writing a program that will roll a given number of dice of any number of sides and sum the total. Your program will continue to run until the user desires to quit. Step By Step Guide: Defining your functions: ● Define a function dice_sides() which takes zero parameters. ○ Get user input for how many sides their dice should have. ○ Return this value. ● Define a function dice_number() which takes zero parameters. ○ Get user input for how many dice they would like to roll. ○ Return this value. ● Define a function roll_dice() which takes in two parameters, the number of sides on the dice, and the number of dice to roll. ○ This function should simulate rolling the dice and store the values in a list. ○ Define a blank list called dice. ○ Print a message informing how many n sided dice the user rolled. ○ Roll the correct number of dice. ○ To roll a die, create a random integer from 1 up to the number of sides on the dice. ■ Type import random as the first line of code in your program. ○ Append this die value to your list. ○ When you have rolled all of the dice, return the list. ● Define a function sum_dice() which takes in one parameter, a list holding all the dice values. ○ This function should sum all the dice in the list. ○ Print the value of the sum. ○ There is no return value for this function. ● Define a function roll_again() which takes zero parameters. ○ Get user input for if they would like to roll again. ○ This can be a y or n value. ○ Return an appropriate Boolean (True or False) based on their response. ○ Use this return value to control a while loop running the app. Your main code: ● Print a welcome message. ● Create an active flag variable and set it to True. ● Use this flag to control a while loop. Page 126 ● ● Run your program to simulate a dice application. Your program should do the following: ○ Create the desired dice by calling the dice_sides() and dice_number() functions. ○ Roll the dice by calling the roll_dice() function. ○ Sum the dice by calling the sum_dice() function. ○ Ask the user if they would like to continue by calling the roll_again() function. ○ When the user wants to stop the program print a goodbye message. ● ● ● ● Use at least 2 comments to describe sections of your code. “Chunk” your code so that is readable. Use appropriate and informative variable names. Format your output as below. Example Output : Welcome to the Python Dice App How many sides would you like on your dice: 6 How many dice would you like to roll: 4 You rolled 4 6 sided dice. -----Results are as followed----3 5 2 4 The total value of your roll is 14. Would you like to roll again (y/n): y How many sides would you like on your dice: 20 How many dice would you like to roll: 5 You rolled 5 20 sided dice. -----Results are as followed----20 7 16 20 13 The total value of your roll is 76. Page 127 Would you like to roll again (y/n): n Thank you for using the Python Dice App. Page 128 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 #Functions Challenge 31: import random The Python Dice App def dice_sides(): """Ask the user how many sides on their die""" sides = int(input("\nHow many sides would you like on your dice: ")) return sides def dice_number(): """Ask the user how many dice to roll""" number = int(input("How many dice would you like to roll: ")) return number def roll_dice(sides, number): """Simulate rolling the dice""" dice = [] print("\nYou rolled " + str(number) + " " + str(sides) + " sided dice.") print("\n-----Results are as followed-----") for i in range(number): value = random.randint(1, sides) print("\t" + str(value)) dice.append(value) return dice def sum_dice(dice): """Add all values of dice in a list""" #Using built in sum() function #print("The total value of your roll is " + str(sum(dice)) + ".") #Using our own method. total = 0 for die in dice: total += die print("The total value of your roll is " + str(total) + ".") def roll_again(): """Ask the user to roll again""" choice = input("\nWould you like to roll again (y/n): ").lower() if choice != 'y': roll = False else: roll = True return roll #The main code print("Welcome to the Python Dice App") rolling = True while rolling: #Get the info for the type of dice d_sides = dice_sides() d_number = dice_number() #Roll and sum the dice my_dice = roll_dice(d_sides, d_number) sum_dice(my_dice) #Roll again rolling = roll_again() print("\nThank you for using the Python Dice App.") Return to index Page 129 Functions Challenge 32: The Python Calculator App Description: You are responsible for writing a program that simulates a calculator application that will take in any two numbers, and a basic mathematical operation (addition, subtraction, multiplication, division, or exponentiation), perform that operation, print a lexical statement of the operation, and return a mathematical statement that describes the mathematical results. Upon completion, your program will print out a history of all calculations performed including any error messages that may have occurred such as division by zero. Step By Step Guide: Defining your functions: ● Define a function add() which takes two parameters, the two numbers you would like to add. ○ Perform the appropriate arithmetic rounded to 4 decimals. ○ Print a lexical statement describing the operation using the word sum. ○ Return a mathematical statement such as "4 + 2 = 6" based off the numbers provided as arguments. ● Define a function subtract() which takes two parameters, the two numbers you would like to subtract. ○ Perform the appropriate arithmetic rounded to 4 decimals. ○ Print a lexical statement describing the operation using the word difference. ○ Return a mathematical statement such as "4 - 2 = 2" based off the numbers provided as arguments. ● Define a function multiply() which takes two parameters, the two numbers you would like to multiply. ○ Perform the appropriate arithmetic rounded to 4 decimals. ○ Print a lexical statement describing the operation using the word product. ○ Return a mathematical statement such as "5 * 8 = 40" based off the numbers provided as arguments. ● Define a function divide() which takes two parameters, the two numbers you would like to divide. ○ If the 2nd parameter is not equal to zero: ■ Perform the appropriate arithmetic rounded to 4 decimals. ■ Print a lexical statement describing the operation using the word quotient. ■ Return a mathematical statement such as "10 / 2 = 5" based off the numbers provided as arguments. ○ Else if the 2nd parameter is zero: ■ Print a message stating that you cannot divide by zero. ■ Return an error message such as “DIV ERROR”. Page 130 ● Define a function exponent() which takes two parameters, the two numbers you would like to use in your exponential. ○ Perform the appropriate arithmetic rounded to 4 decimals. ○ Print a lexical statement describing the operation using the words “raised to the power of”. ○ Return a mathematical statement such as " 2 ** 3 = 8" based off the numbers provided as arguments. Your main code: ● Print a welcome message. ● Create a blank list called history. ● ● ● Create an active flag variable and set it to True. Use this variable to control a while loop. Get user input for two numbers and an operation. ○ Allow the user to enter in either the operation name or a single letter. ■ For example, the following input should result in a call to the addition function: addition, Addition, ADDITION, A, or a. ● Use an if, elif, else chain to make the appropriate function call depending on the users input. Append the return value from your function call to the list history. For an invalid operation such as square root, append an error message such as "OPP ERROR". ● ● ● ● ● Get user input for if they would like to continue the program. If not, print a summary of all calculations and errors performed. Print a thank you and end the program. ● ● ● ● Use at least 2 comments to describe sections of your code. “Chunk” your code so that is readable. Use appropriate and informative variable names. Format your output as below. Example Output: Welcome to The Python Calculator App Enter two numbers and an operation and the desired operation will be performed. Enter a number: 5 Enter a number: 8 Enter an operation (addition, subtraction, multiplication, division, or exponentiation): addition The sum of 5.0 and 8.0 is 13.0. Would you like to run the program again (y/n): y Page 131 Enter a number: 14 Enter a number: 22 Enter an operation (addition, subtraction, multiplication, division, or exponentiation): s The difference of 14.0 and 22.0 is -8.0. Would you like to run the program again (y/n): y Enter a number: 3.25 Enter a number: .6 Enter an operation (addition, subtraction, multiplication, division, or exponentiation): Multiplication The product of 3.25 and 0.6 is 1.95. Would you like to run the program again (y/n): y Enter a number: 4 Enter a number: 0 Enter an operation (addition, subtraction, multiplication, division, or exponentiation): D You cannot divide by zero. Would you like to run the program again (y/n): y Enter a number: 4 Enter a number: 2.5 Enter an operation (addition, subtraction, multiplication, division, or exponentiation): d The quotient of 4.0 and 2.5 is 1.6. Would you like to run the program again (y/n): y Enter a number: 5 Enter a number: 15 Enter an operation (addition, subtraction, multiplication, division, or exponentiation): square root That is not a valid operation. Try again. Would you like to run the program again (y/n): y Enter a number: 4 Enter a number: 3 Enter an operation (addition, subtraction, multiplication, division, or exponentiation): exponentiation The result of 4.0 raised to the 3.0 power is 64.0. Would you like to run the program again (y/n): n Calculation Summary: 5.0 + 8.0 = 13.0 14.0 - 22.0 = -8.0 3.25 * 0.6 = 1.95 DIV ERROR 4.0 / 2.5 = 1.6 OPP ERROR Page 132 4.0 ** 3.0 = 64.0 Thank you for using The Python Calculator App. Goodbye. Page 133 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 #Functions Challenge 32: The Python Calculator App def add(a, b): """Add two numbers and return the sum""" summation = round(a+b, 4) print("The sum of " + str(a) + " and " + str(b) + " is " + str(summation) + ".") return str(a) + " + " + str(b) + " = " + str(summation) def subtract(a, b): """Subtract two numbers and return the difference""" difference = round(a-b, 4) print("The difference of " + str(a) + " and " + str(b) + " is " + str(difference) + ".") return str(a) + " - " + str(b) + " = " + str(difference) def multiply(a, b): """Multiply two numbers and return the product""" product = round(a*b, 4) print("The product of " + str(a) + " and " + str(b) + " is " + str(product) + ".") return str(a) + " * " + str(b) + " = " + str(product) def divide(a, b): """Divide two numbers and return the quotient""" #Perform the division if the denominator is not zero if b != 0: quotient = round(a/b, 4) print("The quotient of " + str(a) + " and " + str(b) + " is " + str(quotient) + ".") return str(a) + " / " + str(b) + " = " + str(quotient) #Denominator is zero, result in error else: print("You cannot divide by zero.") return "DIV ERROR" def exponent(a, b): """Take a number to a power and return the result""" power = round(a**b, 4) print("The result of " + str(a) + " raised to the " + str(b) + " power is " + str(power) + ".") return str(a) + " ** " + str(b) + " = " + str(power) #The main code print("Welcome to the Python Calculator App") print("Enter two numbers and an operation and the desired operation will be performed.") history = [] running = True while running: #Get user input num1 = float(input("\nEnter a number: ")) num2 = float(input("Enter a number: ")) operator = input("Enter an operation (addition, subtraction, multiplication, division, or exponentiation): ").lower()\ #Call the appropriate function based on the value of operator Page 134 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 if operator == 'addition' or operator == 'a': result = add(num1, num2) elif operator == 'subtraction' or operator == 's': result = subtract(num1, num2) elif operator == 'multiplication' or operator == 'm': result = multiply(num1, num2) elif operator == 'division' or operator == 'd': result = divide(num1, num2) elif operator == 'exponentiation' or operator == 'e': result = exponent(num1, num2) else: print("That is not a valid operation. Try again.") result = "OPP ERROR" #Append the mathematical result to the history history.append(result) #Allow user to quit choice = input("Would you like to run the program again (y/n): ").lower() if choice != 'y': print("\nCalculation Summary: ") for calc in history: print(calc) print("\nThank you for using the Python Calculator App. Goodbye.") running = False Return to index Page 135 Functions Challenge 33: Bank Deposit and Withdrawal App Description: You are responsible for writing a program that will simulate an online banking application. A user will create an account with your fictitious bank. The account will include a savings account and a checking account. Users will then be able to make deposits or withdrawals from either account as long as the remaining balance is non negative. Step By Step Guide: Define your functions: ● Define a function get_info() which will take zero parameters. ○ Print a welcome message. ○ Get user input for their name. ○ Get user input for an initial deposit into their savings account. ○ Get user input for an initial deposit into their checking account. ○ Create a dictionary that has three key-value pairs. ■ Each input from the user should be a value that is paired with a corresponding key. ○ Return the dictionary. ● Define a function make_deposit() which will take three parameters; a dictionary representing a bank account, a string which will represent a type of account (savings or checking) and a float representing how much money to deposit to the account. ○ Update the correct key-value pair in the dictionary to add the given amount of money to the correct account. ○ Print a message confirming this update. ○ There is no need to return our dictionary since it is a mutable object and can be changed right inside of the function. ● Define a function make_withdrawal() which will take three parameters; a dictionary representing a bank account, a string which will represent a type of account (savings or checking) and a float representing how much money to withdraw from the account. ○ If the account will have a positive balance after the transaction: ■ Update the correct key-value pair in the dictionary to subtract the given amount of money to the correct account. ■ Print a message confirming this update. ○ Else, the account has a negative balance. ■ Do not update the account. ■ Print a message that the user will have a negative balance and therefore no transaction has occurred. ○ There is no need to return our dictionary since it is a mutable object and can be changed right inside of the function. Page 136 ● Define a function display_info() which will take one parameter; a dictionary representing a bank account. ○ Print all the information in the given dictionary. ○ There is no return value for this function. Your main code: ● Create an account by calling the get_info() function. ● ● Create a flag variable and set it to True. Use this variable with a while loop to. Each iteration you should: ○ Display the current account information by calling the dispaly_info() function. ○ Get user input for the type of account they would like to access. ○ Get user input for the type of transaction they would like to make. ○ Get user input for how much money they wish to work with. ○ If the given account type is either savings or checking: ■ If the transaction is either deposit or withdrawal: ● Call the appropriate function representing the transaction. ■ Else, print a message stating that the transaction cannot be completed. ○ Else, print a message stating that the transaction cannot be completed. ○ Get user input for if they would like to make another transaction. ■ If they do not: ● Display the current account information by calling the display_info() function. ● Print a thank you message and end the program. ● ● ● ● Use at least 2 comments to describe sections of your code. “Chunk” your code so that is readable. Use appropriate and informative variable names. Format your output as below. Example Output: Welcome to the Python First National Bank. Hello, what is your name: john james How much money would you like to set up your savings account with: 1200 How much money would you like to set up your checking account with: 300 Current Account Information: Name: John James Savings: $1200 Checking: $300 What account would you like to access (Savings or Checking): savings What type of transaction would you like to make (Deposit or Withdrawal): deposit How much money: 150 Page 137 Deposited $150 into John James's savings account. Would you like to make another transaction (y/n): y Current Account Information: Name: John James Savings: $1350 Checking: $300 What account would you like to access (Savings or Checking): SAVINGS What type of transaction would you like to make (Deposit or Withdrawal): withdrawal How much money: 50 Withdrew $50 from John James's savings account. Would you like to make another transaction (y/n): y Current Account Information: Name: John James Savings: $1300 Checking: $300 What account would you like to access (Savings or Checking): Checking What type of transaction would you like to make (Deposit or Withdrawal): WITHDRAWAL How much money: 500 Sorry, by withdrawing $500 you will have a negative balance. Would you like to make another transaction (y/n): y Current Account Information: Name: John James Savings: $1300 Checking: $300 What account would you like to access (Savings or Checking): credit What type of transaction would you like to make (Deposit or Withdrawal): deposit How much money: 40 I'm sorry, we cannot do that for you today. Would you like to make another transaction (y/n): y Current Account Information: Name: John James Savings: $1300 Checking: $300 Page 138 What account would you like to access (Savings or Checking): savings What type of transaction would you like to make (Deposit or Withdrawal): d How much money: 550 I'm sorry, we cannot do that for you today. Would you like to make another transaction (y/n): n Thank you. Have a great day! Page 139 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 #Functions Challenge 33: Bank Deposit and Withdrawal App def get_info(): """Get user information to store in a dict that represents a bank account""" print("Welcome to the Python First National Bank.") #Get user input name = input("\nHello, what is your name: ").title().strip() savings = int(input("How much money would you like to set up your savings account with: ")) checking = int(input("How much money would you like to set up your checking account with: ")) #Build a dict that represents a specific bank account bank_account = { "Name":name, "Savings":savings, "Checking":checking, } return bank_account def make_deposit(bank_account, account, money): """Add money to a specific type of account""" bank_account[account] += money print("\nDeposited $" + str(money) + " into " + bank_account['Name'] + "'s " + account.lower() + " account.") def make_withdrawal(bank_account, account, money): """Withdraw money from a specific type of account""" #Check that the balance will still be positive after the withdrawal if bank_account[account] - money >= 0: bank_account[account] -= money print("\nWithdrew $" + str(money) + " from " + bank_account['Name'] + "'s " + account.lower() + " account.") #Not enough money in the account to make the withdrawal else: print("\nSorry, by withdrawing $" + str(money) + " you will have a negative balance.") def display_info(bank_account): """Display all key-value pairs in a given bank account""" print("\nCurrent Account Information") for key, value in bank_account.items(): if key == 'Name': print(key + ": " + str(value)) else: print(key + ": $" + str(value)) #The main code #Create a bank account my_account = get_info() running = True while running: #Show the current state of the bank account display_info(my_account) #Get user input for the transaction information account_type = input("\nWhat account would you like to access (Savings or Checking): ").title() Page 140 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 choice = input("What type of transaction would you like to make (Deposit or Withdrawal): ").title() amount = float(input("How much money: ")) #Make the correct function call based off previous user input if account_type == "Savings" or account_type == "Checking": if choice == "Deposit": make_deposit(my_account, account_type, amount) elif choice == "Withdrawal": make_withdrawal(my_account, account_type, amount) else: print("\nI'm sorry, we cannot do that for you today.") else: print("\nI'm sorry, we cannot do that for you today.") #Allow users to make another transaction choice = input("Would you like to make another transaction (y/n): ").lower() if choice != 'y': display_info(my_account) print("\nThank you. Have a great day!") running = False Return to index Page 141 Functions Challenge 34: Head to Head Tic-Tac-Toe App Description: You are responsible for writing a program that will allow two users to play a game of tic tac toe. Your program should follow the standard rules in which two players alternate turns putting their pieces, X or O, on a board. If a player has three pieces in a row, either vertically, horizontally, or diagonally, they are declared the winner. You will represent the tic tac toe board using the integers 1 through 9 for the 9 spaces on the board. An empty spot on the board will be represented by an underscore “_”. For example, if a player would like to put a piece in the center of the board they would enter 5 as their move. Tic-Tac-Toe ~~~~~~~~~ || 1 || 2 || 3 || ~~~~~~~~~ || 4 || 5 || 6 || ~~~~~~~~~ || 7 || 8 || 9 || ~~~~~~~~~ Tic-Tac-Toe ~~~~~~~~~ || _ || _ || _ || ~~~~~~~~~ || _ || _ || _ || ~~~~~~~~~ || _ || _ || _ || ~~~~~~~~~ Step By Step Guide: Defining your functions ● Define a function draw_board() which takes one parameter; a list holding all of the current pieces on the tic tac toe board. ○ To draw the tic tac toe board for the current state of the game use a print statement to print out each individual row of the tic tac toe board. ○ The elements that take up the spots on the board should either be X, O, or _ which indicates that the spot is empty. ○ Print each element from the list at its correct location on the board. ○ There is no return value for this function. ● Define a function get_player_input() which takes two parameters, the player’s character and a list holding all of the current pieces on the tic tac toe board. Page 142 ○ ○ ○ ○ ○ Use a while loop to loop until the player the player gives an appropriate move. Get user input for where they would like to place their piece. If the given move is a space on the board: ■ If the space on the board does not currently have a piece there: ● Return the move. ■ Else, inform the player that the spot has already been chosen. Else, inform the user that their move is not a spot on the board. You are looping through this function until you hit the return statement which will return the users move. ● Define a function place_char_on_board() which takes three parameters; the player’s character, the player’s desired move, and a list holding all of the current pieces on the tic tac toe board. ○ To simulate putting the players character on the board at the correct spot put the player’s character in the list holding all the current pieces on the tic tac toe board at the index that corresponds to the spot chosen by the player. ○ There is no return for this function as we are directly changing our list. ● Define a function is_winner() which takes two parameters; A list holding all of the current pieces on the tic tac toe board and the player’s character. ○ There are eight different ways you can win tic tac toe; 3 vertical, 3 horizontal, and 2 diagonal. ○ Use compound conditional statements to check for victory. ○ For example, if a player has their piece at position 1 and position 2 and position 3 then they have won. ○ Return a Boolean, True or False value based on whether or not a player has won. Your main code: ● Create a variable player_1 and set it equal to “X”. ● Create a variable player_2 and set it equal to “O”. ● ● ● Create a list called c_list and set it equal to [‘_’]*9. ○ This will create a list of nine “_” which represent empty spots on the tic tac toe board. ○ As you play the game we will replace a “_” with the character of a player. ○ This is the list that will hold all of our moves throughout the game. Create a list called n_list and set it equal to the string values [“1”, “2”, “3”, … “8”, “9”]. ○ This list will give a visual representation for the player as to how to enter their moves. ○ For example, 1, 2, and 3 correspond to the first row, 4, 5, and 6 correspond to the second row, and 7, 8, and 9 correspond to the final row. To begin the game draw a board with the numbers representing each board position by calling the draw_board() function and passing the n_list as an argument. Page 143 ● Next, draw the current state of the board by calling the draw_board() function and passing the c_list as an argument. ● ● Use a while loop to play the game until there is a winner. Each iteration of your loop should do the following, first for player 1 then for player 2: ○ Get the player’s move by calling the get_player_input() function. ○ Update the c_list by calling the place_char_on_board() function. ○ Draw the number board by calling the draw_board() function. ○ Draw the current state of the game board by calling the draw_board() function. ○ Check to see if there is a winner by calling the is_winner() function. ■ If there is print a statement declaring who won. ■ Break the while loop. ○ Check to see if there are no more empty spots on the board. ■ If so, declare a tie. ● ● ● ● Use at least 2 comments to describe sections of your code. “Chunk” your code so that is readable. Use appropriate and informative variable names. Format your output as below. Example Output: Tic-Tac-Toe ~~~~~~~~~ || 1 || 2 || 3 || ~~~~~~~~~ || 4 || 5 || 6 || ~~~~~~~~~ || 7 || 8 || 9 || ~~~~~~~~~ Tic-Tac-Toe ~~~~~~~~~ || _ || _ || _ || ~~~~~~~~~ || _ || _ || _ || ~~~~~~~~~ || _ || _ || _ || ~~~~~~~~~ X: Where would you like to place your piece (1 - 9): 5 Tic-Tac-Toe ~~~~~~~~~ || 1 || 2 || 3 || ~~~~~~~~~ Page 144 || 4 || 5 || 6 || ~~~~~~~~~ || 7 || 8 || 9 || ~~~~~~~~~ Tic-Tac-Toe ~~~~~~~~~ || _ || _ || _ || ~~~~~~~~~ || _ || X || _ || ~~~~~~~~~ || _ || _ || _ || ~~~~~~~~~ O: Where would you like to place your piece (1 - 9): 5 That spot has already been chosen. Try again. O: Where would you like to place your piece (1 - 9): 15 That is not a spot on the board. Try again. O: Where would you like to place your piece (1 - 9): 3 Tic-Tac-Toe ~~~~~~~~~ || 1 || 2 || 3 || ~~~~~~~~~ || 4 || 5 || 6 || ~~~~~~~~~ || 7 || 8 || 9 || ~~~~~~~~~ Tic-Tac-Toe ~~~~~~~~~ || _ || _ || O || ~~~~~~~~~ || _ || X || _ || ~~~~~~~~~ || _ || _ || _ || ~~~~~~~~~ X: Where would you like to place your piece (1 - 9): 6 Tic-Tac-Toe ~~~~~~~~~ || 1 || 2 || 3 || ~~~~~~~~~ || 4 || 5 || 6 || ~~~~~~~~~ || 7 || 8 || 9 || Page 145 ~~~~~~~~~ Tic-Tac-Toe ~~~~~~~~~ || _ || _ || O || ~~~~~~~~~ || _ || X || X || ~~~~~~~~~ || _ || _ || _ || ~~~~~~~~~ O: Where would you like to place your piece (1 - 9): 9 Tic-Tac-Toe ~~~~~~~~~ || 1 || 2 || 3 || ~~~~~~~~~ || 4 || 5 || 6 || ~~~~~~~~~ || 7 || 8 || 9 || ~~~~~~~~~ Tic-Tac-Toe ~~~~~~~~~ || _ || _ || O || ~~~~~~~~~ || _ || X || X || ~~~~~~~~~ || _ || _ || O || ~~~~~~~~~ X: Where would you like to place your piece (1 - 9): 4 Tic-Tac-Toe ~~~~~~~~~ || 1 || 2 || 3 || ~~~~~~~~~ || 4 || 5 || 6 || ~~~~~~~~~ || 7 || 8 || 9 || ~~~~~~~~~ Tic-Tac-Toe ~~~~~~~~~ || _ || _ || O || ~~~~~~~~~ || X || X || X || Page 146 ~~~~~~~~~ || _ || _ || O || ~~~~~~~~~ Congratulations! Player 1 wins! Page 147 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 #Functions Challenge 34: Head to Head Tic Tac Toe App def draw_board(char_list): """Print a game board; either a number board or a tic tac toe print("\n\t Tic-Tac-Toe") print("\t~~~~~~~~~~~~~~~~~") print("\t|| " + char_list[0] + " || " + char_list[1] + " || " + " ||") print("\t~~~~~~~~~~~~~~~~~") print("\t|| " + char_list[3] + " || " + char_list[4] + " || " + " ||") print("\t~~~~~~~~~~~~~~~~~") print("\t|| " + char_list[6] + " || " + char_list[7] + " || " + " ||") print("\t~~~~~~~~~~~~~~~~~") board.""" + char_list[2] + char_list[5] + char_list[8] def get_player_input(player_char, char_list): """Get a players move until it is a valid move on the board with no piece currently there.""" while True: #Get user input player_move = int(input(player_char + ": Where would you like to place your piece (1-9): ")) #Move is on board if player_move > 0 and player_move < 10: #Move is an empty spot if char_list[player_move - 1] == '_': return player_move else: print("That spot has already been chosen. Try again.") else: print("That is not a spot on the board. Try again.") def place_char_on_board(player_char, player_move, char_list): """Put a players character at the correct spot on the board.""" char_list[player_move - 1] = player_char def is_winner(pC, cL): """Return a Bool if the given player return ((cL[0] == pC and cL[1] == pC (cL[3] == pC and cL[4] == pC row (cL[6] == pC and cL[7] == pC (cL[0] == pC and cL[3] == pC column (cL[1] == pC and cL[4] == pC column (cL[2] == pC and cL[5] == pC column (cL[0] == pC and cL[4] == pC 1 (cL[2] == pC and cL[4] == pC is a winner.""" and cL[2] == pC) or #victory in first row and cL[5] == pC) or #victory in second and cL[8] == pC) or #victory in last row and cL[6] == pC) or #victory in first and cL[7] == pC) or #victory in second and cL[8] == pC) or #victory in last and cL[8] == pC) or #victory in diagonal and cL[6] == pC)) #victory in diagonal 2 #The main code #Define variables player_1 = 'X' player_2 = 'O' c_list = ['_']*9 n_list = ['1', '2', '3', '4', '5', '6', '7', '8', '9'] Page 148 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 #Draw the initial state of the game board draw_board(n_list) draw_board(c_list) while True: #Player 1 turn #Get the players move move = get_player_input(player_1, c_list) #Put move on board place_char_on_board(player_1, move, c_list) #Re-draw game boards draw_board(n_list) draw_board(c_list) #Check to see if player 1 won if is_winner(player_1, c_list): print("Player 1 wins!") break #Check if there is a tie elif "_" not in c_list: print("The game was a tie!") break #Player 2 turn #Get the players move move = get_player_input(player_2, c_list) #Put move on board place_char_on_board(player_2, move, c_list) #Re-draw game boards draw_board(n_list) draw_board(c_list) #Check to see if player 1 won if is_winner(player_2, c_list): print("Player 2 wins!") break Return to index Page 149 Functions Challenge 35: Loan Calculator App Description: You are responsible for writing a program that gathers information about a loan such as starting principal, interest rate, and desired monthly payment. From this information, your program will first determine if it is possible to pay off the loan based on the desired monthly payment. If it is possible, your program will simulate making monthly payments until the loan is completely paid off. Your program will then display statistics such as how long it took to pay the loan off, the total amount spent on the loan, and the amount spent on interest. For simplicity, we will assume that the loan compounds once a month, or twelve times in a year. Upon completion of paying off the Loan, your program will make a graph showing the rate of change of the principal to time using the matplotlib library. Step By Step Guide: Defining your functions: ● Define a function get_loan_info() which takes zero parameters. ○ Create a blank dictionary called loan. ○ Get user input for a loan amount. ■ Store this response, as a float, as the value for the key 'principal' in the dictionary loan. ○ Get user input for an interest rate. ■ Store this response, as a float, as the value for the key 'rate' in the dictionary loan. ■ Divide the value of rate by 100 and update the value in the dictionary to turn an example rate of 4.25% into .0425. ○ Get user input for a desired monthly payment. ■ Store this response, as a float, as the value for the key 'monthly payment' in the dictionary loan. ○ Set a key value pair of 'money paid': 0 in the dictionary loan. ○ Return the dictionary loan. ● Define a function show_loan_info() which takes two parameters, a dictionary representing the current loan, and an integer representing the current number of months that have passed during payoff. ○ Print a status for the current loan information after n number of months have passed. ○ Loop through the dictionary to print all the information in the loan. ○ There is no return value for this function. ● Define a function collect_interest() which takes one parameter, a dictionary representing the current loan. ○ Update the value of the principal by taking the current value of the principal and adding the principal*rate/12. ■ We are dividing by 12 because there are 12 months in a year. Page 150 ○ ■ This simulates collecting interest monthly. There is no need to return our dictionary since it is a mutable object and can be changed right inside of the function. ● Define a function make_monthly_payment() which takes one parameter, a dictionary representing the current loan. ○ Update the value of the principal by taking the current value of the principal and subtracting the monthly payment. ○ If the principal is greater than zero, add the monthly payment amount to the money paid key of the loan dictionary. ■ This implies that you were required to make a full payment to the loan for the current month. ○ If the principal is less than zero, don't add a full monthly payment but rather, add the correct amount needed to pay off the loan to the money paid key of the loan dictionary. ■ This implies that on the last month, you were not required to make a full payment. ■ Verify that your principal is zero. ○ There is no need to return our dictionary since it is a mutable object and can be changed right inside of the function. ● Define a function summarize_loan() which takes three parameters, a dictionary representing the current loan, an integer representing the current month number, and a float representing the initial principal of a loan. ○ Print a results summary that summarizes the following: ■ The initial loan value. ■ How many months it took to pay off. ■ How much the user spent in total rounding to two decimals. ■ How much the user spent on interest rounding to two decimals. ○ There is no return value for this function. ● Define a function create_graph() which takes two parameters, a data set containing month number and principal, and a loan. ○ Create a variable x_values and set it equal to a blank list. ○ Create a variable y_values and set it equal to a blank list. ○ Recall that the data set is a list. Each element of the list is a tuple (month number, principal). Therefore, for each element of the list, the month number is at index 0 and principal is at index 1. ○ Loop through the data set. For each iteration: ■ Append the current month number to x_values. ■ Append the current principal to y_values. ○ Create a graph visualization of these two variables. This is outside the scope of traditional Python. To make a graph we must import an extra library of code. ■ Type from matplotlib import pyplot Page 151 ● ■ ■ ■ ■ ■ The matplotlib is pretty big. We don’t need all of it so we’ll only import the part we need; pyplot. Create a plot using our two lists representing month number and principal. ● pyplot.plot(x_values, y_values) Give the plot a descriptive title. ● pyplot.title(str(100*loan['rate']) + "% Interest" + " With $" + str(loan['monthly payment']) + " Monthly Payment") Label your x axis. ● pyplot.xlabel(“Month Number”) Label your y axis. ● pyplot.ylabel(“Principal of Loan”) Show the created graph. ● pyplot.show() Your main code: ● Print a welcome message. ● Create a variable named month_number and set it equal to 0. ● ● ● Create a loan by calling the get_loan_info() function. Create a variable named starting_principal and set it equal to the value of the principal on the loan before you begin collecting interest or paying it off. Create a variable data_to_plot and set it equal to a blank list. ● Show the loan information by calling the show_loan_info() function. ● ● Prompt the user to begin paying off the loan. While the loan is greater than 0: ○ If the loan’s current principal is greater than the starting_principal: ■ Use a break statement to end the loop. ■ You will never pay off the loan. ○ Increment the month number by 1. ○ Collect interest for the month by calling the collect_interest() function. ○ Make a monthly payment by calling the make_monthly_payment() function. ○ Append a tuple to the data_to_plot variable. ■ This tuple should have the current month number as its first index and the current loan principal as its second index. ○ Show the loan information by calling the show_loan_info() function. ● If the loan is paid off: ○ Summarize the loan information by calling the summarize_loan() function. ○ Create a graph showing the rate of change of the principal by calling the create_graph() function. Else: ● Page 152 ● ● ● ● ● ● The loan can never be paid off, meaning, the monthly payment is less than the interest collected. You have broken out of the while loop before the loan’s principal has reached zero. Print a message informing the user that the loan will never be paid off. Use at least 2 comments to describe sections of your code. “Chunk” your code so that is readable. Use appropriate and informative variable names. Format your output as below. Example Output 1: Welcome to the Loan Calculator App Enter the loan amount: 40000 Enter the interest rate: 5.5 Enter the desired monthly payment amount: 175 ----Loan information after 0 months---Principal: 40000.0 Rate: 0.055 Monthly Payment: 175.0 Money Paid: 0 Press 'enter' to begin paying off your loan. ----Loan information after 0 months---Principal: 40183.333333333336 Rate: 0.055 Monthly Payment: 175.0 Money Paid: 0 You will never pay off your loan!!! You cannot get ahead of the interest! :-( Example Output 2: Welcome to the Loan Calculator App Enter the loan amount: 10000 Enter the interest rate: 4.25 Enter the desired monthly payment amount: 250 ----Loan information after 0 months---Principal: 10000.0 Rate: 0.0425 Monthly Payment: 250.0 Money Paid: 0 Page 153 Press 'enter' to begin paying off your loan. ----Loan information after 1 months---Principal: 9785.416666666666 Rate: 0.0425 Monthly Payment: 250.0 Money Paid: 250.0 ----Loan information after 2 months---Principal: 9570.073350694443 Rate: 0.0425 Monthly Payment: 250.0 Money Paid: 500.0 ----Loan information after 3 months---Principal: 9353.967360478153 Rate: 0.0425 Monthly Payment: 250.0 Money Paid: 750.0 ----Loan information after 4 months---Principal: 9137.095994879846 Rate: 0.0425 Monthly Payment: 250.0 Money Paid: 1000.0 ***CUT FOR BREVITY*** ----Loan information after 42 months---Principal: 301.15895867815243 Rate: 0.0425 Monthly Payment: 250.0 Money Paid: 10500.0 ----Loan information after 43 months---Principal: 52.22556332347091 Rate: 0.0425 Monthly Payment: 250.0 Money Paid: 10750.0 ----Loan information after 44 months---Principal: 0 Rate: 0.0425 Monthly Payment: 250.0 Money Paid: 10802.410528860242 Page 154 Congratulations! You paid off your loan in 44 months! Your initial loan was $10000.0 at a rate of 4.25%. Your monthly payment was $250.0 You spent $10802.41 total. You spent $802.41 on interest! Example Output 3: Welcome to the Loan Calculator App Enter the loan amount: 155000 Enter the interest rate: 4.25 Enter the desired monthly payment amount: 650 ----Loan information after 0 months---Principal: 155000.0 Rate: 0.0425 Monthly Payment: 650.0 Money Paid: 0 Press 'enter' to begin paying off your loan. ----Loan information after 1 months---Principal: 154898.95833333334 Rate: 0.0425 Monthly Payment: 650.0 Money Paid: 650.0 ----Loan information after 2 months---Principal: 154797.5588107639 Rate: 0.0425 Monthly Payment: 650.0 Page 155 Money Paid: 1300.0 ----Loan information after 3 months---Principal: 154695.80016488535 Rate: 0.0425 Monthly Payment: 650.0 Money Paid: 1950.0 *** CUT FOR BREVITY *** ----Loan information after 525 months---Principal: 979.1289480172211 Rate: 0.0425 Monthly Payment: 650.0 Money Paid: 341250.0 ----Loan information after 526 months---Principal: 332.596696374782 Rate: 0.0425 Monthly Payment: 650.0 Money Paid: 341900.0 ----Loan information after 527 months---Principal: 0 Rate: 0.0425 Monthly Payment: 650.0 Money Paid: 342233.7746430078 Congratulations! You paid off your loan in 527 months! Your initial loan was $155000.0 at a rate of 4.25%. Your monthly payment was $650.0 You spent $342233.77 total. You spent $187233.77 on interest! Page 156 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 #Functions Challenge 35: Loan Calculator App from matplotlib import pyplot def get_loan_info(): """Get the basic information of a loan and store it in a dictionary""" #Create a blank dict to represent a loan loan = {} #Get user input for the categories of the loan loan['principal'] = float(input("Enter the loan amount: ")) loan['rate'] = float(input("Enter the interest rate: "))/100 loan['monthly payment'] = float(input("Enter the desired monthly payment amount: ")) loan['money paid'] = 0 return loan def show_loan_info(loan, number): """Display the current loan status""" print("\n----Loan information after " + str(number) + " months----") for key, value in loan.items(): print(key.title() + ": " + str(value)) def collect_interest(loan): """Update loan for interest per month""" #Divide by 12 to simulate collecting interest monthly loan['principal'] = loan['principal'] + loan['principal']*loan['rate']/12 def make_monthly_payment(loan): """Simulate making a monthly payment to pay down the principal""" loan['principal'] = loan['principal'] - loan['monthly payment'] #You are required to make a full payment this month, you have not yet payed off your loan if loan['principal'] > 0: loan['money paid'] += loan['monthly payment'] #You are not required to make a full payment this month, you have payed off your loan else: #For this else block, loan['principal'] will be negative loan['money paid'] += loan['monthly payment'] + loan['principal'] loan['principal'] = 0 def summarize_loan(loan, number, initial_principal): """Display the results of paying off the loan""" print("\nCongraulations! You paid off your loan in " + str(number) + " months!") print("Your initial loan was $" + str(initial_principal) + " at a rate of " + str(100*loan['rate']) + "%.") print("Your monthly payment was $" + str(loan['monthly payment']) + ".") print("You spent $" + str(round(loan['money paid'], 2)) + " in total.") #Calculate money spent on interest interest = round(loan['money paid'] - initial_principal, 2) print("You spent $" + str(interest) + " on interest!") def create_graph(data, loan): """Create a graph to show the relationship between principal and time""" x_values = [] #These represent month numbers Page 158 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 y_values = [] #These represent corresponding principal values #Loop through data set. Point is a tuple. #point[0] represents a month number, point[1] represents a principal value. for point in data: x_values.append(point[0]) y_values.append(point[1]) #Create a plot for x_values and y_values (month number and principal) pyplot.plot(x_values, y_values) pyplot.title(str(100*loan['rate']) + "% Interest With $" + str(loan['monthly payment']) + " Monthly Payment") pyplot.xlabel("Month Number") pyplot.ylabel("Principal of Loan") #Display the created graph pyplot.show() #The main code print("Welcome to the Loan Calculator App\n") #Initialize variables month_number = 0 my_loan = get_loan_info() starting_principal = my_loan['principal'] data_to_plot = [] #Display starting conditions of loan show_loan_info(my_loan, month_number) input("Press 'Enter' to begin paying off your loan.") #Simulate paying off the loan as long as the loan's principal > 0 while my_loan['principal'] > 0: #You cannot get ahead of the interest, you will never pay off the loan so break if my_loan['principal'] > starting_principal: break #It is possible to pay off the loan, so simulate a single month #Increment month number, collect interest, make a payment, add data to plot, and show loan info month_number += 1 collect_interest(my_loan) make_monthly_payment(my_loan) data_to_plot.append((month_number, my_loan['principal'])) show_loan_info(my_loan, month_number) #The loan is either paid off in full or it can NEVER be paid off... #The loan was paid off in full if my_loan['principal'] <= 0: summarize_loan(my_loan, month_number, starting_principal) create_graph(data_to_plot, my_loan) #The loan can NEVER be paid off, can't get ahead of interest else: print("\nYou will NEVER pay off your loan!!!") print("You cannot get ahead of the interest! :-(") Return to index Page 159 Classes Challenge 36: Pythonagachi Simulator App Description: You will be responsible for writing a program that simulates the behavior of a retro 90’s Tamagachi toy. You program will allow a user to create their own creature, give it a name, and care for it until it unfortunately parishes. Users will monitor the creatures hunger, boredom, tiredness, and dirtiness and take actions to prevent any of the categories from getting to high. If the categories get too high there will be unfortunate consequences. Step By Step Guide: Defining your classes ● Define a class Creature. Defining your class methods ● Define an __init__() method for the Creature class which takes two parameters, the required self parameter and a name. ○ Set the name of the creature to the name provided in title case. ○ Initialize the following creature attributes and set them equal to zero: ■ hunger, boredom, tiredness, dirtiness ○ Initialize an attribute called food which will track how much food is in the creatures inventory and set it equal to two. ○ Initialize an attribute called is_sleeping and set it equal to False. ○ Initialize an attribute called is_alive and set it equal to True. ● Define an eat() method for the Creature class which takes one parameter, the required self parameter. ○ If the creature has food available: ■ Decrease the food supply by one. ■ Decrease the creatures hunger by a random value from 1 to 4. ■ Print a statement stating the creature ate a great meal. ○ Else: ■ Print a statement stating the creature has no food. ○ If the current value of the creatures hunger is less than zero, set it to zero. ● Define a play() method for the Creature class which takes one parameter, the required self parameter. ○ Create a random integer from 0 to 2. ○ Inform the user that the creature wants to play a game. ○ The creature is thinking of a number 0, 1, or 2. ○ Get user input for a number guess. ○ If the guess is correct: ■ Print a statement stating the user is correct. ■ Decrease the creatures boredom by 3. ○ Else, the guess is incorrect: Page 160 ○ ■ Print a statement stating the user was incorrect. ■ Decrease the creatures boredom by 1. If the current value of the creatures boredom is less than zero, set it equal to zero. ● Define a sleep() method for the Creature class which takes one parameter, the required self parameter. ○ Set the creatures is_sleeping attribute to True. ○ Decrease the creatures tiredness by 3. ○ Decrease the creatures boredom by 2. ○ Print a message indicating the creature is sleeping. ○ If the current value of the creatures tiredness is less than zero, set it equal to zero. ○ If the current value of the creatures boredom is less than zero, set it equal to zero. ● Define an awake() method for the Creature class which takes one parameter, the required self parameter. ○ Create a random integer from 0 to 2. ○ If the integer created is equal to 0: ■ Print a message that the creature just woke up. ■ Set the creatures is_sleeping attribute to False. ■ Set the creatures boredom to 0. ○ Else: ■ Print a message that the creature won’t wake up. ■ Call the creatures sleep() method. ● Define a clean() method for the Creature class which takes one parameter, the required self parameter. ○ Set the creatures dirtiness to 0. ○ Print a message stating that the creature took a bath. ● Define a forage() method for the Creature class which takes one parameter, the required self parameter. ○ Create a variable called food_found and set it equal to a random integer from 0 to 4. ○ Increase the creatures food by this amount. ○ Increase the creatures dirtiness by 2. ○ Print a message stating how much food the creature found. ● Define a show_values() method for the Creature class which takes one parameter, the required self parameter. ○ Display all of the current attributes for the creature. ■ Name, hunger, boredom, tiredness, dirtiness, food inventory, and sleeping status. Page 161 ● Define an incriment_values() method for the Creature class which takes two parameters, the required self parameter and an integer representing the game difficulty . ○ The user will set the difficulty (1 - 5) at the start of the game. ○ Increase the creatures hunger by a random integer from 0 to the value of the difficulty set by the user. ○ ○ ● If the creatures is_sleeping attribute is False: ■ Increase the creatures boredom by a random integer from 0 to the value of the difficulty set by the user. ■ Increase the creatures tiredness by a random integer from 0 to the value of the difficulty set by the user. Increase the creatures dirtiness by a random integer from 0 to the value of the difficulty set by the user. Define a kill() method for the Creature class which takes one parameter, the required self parameter. ○ If the creatures hunger is greater than or equal to 10: ■ Print a message stating the creatures starved to death. ■ Set the creatures is_alive attribute to False. ○ Elif the creatures dirtiness is greater than or equal to 10: ■ Print a message that the creature suffered an infection and died. ■ Set the creatures is_alive attribute to False. ○ Elif the creatures boredom is greater than or equal to 10: ■ Set the creatures boredom equal to 10. ■ Print a message stating the creature is bored and falling asleep. ■ Set the creatures is_sleeping attribute to True. ○ Elif the creatures tiredness is greater than or equal to 10: ■ Set the creatures tiredness equal to 10. ■ Print a message that the creature is sleepy and falling asleep. ■ Set the creatures is_sleeping attribute to True. ○ Defining your functions ● Define a function show_menu() which takes one parameter, a creature object. ○ If the creatures is_sleeping attribute is True: ■ Get user input for a choice that represents a creature method call. ■ Only give them the option to press 6 if the creature is sleeping. ■ Hard code their choice to be 6 to take precaution. ■ A value of 6 will eventually call the awake() method for the creature. If the creature is sleeping, this is the only method we want the user to be able to call. ○ Else, the creature is not sleeping so give the user more options: ■ Enter 1 to eat. ■ Enter 2 to play. Page 162 ○ ● ■ Enter 3 to sleep. ■ Enter 4 to take a bath. ■ Enter 5 to forage for food. ■ Get user input for their choice. Return this choice as a string. Define a function call_action() which takes two parameters, a creature object and a string representing a choice by the user. ○ If choice is equal to 1 call the creatures eat() method. ○ Elif choice is equal to 2 call the creatures play() method. ○ Elif choice is equal to 3 call the creatures sleep() method. ○ Elif choice is equal to 4 call the creatures clean() method. ○ Elif choice is equal to 5 call the creatures forage() method. ○ Elif choice is equal to 6 call the creatures awake() method. ○ Else print a message that the user entered a non valid choice. Your main code ● Print a welcome message. ● Get user input for their difficulty level ranging from 1 to 5 and store it as an integer in a variable difficulty. ○ If the difficulty is greater than 5, set it equal to 5. ○ Elif the difficulty is less than 1, set it equal to 1. ● Create an active variable and set it to True. Use this variable to control a while loop. ● ● ● Get user input for the name of their creature. Create a creature object and store it in a variable player. Create a variable rounds and set it equal to 1. ● Create a while loop that will run as long as the creature is alive. ○ Print a message stating the current round. ○ Call creatures show_values() method. ○ Call the show_menu() function. ○ Call the call_action() function. ● ● ● ○ ○ ○ Print a message stating the round summary. Call creatures show_values() method. Prompt the user to press enter to continue. ○ ○ ○ Call the creatures increment_values() method. Call the creatures kill() method. Increment the round number by 1. Once the creature has died print an R.I.P message. Print a message informing the user how many rounds the creatures survived. Get user input for if they would like to play again. Page 163 ● If not, set the active variable controlling the game loop to False and thank the user for playing. Example Output: Welcome to the Pythonagachi Simulator App Please choose a difficulty level (1-5): 4 What name would you like to give your pet Pythonogachi: bobon ---------------------------------------------------------------------------Round #1 Creature Name: Bobon Hunger (0-10): 0 Boredom (0-10): 0 Tiredness (0-10): 0 Dirtiness (0-10): 0 Food Inventory: 2 pieces Current Status: Awake Enter (1) to eat. Enter (2) to play. Enter (3) to sleep. Enter (4) to take a bath. Enter (5) to forage for food. What is your choice: 5 Bobon found 3 pieces of food! Round #1 Summary: Creature Name: Bobon Hunger (0-10): 0 Boredom (0-10): 0 Tiredness (0-10): 0 Dirtiness (0-10): 2 Food Inventory: 5 pieces Current Status: Awake Press (enter) to continue... ---------------------------------------------------------------------------Round #2 Page 164 Creature Name: Bobon Hunger (0-10): 0 Boredom (0-10): 1 Tiredness (0-10): 4 Dirtiness (0-10): 5 Food Inventory: 5 pieces Current Status: Awake Enter (1) to eat. Enter (2) to play. Enter (3) to sleep. Enter (4) to take a bath. Enter (5) to forage for food. What is your choice: 5 Bobon found 3 pieces of food! Round #2 Summary: Creature Name: Bobon Hunger (0-10): 0 Boredom (0-10): 1 Tiredness (0-10): 4 Dirtiness (0-10): 7 Food Inventory: 8 pieces Current Status: Awake Press (enter) to continue... ---------------------------------------------------------------------------Round #3 Creature Name: Bobon Hunger (0-10): 4 Boredom (0-10): 3 Tiredness (0-10): 4 Dirtiness (0-10): 8 Food Inventory: 8 pieces Current Status: Awake Enter (1) to eat. Enter (2) to play. Enter (3) to sleep. Page 165 Enter (4) to take a bath. Enter (5) to forage for food. What is your choice: 4 Bobon has taken a bath. All clean! Round #3 Summary: Creature Name: Bobon Hunger (0-10): 4 Boredom (0-10): 3 Tiredness (0-10): 4 Dirtiness (0-10): 0 Food Inventory: 8 pieces Current Status: Awake Press (enter) to continue... ---------------------------------------------------------------------------Round #4 Creature Name: Bobon Hunger (0-10): 8 Boredom (0-10): 5 Tiredness (0-10): 5 Dirtiness (0-10): 4 Food Inventory: 8 pieces Current Status: Awake Enter (1) to eat. Enter (2) to play. Enter (3) to sleep. Enter (4) to take a bath. Enter (5) to forage for food. What is your choice: 1 Yumm! Bobon ate a great meal! Round #4 Summary: Creature Name: Bobon Hunger (0-10): 4 Boredom (0-10): 5 Tiredness (0-10): 5 Dirtiness (0-10): 4 Page 166 Food Inventory: 7 pieces Current Status: Awake Press (enter) to continue... ---------------------------------------------------------------------------Round #5 Creature Name: Bobon Hunger (0-10): 6 Boredom (0-10): 8 Tiredness (0-10): 5 Dirtiness (0-10): 6 Food Inventory: 7 pieces Current Status: Awake Enter (1) to eat. Enter (2) to play. Enter (3) to sleep. Enter (4) to take a bath. Enter (5) to forage for food. What is your choice: 2 Bobon wants to play a game. Bobon is thinking of a number 0, 1, or 2. What is your guess: 0 That is correct!!! Round #5 Summary: Creature Name: Bobon Hunger (0-10): 6 Boredom (0-10): 5 Tiredness (0-10): 5 Dirtiness (0-10): 6 Food Inventory: 7 pieces Current Status: Awake Press (enter) to continue... ---------------------------------------------------------------------------Round #6 Page 167 Creature Name: Bobon Hunger (0-10): 9 Boredom (0-10): 7 Tiredness (0-10): 6 Dirtiness (0-10): 7 Food Inventory: 7 pieces Current Status: Awake Enter (1) to eat. Enter (2) to play. Enter (3) to sleep. Enter (4) to take a bath. Enter (5) to forage for food. What is your choice: 3 Zzzzzz....Zzzzzz....Zzzzzz.... Round #6 Summary: Creature Name: Bobon Hunger (0-10): 9 Boredom (0-10): 5 Tiredness (0-10): 3 Dirtiness (0-10): 7 Food Inventory: 7 pieces Current Status: Sleeping Press (enter) to continue... Bobon has starved to death... R.I.P. Bobon survived a total of 6 rounds. would you like to play again (y/n): n Thank you for playing Pythonagachi! Page 168 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 #Classes Challenge 36: Pythonagachi Simulator App import random #Define the Creature class class Creature(): """Create a simple Tomogachi clone.""" def __init__(self, name): """Initialize attributes""" self.name = name.title() #Attributes to track playing the game (0-10) self.hunger = 0 self.boredom = 0 self.tiredness = 0 self.dirtiness = 0 self.food = 2 #Represents food inventory self.is_sleeping = False #Bool to track if creature is sleeping self.is_alive = True #Bool to track if creature is alive def eat(self): """Simulate eating. Each time you eat, take one food away from the inventory and randomly take a value away from hunger.""" #First, make sure there is food available if self.food > 0: self.food -= 1 self.hunger -= random.randint(1,4) print("Yum! " + self.name + " ate a great meal!") else: print(self.name + " doesn't have any food! Better forage for some.") #If the hunger is less than zero, set it to zero if self.hunger < 0: self.hunger = 0 def play(self): """Play a guessing game to lower the creatures boredom. If you win the game, lower the boredom even move.""" #Simple guessing game value = random.randint(0,2) print("\n" + self.name + " wants to play a game.") print(self.name + " is thinking of a number 0, 1, or 2.") guess = int(input("What is your guess: ")) #Lower the boredom attribute based on the users guess if guess == value: print("That is correct!!!") self.boredom -= 3 else: print("WRONG! " + self.name + " was thinking of " + str(value) + ".") self.boredom -= 1 #If the boredom is less than zero, set it to zero if self.boredom < 0: self.boredom = 0 def sleep(self): """Simulate sleeping. is sleeping The only thing a player can do when the creature Page 169 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 is try to wake up. However, tiredness and boredom should decrease each round when sleeping""" #Put the creature to sleep self.is_sleeping = True self.tiredness -= 3 self.boredom -= 2 print("Zzzzzzz.....Zzzzzzz.....Zzzzzzz.....") #If tiredness or boredom is less than zero, set it to zero if self.tiredness < 0: self.tiredness = 0 if self.boredom < 0: self.boredom = 0 def awake(self): """Simulate randomly waking a creature up.""" #Creature has a 1/3 chance to randomly wake up value = random.randint(0,2) #If creature wakes up, set tiredness to zero! if value == 0: print(self.name + " just woke up!") self.is_sleeping = False self.tiredness = 0 else: print(self.name + " won't wake up...") self.sleep() def clean(self): """Simulate taking a bath to completely clean the creature""" self.dirtiness = 0 print(self.name + " has taken a bath. All clean!") def forage(self): """Simulate foraging for food. This will increase the creatures food attribute however, it will also increase their dirtiness""" #Randomly find food from 0 to 4 pieces food_found = random.randint(0,4) self.food += food_found #Creature gets dirty from foraging self.dirtiness += 2 print(self.name + " found " + str(food_found) + " pieces of food!") def show_values(self): """Show the current information about the creature""" #Show creature attributes print("\nCreature Name: " + self.name) print("Hunger (0-10): " + str(self.hunger)) print("Boredom (0-10): " + str(self.boredom)) print("Tiredness (0-10): " + str(self.tiredness)) print("Dirtiness (0-10): " + str(self.dirtiness)) print("\nFood Inventory: " + str(self.food) + " pieces") #Show current sleeping status if self.is_sleeping: print("Current Status: Sleeping") else: Page 170 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 print("Current Status: Awake") def incriment_values(self, diff): """User must set an arbitrary difficulty. This will control how much "damage" you take each round. Update the current values of the creature based on this difficulty.""" #Increase the hunger and dirtiness regardless if the creature is awake or sleeping. self.hunger += random.randint(0, diff) self.dirtiness += random.randint(0, diff) #If the creature is awake, he should be growing tired and growing bored. if self.is_sleeping == False: self.boredom += random.randint(0, diff) self.tiredness += random.randint(0, diff) def kill(self): """Check for all conditions to kill or sleep the creature.""" #First two checks, will kill the creature if self.hunger >= 10: print(self.name + " has starved to death...") self.is_alive = False elif self.dirtiness >= 10: print(self.name + " has suffered an infection and died...") self.is_alive = False #Next two checks, will put the creature to sleep elif self.boredom >= 10: self.boredom = 10 print(self.name + " is bored. Falling asleep...") self.is_sleeping = True elif self.tiredness >= 10: self.tirednress = 10 print(self.name + " is sleepy. Falling asleep...") self.is_sleeping = True #Helper functions outside of the creature class def show_menu(creature): """Show the menu options for the player. If the creature is sleeping, the player can ONLY try to wake the creature up by default.""" #If the creature is sleeping, only allow the user to wake the creature. #Hard code the value for sneaky users. if creature.is_sleeping: choice = input("\nEnter (6) to try and wake up: ") choice = '6' #Creature is awake, give full functionality to user else: print("\nEnter (1) to eat.") print("Enter (2) to play.") print("Enter (3) to sleep.") print("Enter (4) to take a bath.") print("Enter (5) to forage for food.") choice = input("What is your choice: ") return choice def call_action(creature, choice): """Given the players choice, call the appropriate class method.""" #Call the appropriate creature method Page 171 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 if choice == '1': creature.eat() elif choice == '2': creature.play() elif choice == '3': creature.sleep() elif choice == '4': creature.clean() elif choice == '5': creature.forage() elif choice == '6': creature.awake() #User entered in invalid input. Do not call any methods. else: print("Sorry, that is not a valid move.") #The main code print("Welcome to the Pythonagachi Simulator App") #Set the difficulty level difficulty = int(input("Please choose a difficulty level (1-5): ")) if difficulty > 5: difficulty = 5 elif difficulty < 1: difficulty = 1 #The overall main game loop running = True while running: #Get user input for creature name and make a creature name = input("What name would you like to give your pet Pythonagachi: ") player = Creature(name) rounds = 1 #The game loop that simulates an individual round #This loop should run as long as the creature is alive while player.is_alive: print("\n--------------------------------------------------------------------------------") print("Round #" + str(rounds)) #An individual round should show values, get a players move, and call the appropriate method player.show_values() round_move = show_menu(player) call_action(player, round_move) print("\nRound #" + str(rounds) + " Summary: ") #Summarize the effects of the current round player.show_values() input("\nPress (enter) to continue...") #Increment values and check for death player.incriment_values(difficulty) player.kill() #Round is over rounds += 1 #The creatures has died. Game over print("\nR.I.P.") print(player.name + " survived a total of " + str(rounds-1) + " rounds.") Page 172 247 248 249 250 251 252 #Ask the user to play again. choice = input("Would you like to play again (y/n): ").lower() if choice != 'y': running = False print("Thank you for playing Pythonagachi!") Return to index Page 173 Classes Challenge 37: Casino Black Jack App Description: You are responsible for writing a program that allows a user to play casino Black Jack. The user will put a set amount of money onto the table and make a minimum $20 bet each hand. Each hand, the user will be dealt two cards and be given the option to hit or stay. If the user hits 21 or goes over the round will end. The dealer will continue to hit until their hand has a minimum value of 17 as per casino guidelines. The user will be able to play as long as their total money is greater than or equal to the minimum bet of the table. Step By Step Guide: Defining your classes ● Define a class Card. ● Define a class Deck. ● Define a class Player. ● Define a class Dealer. ● Define a class Game. Defining your class methods The Card Class ● Define an __init__() method for the Card class which takes four parameters, the required self parameter, a rank, a value, and a suit. ○ Set the rank of the card to the given rank. ○ Set the value of the card to the given value. ○ Set the suit of the card to the given suit. ● Define a display_card() method for the Card class which takes one parameter, the required self parameter. ○ Print a statement describing the cards rank and suit such as “K of Hearts” . The Deck Class ● Define an __init__() method for the Deck class which takes one parameter, the required self parameter. ○ Initialize an attribute called cards and set it equal to a blank list. ● Define a build_deck() method for the Deck class which takes one parameter, the required self parameter. ○ Create a list called suits that holds the four card suits. ○ Create a dictionary called ranks. ■ Each key should be the rank of a card: 2-10, J, Q, K, A ■ Each value should be the corresponding value of the card. ● Numeric cards are their integer value. ● J, Q, K are 10. ● A is 11. Page 174 ○ Use a for loop to loop through the suits. ■ Use a for loop to loop through the keys and values in the dictionary: ● Create a card for the given rank, value and suit. ● Append this card to the Deck’s cards list. ● Define a shuffle_deck() method for the Deck class which takes one parameter, the required self parameter. ○ Shuffling the deck will consist of randomizing the elements of the cards list. ○ Type import random as the first line of code in your program. ○ Use the random library to shuffle the list of cards. ● Define a deal_card() method for the Deck class which takes one parameter, the required self parameter. ○ Pop a card off the list of cards associated with the Deck. ○ Return this card. The Player Class ● Define an __init__() method for the Player class which takes one parameter, the required self parameter. ○ Initialize an attribute called hand and set it equal to a blank list. ○ Initialize an attribute called hand_value and set it equal to zero. ○ Initialize an attribute called playing_hand and set it equal to True. ● Define a draw_hand() method for the Player class which takes two parameters, the required self parameter, and a deck of cards. ○ Use a for loop to deal 2 cards to the player. ■ Call the deck’s deal_card() method to get a card. ■ Append this card to the players hand. ● Define a display_hand() method for the Player class which takes one parameter, the required self parameter. ○ Print a message declaring the player’s hand. ○ For each card in the players hand: ■ Call the card’s display_card() method. ● Define a hit() method for the Player class which takes two parameters, the required self parameter and a deck of cards. ○ Call the deck’s deal_card() method to get a card. ○ Append this card to the players hand. ● Define a get_hand_value() method for the Player class which takes one parameter, the required self parameter. ○ Set the hand_value attribute to 0. ○ Create a variable ace_in_hand and set it equal to False. ○ Use a for loop to loop through each card in the player’s hand: Page 175 ■ ○ ○ ● Update the current value of hand_value by adding the current cards value. ■ If the current cards rank is ‘A’: ● Set ace_in_hand equal to True. If the hand’s value greater than 21 and there is an ace in the hand: ■ Treat the Ace as if it were 1 instead of 11 by subtracting ten from the hands current value. Print the total value of the hand. Define an update_hand() method for the Player class which takes two parameters, the required self parameter and a deck of cards. ○ If the value of the players current hand is less than 21: ■ Get user input for if they would like to hit. ■ If yes: ● Call the players hit() method. ■ Else: ● Set the player’s playing_hand attribute to False. ○ Else, the player either has blackjack or is over 21: ■ Set the player’s playing_hand attribute to False. The Dealer Class ● Define an __init__() method for the Dealer class which takes one parameter, the required self parameter. ○ Initialize an attribute called hand and set it equal to a blank list. ○ Initialize an attribute called hand_value and set it equal to zero. ○ Initialize an attribute called playing_hand and set it equal to True. ● Define a draw_hand() method for the Dealer class which takes two parameters, the required self parameter, and a deck of cards. ○ Use a for loop to deal 2 cards to the dealer. ■ Call the deck’s deal_card() method to get a card. ■ Append this card to the dealer's hand. ● Define a display_hand() method for the Dealer class which takes one parameter, the required self parameter. ○ Prompt the user to press enter to reveal the dealer cards. ○ Use a for loop to loop through the dealer's hand. ■ Reveal an individual card by calling the cards display_card() method. ■ Pause the program for added suspense between cards. ● To do this, you must import the time library. ○ Type import time as the second line of code in your program. ○ Pause the program for 1 second. ■ To pause a program use the time library’s sleep() function. Page 176 ● Define a hit() method for the Dealer class which takes two parameters, the required self parameter and a deck of cards. ○ The dealer must hit until they reach 17, then they must stop. ○ Get the dealers current hand value by calling the get_hand_value() method. ○ While the hand value is less than 17: ■ Get a card from the deck by calling the decks deal_card() method. ■ Append the card to the dealer's hand. ■ Get the current hands value. ○ Print how many cards are in the dealer's hand. ● Define a get_hand_value() method for the Dealer class which takes one parameter, the required self parameter. ○ Set the hand_value attribute to 0. ○ Create a variable ace_in_hand and set it equal to False. ○ Use a for loop to loop through each card in the player’s hand: ■ Update the current value of hand_value by adding the current cards value. ■ If the current cards rank is ‘A’: ● Set ace_in_hand equal to True. ○ If the hand’s value greater than 21 and there is an ace in the hand: ■ Treat the Ace as if it were 1 instead of 11 by subtracting ten from the hands current value. The Game Class ● Define an __init__() method for the Game class which takes two parameters, the required self parameter and an amount of money. ○ Initialize an attribute called money and set it equal to the given money as an integer. ○ Initialize an attribute called bet and set it equal to 20. ○ Initialize an attribute called winner and set it equal to a blank string. ● Define a set_bet() method for the Game class which takes one parameter, the required self parameter. ○ Create a variable betting and set it to True. ○ Run a while loop as long as betting is True. ■ Get user input for their bet. ■ If the bet is less than 20 set the game’s bet attribute equal to 20. ■ If the bet is more than the game objects total money: ● Inform the user that they cannot afford the bet. ■ Else: ● Set the game’s bet attribute to the users given bet. ● Set betting to False. Page 177 ● Define a scoring() method for the Game class which takes three parameters, the required self parameter, the player’s hand value, and the dealer's hand value. ○ If the player’s hand value is equal to 21: ■ Print that they got black jack. ■ Set the game’s winner attribute to p. ○ Elif the dealer's hand value is equal to 21: ■ Print they got black jack. ■ Set the game’s winner attribute to d. ○ Elif the player’s hand value is greater than 21: ■ Print that the player went over 21. ■ Set the game’s winner attribute to d. ○ Elif the dealer's hand is greater than 21. ■ Print the dealer went over 21. ■ Set the game’s winner attribute to p. ○ Else: ■ If the player's hand is greater than the dealer's hand. ● Print a summary. ● Set the game’s winner attribute to p. ■ Elif the dealer’s hand is greater than the player’s hand: ● Print a summary. ● Set the game’s winner attribute to d. ■ Else: ● It was a tie, print the summary. ● Set the game’s winner attribute to tie. ● Define a payout() method for the Game class which takes one parameter, the required self parameter. ○ If the game’s winner attribute is equal to p: ■ Add the game objects bet to the game objects money. ○ Elif , the game’s winner attribute is equal to d: ■ Subtract the game objects bet from the game objects money. ● Define a display_money() method for the Game class which takes one parameter, the required self parameter. ○ Print how much money the current game object holds. ● Define a display_money_and_bet() method for the Game class which takes one parameter, the required self parameter. ○ Print how much money the current game object holds and the current bet. The main code ● Print a welcome message ● Print a message informing the user of the minimum bet of $20. ● Get user input for how much money they would like to place on the table. ● Create a Game() object called game. Page 178 ● ● Create an active variable playing and set it equal to True. Use this variable to control a while loop: ○ Create a Deck() object called game_deck. ○ Build the deck by calling game_deck’s build_deck() method. ○ Shuffle the deck by calling game_deck’s shuffle_deck() method ○ ○ Create a Player() object called player. Create a Dealer() object called dealer. ○ ○ Display how much money the game has by calling the game’s display_money() method. Get the bet for the game by calling the game’s set_bet() method. ○ ○ Draw the player’s hand by calling the player’s draw_hand() method. Draw the dealer’s hand by calling the dealer’s draw_hand() method. ○ Display the games money and bet by calling the game’s display_money_and_bet() method. Print a statement that reveals the dealers first card. ○ ○ While the player is playing their hand: ■ Display the player’s hand by calling the player’s display_hand() method. ■ Get the value of the player’s hand by calling the player’s get_hand_value() method. ■ Update the players hand (hit or stay) by calling the player’s update_hand() method. ○ ○ Have the dealer hit until they reach 17 by calling the dealer’s hit() method. Display the dealer's hand by calling the dealer’s display_hand() method. ○ ○ Score the round of black jack by calling the game’s scoring() method. Payout the round of black jack by calling the game’s payout() method. ○ If the user has less than the minimum bet of $20: ■ Set playing equal to False ■ Print a message that the user ran out of money. Example Output: Welcome to the Blackjack App. The minimum bet at this table is $20. How much money are you willing to play with today: 100 Page 179 Current Money: $100 What would you like to bet (minimum bet of 20): 20 Current Money: $100 Current Bet: $20 The dealer is showing a K of Clubs. Player's Hand: A of Clubs 2 of Diamonds Total value: 13 Would you like to hit (y/n): y Player's Hand: A of Clubs 2 of Diamonds J of Spades Total value: 13 Would you like to hit (y/n): y Player's Hand: A of Clubs 2 of Diamonds J of Spades Q of Diamonds Total value: 23 Dealer is set with a total of 2 cards. Press enter to reveal the dealer's hand. K of Clubs 10 of Spades You went over 21....you loose! Current Money: $80 What would you like to bet (minimum bet of 20): 40 Current Money: $80 Current Bet: $40 The dealer is showing a Q of Spades. Player's Hand: Q of Clubs 9 of Diamonds Total value: 19 Would you like to hit (y/n): n Page 180 Dealer is set with a total of 3 cards. Press enter to reveal the dealer's hand. Q of Spades 4 of Diamonds K of Diamonds Dealer went over 21. You win! Current Money: $120 What would you like to bet (minimum bet of 20): 110 Current Money: $120 Current Bet: $110 The dealer is showing a A of Clubs. Player's Hand: Q of Diamonds 7 of Clubs Total value: 17 Would you like to hit (y/n): y Player's Hand: Q of Diamonds 7 of Clubs J of Diamonds Total value: 27 Dealer is set with a total of 2 cards. Press enter to reveal the dealer's hand. A of Clubs Q of Hearts The dealer got black jack, you loose! Sorry, you ran out of money. Please play again. Page 181 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 #Classes Challenge 37: import random import time Casino Black Jack App class Card(): """Simulate a single card with rank, value, and suit.""" def __init__(self, rank, value, suit): """Initialize card attributes""" self.rank = rank #2-10, J, Q, K, A self.value = value #1-11 self.suit = suit def display_card(self): """show the rank and suit of an individual card.""" print(self.rank + " of " + self.suit) class Deck(): """Simulate a deck of 52 individual playing cards.""" def __init__(self): """Initialize deck attributes""" self.cards = [] #A list to hold all future cards in the deck def build_deck(self): """Build a deck consisting of 52 unique cards.""" #Information for all potential cards in a deck suits = ['Hearts', 'Diamonds', 'Spades', 'Clubs'] ranks = {'2':2, '3':3, '4':4, '5':5, '6':6, '7':7, '8':8, '9':9, '10':10, 'J':10, 'Q':10, 'K':10, 'A':11,} #Build the deck, creating 52 individual cards and append them to the cards list. for suit in suits: for rank, value in ranks.items(): card = Card(rank, value, suit) self.cards.append(card) def shuffle_deck(self): """Shuffle a deck of cards""" #Use random.shuffle() to shuffle deck random.shuffle(self.cards) def deal_card(self): """Remove a card from the deck to be dealt.""" #Deal the last card in the shuffled deck card = self.cards.pop() return card class Player(): """A class for the user to play Black Jack.""" def __init__(self): """Initialize the self.hand = [] #A self.hand_value = self.playing_hand player.""" list to hold the players cards 0 #Total value of the players current hand = True #A bool to track if the player is playing the hand Page 182 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 def draw_hand(self, deck): """Deal the players starting hand""" #Player must start with 2 cards in hand for i in range(2): card = deck.deal_card() self.hand.append(card) def display_hand(self): """show the players hand.""" print("\nPlayer's Hand: ") for card in self.hand: card.display_card() def hit(self, deck): """Give the player a new card.""" card = deck.deal_card() self.hand.append(card) def get_hand_value(self): """Compute the value of the players hand.""" self.hand_value = 0 #Bool to track if you have an Ace ace_in_hand = False for card in self.hand: self.hand_value += card.value #Check for Ace if card.rank == 'A': ace_in_hand = True #The user went over 21, but they have an ace so treat ace as a 1. if self.hand_value > 21 and ace_in_hand: self.hand_value -= 10 #Ace is treated as 1 instead of 11 so subtract 10 from hand_value. print("Total value: " + str(self.hand_value)) def update_hand(self, deck): """Update the players hand by allowing them to hit.""" #The player has the option to hit if self.hand_value < 21: choice = input("Would you like to hit (y/n): ").lower() if choice == 'y': self.hit(deck) #Player is happy with hand value, done playing hand else: self.playing_hand = False #Player is over 21, cannot hit again else: self.playing_hand = False class Dealer(): """A class simulating the black jack dealer. and they must reveal their first card.""" They must hit up to 17 def __init__(self): Page 183 """Initialize the self.hand = [] #A self.hand_value = self.playing_hand 126 127 128 129 dealer""" list to hold the dealers cards 0 #Total value of the dealers current hand = True #A bool to track if the dealer is playing the hand 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 def draw_hand(self, deck): """Deal the dealers starting hand""" #Dealer must start with 2 cards in hand for i in range(2): card = deck.deal_card() self.hand.append(card) def display_hand(self): """Show the dealers hand one card at a time.""" input("\nPress enter to reveal the dealer's hand. ") #Show all cards in the dealer's hand for card in self.hand: card.display_card() #Pause the program for 1 second to build suspense time.sleep(1) def hit(self, deck): """The dealer must hit until they have reached 17, then they stop.""" self.get_hand_value() #As long as the hand_value is less than 17, dealer must hit. while self.hand_value < 17: card = deck.deal_card() self.hand.append(card) self.get_hand_value() print("\nDealer is set with a total of " + str(len(self.hand)) + " cards.") 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 def get_hand_value(self): """Compute the value of the dealers hand.""" self.hand_value = 0 #Bool to track if you have an Ace ace_in_hand = False for card in self.hand: self.hand_value += card.value #Check for Ace if card.rank == 'A': ace_in_hand = True #The dealer went over 21, but they have an ace so treat ace as a 1. if self.hand_value > 21 and ace_in_hand: self.hand_value -= 10 #Ace is treated as 1 instead of 11 so subtract 10 from hand_value. class Game(): """A class to hold bets and payouts""" def __init__(self, money): """Initialize attributes""" Page 184 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 self.money = int(money) #Total money the user is playing with self.bet = 20 #Minimum bet per hand is $20 self.winner = "" #No winner yet, no hand has been played def set_bet(self): """Get a users bet for a hand of black jack.""" betting = True while betting: #Get a users bet bet = int(input("What would you like to bet (minimum bet of 20): ")) #Bet is too small, set to min value if bet < 20: bet = 20 #Bet is too high, make them bet again if bet > self.money: print("Sorry, you can't afford that bet.") #Bet is acceptable, set bet and stop betting. else: self.bet = bet betting = False def scoring(self, p_value, d_value): """Score a round of black jack.""" #Someone got black jack 21! if p_value == 21: print("You got BLACK JACK!!! You win!") self.winner = 'p' elif d_value == 21: print("The dealer got black jack...You loose!") self.winner = 'd' #Someone went over 21. elif p_value > 21: print("You went over 21...You loose!") self.winner = 'd' elif d_value > 21: print("Dealer went over 21! You win!") self.winner = 'p' #Other cases. else: if p_value > d_value: print("Dealer gets " + str(d_value) + ". You win!") self.winner = 'p' elif d_value > p_value: print("Dealer gets " + str(d_value) + ". You loose.") self.winner = 'd' else: print("Dealer gets " + str(d_value) + ". It's a push...") self.winner = 'tie' def payout(self): """Update the money attribute based on who won a hand.""" #You won, you earn money if self.winner == 'p': self.money += self.bet #You lost, you loose money elif self.winner == 'd': self.money -= self.bet Page 185 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 def display_money(self): """Display current money for the overall game""" print("\nCurrent Money: $" + str(self.money)) def display_money_and_bet(self): """Display the current money and bet for a game round.""" print("\nCurrent Money: $" + str(self.money) + "\t\tCurrent Bet: $" + str(self.bet)) #The main code print("Welcome to the Casino Blackjack App") print("The minimum bet at this table is $20.") #Create a game object to keep track of bets, total cash, round winners, and payouts money = int(input("\nHow much money are you willing to play with today: ")) game = Game(money) #The main game loop playing = True while playing: #Build a deck, populate it with cards, and shuffle. game_deck = Deck() game_deck.build_deck() game_deck.shuffle_deck() #Create a player and dealer player = Player() dealer = Dealer() #Show how much money the player has and get the players bet game.display_money() game.set_bet() #Draw the player and dealer hands player.draw_hand(game_deck) dealer.draw_hand(game_deck) #Simulate a single round of black jack for the player game.display_money_and_bet() print("The dealer is showing a " + dealer.hand[0].rank + " of " + dealer.hand[0].suit + ".") 293 294 #While the player is playing, show hand, calc values, allow player to hit or stay 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 while player.playing_hand: player.display_hand() player.get_hand_value() player.update_hand(game_deck) #Simulate a single round of black jack for the dealer dealer.hit(game_deck) dealer.display_hand() #Determine the winner and the payout game.scoring(player.hand_value, dealer.hand_value) game.payout() #The user ran out of money, kick them out if game.money < 20: playing = False Page 186 311 print("Sorry, you ran out of money. Return to index Please try again.") Page 187 Classes Challenge 38: Pykemon Simulation App Description: You will be responsible for writing a program the emulates playing the hit game Pokemon. Your program will generate Pykemon creatures randomly. Each Pykemon creature will be one of three different elemental types: fire, water, or grass. Each Pykemon type will have its own set of unique moves and each individual Pykemon will have it’s one name, health stat, and speed stat.You will be given one Pykemon and then be tasked with fighting other pykemon until you run out of health. In the original Pokemon, the user is presented with three Pokemon to choose from at the start of the game; one of each elemental type. Pykemon is no different. You will choose your starting Pykemon and then be off on a journey to battle other wild Pykemon until your Pykemon faints. Step By Step Guide: Defining your classes ● Define a class Pykemon() ○ This will be a parent class in which the child classes, Fire, Water, and Grass will inherit from. ● Define a class Fire() ○ A child of the Pykemon class. ● Define a class Water() ○ A child of the Pykemon class. ● Define a class Grass() ○ A child of the Pykemon class. ● Define a class Game() Defining your class methods The Pykemon Class ● Define an __init__() method for the Pykemon class which takes five parameters, the required self parameter, a name, an element, a health, and a speed. ○ Initialize an attribute name and set it equal to the given name in title case. ○ Initialize an attribute element and set it equal to the given element. ○ Initialize an attribute current_health and set it equal to the given health. ○ Initialize an attribute max_health and set it equal to the given health. ○ Initialize an attribute speed and set it equal to the given speed. ○ Initialize an attribute is_alive and set it equal to True. ● Define a light_attack() method for the Pykemon class which takes two parameters, the required self parameter and an enemy pykemon. ○ The light attack will be guaranteed to do minimal damage to the enemy Pykmeon. This light attack will have a different name, depending on the elemental type of the pokemon. However, all light attacks will appear in a list called moves, which is an attribute of a specific Pykemon, at index 0. ○ Create a random integer from 15 to 25 and store it in a variable damage. Page 188 ○ ○ ○ ■ Type import random as the first line of code in your program. Print a message stating that the Pykemon performed a specific attack. ■ Use the Pykemon’s name and the name of the move. ■ self.name and self.moves[0] Print a message stating how much damage was dealt. Subtract that damage from the enemy Pykemon’s current_health attribute. ● Define a heavy_attack() method for the Pykemon class which takes two parameters, the required self parameter and an enemy pykemon. ○ The heavy attack has the potential to deal massive damage to the enemy Pykemon but it could also deal no damage at all; it is risky. This heavy attack will have a different name, depending on the element type of the pokemon. However, all heavy attacks will appear in a list called moves, which is an attribute of a specific Pykemon at index 1. ○ Create a random integer from 0 to 50 and store it in a variable called damage. ○ Print a message stating that the Pykemon performed a specific attack. ■ Use the Pykemon’s name and the name of the move. ■ self.name and self.moves[1] ○ If the damage was less than 10: ■ Print a message stating the attack missed. ■ Deal no damage. ○ Else: ■ Print a message stating how much damage was dealt. ■ Subtract that damage from the enemy Pykemon’s current_health attribute. ● Define a restore() method for the Pykemon class which takes one parameter; the required self parameter. ○ The restore move doesn’t deal any damage at all but instead restores a small portion of health to the Pykemon calling the move. This restore move will have a different name, depending on the element type of the pokemon. However, all restore moves will appear in a list called moves, which is an attribute of a specific Pykemon at index 2. ○ Create a random integer from 15 to 25 and store it in a variable called heal. ○ Print a message stating that the Pykemon performed a specific attack. ■ Use the Pykemon’s name and the name of the move. ■ self.name and self.moves[2] ○ Print a message stating how many points the Pykemon is healed by. ○ Add that heal value to the Pykemon’s current_health attribute. ○ If the value of the Pykemon’s current_health attribute is greater than the Pykemon’s max_health attribute: ■ Set the current_health attribute equal to the max_health attribute. ● Define a faint() method for the Pykemon class which takes one parameter, the required self parameter. Page 189 ○ ● If the Pykemon’s current_health attribute is less than or equal to zero: ■ Set the Pykemon’s is_alive attribute to False. ■ Print a message stating that the Pykemon has fainted. ■ Prompt the user to press enter to continue. Define a show_stats() method for the Pykemon class which takes one parameter, the required self parameter. ○ Print the Pykemon’s name. ○ Print the Pykemon’s element type. ○ Print the Pykemon’s current health and maximum health. ○ Print the Pykemon’s speed. The Fire Class ● Define an __init__() method for the Fire class which takes five parameters, the required self parameter, a name, and element, a health, and a speed. ○ Call the super function to inherit from the parent Pykemon class. ■ Pass the correct arguments required by the Pykemon class: name, element, health, and speed. ○ Initialize an attribute called moves and set it equal to a list containing the following four strings: ‘Scratch’, ‘Ember’, ‘Light’, ‘Fire Blast’ ■ These are the light attack, heavy attack, restore move, and special attack for all fire Pykemon. ● Define a special_attack() method for the Fire class which takes two parameters, the required self parameter and an enemy Pykemon. ○ The special attack deals massive damage to grass type Pykemon, normal damage to fire type Pykemon, and minimal damage to water type Pykemon. This special attack will have a different name, depending on the element type of the pokemon. However, all special attacks will appear in a list called moves, which is an attribute of a specific Pykemon at index 3. ○ Print a message stating that the Pykemon performed a specific attack. ■ Use the Pykemon’s name and the name of the move. ■ self.name and self.moves[3] ○ If the enemy Pykemon’s element attribute is GRASS: ■ Print a message stating that the move is super effective. ■ Create a random integer between 35 and 50 and store it in a variable damage. ○ Elif the enemy Pykemon’s element attribute is WATER: ■ Print a message stating that the move is not very effective. ■ Create a random integer between 5 and 10 and store it in a variable damage. ○ Else: ■ Create a random integer between 10 and 30 and store it in a variable damage. ○ Print a message stating how much damage was dealt. Page 190 ○ ● Subtract that damage from the enemy Pykemon’s current_health attribute. Define a move_info() method for the Fire class which takes one parameter, the required self parameter. ○ Print a message header for the Pykemon’s moves. ○ Print the name of each move and a brief description. ■ Moves will be stored in the moves lists. ■ See example output for formatting options. The Water Class ● Define an __init__() method for the Water class which takes five parameters, the required self parameter, a name, and element, a health, and a speed. ○ Call the super function to inherit from the parent Pykemon class. ■ Pass the correct arguments required by the Pykemon class: name, element, health, and speed. ○ Initialize an attribute called moves and set it equal to a list containing the following four strings: ‘Bite’, ‘Splash’, ‘Dive’, ‘Water Cannon’ ■ These are the light attack, heavy attack, restore move, and special attack for all water Pykemon. ● Define a special_attack() method for the Water class which takes two parameters, the required self parameter and an enemy Pykemon. ○ The special attack deals massive damage to fire type Pykemon, normal damage to water type Pykemon, and minimal damage to grass type Pykemon. This special attack will have a different name, depending on the element type of the pokemon. However, all special attacks will appear in a list called moves, which is an attribute of a specific Pykemon at index 3. ○ Print a message stating that the Pykemon performed a specific attack. ■ Use the Pykemon’s name and the name of the move. ■ self.name and self.moves[3] ○ If the enemy Pykemon’s element attribute is FIRE: ■ Print a message stating that the move is super effective. ■ Create a random integer between 35 and 50 and store it in a variable damage. ○ Elif the enemy Pykemon’s element attribute is GRASS: ■ Print a message stating that the move is not very effective. ■ Create a random integer between 5 and 10 and store it in a variable damage. ○ Else: ■ Create a random integer between 10 and 20 and store it in a variable damage. ○ Print a message stating how much damage was dealt. ○ Subtract that damage from the enemy Pykemon’s current_health attribute. Page 191 ● Define a move_info() method for the Water class which takes one parameter, the required self parameter. ○ Print a message header for the Pykemon’s moves. ○ Print the name of each move and a brief description. ■ Moves will be stored in the moves lists. ■ See example output for formatting options. The Grass Class ● Define an __init__() method for the Grass class which takes five parameters, the required self parameter, a name, and element, a health, and a speed. ○ Call the super function to inherit from the parent Pykemon class. ■ Pass the correct arguments required by the Pykemon class: name, element, health, and speed. ○ Initialize an attribute called moves and set it equal to a list containing the following four strings: ‘Vine Whip’, ‘Wrap’, ‘Grow’, ‘Leaf Blade’ ■ These are the light attack, heavy attack, restore move, and special attack for all grass Pykemon. ● Define a special_attack() method for the Grass class which takes two parameters, the required self parameter and an enemy Pykemon. ○ The special attack deals massive damage to water type Pykemon, normal damage to grass type Pykemon, and minimal damage to fire type Pykemon. This special attack will have a different name, depending on the element type of the pokemon. However, all special attacks will appear in a list called moves, which is an attribute of a specific Pykemon at index 3. ○ Print a message stating that the Pykemon performed a specific attack. ■ Use the Pykemon’s name and the name of the move. ■ self.name and self.moves[3] ○ If the enemy Pykemon’s element attribute is WATER: ■ Print a message stating that the move is super effective. ■ Create a random integer between 35 and 50 and store it in a variable damage. ○ Elif the enemy Pykemon’s element attribute is FIRE: ■ Print a message stating that the move is not very effective. ■ Create a random integer between 5 and 10 and store it in a variable damage. ○ Else: ■ Create a random integer between 10 and 20 and store it in a variable damage. ○ Print a message stating how much damage was dealt. ○ Subtract that damage from the enemy Pykemon’s current_health attribute. ● Define a move_info() method for the Grass class which takes one parameter, the required self parameter. ○ Print a message header for the Pykemon’s moves. Page 192 ○ Print the name of each move and a brief description. ■ Moves will be stored in the moves lists. ■ See example output for formatting options. The Game Class ● Define an __init__() method for the Game class that takes one parameter, the required self parameter. ○ Initialize an attribute pykemon_elements and set it equal to a list containing the strings ‘FIRE’, ‘WATER’, and ‘GRASS’. ○ Initialize an attribute called pykemon_names and set it equal to a list containing strings that represent various Pykemon names. ■ For this challenge the following names were used: 'Chewdie', 'Spatol', 'Burnmander', 'Pykachu', 'Pyonx', 'Abbacab', 'Sweetil', 'Jampot', 'Hownstooth', 'Swagilybo', 'Muttle', 'Zantbat', 'Wiggly Poof', 'Rubblesaur' ○ Initialize an attribute called battles_won and set it equal to zero. ■ This will keep track of how many Pykemon you have defeated. ● Define a create_pykemon() method for the Game class which takes one parameter, the required self parameter. ○ Create a variable health and set it equal to a random integer from 70 to 100. ○ Create a variable speed and set it equal to a random integer from 1 to 10. ○ Create a variable element and set it equal to a random element from the Game classes’ pykemon_elements attribute. ○ Create a variable name and set it equal to a random name from the game classes’ pykemon_names attribute. ○ If element is equal to “FIRE”: ■ Create a Fire Pykemon passing the name, elmement, health, and speed. ○ Elif element is equal to “WATER: ■ Create a Water Pykemon passing the name, element, health, and speed. ○ Else: ■ Create a Grass pykemon passing the name, element, health, and speed. ○ Return the created pykemon. ● Define a choose_pykemon() method for the Game class which takes one parameter, the required self parameter. ○ Create a variable starters and set it equal to a blank list. ○ While the length of the list starters is less than 3: ■ Create a Pykemon by calling the Game classes’ create_pykemon method. ■ Create a variable valid_pykemon and set it equal to True. ■ Loop through the list starters. For each iteration: ● Check if the given starter’s name is equal to the currently created Pykemon’s name or if the starter’s element is equal to the currently created Pykemon’s element. We do not want repeated Pykemon names or elements in our starter options. Page 193 ○ ○ ○ ○ ○ ○ ○ If they are repeating, set valid_pykemon equal to False. ■ After the loop has run, if valid_pykemon is still True: ● Append the currently created Pykemon to the list starters as it is a unique Pykemon. Loop through the list starters. For each iteration: ■ Show the given Pykemon’s stats by calling the Pykemon’s show_stats() method. ■ Show the given Pykemon’s moves by calling the Pykemon’s move_info() method. Print a message stating that the Professor presents three Pykemon. Print a message that informs the user to press 1 for the first Pykemon, 2 for the second Pykemon, and 3 for the third Pykemon. ■ Use the Pykemon’s name. Get user input for their choice. Create a variable pykemon and set it equal to the users choice. ■ Their choice 1, 2, or 3 corresponds to an index in the list starters 0, 1, or 2. Return chosen pykemon. ● Define a get_attack() method for the Game class which takes two parameters, the required self parameter and a Pykemon. ○ Print a message asking the user what move they would like. ○ Print a message stating the user should press 1 for the light attack, 2 for the heavy attack, 3 for the restore move, and 4 for the special attack. ■ Use the Pykemon specific move names. ○ Ge user input for their choice. ○ Print a blank line ○ Print a line of dashes for formatting reasons “------------------------------------------” ○ Return the users choice. ● Define a player_attack() method for the Game class which takes four parameters, the required self parameter, a move, a player, and a computer. ○ If the given move equals 1: ■ Call the player’s light_attack() method. ○ Elif the given move equals 2: ■ Call the player’s heavy_attack() method. ○ Elif the given move equals 3: ■ Call the player’s restore() method. ○ Elif the given move equals 4: ■ Call the player’s special_attack() method. ○ Check if the computer fainted by calling the computer’s faint() method. ● Define a computer_attack() method for the Game class which takes three parameters, the required self parameter, a player, and a computer. ○ Create a variable move and set it equal to a random integer from 1 to 4. Page 194 ○ ○ ○ ○ ○ ● If the given move equals 1: ■ Call the computer’s light_attack() method. Elif the given move equals 2: ■ Call the computers’s heavy_attack() method. Elif the given move equals 3: ■ Call the computer’s restore() method. Elif the given move equals 4: ■ Call the computer’s special_attack() method. Check if the player fainted by calling the player’s faint() method. Define a battle() method for the Game class which takes three parameters, the required self parameter, a player, and a computer. ○ Get the players move by calling the Game classes’ get_attack() method. ○ If the player’s speed is greater than or equal to the computer’s speed: ■ Let the player attack by calling the Game classes’ player_attack() method. ■ If the computer is still alive after the attack: ● Let the computer attack by calling the Game classes’ computer_attack() method. ○ Else: ■ Let the computer attack by calling the Game classes’ computer_attack() method. ■ If the player is still alive after the attack: ● Let the player attack by calling the Game classes’ player_attack() method. The main code ● Print a welcome summary about Pykemon. ○ This summary should include a narrative about how a professor is going to give you a Pykemon. ● Prompt the user to press enter to continue. ● ● Create an active variable playing_main and set it equal to True. Use this variable to control a while loop. ○ Create a Game object called game. ○ Allow the player to choose their Pykemon by calling the game object’s choose_pykemon() method. ○ Print a message summarizing the Pykemon chosen. ○ Prompt the user to press enter to continue. ○ While the player’s pykemon is alive: ■ Create a Pykemon for the computer by calling the game object’s create_pykemon() method. ■ Print a message stating the computer Pykemon’s name. ■ Show the stats of the computer Pykemon by calling the show_stats() method. Page 195 ■ ■ ○ ○ ○ ○ ○ While the computer Pykemon is alive and while the player Pykemon is alive: ● Simulate battle by calling the game objects battle() method. ● If the computer Pykemon is alive and if the player Pykemon is alive: ○ Show the player’s stats by calling the show_stats() method. ○ Show the computer’s stats by calling the show_stats() method. ○ Print a line of dashes for formatting reasons “-------------------------------------------------------------------------------” If the player is alive: ● Increment the game object’s kills attribute by 1. Print a message stating your Pykmeon has fainted. ■ Use the Pykemon’s name. Print a message stating how many Pykemon they defeated. R Get user input for whether they would like to play again. If they do not want to play again: ■ Set playing_main equal to False. ■ Print a message thanking the user for playing. Example Output: Welcome to Pykemon! Can you become the worlds greatest Pykemon Trainer??? Don't worry! Prof Eramo is here to help you on your quest. He would like to gift you your first Pykemon! Here are three potential Pykemon partners. Press Enter to choose your Pykemon! Name: Abbacab Element Type: GRASS Health: 92 / 92 Speed: 5 Abbacab Moves: -- Vine Whip -An efficient attack... Guaranteed to do damage within the range of 15 to 25 damage points. -- Wrap -- Page 196 A risky attack... Could deal up to 50 damage points or as little as 0 damage points. -- Grow -A restorative move... Guaranteed to heal your Pykemon 15 to 25 health points. -- Leaf Blade -A powerful GRASS based attack... Guaranteed to deal MASSIVE damage to WATER type Pykemon. Name: Pyonx Element Type: WATER Health: 84 / 84 Speed: 3 Pyonx Moves: -- Bite -An efficient attack... Guaranteed to do damage within the range of 15 to 25 damage points. -- Splash -A risky attack... Could deal up to 50 damage points or as little as 0 damage points. -- Dive -A restorative move... Guaranteed to heal your Pykemon 15 to 25 health points. -- Water Cannon -A powerful WATER based attack... Guaranteed to deal MASSIVE damage to FIRE type Pykemon. Name: Spatol Element Type: FIRE Health: 94 / 94 Speed: 5 Spatol Moves: -- Scratch -An efficient attack... Guaranteed to do damage within the range of 15 to 25 damage points. -- Ember -A risky attack... Page 197 Could deal up to 50 damage points or as little as 0 damage points. -- Light -A restorative move... Guaranteed to heal your Pykemon 15 to 25 health points. -- Fire Blast -A powerful FIRE based attack... Guaranteed to deal MASSIVE damage to GRASS type Pykemon. Professor Eramo presents you with three Pykemon: (1) - Abbacab (2) - Pyonx (3) - Spatol Which Pykemon would you like to choose: 3 Congratulations Trainer, you have chosen Spatol! Your journey with Spatol beings now...Press Enter OH NO! A wild Muttle has approached! Name: Muttle Element Type: GRASS Health: 93 / 93 Speed: 2 What would you like to do.... (1) - Scratch (2) - Ember (3) - Light (4) - Fire Blast Please enter your move choice: 2 ------------------------------------------------------------Pykemon Spatol used Ember. It dealt 31 damage. Pykemon Muttle used Vine Whip. It dealt 15 damage. Name: Spatol Element Type: FIRE Health: 79 / 94 Speed: 5 Page 198 Name: Muttle Element Type: GRASS Health: 62 / 93 Speed: 2 ------------------------------------------------------------What would you like to do.... (1) - Scratch (2) - Ember (3) - Light (4) - Fire Blast Please enter your move choice: 1 ------------------------------------------------------------Pykemon Spatol used Scratch. It dealt 25 damage. Pykemon Muttle used Grow. It healed 15 health points. Name: Spatol Element Type: FIRE Health: 79 / 94 Speed: 5 Name: Muttle Element Type: GRASS Health: 52 / 93 Speed: 2 ------------------------------------------------------------What would you like to do.... (1) - Scratch (2) - Ember (3) - Light (4) - Fire Blast Please enter your move choice: 3 ------------------------------------------------------------Pykemon Spatol used Light. It healed 23 health points. Pykemon Muttle used Wrap. The attack missed!!! Name: Spatol Element Type: FIRE Page 199 Health: 94 / 94 Speed: 5 Name: Muttle Element Type: GRASS Health: 52 / 93 Speed: 2 ------------------------------------------------------------What would you like to do.... (1) - Scratch (2) - Ember (3) - Light (4) - Fire Blast Please enter your move choice: 4 ------------------------------------------------------------Pykemon Spatol used FIRE BLAST! It's SUPER effective! It dealt 39 damage. Pykemon Muttle used Wrap. It dealt 27 damage. Name: Spatol Element Type: FIRE Health: 67 / 94 Speed: 5 Name: Muttle Element Type: GRASS Health: 13 / 93 Speed: 2 ------------------------------------------------------------What would you like to do.... (1) - Scratch (2) - Ember (3) - Light (4) - Fire Blast Please enter your move choice: 4 ------------------------------------------------------------Pykemon Spatol used FIRE BLAST! It's SUPER effective! It dealt 49 damage. Page 200 Pykemon Muttle has fainted! Press Enter to continue OH NO! A wild Pyonx has approached! Name: Pyonx Element Type: FIRE Health: 89 / 89 Speed: 9 What would you like to do.... (1) - Scratch (2) - Ember (3) - Light (4) - Fire Blast Please enter your move choice: 2 ------------------------------------------------------------Pykemon Pyonx used Scratch. It dealt 20 damage. Pykemon Spatol used Ember. It dealt 45 damage. Name: Spatol Element Type: FIRE Health: 47 / 94 Speed: 5 Name: Pyonx Element Type: FIRE Health: 44 / 89 Speed: 9 ------------------------------------------------------------What would you like to do.... (1) - Scratch (2) - Ember (3) - Light (4) - Fire Blast Please enter your move choice: 3 ------------------------------------------------------------Pykemon Pyonx used Scratch. It dealt 23 damage. Pykemon Spatol used Light. Page 201 It healed 24 health points. Name: Spatol Element Type: FIRE Health: 48 / 94 Speed: 5 Name: Pyonx Element Type: FIRE Health: 44 / 89 Speed: 9 ------------------------------------------------------------What would you like to do.... (1) - Scratch (2) - Ember (3) - Light (4) - Fire Blast Please enter your move choice: 1 ------------------------------------------------------------Pykemon Pyonx used Ember. It dealt 28 damage. Pykemon Spatol used Scratch. It dealt 15 damage. Name: Spatol Element Type: FIRE Health: 20 / 94 Speed: 5 Name: Pyonx Element Type: FIRE Health: 29 / 89 Speed: 9 ------------------------------------------------------------What would you like to do.... (1) - Scratch (2) - Ember (3) - Light (4) - Fire Blast Please enter your move choice: 2 ------------------------------------------------------------- Page 202 Pykemon Pyonx used FIRE BLAST! It dealt 22 damage. Pykemon Spatol has fainted! Press Enter to continue Poor Spatol has fainted... But not before defeating 1 Pykemon! Would you like to play again (y/n): n Thank you for playing Pykemon! Page 203 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 #Classes Challenge 38: import random Pykemon Simulation App #Parent class class Pykemon(): """A model of a generic Pykemon character.""" def __init__(self, name, element, health, speed): """Initialize attributes.""" self.name = name.title() self.element = element #Current health is current, max health will be referenced for healing self.current_health = health self.max_health = health self.speed = speed self.is_alive = True def light_attack(self, enemy): """A light attack guaranteed to do minimal damage.""" #Generate damage damage = random.randint(15, 25) #All pykemon will have a list moves = [light, heavy, restore, special] #All light attacks will appear at index 0 in the list moves #This attribute will be initialized in the child class print("Pykemon " + self.name + " used " + self.moves[0] + ".") print("It dealt " + str(damage) + " damage.") #Deal damage to the enemy enemy.current_health -= damage def heavy_attack(self, enemy): """A heavy attack that could deal MASSIVE damage, or no damage at all.""" #Generate damage damage = random.randint(0, 50) #All pykemon will have a list moves = [light, heavy, restore, special] #All heavy attacks will appear at index 1 in the list moves #This attribute will be initialized in the child class print("Pykemon " + self.name + " used " + self.moves[1] + ".") #Dealt no damage if damage < 10: print("The attack missed!!!") else: print("It dealt " + str(damage) + " damage.") #Deal the damage to the enemy enemy.current_health -= damage def restore(self): """A healing move that will restore our current health.""" #Generate restore value heal = random.randint(15, 25) #All pykemon will have a list moves = [light, heavy, restore, special] #All restore moves will appear at index 2 in the list moves #This attribute will be initialized in the child class print("Pykemon " + self.name + " used " + self.moves[2] + ".") print("It healed " + str(heal) + " health points.") #Heal the pykemon Page 204 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 self.current_health += heal #Check to see if we have exceeded the max health of the pykemon if self.current_health > self.max_health: self.current_health = self.max_health def faint(self): """If you run out of health, you faint...""" if self.current_health <= 0: self.is_alive = False print("Pykemon " + self.name + " has fainted!") input("Press Enter to continue.") def show_stats(self): """Display the current pykemon stats.""" print("\nName: " + self.name) print("Element Type: " + self.element) print("Health: " + str(self.current_health) + " / " + str(self.max_health)) print("Speed: " + str(self.speed)) #Child Classes class Fire(Pykemon): """A Fire based pykemon that is a child of the Pykemon parent class.""" def __init__(self, name, element, health, speed): """Initialize attributes from the parent Pykemon class.""" super().__init__(name, element, health, speed) #Move list unique to all Fire type Pykemon self.moves = ['Scratch', 'Ember', 'Light', 'Fire Blast'] def special_attack(self, enemy): """FIRE BLAST: an elemental fire move. Massive damage to grass type, normal damage to fire type, minimal damage to water type.""" print("Pykemon " + self.name + " used " + self.moves[3].upper() + "!") #Generate damage based on enemy type if enemy.element == 'GRASS': print("It's SUPER effective!") damage = random.randint(35, 50) elif enemy.element == 'WATER': print("It's not very effective...") damage = random.randint(5, 10) else: random.randint(10, 30) #Deal damage print("It dealt " + str(damage) + " damage.") enemy.current_health -= damage def move_info(self): """Display pykemon move info""" print("\n" + self.name + " Moves: ") #Light attack print("-- " + self.moves[0] + " --") print("\tAn efficient attack...") print("\tGuaranteed to do damage within a range of 15 to 25 damage points.") #Heavy attack Page 205 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 print("-- " + self.moves[1] + " --") print("\tAn risky attack...") print("\tCould deal damage up to 50 damage points or as little as 0 damage points.") #Restore move print("-- " + self.moves[2] + " --") print("\tA restorative move...") print("\tGuaranteed to heal your Pykemon 15 to 25 damage points.") #Special attack print("-- " + self.moves[3] + " --") print("\tA powerful FIRE based attack...") print("\tGuaranteed to deal MASSIVE damage to GRASS type Pykemon.") class Water(Pykemon): """A Water based pykemon that is a child of the Pykemon parent class.""" def __init__(self, name, element, health, speed): """Initialize attributes from the parent Pykemon class.""" super().__init__(name, element, health, speed) #Move list unique to all Water type Pykemon self.moves = ['Bite', 'Splash', 'Dive', 'Water Cannon'] def special_attack(self, enemy): """WATER CANNON: an elemental water move. Massive damage to fire type, normal damage to water type, minimal damage to grass type.""" print("Pykemon " + self.name + " used " + self.moves[3].upper() + "!") #Generate damage based on enemy type if enemy.element == 'FIRE': print("It's SUPER effective!") damage = random.randint(35, 50) elif enemy.element == 'GRASS': print("It's not very effective...") damage = random.randint(5, 10) else: random.randint(10, 30) #Deal damage print("It dealt " + str(damage) + " damage.") enemy.current_health -= damage def move_info(self): """Display pykemon move info""" print("\n" + self.name + " Moves: ") #Light attack print("-- " + self.moves[0] + " --") print("\tAn efficient attack...") print("\tGuaranteed to do damage within a range of 15 to 25 damage points.") #Heavy attack print("-- " + self.moves[1] + " --") print("\tAn risky attack...") print("\tCould deal damage up to 50 damage points or as little as 0 damage points.") #Restore move print("-- " + self.moves[2] + " --") print("\tA restorative move...") print("\tGuaranteed to heal your Pykemon 15 to 25 damage points.") #Special attack print("-- " + self.moves[3] + " --") print("\tA powerful WATER based attack...") Page 206 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 print("\tGuaranteed to deal MASSIVE damage to FIRE type Pykemon.") class Grass(Pykemon): """A Grass based pykemon that is a child of the Pykemon parent class.""" def __init__(self, name, element, health, speed): """Initialize attributes from the parent Pykemon class.""" super().__init__(name, element, health, speed) #Move list unique to all Grass type Pykemon self.moves = ['Vine Whip', 'Wrap', 'Grow', 'Leaf Blade'] def special_attack(self, enemy): """LEAF BLADE: an elemental grass move. Massive damage to water type, normal damage to grass type, minimal damage to fire type.""" print("Pykemon " + self.name + " used " + self.moves[3].upper() + "!") #Generate damage based on enemy type if enemy.element == 'WATER': print("It's SUPER effective!") damage = random.randint(35, 50) elif enemy.element == 'FIRE': print("It's not very effective...") damage = random.randint(5, 10) else: random.randint(10, 30) #Deal damage print("It dealt " + str(damage) + " damage.") enemy.current_health -= damage def move_info(self): """Display pykemon move info""" print("\n" + self.name + " Moves: ") #Light attack print("-- " + self.moves[0] + " --") print("\tAn efficient attack...") print("\tGuaranteed to do damage within a range of 15 to 25 damage points.") #Heavy attack print("-- " + self.moves[1] + " --") print("\tAn risky attack...") print("\tCould deal damage up to 50 damage points or as little as 0 damage points.") #Restore move print("-- " + self.moves[2] + " --") print("\tA restorative move...") print("\tGuaranteed to heal your Pykemon 15 to 25 damage points.") #Special attack print("-- " + self.moves[3] + " --") print("\tA powerful GRASS based attack...") print("\tGuaranteed to deal MASSIVE damage to WATER type Pykemon.") #Game class class Game(): """A game object to control the creation and flow of pykemon and simulate battle!""" def __init__(self): """Initialize attributes""" #Upon creating a pykemon, element and name will be chosen randomly Page 207 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 self.pykemon_elements = ['FIRE', 'WATER', 'GRASS'] self.pykemon_names = ['Chewdie', 'Spatol', 'Burnmander', 'Pykachu', 'Pyonx', 'Abbacab', 'Sweetil', 'Jampot', 'Hownstooth', 'Swagilybo', 'Muttle', 'Zantbat', 'Wiggly Poof', 'Rubblesaur'] #Upon creating a pykemon, no battles are won self.battles_won = 0 def create_pykemon(self): """Randomly generate a Pykemon!""" #Randomly generate health and speed attributes health = random.randint(70, 100) speed = random.randint(1, 10) #Randomly choose an element and name element = self.pykemon_elements[random.randint(0, len(self.pykemon_elements)-1)] name = self.pykemon_names[random.randint(0, len(self.pykemon_names)-1)] #Create the right elemental pykemon if element == 'FIRE': pykemon = Fire(name, element, health, speed) elif element == 'WATER': pykemon = Water(name, element, health, speed) else: pykemon = Grass(name, element, health, speed) return pykemon def choose_pykemon(self): """A method to simulate choosing a starting Pykemon similar to Pokemon""" #A list to hold 3 unique starter pykemon starters = [] #Pick 3 different elemental type pykemon for the starter list while len(starters) < 3: #Make a starter pykemon pykemon = self.create_pykemon() #Bool to determine if it is unique and should be added to the starters list valid_pykemon = True for starter in starters: #Check if the name or element is already used by another starter if starter.name == pykemon.name or starter.element == pykemon.element: valid_pykemon = False #The created pykemon is unique, add it to the list starter if valid_pykemon: starters.append(pykemon) #Starters list is complete, show off the starter pykemon for starter in starters: starter.show_stats() starter.move_info() #Present information to user print("\nProfessor Eramo presents you with three Pykemon: ") print("(1) - " + starters[0].name) print("(2) - " + starters[1].name) Page 208 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 print("(3) - " + starters[2].name) choice = int(input("Which Pykemon would you like to choose: ")) pykemon = starters[choice-1] return pykemon def get_attack(self, pykemon): """Get a users attack choice""" #Show the moves list using pykemon specific move names print("\nWhat would you like to do...") print("(1) - " + pykemon.moves[0]) print("(2) - " + pykemon.moves[1]) print("(3) - " + pykemon.moves[2]) print("(4) - " + pykemon.moves[3]) choice = int(input("Please enter your move choice: ")) #Formatting print() print("-----------------------------------------------------------------------------") 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 return choice def player_attack(self, move, player, computer): """Attack the computer AI""" #Call the appropriate attack method based on the given move if move == 1: player.light_attack(computer) elif move == 2: player.heavy_attack(computer) elif move == 3: player.restore() elif move == 4: player.special_attack(computer) #Check to see if the computer has fainted computer.faint() def computer_attack(self, player, computer): """Let the computer AI attack the player""" #Randomly pick a move for the computer to execute move = random.randint(1, 4) #Call the appropriate attack method based on the given move if move == 1: computer.light_attack(player) elif move == 2: computer.heavy_attack(player) elif move == 3: computer.restore() elif move == 4: computer.special_attack(player) #Check to see if the player has fainted player.faint() def battle(self, player, computer): """Simulate a battle round. Faster Pykemon go first.""" #Get the players move for the round move = self.get_attack(player) #If the player's pykemon is faster than the computer, they go first Page 209 if player.speed >= computer.speed: #Player attacks self.player_attack(move, player, computer) if computer.is_alive: #Computer is still alive, let them attack self.computer_attack(player, computer) #The player's pykemon is slower than the computer, the computer goes 371 372 373 374 375 376 377 first 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 else: self.computer_attack(player, computer) if player.is_alive: #Player is still alive, let them attack self.player_attack(move, player, computer) #The main code #Narrative introduction print("Welcome to Pykemon!") print("Can you become the worlds greatest Pykemon Trainer???") print("\nDon't worry! Prof Eramo is here to help you on your quest.") print("He would like to gift you your first Pykemon!") print("Here are three potential Pykemon partners.") input("Press Enter to choose your Pykemon!") #The main game loop playing_main = True while playing_main: #Create a game instance game = Game() #Choose your starter pykemon player = game.choose_pykemon() print("\nCongratulations Trainer, you have chosen " + player.name + "!") input("\nYour journey with " + player.name + " begins now...Press Enter!") #While your pykemon is alive, continue to do battle while player.is_alive: #Create a computer pykemon to battle computer = game.create_pykemon() print("\nOH NO! A wild " + computer.name + " has approached!") computer.show_stats() #While this enemy pykemon is alive and the player pykemon is alive, engage in battle while computer.is_alive and player.is_alive: game.battle(player, computer) #Both parties survived a round, show their current stats if computer.is_alive and player.is_alive: player.show_stats() computer.show_stats() #Formatting print("-----------------------------------------------------------------------------") 422 423 424 425 426 427 428 429 430 431 #If the player survived the battle, increment battles_won if player.is_alive: game.battles_won += 1 #The player has finally fainted print("\nPoor " + player.name + " has fainted...") print("But not before defeating " + str(game.battles_won) + " Pykemon!") #Ask the user if they want to play again Page 210 432 433 434 435 choice = input("Would you like to play again (y/n): ").lower() if choice != 'y': playing_main = False print("Thank you for playing Pykemon!") Return to index Page 211 Classes Challenge 39: Epidemic Outbreak Terminal App Description: You will be responsible for writing a program that simulates the spread of an infectious disease throughout a population. Using classes, you will model an individual person’s and an entire population’s attributes and behaviors. Your program will allow users to set various initial conditions in regards to the infection such as population size, infection rate, mortality rate, and infection duration. The program will then simulate the interaction of people within a population and spread the disease. Each iteration of spreading the disease will result in a summary displaying statistics of the population. Step By Step Guide: Defining your classes ● Define a class Simulation ● Define a class Person ● Define a class Population Defining your class methods The Simulation Class ● Define an __init__() method for the Simulation class, which takes one parameter, the required self parameter. ○ Initialize an attribute called day_number and set it equal to 1. ○ ○ ○ Print a message about needing to know population size. Get user input for the population size. Store the response in an attribute called population_size. ○ Print a message about needing to know the percentage of the population initially infected. Get user input for the starting infection size. ■ Divide this value by 100 to turn it into a percentage. Store the response in an attribute called infection_percent. ○ ○ ○ ○ ○ Print a message about needing to know the probability that a person will get infected if they come in contact with the disease. Get user input for the infection probability. Store the response in an attribute called infection_probability. ○ ○ ○ Print a message about needing to know how long the infection will last. Get user input for the infection duration. Store the response in an attribute called infection_duration. Page 212 ○ ○ ○ Print a message about needing to know the mortality rate of those infected. Get user input for the mortality rate. Store the response in an attribute called mortality_rate. ○ ○ ○ Print a message about needing to know how long to run the simulation for. Get user input for the number of days to simulate. Store the response in an attribute called sim_days. The Person Class ● Define an __init__() method for the Person class which takes one parameter, the required self parameter. ○ Initialize an attribute called is_infected and set it equal to False. ○ Initialize an attribute called is_dead and set it equal to False. ○ Initialize an attribute called days_infected and set it equal to zero. ● Define an infect() method for the Person class which takes two parameters, the required self parameter, and a simulation object. ○ Create a random integer from 0 to 100 to represent the chance this individual person becomes infected. ■ Type import random as the first line of code in your program. ○ If this value if less that the simulations infection_probability attribute: ■ Infect the person by setting their is_infected attribute to True. ● Define a heal() method for the Person class which takes one parameter, the required self parameter. ○ Set the persons is_infected attribute to False. ○ Set the persons days_infected attribute to 0. ● Define a die() method for the Person class which takes one parameter, the required self parameter. ○ Set the persons is_dead attribute to True. ● Define an update() method for the Person class which takes two parameters, the required self parameter and a simulation object. ○ First, check that the person is not dead. If the person is not dead: ■ Check if they are infected. If the person is infected: ● Increase their days_infected attribute by 1. ● Create a random integer from 0 to 100. ● If this integer is less than the simulations mortality_rate attribute: ○ Call the persons die() method to kill the person. ● Elif, the person didn’t die, check to see if they can be healed. If the persons days_infected attribute is equal to the simulations infection_duration attribute: ○ Call the persons heal() method to heal the person. Page 213 The Population Class ● Define an __init__() method for the Population class, which takes two parameters, the required self parameter, and a simulation object. ○ Initialize an attribute called population and set it equal to a blank list. ○ Now, you must create the correct number of Person objects and store them in your Population object. To accomplish this use a for loop. ○ Loop until you have reached the population size, which is stored in the simulation objects population_size attribute. Each iteration of the loop you should: ■ Create a Person object. ■ Append the Person to the Populations population attribute. ● Define an initial_infection() method for the Population class, which takes two parameters, the required self parameter, and a simulation object. ○ Create a variable called infected_count. This will represent the number of people who must start infected based on the user’s initial conditions. ○ To determine this value, multiply the simulation objects infection_percent and population_size attributes together. ■ Round this value to zero decimals. ■ Cast this value to an integer so we can use it in a for loop. ○ Use a for loop. Loop until you have infected infected_count people in the population. Each iteration of the loop you should: ■ Set the is_infected attribute to True for the current person in the population. ● Recall the Population object has an attribute population which is a list. Each element in the list represents a Person object. Therefore, self.population[i] represents a Person object. ■ Set the days_infected attribute to 1 for the current Person in the population. ○ Now that you have initially infected the correct number of people, you need to spread them through the list. They are currently all located at the start of the list. This is bad because our simulation will spread the infection by looking at adjacent Person objects in the population list. Therefore, we need to shuffle the list. ■ Use the random module to shuffle the list. ● Define a spread_infection() method for the Population class which takes two parameters, the required self parameter, and a simulation object. ○ Use a for loop to loop through the length of the population list. ○ For example, for i in range(len(self.population)): ○ Recall that an individual Person will be represented as self.population[i]. ■ If the is_dead attribute is False for the current person in the population, meaning they are currently alive, we will check to spread the infection. ● If i is equal to 0: ○ This is the first Person in the population list, so we can only check to see if the Person to the right of them is infected. ○ If the Person object in the next index, i+1, is infected: Page 214 ● ● ■ Call the current Persons infect() method. Elif i is less than the length of the population list minus 1. ○ These Person objects are in the middle of the list so we will check both to the right and left of them. ○ If the Person object in the next index, i+1, is infected or if the Person object in the previous index, i-1, is infected: ■ Call the Persons infect() method. Elif i is equal to the length of the population list minus 1. ○ This Person is the last Person in the list, so we can only check to see if the Person to the left of them is infected. ○ If the Person object in the previous index, i-1, is infected: ■ Call the Persons infect() method. ● Define an update() method for the Population class which takes two parameters, the required self parameter, and a simulation object. ○ Increase the simulation objects day_number attribute by 1. ○ Loop through the population list. For each iteration you should: ■ Call the Persons update() method. ● Define a display_statistics() method which takes two parameters, the required self parameter, and a simulation object. ○ Create a variable total_infected_count and set it equal to 0. ○ Create a variable total_death_count and set it equal to 0. ○ Loop through the population list. For each iteration you should: ■ Check if the current Person is infected. If they are: ● Increment total_infected_count by 1. ● Check if the current Person is dead. If they are: ○ Increment total_death_count by 1. ○ Create a variable infected_percent and calculate the percentage of the population that is infected. ■ Round this value to 4 decimals. ○ Create a variable death_percent and calculate the percentage of the population that is dead. ■ Round this value to 4 decimals. ○ Print a summary of the population statistics for the current day of the simulation. ■ This should include the day number. ■ The percentage of the population infected. ■ The percentage of the population that is dead. ■ The total number of people infected. ■ The total number of deaths that have occured. ■ See example output for formatting. ● Define a graphics() method for the Population class which takes one parameter, the required self parameter. ○ Create a blank list called status. Page 215 ○ ○ Loop through the population list. For each iteration you should: ■ Check if the person is dead. If they are: ● Set a variable char equal to the letter X. ■ Else the person is alive. ● If the person is infected: ○ Set a variable char equal to the letter I. ● Else: ○ Set a variable char equal to the letter O ■ Append the current value of char to the list status. Loop through the list status. For each iteration of the loop: ■ Print the current value using the end=’-’ argument to keep the elements on one line separated by a ‘-’. Your list should look something like this: O-O-I-I-X-O-O-X-O-O-I. ● O represents a healthy person. ● I represents an infected person. ● X represents a dead person. The main code ● Create a Simulation object. ● Create a Population object. ● ● ● ● Call the Populations initial_infection() method. Call the Populations display_statistics() method. Call the Populations graphics() method. Prompt the user to press enter to being the simulation. ● Use a for loop to simulate each day of the simulation. For each iteration you should: ○ Spread the infection by calling the Populations spread_infection() method. ○ Update the population by calling the Populations update() method. ○ Display the statistics for the current day by calling the Populations display_statistics() method. ○ Show the graphics of the data by calling the Populations graphics() method. ○ If you are currently not on the last day of the simulation: ■ Prompt the user to press enter to advance to the next day of the simulation. Example Output: To simulate an epidemic outbreak, we must know the population size. ---Enter the population size: 100 We must first start by infecting a portion of the population. --Enter the percentage (0-100) of the population to initially infect: 12 Page 216 We must know the risk a person has to contract the disease when exposed. --Enter the probability (0-100) that a person gets infected when exposed to the disease: 25 We must know how long the infection will last when exposed. --Enter the duration (in days) of the infection: 4 we must know the mortality rate of those infected. --Enter the mortality rate (0-100) of the infection: 35 We must know how long to run the simulation. --Enter the number of days to simulate: 10 -----Day # 1----Percentage of Population Infected: 12.0% Percentage of Population Dead: 0.0% Total People Infected: 12 / 100 Total Deaths: 0 / 100 O-O-O-I-O-O-I-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-I-O-O-O-O-I-O-O-I-O-OO-O-O-O-O-O-O-O-I-O-I-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-I-O-I-O-O-O-IO-O-O-O-O-O-O-O-O-O-O-I-I-O-O-O-O-O-O-OPress enter to begin the simulation. -----Day # 2----Percentage of Population Infected: 18.0% Percentage of Population Dead: 6.0% Total People Infected: 18 / 100 Total Deaths: 6 / 100 O-O-I-I-I-O-X-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-X-I-O-O-O-I-O-O-I-O-O-OO-O-O-O-O-O-O-I-X-X-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-I-I-O-I-O-O-O-I-O-O -O-O-O-O-O-O-O-O-X-X-I-O-O-O-O-O-O-OPress enter to advance to the next day. -----Day # 3----Percentage of Population Infected: 21.0% Percentage of Population Dead: 11.0% Total People Infected: 21 / 100 Total Deaths: 11 / 100 O-O-I-I-I-X-X-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-X-I-O-O-O-I-O-I-X-O-O-OO-O-O-O-O-O-O-I-X-X-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-I-I-O-I-O-O-O-X-XO-O-O-O-O-O-O-O-O-X-X-X-O-O-O-O-O-O-OPress enter to advance to the next day. -----Day # 4----Percentage of Population Infected: 24.0% Percentage of Population Dead: 17.0% Page 217 Total People Infected: 24 / 100 Total Deaths: 17 / 100 O-O-I-O-I-X-X-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-X-I-X-X-I-X-O-I-X-X-O-OO-O-O-O-O-O-O-O-X-X-I-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-X-X-O-O-O-O-O-XX-O-O-O-O-O-O-O-O-O-X-X-X-I-O-O-O-O-O-OPress enter to advance to the next day. -----Day # 5----Percentage of Population Infected: 29.0% Percentage of Population Dead: 21.0% Total People Infected: 29 / 100 Total Deaths: 21 / 100 O-I-O-O-X-X-X-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-X-O-X-X-I-X-O-X-X-X-I-X -X-O-O-O-O-O-O-O-X-X-I-I-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-I-X-X-O-O-O-O-I-X-XO-O-O-O-O-O-O-O-O-X-X-X-I-O-O-O-O-O-OPress enter to advance to the next day. -----Day # 6----Percentage of Population Infected: 33.0% Percentage of Population Dead: 26.0% Total People Infected: 33 / 100 Total Deaths: 26 / 100 X-I-O-X-X-X-X-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-X-I-X-X-I-X-O-X-X-X-X-XX-O-O-O-O-O-O-X-X-X-I-I-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-X-X-X-O-O-O-O-I-X-XO-O-O-O-O-O-O-O-O-X-X-X-I-O-O-O-O-O-OPress enter to advance to the next day. -----Day # 7----Percentage of Population Infected: 34.0% Percentage of Population Dead: 29.0% Total People Infected: 34 / 100 Total Deaths: 29 / 100 X-I-O-X-X-X-X-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-X-I-X-X-O-X-O-X-X-X-XX-X-O-O-O-O-O-I-X-X-X-X-I-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-X-X-X-O-O-O-O-X-XX-O-O-O-O-O-O-O-O-I-X-X-X-X-O-O-O-O-O-OPress enter to advance to the next day. -----Day # 8----Percentage of Population Infected: 38.0% Percentage of Population Dead: 32.0% Total People Infected: 38 / 100 Total Deaths: 32 / 100 X-O-O-X-X-X-X-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-X-I-X-X-O-X-I-X-X-X-XX-X-X-I-O-O-O-X-X-X-X-X-X-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-I-X-X-X-O-O-O-O-X-X-X -O-O-O-O-O-O-O-I-I-X-X-X-X-O-O-O-O-O-O- Page 218 Press enter to advance to the next day. -----Day # 9----Percentage of Population Infected: 41.0% Percentage of Population Dead: 37.0% Total People Infected: 41 / 100 Total Deaths: 37 / 100 X-O-X-X-X-X-X-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-X-X-X-X-O-X-I-X-X-X-XX-X-X-X-O-O-O-X-X-X-X-X-X-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-X-I-X-X-X-O-O-O-O-X-XX-O-O-O-O-O-O-O-X-I-X-X-X-X-I-O-O-O-O-OPress enter to advance to the next day. -----Day # 10----Percentage of Population Infected: 44.0% Percentage of Population Dead: 40.0% Total People Infected: 44 / 100 Total Deaths: 40 / 100 X-I-X-X-X-X-X-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-X-X-X-X-I-X-X-X-X-X-X-X -X-X-X-O-O-O-X-X-X-X-X-X-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-X-X-X-X-X-X-O-O-O-X-X-X -O-O-O-O-O-O-I-X-O-X-X-X-X-I-O-O-O-O-O- Page 219 1 2 3 4 5 6 7 8 9 10 11 12 #Classes Challenge 39: import random Epidemic Outbreak Terminal App class Simulation(): """A class to control the simulation and help facilitate in the spread of the disease.""" def __init__(self): """Initialize attributes""" self.day_number = 1 #Get simulation initial conditions from the user print("To simulate an epidemic outbreak, we must know the population size.") 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 self.population_size = int(input("---Enter the population size: ")) print("\nWe must first start by infecting a portion of the population.") self.infection_percent = float(input("---Enter the percentage (0-100) of the population to initially infect: ")) self.infection_percent /= 100 print("\nWe must know the risk a person has to contract the disease when exposed.") self.infection_probability = float(input("---Enter the probability (0-100) that a person gets infected when exposed to the disease: ")) print("\nWe must know how long the infection will last when exposed.") self.infection_duration = int(input("---Enter the duration (in days) of the infection: ")) print("\nWe must know the mortality rate of those infected.") self.mortality_rate = float(input("---Enter the mortality rate (0-100) of the infection: ")) print("\nWe must know how long to run the simulation.") self.sim_days = int(input("---Enter the number of days to simulate: ")) class Person(): """A class to model an individual person in a population.""" def __init__(self): """Initialize attributes""" self.is_infected = False #Person starts healthy, not infected self.is_dead = False #Person starts ALIVE self.days_infected = 0 #Keeps track of days infected for individual person def infect(self, simulation): """Infect a person based on sim conditions""" #random number generated must be less than infection_probability to infect if random.randint(0, 100) < simulation.infection_probability: self.is_infected = True def heal(self): """Heals a person from an infection""" self.is_infected = False self.days_infected = 0 def die(self): Page 220 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 """Kill a person""" self.is_dead = True def update(self, simulation): """Update an individual person if the person is not dead. Check if they are infected If they are, increase the days infected count, then check if they should die or be healed.""" #Check if the person is not dead before updating if not self.is_dead: #Check if the person is infected if self.is_infected: self.days_infected += 1 #Check to see if the person will die if random.randint(0, 100) < simulation.mortality_rate: self.die() #Check if the infection is over, if it is, heal the person elif self.days_infected == simulation.infection_duration: self.heal() class Population(): """A class to model a whole population of Person objects""" def __init__(self, simulation): """Initialize attributes""" self.population = [] #A list to hold all Person instances once created #Create the correct number of Person instances based on the sim conditions for i in range(simulation.population_size): person = Person() self.population.append(person) def initial_infection(self, simulation): """Infect an initial portion of the population.""" #The number of people to infect is found by taking the pop size * infection percentage #We must round to 0 decimals and cast to an int so we can use infected_count in a for loop. infected_count = int(round(simulation.infection_percent*simulation.population_size, 0)) #Infect the correct number of people for i in range(infected_count): #Infect the ith person in the population attribute self.population[i].is_infected = True self.population[i].days_infected = 1 #Shuffle the population list so we spread the infection out randomly random.shuffle(self.population) def spread_infection(self, simulation): """Spread the infection to all adjacent people in the list population.""" for i in range(len(self.population)): #ith person is ALIVE, see if they should be infected. #Don't bother infecting a dead person, they are infected and dead. #Check to see if adjacent Persons are infected if self.population[i].is_dead == False: #i is the first person in the list, can only check to the right [i+1]. Page 221 if i == 0: if self.population[i+1].is_infected: self.population[i].infect(simulation) #i is in the middle of the list, can check to the left [i-1] and 113 114 115 116 right [i+1]. 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 elif i < len(self.population)-1: if self.population[i-1].is_infected or self.population[i+1].is_infected: self.population[i].infect(simulation) #i is the last person in the list, can only check to the left [i-1]. elif i == len(self.population)-1: if self.population[i-1].is_infected: self.population[i].infect(simulation) def update(self, simulation): """Update the whole population by updating each individual person in the population.""" simulation.day_number += 1 #Call the update method for all person instances in the population for person in self.population: person.update(simulation) def display_statistics(self, simulation): """Display the current statistics of a population.""" #Initialize values total_infected_count = 0 total_death_count = 0 #Loop through whole population for person in self.population: #Person is infected if person.is_infected: total_infected_count += 1 #Person is dead if person.is_dead: total_death_count += 1 #Calculate percentage of population that is infected and dead infected_percent = round(100*(total_infected_count/ simulation.population_size), 4) death_percent = round(100*(total_death_count/ simulation.population_size), 4) 153 154 155 156 #Statistics summary print("\n-----Day # " + str(simulation.day_number) + "-----") print("Percentage of Population Infected: " + str(infected_percent) + "%") 157 158 159 160 161 162 163 164 print("Percentage of Population Dead: " + str(death_percent) + "%") print("Total People Infected: " + str(total_infected_count) + " / " + str(simulation.population_size)) print("Total Deaths: " + str(total_death_count) + " / " + str(simulation.population_size)) def graphics(self): """A graphical representation for a population. O is healthy, I infected, X dead.""" status = [] #A list to hold all X, I, and O to represent the status of each person 165 Page 222 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 for person in self.population: #Person is dead, X if person.is_dead: char = 'X' #Person is alive, are they infected or healthy? else: #Person is infected, I if person.is_infected: char = 'I' #Person is healthy, O else: char = 'O' status.append(char) #Print out all status characters separated by a for letter in status: print(letter, end='-') #The main code #Create a simulation and population object sim = Simulation() pop = Population(sim) #Set the initial infection conditions of the population pop.initial_infection(sim) pop.display_statistics(sim) pop.graphics() input("\nPress enter to begin the simulation") #Run the simulation for i in range(1, sim.sim_days): #For a single day, spread the infection, update the population, display statistics and graphics pop.spread_infection(sim) pop.update(sim) pop.display_statistics(sim) pop.graphics() #If it is not the last day of the simulation, pause the program if i != sim.sim_days - 1: input("\nPress enter to advance to the next day.") Return to index Page 223 Classes Challenge 40: Epidemic Outbreak GUI App Description: You will be responsible for writing a program that simulates the spread of an infectious disease throughout a population similar to the previous program. Using classes, you will model an individual person’s and an entire population’s attributes and behaviors. Your program will allow users to set various initial conditions in regards to the infection such as population size, infection rate, mortality rate, and infection duration. The program will then simulate the interaction of people within a population and spread the disease. Each iteration of spreading the disease will result in a summary displaying statistics of the population. This time however, rather than storing the population in a list and checking if the person to the left or right of the current person is infected, we will store the population in a two dimensional list using nested for loops. This will allow us to check for infections both to the left and right and above and below. This added feature will help allow the program to create a Graphical User Interface or GUI (goo-e) to visually show the spread of the infection. Rather than representing the spread of the infection using O, I, and X in the terminal, each person in the population will be represented by a color square in a GUI; green being healthy, yellow being infected, and red being dead. Step BY Step Guide: Defining your classes ● Define a class Simulation ● Define a class Person ● Define a class Population Defining your class methods The Simulation Class ● Define an __init__() method for the Simulation class, which takes one parameter, the required self parameter. ○ Initialize an attribute called day_number and set it equal to 1. ○ ○ ○ ○ ○ Print a message about needing to know population size. Get user input for the population size. For visual purposes, we only want user input that is a perfect square. Create a variable root and set it equal to the square root of the given population size. ■ Type import math as the first line of code in your program. If int(root + .5)**2 is not equal to the given population size, then you do not have a perfect square: ■ The reason is that the int function will round the decimal value. If we add .5 to the root, unless it is a perfect square, it will always be rounded up and the condition will hold. ● For example, if the user entered in 79, the square root of 79 is 8.8881. ● Adding 0.5 to that yields 9.3881. Page 224 ● ● ● ○ ○ ○ ○ ○ ○ Taking the int of that yields 9. Squaring that yields 81. Since 81 is not equal to 79, we must change the simulations population_size attribute.. ■ Round root to 0 decimals. ● In our example, the user entered 79. ● Taking the root yields 8.8881. ● Rounding this to zero decimals yields 9. ■ Initialize an attribute called grid_size and set it equal to the integer value of root. ■ Set the attribute population_size equal to the grid_size attribute squared. ● This will be used to create an NxN grid. In our previous example, the grid would be 9x9 for 81 people in the population. ■ Print a message informing the user that the program is rounding the population to the given size for visual purposes. Else, the given population is a perfect square: ■ Initialize an attribute called grid_size and set it equal to the square of the population_size attribute. Store the response in an attribute called population_size. Print a message about needing to know the percentage of the population initially infected. Get user input for the starting infection size. ■ Divide this value by 100 to turn it into a percentage. Store the response in an attribute called infection_percent. ○ ○ Print a message about needing to know the probability that a person will get infected if they come in contact with the disease. Get user input for the infection probability. Store the response in an attribute called infection_probability. ○ ○ ○ Print a message about needing to know how long the infection will last. Get user input for the infection duration. Store the response in an attribute called infection_duration. ○ ○ ○ Print a message about needing to know the mortality rate of those infected. Get user input for the mortality rate. Store the response in an attribute called mortality_rate. ○ ○ ○ Print a message about needing to know how long to run the simulation for. Get user input for the number of days to simulate. Store the response in an attribute called sim_days. The Person Class Page 225 ● Define an __init__() method for the Person class which takes one parameter, the required self parameter. ○ Initialize an attribute called is_infected and set it equal to False. ○ Initialize an attribute called is_dead and set it equal to False. ○ Initialize an attribute called days_infected and set it equal to zero. ● Define an infect() method for the Person class which takes two parameters, the required self parameter, and a simulation object. ○ Create a random integer from 0 to 100 to represent the chance this individual person becomes infected. ■ Type import random as the first line of code in your program. ○ If this value if less that the simulations infection_probability attribute: ■ Infect the person by setting their is_infected attribute to True. ● Define a heal() method for the Person class which takes one parameter, the required self parameter. ○ Set the persons is_infected attribute to False. ○ Set the persons days_infected attribute to 0. ● Define a die() method for the Person class which takes one parameter, the required self parameter. ○ Set the persons is_dead attribute to True. ● Define an update() method for the Person class which takes two parameters, the required self parameter and a simulation object. ○ First, check that the person is not dead. If the person is not dead: ■ Check if they are infected. If the person is infected: ● Increase their days_infected attribute by 1. ● Create a random integer from 0 to 100. ● If this integer is less than the simulations mortality_rate attribute: ○ Call the persons die() method to kill the person. ● Elif, the person didn’t die, check to see if they can be healed. If the persons days_infected attribute is equal to the simulations infection_duration attribute: ○ Call the persons heal() method to heal the person. The Population Class ● Define an __init__() method for the Population class, which takes two parameters, the required self parameter, and a simulation object. ○ Initialize an attribute called population and set it equal to a blank list. This list will represent a two dimensional list or array. ■ This list will be a list of N lists. ■ Each list within the list will represent a row in an NxN grid. ■ Each element of the row will represent a Person object. ■ Each of these lists will hold N Person objects. Page 226 ○ Use a for loop to loop through the needed number of rows. This information is stored in the simulation objects grid_size attribute. For each iteration of the loop you should: ■ Create a variable called row and set it equal to a blank list. ■ Loop through the needed number of Person objects. This information is stored in the simulation objects grid_size attribute. For each iteration of the loop you should: ● Create a person object. ● Append the person to the row. ■ Append the completed row to the Populations population attribute. ● Define an initial_infection() method for the Population class, which takes two parameters, the required self parameter, and a simulation object. ○ Create a variable called infected_count. This will represent the number of people who must start infected based on the user’s initial conditions. ○ To determine this value, multiply the simulation objects infection_percent and population_size attributes together. ■ Round this value to zero decimals. ■ Cast this value to an integer so we can use it in a for loop. ○ Create a variable infections and set it equal to 0. ○ While infections is less than infected_count: ■ Create a random integer x from zero to the simulations grid_size attribute - 1. ■ Create a random integer y from zero to the simulations grid_size attribute - 1. ■ self.population[x][y] represents an individual person in the two dimensional list. ■ If this given person is not infected: ● Set the is_infected attribute to True for the current person in the population. ● Set the days_infected attribute to 1 for the current Person in the population. ● Increment the infections variable by 1. ● Define a spread_infection() method for the Population class which takes two parameters, the required self parameter, and a simulation object. ○ Use a numerical for loop to loop through the simulations grid_size attribute. This represents each row of the grid. Each iteration you should: ■ Use a numerical for loop to loop through the simulations grid_size attribute. This represents an individual Person object in a row. Each iteration you should: ● Check if the is_dead attribute is False for the current person in the population, meaning they are currently alive. If they are alive we will check to spread the infection. ● If i is equal to 0: Page 227 ○ ■ This is the first row in the population list, so you cannot check rows above. ○ If j is equal to 0: ■ This is the first person in the first row. You cannot check to the left. ○ Elif j is equal to the simulation objects grid_size attribute 1: ■ This is the last person in the first row. You cannot check to the right. ○ Else: ■ You can check to the right, left, and below. ● If i is equal to the simulation objects grid_size attribute - 1: ○ This is the last row in the population list, so you cannot check rows below: ○ If j is equal to 0: ■ This is the first person in the last row. You cannot check to the left. ○ Elif j is equal to the simulation objects grid_size attribute 1: ■ This is the last person in the last row. You cannot check to the right. ○ Else: ■ You can check to the right, left, and above. ● Else: ○ i represents any row other than the first or last row in the grid. ○ You can check to the left, right, above, and below. ○ If j is equal to 0: ■ This is the first person in a row. You cannot check to the left. ○ Elif j is equal to the simulation objects grid_size attribute 1: ■ This is the last person in a row. You cannot check to the right. ○ Else: ■ You can check to the right, left, above, and below. Recall, an individual Person object in this function is represented by self.population[i][j]. ● To check if the person to the right is infected: ○ self.population[i][j+1].is_infected ● To check if the person to the left is infected: ○ self.population[i][j-1].is_infected ● To check if the person above is infected: ○ self.population[i-1][j].is_infected ● To check if the person below is infected: Page 228 ■ ○ self.population[i+1][j].is_infected Make the appropriate checks based on the position of the current Person object in the loop. If any of the adjacent Person objects in the NxN grid are infected, call the current persons infect() method. ● self.population[i][j].infect() ● Define an update() method for the Population class which takes two parameters, the required self parameter, and a simulation object. ○ Increase the simulation objects day_number attribute by 1. ○ Loop through the population list. Recall that each element in this list is another list that represents a row in an NxN grid. For each iteration you should: ■ Loop through the elements of the row. For each iteration you should: ● Call the Persons update() method. ● Define a display_statistics() method which takes two parameters, the required self parameter, and a simulation object. ○ Create a variable total_infected_count and set it equal to 0. ○ Create a variable total_death_count and set it equal to 0. ○ Loop through the population list. Recall that each element in this list is another list that represents a row in an NxN grid. For each iteration you should: ■ Loop through each element of the row: For each iteration you should: ● Check if the current Person is infected. If they are: ○ Increment total_infected_count by 1. ○ Check if the current Person is dead. If they are: ■ Increment total_death_count by 1. ○ Create a variable infected_percent and calculate the percentage of the population that is infected. ■ Round this value to 4 decimals. ○ Create a variable death_percent and calculate the percentage of the population that is dead. ■ Round this value to 4 decimals. ○ Print a summary of the population statistics for the current day of the simulation. ■ This should include the day number. ■ The percentage of the population infected. ■ The percentage of the population that is dead. ■ The total number of people infected. ■ The total number of deaths that have occured. ■ See example output for formatting. Defining your functions ● Define a function graphics() which is not associated with any Class. This function should have three parameters, a Simulation object, a Population object, and a canvas. This is a helper function that will draw squares, that represent a Person object, onto a Tkinter canvas. Page 229 ○ ○ Create a variable square_dimension and set it equal to 600 divided by the simulation objects grid_size attribute. ■ Make sure to use floor division //. ■ I am using 600 because that is the size of the overall GUI window 600 x 600. If you decide to change your window size, change this value. Use a numerical for loop to loop through all of the possible rows of the grid. This is represented by the simulation objects grid_size attribute. For each iteration: ■ Define a variable y and set it equal to i*square_dimension. ■ Use a numerical for loop to loop through all of the possible people in each row of the grid. This is represented by the simulation objects grid_size attribute. For each iteration: ● Define a variable x and set it equal to j*square_dimension. ● If the Person object stored at index i, j in the Population object is dead: ○ Draw a red rectangle onto the Tkinter canvas. ○ canvas.create_rectangle(x, y, x+square_dimension, y+square_dimension, fill=”red”) ● Else: ○ If the Person object stored at index i,j in the Population object is infected: ■ Draw a yellow rectangle onto the Tkinter canvas. ■ canvas.create_rectangle(x, y, x+square_dimension, y+square_dimension, fill=”Yellow”) ○ Else: ■ The person is healthy. ■ Draw a green rectangle onto the Tkinter canvas. ■ canvas.create_rectangle(x, y, x+square_dimension, y+square_dimension, fill=”green”) The main code ● Create a Simulation object. ● ● Create a constant variable called WINDOW_WIDTH and set it equal to 600. Create a constant variable called WINDOW_HEIGHT and set it equal to 600. ● Create a Tkinter window and canvas. ○ Tkinter is a library which allows users to make a graphical user interface (GUI) for their python applications. ○ Type import tkinter as the first line of code in your program. ● Create a tkinter object, set it as our window, and give the window a title. ○ sim_window = tkinter.Tk() ○ sim_window.title(“Epidemic Outbreak”) Page 230 ● Create a canvas object that we can draw on and assign it to the created window. ○ sim_canvas = tkinter.Canvas(sim_window, width=WINDOW_WIDTH, height=WINDOW_HEIGHT, bg=”lightblue”) ○ sim_canvas.pack(side=tkinter.LEFT) ● Create a Population object. ● ● ● Call the Populations initial_infection() method. Call the Populations display_statistics() method. Prompt the user to press enter to being the simulation. ● Use a for loop to simulate each day of the simulation. For each iteration you should: ○ Spread the infection by calling the Populations spread_infection() method. ○ Update the population by calling the Populations update() method. ○ Display the statistics for the current day by calling the Populations display_statistics() method. ○ Show the graphics of the data by calling the graphics() function. ○ Use tkinters built in update() method on to update the window. ■ sim_window.update() ○ If you are currently not on the last day of the simulation: ■ Use tkinters built in delete() method to erase the previously draw information on the given canvas. ● sim_canvas.delete(“all”) Example Output: To simulate an epidemic outbreak, we must know the population size. ---Enter the population size: 9700 Rounding population size to 9604 for visual purposes. We must first start by infecting a portion of the population. --Enter the percentage (0-100) of the population to initially infect: 3 We must know the risk a person has to contract the disease when exposed. --Enter the probability (0-100) that a person gets infected when exposed to the disease: 15 We must know how long the infection will last when exposed. --Enter the duration (in days) of the infection: 5 we must know the mortality rate of those infected. --Enter the mortality rate (0-100) of the infection: 10 We must know how long to run the simulation. --Enter the number of days to simulate: 365 Page 231 -----Day # 1----Percentage of Population Infected: 2.9988% Percent of Population Dead: 0.0% Total People Infected: 288 / 9604 Total Deaths: 0 / 9604 Press enter to begin simulation. -----Day # 2----Percentage of Population Infected: 4.7168% Percent of Population Dead: 0.5831% Total People Infected: 453 / 9604 Total Deaths: 56 / 9604 -----Day # 3----Percentage of Population Infected: 6.8721% Percent of Population Dead: 1.3744% Total People Infected: 660 / 9604 Total Deaths: 132 / 9604 -----Day # 4----Percentage of Population Infected: 9.5377% Percent of Population Dead: 2.2178% Total People Infected: 916 / 9604 Total Deaths: 213 / 9604 -----Day # 5----Percentage of Population Infected: 10.7039% Percent of Population Dead: 3.2799% Total People Infected: 1028 / 9604 Total Deaths: 315 / 9604 ****CUT FOR BREVITY**** Page 232 Example Screenshots: Page 233 Page 234 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #Classes Challenge 40: import math import random import tkinter Epidemic Outbreak GUI App class Simulation(): """A class to control a simulation and facilitate the spread of a disease.""" def __init__(self): """Initialize attributes""" self.day_number = 1 #Get simulation initial conditions from the user #Population size must be a perfect square for this program print("To simulate an epidemic outbreak, we must know the population size.") self.population_size = int(input("---Enter the population size: ")) #Convert users population size to nearest perfect square for visual 16 17 purposes 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 root = math.sqrt(self.population_size) #For example, if population_size is 79, root = 8.8881 #User did not enter a perfect square for the population if int(root + .5)**2 != self.population_size: # int(8.881 +.5)**2 = int(9.3881)**2 = 9**2 = 81 != 79 root = round(root, 0) # round(8.881, 0) = 9.0 self.grid_size = int(root) #grid_size = 9 self.population_size = self.grid_size**2 #population_size = 9*9 = 81 the closest PERFECT SQUARE TO 79 print("Rounding population size to " + str(self.population_size) + " for visual purposes.") #The user did enter a perfect square for the population else: self.grid_size = int(math.sqrt(self.population_size)) print("\nWe must first start by infecting a portion of the population.") self.infection_percent = float(input("---Enter the percentage (0-100) of the population to initially infect: ")) self.infection_percent /= 100 print("\nWe must know the risk a person has to contract the disease when exposed.") self.infection_probability = float(input("---Enter the probability (0-100) that a person gets infected when exposed to the disease: ")) print("\nWe must know how long the infection will last when exposed.") self.infection_duration = int(input("---Enter the duration (in days) of the infection: ")) print("\nWe must know the mortality rate of those infected.") self.mortality_rate = float(input("---Enter the mortality rate (0-100) of the infection: ")) print("\nWe must know how long to run the simulation.") self.sim_days = int(input("---Enter the number of days to simulate: ")) class Person(): """A class to model an individual person.""" def __init__(self): """Initialize attributes""" self.is_infected = False #Person starts healthy, not infected self.is_dead = False #Person starts ALIVE Page 235 self.days_infected = 0 #Keeps track of days infected for individual 54 person 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 def infect(self, simulation): """Infect a person based on sim conditions""" #random number generated must be less than infection_probability to infect if random.randint(0, 100) < simulation.infection_probability: self.is_infected = True def heal(self): """Heals a person from an infection""" self.is_infected = False self.days_infected = 0 def die(self): """Kill a person""" self.is_dead = True def update(self, simulation): """Update an individual person if the person is not dead. Check if they are infected If they are, increase the days infected count, then check if they should die or be healed.""" #Check if the person is not dead before updating if not self.is_dead: #Check if the person is infected if self.is_infected: self.days_infected += 1 #Check to see if the person will die if random.randint(0, 100) < simulation.mortality_rate: self.die() #Check if the infection is over, if it is, heal the person elif self.days_infected == simulation.infection_duration: self.heal() class Population(): """A class to model a whole population of Person objects""" def __init__(self, simulation): """Initialize attributes""" #This will be a list of N lists, where N is the simulation grid size. #Each list within the list will represent a row in an NxN grid. #Each element of the row will represent an individual Person object. #Each of these lists will hold N Person objects and there will be N lists. self.population = [] #A list to hold all Persons in the population. #Loop through the needed number of rows for i in range(simulation.grid_size): row = [] #Loop through the needed number of Person objects for each row for j in range(simulation.grid_size): person = Person() row.append(person) #The entire row is complete, append it to the population self.population.append(row) Page 236 113 114 115 116 117 def initial_infection(self, simulation): """Infect an initial portion of the population based on initial conditions of the sim""" #Infect the infection_percent*population_size gives the total number to infect #Round to 0 decimals and cast to int so it can be used in a loop. infected_count = int(round(simulation.infection_percent*simulation.population_size, 0)) 118 119 120 infections = 0 #Infect the population until you have infected the correct starting amount 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 while infections < infected_count: #x is a random row in the population, y is a random person in the random row #self.population[x][y] represents a random person in the population list x = random.randint(0, simulation.grid_size - 1) y = random.randint(0, simulation.grid_size - 1) #If the person is not infected, infect them! if not self.population[x][y].is_infected: self.population[x][y].is_infected = True self.population[x][y].days_infected = 1 infections += 1 def spread_infection(self, simulation): """Spread the infection in a 2D array to all adjacent people to a given person. A given person in the population attribute is referenced as self.population[i][j] A person to the right of the given person is referenced as self.population[i][j+1] A person to the left of the given person is referenced as self.population[i][j-1] A person below the given person is referenced as self.population[i+1] [j] A person above the given person is referenced as self.population[i-1] [j]""" 141 142 143 144 145 146 #Loop through all rows of the population for i in range(simulation.grid_size): #Loop through all of the Person objects in a given row for j in range(simulation.grid_size): #Check to see if this given person self.population[i][j] is not dead 147 148 149 150 151 152 153 154 155 156 157 158 159 if self.population[i][j].is_dead == False: #Check to see if we need to infect this person. #We will try infect the given person if an adjacent person is already infected #If i == 0, we are in the first row so, we can't look above if i == 0: #If j == 0, we are in the first column, so we can't look left. if j == 0: if self.population[i][j+1].is_infected or self.population[i+1][j].is_infected: self.population[i][j].infect(simulation) #If we are in the last column, we can't look right elif j == simulation.grid_size-1: if self.population[i][j-1].is_infected or self.population[i+1][j].is_infected: self.population[i][j].infect(simulation) Page 237 #If we are in any other column, we can look left, right, 160 or below 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 else: if self.population[i][j-1].is_infected or self.population[i][j+1].is_infected or self.population[i+1][j].is_infected: self.population[i][j].infect(simulation) #If i == simulation.grid_size -1 we are in the last row, so we can't look below elif i == simulation.grid_size-1: #If j == 0, we are in the first column, so we can't look left. if j == 0: if self.population[i][j+1].is_infected or self.population[i-1][j].is_infected: self.population[i][j].infect(simulation) #If we are in the last column, we can't look right elif j == simulation.grid_size-1: if self.population[i][j-1].is_infected or self.population[i-1][j].is_infected: self.population[i][j].infect(simulation) #If we are in any other column, we can look left, right, or above else: if self.population[i][j-1].is_infected or self.population[i][j+1].is_infected or self.population[i-1][j].is_infected: self.population[i][j].infect(simulation) #Otherwise, we are in a row in between, we can look left, right, below or above else: #If j == 0, we are in the first column, so we can't look left. if j == 0: if self.population[i][j+1].is_infected or self.population[i+1][j].is_infected or self.population[i-1][j].is_infected: self.population[i][j].infect(simulation) #If we are in the last column, we can't look right elif j == simulation.grid_size-1: if self.population[i][j-1].is_infected or self.population[i+1][j].is_infected or self.population[i-1][j].is_infected: self.population[i][j].infect(simulation) #If we are in any other column, we can look left, right, below, or above else: if self.population[i][j-1].is_infected or self.population[i][j+1].is_infected or self.population[i+1][j].is_infected or self.population[i-1][j].is_infected: self.population[i][j].infect(simulation) def update(self, simulation): """Update the whole population by updating each individual Person""" simulation.day_number += 1 #Loop through the population to access each row for row in self.population: #Loop through the row to update each Person for person in row: person.update(simulation) def display_statistics(self, simulation): """Display the statistics of the population""" #Initialize values total_infected_count = 0 total_death_count = 0 Page 238 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 #Loop through the population to access each row for row in self.population: #Loop through the row to access each person for person in row: #Person is infected if person.is_infected: total_infected_count += 1 #Person is dead if person.is_dead: total_death_count += 1 #Calculate percentage of population that is infected and dead infected_percent = round(100*(total_infected_count/ simulation.population_size), 4) death_percent = round(100*(total_death_count/ simulation.population_size), 4) 224 225 226 227 #Statistics summary print("\n-----Day # " + str(simulation.day_number) + "-----") print("Percentage of Population Infected: " + str(infected_percent) + "%") 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 print("Percentage of Population Dead: " + str(death_percent) + "%") print("Total People Infected: " + str(total_infected_count) + " / " + str(simulation.population_size)) print("Total Deaths: " + str(total_death_count) + " / " + str(simulation.population_size)) #A helper function to create graphics def graphics(simulation, population, canvas): """A helper function to update the tkinter display.""" #Get the dimensions of an individual square in a grid #Each square represents a person in the population #Use 600 for a GUI window that is 600x600, change if desired. #To get the dimensions of a square, take the dimensions of the window and divide by total number of squares in a row square_dimension = 600//simulation.grid_size #Loop through all rows in the population for i in range(simulation.grid_size): #y is the starting index of where a given square should be drawn y = i*square_dimension #Loop through all persons in the row for j in range(simulation.grid_size): #x is the starting index of where a given square should be drawn. x = j*square_dimension #Check to see if the given person is dead if population.population[i][j].is_dead: #Create a red square at the correct location canvas.create_rectangle(x, y, x+square_dimension, y+square_dimension, fill='red') #The current person is not dead, check if they are infected or healthy else: if population.population[i][j].is_infected: #Create a yellow square at the correct location canvas.create_rectangle(x, y, x+square_dimension, y+square_dimension, fill='yellow') else: canvas.create_rectangle(x, y, x+square_dimension, y+square_dimension, fill='green') 262 Page 239 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 #The main code #Create a simulation object sim = Simulation() #Set constant variables for window size WINDOW_WIDTH = 600 WINDOW_HEIGHT = 600 #Create the tkinter window and canvas sim_window = tkinter.Tk() sim_window.title("Epidemic Outbreak") sim_canvas = tkinter.Canvas(sim_window, width=WINDOW_WIDTH, height=WINDOW_HEIGHT, bg='lightblue') sim_canvas.pack(side=tkinter.LEFT) #Create a population object pop = Population(sim) #Set the initial conditions of the population pop.initial_infection(sim) pop.display_statistics(sim) input("Press Enter to begin simulation.") #Run the simulation for i in range(1, sim.sim_days): pop.spread_infection(sim) pop.update(sim) pop.display_statistics(sim) graphics(sim, pop, sim_canvas) #Update the tkinter window to reflect the graphics change sim_window.update() #If we are currently not on the last day of the simulation, wipe the canvas clean if i != sim.sim_days-1: sim_canvas.delete('all') Return to index Page 240