├── .gitignore ├── README.md ├── Snippet_CCS-07.py ├── Snippet_CCS-10.py ├── Snippet_CCS-08.py ├── LICENSE.txt ├── Snippet_CCS-01.py ├── coffee_shop_simulator_tests.py ├── Snippet_CCS-15.py ├── main.py ├── Snippet_CCS-13.py ├── Snippet_CCS-02.py ├── Snippet_CCS-04.py ├── Snippet_CCS-03.py ├── Snippet_CCS-05.py ├── Snippet_CCS-09.py ├── Snippet_CCS-11.py ├── Snippet_CCS-06.py ├── Snippet_CCS-12.py ├── coffee_shop_simulator.py └── Snippet_CCS-14.py /.gitignore: -------------------------------------------------------------------------------- 1 | savegame.dat 2 | .idea 3 | .DS_Store 4 | __pycache__ 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Coffee Shop Simulator 2 | *From the Python QuickStart Guide by Clydebank Media* 3 | 4 | Copyright (C) 2022 ClydeBank Media, All Rights Reserved. 5 | -------------------------------------------------------------------------------- /Snippet_CCS-07.py: -------------------------------------------------------------------------------- 1 | # ClydeBank Coffee Shop Simulator 4000 2 | # Copyright 2022 (C) ClydeBank Media, All Rights Reserved. 3 | 4 | # Import all functions from the utility module 5 | from utilities import * 6 | 7 | # Import the game class from the coffee_shop_simulator module 8 | from coffee_shop_simulator import CoffeeShopSimulator 9 | 10 | # Print welcome message 11 | welcome() 12 | 13 | # Get name and store name 14 | t_name = prompt("What is your name?", True) 15 | t_shop_name = prompt("What do you want to name your coffee shop?", True) 16 | 17 | # Create the game object 18 | game = CoffeeShopSimulator(t_name, t_shop_name) 19 | 20 | # Run the game 21 | game.run() 22 | -------------------------------------------------------------------------------- /Snippet_CCS-10.py: -------------------------------------------------------------------------------- 1 | # ClydeBank Coffee Shop Simulator 4000 2 | # Copyright 2022 (C) ClydeBank Media, All Rights Reserved. 3 | 4 | # Import all functions from the utility module 5 | from utilities import * 6 | 7 | # Import the game class from the coffee_shop_simulator module 8 | from coffee_shop_simulator import CoffeeShopSimulator 9 | 10 | # Print welcome message 11 | welcome() 12 | 13 | # Get name and store name 14 | t_name = prompt("What is your name?", True) 15 | t_shop_name = prompt("What do you want to name your coffee shop?", True) 16 | 17 | # Create the game object 18 | game = CoffeeShopSimulator(t_name, t_shop_name) 19 | 20 | # Run the game 21 | game.run() 22 | 23 | # Say goodbye! 24 | print("\nThanks for playing. Have a great rest of your day!\n") 25 | -------------------------------------------------------------------------------- /Snippet_CCS-08.py: -------------------------------------------------------------------------------- 1 | def welcome(): 2 | print("ClydeBank Coffee Shop Simulator 4000, Version 1.00") 3 | print("Copyright (C) 2022 ClydeBank Media, All Rights Reserved.\n") 4 | print("Let's collect some information before we start the game.\n") 5 | 6 | 7 | def prompt(display="Please input a string", require=True): 8 | if require: 9 | s = False 10 | while not s: 11 | s = input(display + " ") 12 | else: 13 | s = input(display + " ") 14 | return s 15 | 16 | 17 | def convert_to_float(s): 18 | # If conversion fails, assign it to 0 19 | try: 20 | f = float(s) 21 | except ValueError: 22 | f = 0 23 | return f 24 | 25 | 26 | def x_of_y(x, y): 27 | num_list = [] 28 | # Return a list of x numbers of y 29 | for i in range(x): 30 | num_list.append(y) 31 | return num_list 32 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | ClydeBank Media Educational Use License 2 | Version 1.0 — October 2025 3 | 4 | Copyright © 2025 ClydeBank Media LLC. All rights reserved. 5 | 6 | This repository is provided for educational use by customers and users of ClydeBank Media’s learning programs. 7 | 8 | Permissions: 9 | - You may view, copy, and modify the code in this repository for your own personal, non-commercial learning and experimentation. 10 | 11 | Restrictions: 12 | - You may not redistribute, republish, or share this code or any modified versions publicly. 13 | - You may not use this code or derivatives for commercial purposes, products, or services. 14 | - You may not remove or alter this license or any copyright notices. 15 | 16 | Disclaimer: 17 | This code is provided “as is,” without warranty of any kind. ClydeBank Media makes no guarantees regarding fitness for any particular purpose. 18 | -------------------------------------------------------------------------------- /Snippet_CCS-01.py: -------------------------------------------------------------------------------- 1 | # ClydeBank Coffee Shop Simulator 4000 2 | # Copyright 2022 (C) ClydeBank Media, All Rights Reserved. 3 | 4 | print("ClydeBank Coffee Shop Simulator 4000, Version 1.00") 5 | print("Copyright (C) 2022 ClydeBank Media, All Rights Reserved.\n") 6 | print("Let's collect some information before we start the game.\n") 7 | 8 | # Get name and shop name 9 | name = input("What is your name? ") 10 | shop_name = input("What do you want to name your coffee shop? ") 11 | 12 | print("\nThanks, " + name + ". Let's set some initial pricing.\n") 13 | 14 | # Get initial price of a cup of coffee 15 | cup_price = input("What do you want to charge per cup of coffee? ") 16 | 17 | # Display what we have 18 | print("\nGreat. Here's what we've collected so far.\n") 19 | print("Your name is " + name + " and you're opening " + shop_name + "!") 20 | print("Your first cup of coffee will sell for $" + cup_price + ".\n") 21 | -------------------------------------------------------------------------------- /coffee_shop_simulator_tests.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from coffee_shop_simulator import CoffeeShopSimulator 3 | 4 | 5 | class CoffeeShopSimulatorTests(unittest.TestCase): 6 | def test_convert_to_float(self): 7 | # Test a string conversion to float 8 | test_float = 1.23 9 | test_string = "1.23" 10 | self.assertEqual(CoffeeShopSimulator.convert_to_float(test_string), test_float) 11 | 12 | def test_x_of_y_with_numbers(self): 13 | # Test that x_of_y returns a list of x numbers of y 14 | number_list = [1, 1, 1, 1, 1] 15 | self.assertEqual(CoffeeShopSimulator.x_of_y(5, 1), number_list) 16 | 17 | def test_x_of_y_with_strings(self): 18 | # Test that x_of_y returns a list of x strings of y 19 | string_list = ["a", "a", "a", "a"] 20 | self.assertEqual(CoffeeShopSimulator.x_of_y(4, "a"), string_list) 21 | 22 | 23 | if __name__ == '__main__': 24 | unittest.main() 25 | -------------------------------------------------------------------------------- /Snippet_CCS-15.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from coffee_shop_simulator import CoffeeShopSimulator 3 | 4 | 5 | class CoffeeShopSimulatorTests(unittest.TestCase): 6 | def test_convert_to_float(self): 7 | # Test a string conversion to float 8 | test_float = 1.23 9 | test_string = "1.23" 10 | self.assertEqual(CoffeeShopSimulator.convert_to_float( 11 | test_string), test_float) 12 | 13 | def test_x_of_y_with_numbers(self): 14 | # Test that x_of_y returns a list of x numbers of y 15 | number_list = [1, 1, 1, 1, 1] 16 | self.assertEqual(CoffeeShopSimulator.x_of_y(5, 1), number_list) 17 | 18 | def test_x_of_y_with_strings(self): 19 | # Test that x_of_y returns a list of x strings of y 20 | string_list = ["a", "a", "a", "a"] 21 | self.assertEqual(CoffeeShopSimulator.x_of_y(4, "a"), string_list) 22 | 23 | 24 | if __name__ == '__main__': 25 | unittest.main() 26 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | # ClydeBank Coffee Shop Simulator 4000 2 | # Copyright 2022 (C) ClydeBank Media, All Rights Reserved. 3 | 4 | import pickle 5 | import re 6 | from pathlib import Path 7 | 8 | # Import the game class from the coffee_shop_simulator module 9 | from coffee_shop_simulator import CoffeeShopSimulator 10 | 11 | print("ClydeBank Coffee Shop Simulator 4000, Version 1.00") 12 | print("Copyright (C) 2022 ClydeBank Media, All Rights Reserved.\n") 13 | 14 | # If save file exists, see if the player wants to load it 15 | run_game = True 16 | if Path(CoffeeShopSimulator.SAVE_FILE).is_file(): 17 | # Save game exists, do they want to load it? 18 | response = CoffeeShopSimulator.prompt("There's a saved game. Do you want to load it? (Y/N)", True) 19 | if re.search("y", response, re.IGNORECASE): 20 | # Load the game and run! 21 | with open(CoffeeShopSimulator.SAVE_FILE, mode="rb") as f: 22 | game = pickle.load(f) 23 | game.run() 24 | # We don't need to run the game again 25 | run_game = False 26 | else: 27 | print("HINT: If you don't want to see this prompt again, remove the savegame.dat file.\n") 28 | 29 | if run_game: 30 | # Create the game object and run it! 31 | game = CoffeeShopSimulator() 32 | game.run() 33 | 34 | # Say goodbye! 35 | print("\nThanks for playing. Have a great rest of your day!\n") -------------------------------------------------------------------------------- /Snippet_CCS-13.py: -------------------------------------------------------------------------------- 1 | # ClydeBank Coffee Shop Simulator 4000 2 | # Copyright 2022 (C) ClydeBank Media, All Rights Reserved. 3 | 4 | import pickle 5 | import re 6 | from pathlib import Path 7 | 8 | # Import the game class from the coffee_shop_simulator module 9 | from coffee_shop_simulator import CoffeeShopSimulator 10 | 11 | print("ClydeBank Coffee Shop Simulator 4000, Version 1.00") 12 | print("Copyright (C) 2022 ClydeBank Media, All Rights Reserved.\n") 13 | 14 | # If save file exists, see if the player wants to load it 15 | run_game = True 16 | if Path(CoffeeShopSimulator.SAVE_FILE).is_file(): 17 | # Save game exists, do they want to load it? 18 | response = CoffeeShopSimulator.prompt( 19 | "There's a saved game. Do you want to load it? (Y/N)", True) 20 | if re.search("y", response, re.IGNORECASE): 21 | # Load the game and run! 22 | with open(CoffeeShopSimulator.SAVE_FILE, mode="rb") as f: 23 | game = pickle.load(f) 24 | game.run() 25 | # We don't need to run the game again 26 | run_game = False 27 | else: 28 | print("HINT: If you don't want to see this prompt again, remove the " + CoffeeShopSimulator.SAVE_FILE + " file.\n") 29 | 30 | if run_game: 31 | # Create the game object and run it! 32 | game = CoffeeShopSimulator() 33 | game.run() 34 | 35 | # Say goodbye! 36 | print("\nThanks for playing. Have a great rest of your day!\n") 37 | -------------------------------------------------------------------------------- /Snippet_CCS-02.py: -------------------------------------------------------------------------------- 1 | # ClydeBank Coffee Shop Simulator 4000 2 | # Copyright 2022 (C) ClydeBank Media, All Rights Reserved. 3 | 4 | # Current day number 5 | day = 1 6 | 7 | # Sales list of dictionaries 8 | # sales = [ 9 | # { 10 | # "day": 1, 11 | # "coffee_inv": 100, 12 | # "advertising": "10", 13 | # "temp": 68, 14 | # "cups_sold": 16 15 | # }, 16 | # { 17 | # "day": 2, 18 | # "coffee_inv": 84, 19 | # "advertising": "15", 20 | # "temp": 72, 21 | # "cups_sold": 20 22 | # }, 23 | # { 24 | # "day": 3, 25 | # "coffee_inv": 64, 26 | # "advertising": "5", 27 | # "temp": 78, 28 | # "cups_sold": 10 29 | # }, 30 | # ] 31 | 32 | # Create an empty sales list 33 | sales = [] 34 | 35 | # Print welcome message 36 | print("ClydeBank Coffee Shop Simulator 4000, Version 1.00") 37 | print("Copyright (C) 2022 ClydeBank Media, All Rights Reserved.\n") 38 | print("Let's collect some information before we start the game.\n") 39 | 40 | # Get name and shop name 41 | name = input("What is your name? ") 42 | shop_name = input("What do you want to name your coffee shop? ") 43 | 44 | print("\nThanks, " + name + ". Let's set some initial pricing.\n") 45 | 46 | # Get initial price of a cup of coffee 47 | cup_price = input("What do you want to charge per cup of coffee? ") 48 | 49 | # Display what we have 50 | print("\nGreat. Here's what we've collected so far.\n") 51 | print("Your name is " + name + " and you're opening " + shop_name + "!") 52 | print("Your first cup of coffee will sell for $" + str(cup_price) + ".\n") 53 | -------------------------------------------------------------------------------- /Snippet_CCS-04.py: -------------------------------------------------------------------------------- 1 | # ClydeBank Coffee Shop Simulator 4000 2 | # Copyright 2022 (C) ClydeBank Media, All Rights Reserved. 3 | 4 | # Import items from the random module to generate weather 5 | from random import seed 6 | from random import randint 7 | 8 | # Current day number 9 | day = 1 10 | 11 | # Starting cash on hand 12 | cash = 100.00 13 | 14 | # Coffee on hand (cups) 15 | coffee = 100 16 | 17 | # Sales list of dictionaries 18 | # sales = [ 19 | # { 20 | # "day": 1, 21 | # "coffee_inv": 100, 22 | # "advertising": "10", 23 | # "temp": 68, 24 | # "cups_sold": 16 25 | # }, 26 | # { 27 | # "day": 2, 28 | # "coffee_inv": 84, 29 | # "advertising": "15", 30 | # "temp": 72, 31 | # "cups_sold": 20 32 | # }, 33 | # { 34 | # "day": 3, 35 | # "coffee_inv": 64, 36 | # "advertising": "5", 37 | # "temp": 78, 38 | # "cups_sold": 10 39 | # }, 40 | # ] 41 | 42 | # Create an empty sales list 43 | sales = [] 44 | 45 | # Print welcome message 46 | print("ClydeBank Coffee Shop Simulator 4000, Version 1.00") 47 | print("Copyright (C) 2022 ClydeBank Media, All Rights Reserved.\n") 48 | print("Let's collect some information before we start the game.\n") 49 | 50 | # Get name and shop name using the following approach: 51 | # 1. Set name and shop_name to False 52 | # 2. Use while not name and shop_name to continue to prompt for a non-empty string 53 | 54 | name = False 55 | while not name: 56 | name = input("What is your name? ") 57 | 58 | shop_name = False 59 | while not shop_name: 60 | shop_name = input("What do you want to name your coffee shop? ") 61 | 62 | # We have what we need, so let's get started! 63 | 64 | print("\nOk, let's get started. Have fun!") 65 | 66 | # The main game loop 67 | running = True 68 | while running: 69 | # Display the day and add a "fancy" text effect 70 | print("\n-----| Day " + str(day) + " @ " + shop_name + " |-----") 71 | 72 | # Generate a random temperature between 20 and 90 73 | # We'll consider seasons later on, but this is good enough for now 74 | temperature = randint(20, 90) 75 | 76 | # Display the cash and weather 77 | print("You have $" + str(cash) + 78 | " cash on hand and the temperature is " + str(temperature) + ".") 79 | print("You have enough coffee on hand to make " + str(coffee) + " cups.\n") 80 | 81 | # Get price of a cup of coffee 82 | cup_price = input("What do you want to charge per cup of coffee? ") 83 | 84 | # Get price of a cup of coffee 85 | print("\nYou can buy advertising to help promote sales.") 86 | advertising = input( 87 | "How much do you want to spend on advertising (0 for none)? ") 88 | 89 | # Convert advertising into a float 90 | # If it fails, assign it to 0 91 | try: 92 | advertising = float(advertising) 93 | except ValueError: 94 | advertising = 0 95 | 96 | # Deduct advertising from cash on hand 97 | cash -= advertising 98 | 99 | # TODO: Calculate today's performance 100 | # TODO: Display today's performance 101 | 102 | # Before we loop around, add a day 103 | day += 1 104 | -------------------------------------------------------------------------------- /Snippet_CCS-03.py: -------------------------------------------------------------------------------- 1 | # ClydeBank Coffee Shop Simulator 4000 2 | # Copyright 2022 (C) ClydeBank Media, All Rights Reserved. 3 | 4 | # Import items from the random module to generate weather 5 | from random import seed 6 | from random import randint 7 | 8 | # Current day number 9 | day = 1 10 | 11 | # Starting cash on hand 12 | cash = 100.00 13 | 14 | # Coffee on hand (cups) 15 | coffee = 100 16 | 17 | # Sales list of dictionaries 18 | # sales = [ 19 | # { 20 | # "day": 1, 21 | # "coffee_inv": 100, 22 | # "advertising": "10", 23 | # "temp": 68, 24 | # "cups_sold": 16 25 | # }, 26 | # { 27 | # "day": 2, 28 | # "coffee_inv": 84, 29 | # "advertising": "15", 30 | # "temp": 72, 31 | # "cups_sold": 20 32 | # }, 33 | # { 34 | # "day": 3, 35 | # "coffee_inv": 64, 36 | # "advertising": "5", 37 | # "temp": 78, 38 | # "cups_sold": 10 39 | # }, 40 | # ] 41 | 42 | # Create an empty sales list 43 | sales = [] 44 | 45 | # Print welcome message 46 | print("ClydeBank Coffee Shop Simulator 4000, Version 1.00") 47 | print("Copyright (C) 2022 ClydeBank Media, All Rights Reserved.\n") 48 | print("Let's collect some information before we start the game.\n") 49 | 50 | # Get name and shop name using the following approach: 51 | # 1. Set name and shop_name to False 52 | # 2. Use while not name and shop_name to continue to prompt for a non-empty string 53 | 54 | name = False 55 | while not name: 56 | name = input("What is your name? ") 57 | 58 | shop_name = False 59 | while not shop_name: 60 | shop_name = input("What do you want to name your coffee shop? ") 61 | 62 | # We have what we need, so let's get started! 63 | 64 | print("\nOk, let's get started. Have fun!") 65 | 66 | # The main game loop 67 | running = True 68 | while running: 69 | # Display the day and add a "fancy" text effect 70 | print("\n-----| Day " + str(day) + " @ " + shop_name + " |-----") 71 | 72 | # Generate a random temperature between 20 and 90 73 | # We'll consider seasons later on, but this is good enough for now 74 | temperature = randint(20, 90) 75 | 76 | # Display the cash and weather 77 | print("You have $" + str(cash) + " cash on hand and the temperature is " + str(temperature) + ".") 78 | print("You have enough coffee on hand to make " + str(coffee) + " cups.\n") 79 | 80 | # Get price of a cup of coffee 81 | cup_price = input("What do you want to charge per cup of coffee? ") 82 | 83 | # Get price of a cup of coffee 84 | print("\nYou can buy advertising to help promote sales.") 85 | advertising = input("How much do you want to spend on advertising (0 for none)? ") 86 | 87 | # Convert advertising into a float 88 | # If it fails, assign it to 0 89 | try: 90 | advertising = float(advertising) 91 | except ValueError: 92 | advertising = 0 93 | 94 | # Deduct advertising from cash on hand 95 | cash -= advertising 96 | 97 | # TODO: Calculate today's performance 98 | # TODO: Display today's performance 99 | 100 | # Before we loop around, add a day 101 | day += 1 102 | 103 | 104 | -------------------------------------------------------------------------------- /Snippet_CCS-05.py: -------------------------------------------------------------------------------- 1 | # ClydeBank Coffee Shop Simulator 4000 2 | # Copyright 2022 (C) ClydeBank Media, All Rights Reserved. 3 | 4 | # Import items from the random module to generate weather 5 | from random import seed 6 | from random import randint 7 | 8 | # Current day number 9 | day = 1 10 | 11 | # Starting cash on hand 12 | cash = 100.00 13 | 14 | # Coffee on hand (cups) 15 | coffee = 100 16 | 17 | # Sales list of dictionaries 18 | # sales = [ 19 | # { 20 | # "day": 1, 21 | # "coffee_inv": 100, 22 | # "advertising": "10", 23 | # "temp": 68, 24 | # "cups_sold": 16 25 | # }, 26 | # { 27 | # "day": 2, 28 | # "coffee_inv": 84, 29 | # "advertising": "15", 30 | # "temp": 72, 31 | # "cups_sold": 20 32 | # }, 33 | # { 34 | # "day": 3, 35 | # "coffee_inv": 64, 36 | # "advertising": "5", 37 | # "temp": 78, 38 | # "cups_sold": 10 39 | # }, 40 | # ] 41 | 42 | # Create an empty sales list 43 | sales = [] 44 | 45 | 46 | def welcome(): 47 | print("ClydeBank Coffee Shop Simulator 4000, Version 1.00") 48 | print("Copyright (C) 2022 ClydeBank Media, All Rights Reserved.\n") 49 | print("Let's collect some information before we start the game.\n") 50 | 51 | 52 | def prompt(display="Please input a string", require=True): 53 | if require: 54 | s = False 55 | while not s: 56 | s = input(display + " ") 57 | else: 58 | s = input(display + " ") 59 | return s 60 | 61 | 62 | def daily_stats(cash_on_hand, weather_temp, coffee_inventory): 63 | print("You have $" + str(cash_on_hand) + " cash on hand and the temperature is " + str(weather_temp) + ".") 64 | print("You have enough coffee on hand to make " + str(coffee_inventory) + " cups.\n") 65 | 66 | 67 | def convert_to_float(s): 68 | # If conversion fails, assign it to 0 69 | try: 70 | f = float(s) 71 | except ValueError: 72 | f = 0 73 | return f 74 | 75 | 76 | def get_weather(): 77 | # Generate a random temperature between 20 and 90 78 | # We'll consider seasons later on, but this is good enough for now 79 | return randint(20, 90) 80 | 81 | 82 | # Print welcome message 83 | welcome() 84 | 85 | # Get name and store name 86 | name = prompt("What is your name?", True) 87 | shop_name = prompt("What do you want to name your coffee shop?", True) 88 | 89 | # We have what we need, so let's get started! 90 | print("\nOk, let's get started. Have fun!") 91 | 92 | # The main game loop 93 | running = True 94 | while running: 95 | # Display the day and add a "fancy" text effect 96 | print("\n-----| Day " + str(day) + " @ " + shop_name + " |-----") 97 | 98 | temperature = get_weather() 99 | 100 | # Display the cash and weather 101 | daily_stats(cash, temperature, coffee) 102 | 103 | # Get price of a cup of coffee 104 | cup_price = prompt("What do you want to charge per cup of coffee?") 105 | 106 | # Get price of a cup of coffee 107 | print("\nYou can buy advertising to help promote sales.") 108 | advertising = prompt("How much do you want to spend on advertising (0 for none)?", False) 109 | 110 | # Convert advertising into a float 111 | advertising = convert_to_float(advertising) 112 | 113 | # Deduct advertising from cash on hand 114 | cash -= advertising 115 | 116 | # TODO: Calculate today's performance 117 | # TODO: Display today's performance 118 | 119 | # Before we loop around, add a day 120 | day += 1 121 | -------------------------------------------------------------------------------- /Snippet_CCS-09.py: -------------------------------------------------------------------------------- 1 | # Import needed modules 2 | import random 3 | import re 4 | from utilities import * 5 | 6 | class CoffeeShopSimulator: 7 | 8 | # Minimum and maximum temperatures 9 | TEMP_MIN = 20 10 | TEMP_MAX = 90 11 | 12 | # Faux temp distributions. We'll do this better 13 | # later with a bell curve, but for now a quick hack 14 | 15 | def __init__(self, player_name, shop_name): 16 | 17 | # Set player and coffee shop names 18 | self.player_name = player_name 19 | self.shop_name = shop_name 20 | 21 | # Current day number 22 | self.day = 1 23 | 24 | # Cash on hand at start 25 | self.cash = 100.00 26 | 27 | # Inventory at start 28 | self.coffee_inventory = 100 29 | 30 | # Sales list 31 | self.sales = [] 32 | 33 | # Possible temperatures 34 | self.temps = self.make_temp_distribution() 35 | 36 | def run(self): 37 | print("\nOk, let's get started. Have fun!") 38 | 39 | # The main game loop 40 | running = True 41 | while running: 42 | # Display the day and add a "fancy" text effect 43 | self.day_header() 44 | 45 | # Get the weather 46 | temperature = self.weather 47 | 48 | # Display the cash and weather 49 | self.daily_stats(temperature) 50 | 51 | # Get price of a cup of coffee 52 | cup_price = float( 53 | prompt("What do you want to charge per cup of coffee?")) 54 | 55 | # Get advertising spend 56 | print("\nYou can buy advertising to help promote sales.") 57 | advertising = prompt( 58 | "How much do you want to spend on advertising (0 for none)?", False) 59 | 60 | # Convert advertising into a float 61 | advertising = convert_to_float(advertising) 62 | 63 | # Deduct advertising from cash on hand 64 | self.cash -= advertising 65 | 66 | # Simulate today's sales 67 | cups_sold = self.simulate(temperature, advertising, cup_price) 68 | gross_profit = cups_sold * cup_price 69 | 70 | # Display the results 71 | print("You sold " + str(cups_sold) + " cups of coffee today.") 72 | print("You made $" + str(gross_profit) + ".") 73 | 74 | # Add the profit to our coffers 75 | self.cash += gross_profit 76 | 77 | # Subtract inventory 78 | self.coffee_inventory -= cups_sold 79 | 80 | # Before we loop around, add a day 81 | self.increment_day() 82 | 83 | def simulate(self, temperature, advertising, cup_price): 84 | # Find out how many cups were sold 85 | cups_sold = self.daily_sales(temperature, advertising) 86 | 87 | # Save the sales data for today 88 | self.sales.append({ 89 | "day": self.day, 90 | "coffee_inv": self.coffee_inventory, 91 | "advertising": advertising, 92 | "temp": temperature, 93 | "cup_price": cup_price, 94 | "cups_sold": cups_sold 95 | }) 96 | 97 | # We technically don't need this, but why make the next step 98 | # read from the sales list when we have the data right here 99 | return cups_sold 100 | 101 | def make_temp_distribution(self): 102 | # This is not a good bell curve, but it will do for now 103 | # until we get to more advanced mathematics 104 | temps = [] 105 | 106 | # First, find the average between TEMP_MIN and TEMP_MAX 107 | avg = (self.TEMP_MIN + self.TEMP_MAX) / 2 108 | # Find the distance between TEMP_MAX and the average 109 | max_dist_from_avg = self.TEMP_MAX - avg 110 | 111 | # Loop through all possible temperatures 112 | for i in range(self.TEMP_MIN, self.TEMP_MAX): 113 | # How far away is the temperature from average? 114 | # abs() gives us the absolute value 115 | dist_from_avg = abs(avg - i) 116 | # How far away is the dist_from_avg from the maximum? 117 | # This will be lower for temps at the extremes 118 | dist_from_max_dist = max_dist_from_avg - dist_from_avg 119 | # If the value is zero, make it one 120 | if dist_from_max_dist == 0: 121 | dist_from_max_dist = 1 122 | # Append the output of x_of_y to temps 123 | for t in x_of_y(int(dist_from_max_dist), i): 124 | temps.append(t) 125 | return temps 126 | 127 | def increment_day(self): 128 | self.day += 1 129 | 130 | def daily_stats(self, temperature): 131 | print("You have $" + str(self.cash) + 132 | " cash on hand and the temperature is " + str(temperature) + ".") 133 | print("You have enough coffee on hand to make " + 134 | str(self.coffee_inventory) + " cups.\n") 135 | 136 | def day_header(self): 137 | print("\n-----| Day " + str(self.day) + 138 | " @ " + self.shop_name + " |-----") 139 | 140 | def daily_sales(self, temperature, advertising): 141 | return int((self.TEMP_MAX - temperature) * (advertising * 0.5)) 142 | 143 | @property 144 | def weather(self): 145 | # Generate a random temperature between 20 and 90 146 | # We'll consider seasons later on, but this is good enough for now 147 | return random.choice(self.temps) 148 | -------------------------------------------------------------------------------- /Snippet_CCS-11.py: -------------------------------------------------------------------------------- 1 | # Import needed modules 2 | import random 3 | import re 4 | from utilities import * 5 | 6 | class CoffeeShopSimulator: 7 | 8 | # Minimum and maximum temperatures 9 | TEMP_MIN = 20 10 | TEMP_MAX = 90 11 | 12 | def __init__(self, player_name, shop_name): 13 | 14 | # Set player and coffee shop names 15 | self.player_name = player_name 16 | self.shop_name = shop_name 17 | 18 | # Current day number 19 | self.day = 1 20 | 21 | # Cash on hand at start 22 | self.cash = 100.00 23 | 24 | # Inventory at start 25 | self.coffee_inventory = 100 26 | 27 | # Sales list 28 | self.sales = [] 29 | 30 | # Possible temperatures 31 | self.temps = self.make_temp_distribution() 32 | 33 | def run(self): 34 | print("\nOk, let's get started. Have fun!") 35 | 36 | # The main game loop 37 | running = True 38 | while running: 39 | # Display the day and add a "fancy" text effect 40 | self.day_header() 41 | 42 | # Get the weather 43 | temperature = self.weather 44 | 45 | # Display the cash and weather 46 | self.daily_stats(temperature) 47 | 48 | # Get price of a cup of coffee (but provide an escape hatch) 49 | response = prompt( 50 | "What do you want to charge per cup of coffee? (type exit to quit)") 51 | if re.search("^exit", response, re.IGNORECASE): 52 | running = False 53 | continue 54 | else: 55 | cup_price = int(response) 56 | 57 | # Do they want to buy more coffee inventory? 58 | response = prompt( 59 | "Want to buy more coffee? (hit ENTER for none or enter number)", False) 60 | 61 | if response: 62 | if not self.buy_coffee(response): 63 | print("Could not buy additional coffee.") 64 | 65 | # Get advertising spend 66 | print("\nYou can buy advertising to help promote sales.") 67 | advertising = prompt( 68 | "How much do you want to spend on advertising (0 for none)?", False) 69 | 70 | # Convert advertising into a float 71 | advertising = convert_to_float(advertising) 72 | 73 | # Deduct advertising from cash on hand 74 | self.cash -= advertising 75 | 76 | # Simulate today's sales 77 | cups_sold = self.simulate(temperature, advertising, cup_price) 78 | gross_profit = cups_sold * cup_price 79 | 80 | # Display the results 81 | print("You sold " + str(cups_sold) + " cups of coffee today.") 82 | print("You made $" + str(gross_profit) + ".") 83 | 84 | # Add the profit to our coffers 85 | self.cash += gross_profit 86 | 87 | # Subtract inventory 88 | self.coffee_inventory -= cups_sold 89 | 90 | if self.cash < 0: 91 | print("\n:( GAME OVER! You ran out of cash.") 92 | running = False 93 | continue 94 | 95 | # Before we loop around, add a day 96 | self.increment_day() 97 | 98 | def simulate(self, temperature, advertising, cup_price): 99 | # Find out how many cups were sold 100 | cups_sold = self.daily_sales(temperature, advertising) 101 | 102 | # Save the sales data for today 103 | self.sales.append({ 104 | "day": self.day, 105 | "coffee_inv": self.coffee_inventory, 106 | "advertising": advertising, 107 | "temp": temperature, 108 | "cup_price": cup_price, 109 | "cups_sold": cups_sold 110 | }) 111 | 112 | # We technically don't need this, but why make the next step 113 | # read from the sales list when we have the data right here 114 | return cups_sold 115 | 116 | def buy_coffee(self, amount): 117 | try: 118 | i_amount = int(amount) 119 | except ValueError: 120 | return False 121 | 122 | if i_amount <= self.cash: 123 | self.coffee_inventory += i_amount 124 | self.cash -= i_amount 125 | return True 126 | else: 127 | return False 128 | 129 | def make_temp_distribution(self): 130 | # This is not a good bell curve, but it will do for now 131 | # until we get to more advanced mathematics 132 | temps = [] 133 | 134 | # First, find the average between TEMP_MIN and TEMP_MAX 135 | avg = (self.TEMP_MIN + self.TEMP_MAX) / 2 136 | # Find the distance between TEMP_MAX and the average 137 | max_dist_from_avg = self.TEMP_MAX - avg 138 | 139 | # Loop through all possible temperatures 140 | for i in range(self.TEMP_MIN, self.TEMP_MAX): 141 | # How far away is the temperature from average? 142 | # abs() gives us the absolute value 143 | dist_from_avg = abs(avg - i) 144 | # How far away is the dist_from_avg from the maximum? 145 | # This will be lower for temps at the extremes 146 | dist_from_max_dist = max_dist_from_avg - dist_from_avg 147 | # If the value is zero, make it one 148 | if dist_from_max_dist == 0: 149 | dist_from_max_dist = 1 150 | # Append the output of x_of_y to temps 151 | for t in x_of_y(int(dist_from_max_dist), i): 152 | temps.append(t) 153 | return temps 154 | 155 | def increment_day(self): 156 | self.day += 1 157 | 158 | def daily_stats(self, temperature): 159 | print("You have $" + str(self.cash) + 160 | " cash on hand and the temperature is " + str(temperature) + ".") 161 | print("You have enough coffee on hand to make " + 162 | str(self.coffee_inventory) + " cups.\n") 163 | 164 | def day_header(self): 165 | print("\n-----| Day " + str(self.day) + 166 | " @ " + self.shop_name + " |-----") 167 | 168 | def daily_sales(self, temperature, advertising): 169 | sales = int((self.TEMP_MAX - temperature) * (advertising * 0.5)) 170 | if sales > self.coffee_inventory: 171 | sales = self.coffee_inventory 172 | print( 173 | "You would have sold more coffee but you ran out. Be sure to buy additional inventory.") 174 | return sales 175 | 176 | @property 177 | def weather(self): 178 | # Generate a random temperature between 20 and 90 179 | # We'll consider seasons later on, but this is good enough for now 180 | return random.choice(self.temps) 181 | -------------------------------------------------------------------------------- /Snippet_CCS-06.py: -------------------------------------------------------------------------------- 1 | 2 | # ClydeBank Coffee Shop Simulator 4000 3 | # Copyright 2022 (C) ClydeBank Media, All Rights Reserved. 4 | 5 | # Import the random module 6 | import random 7 | 8 | 9 | def welcome(): 10 | print("ClydeBank Coffee Shop Simulator 4000, Version 1.00") 11 | print("Copyright (C) 2022 ClydeBank Media, All Rights Reserved.\n") 12 | print("Let's collect some information before we start the game.\n") 13 | 14 | 15 | def prompt(display="Please input a string", require=True): 16 | if require: 17 | s = False 18 | while not s: 19 | s = input(display + " ") 20 | else: 21 | s = input(display + " ") 22 | return s 23 | 24 | 25 | def convert_to_float(s): 26 | # If conversion fails, assign it to 0 27 | try: 28 | f = float(s) 29 | except ValueError: 30 | f = 0 31 | return f 32 | 33 | 34 | def x_of_y(x, y): 35 | num_list = [] 36 | # Return a list of x numbers of y 37 | for i in range(x): 38 | num_list.append(y) 39 | return num_list 40 | 41 | 42 | class CoffeeShopSimulator: 43 | 44 | # Minimum and maximum temperatures 45 | TEMP_MIN = 20 46 | TEMP_MAX = 90 47 | 48 | def __init__(self, player_name, shop_name): 49 | 50 | # Set player and coffee shop names 51 | self.player_name = player_name 52 | self.shop_name = shop_name 53 | 54 | # Current day number 55 | self.day = 1 56 | 57 | # Cash on hand at start 58 | self.cash = 100.00 59 | 60 | # Inventory at start 61 | self.coffee_inventory = 100 62 | 63 | # Sales list 64 | self.sales = [] 65 | 66 | # Possible temperatures 67 | self.temps = self.make_temp_distribution() 68 | 69 | def run(self): 70 | print("\nOk, let's get started. Have fun!") 71 | 72 | # The main game loop 73 | running = True 74 | while running: 75 | # Display the day and add a "fancy" text effect 76 | self.day_header() 77 | 78 | # Get the weather 79 | temperature = self.weather 80 | 81 | # Display the cash and weather 82 | self.daily_stats(temperature) 83 | 84 | # Get price of a cup of coffee 85 | cup_price = float( 86 | prompt("What do you want to charge per cup of coffee?")) 87 | 88 | # Get advertising spend 89 | print("\nYou can buy advertising to help promote sales.") 90 | advertising = prompt( 91 | "How much do you want to spend on advertising (0 for none)?", False) 92 | 93 | # Convert advertising into a float 94 | advertising = convert_to_float(advertising) 95 | 96 | # Deduct advertising from cash on hand 97 | self.cash -= advertising 98 | 99 | # Simulate today's sales 100 | cups_sold = self.simulate(temperature, advertising, cup_price) 101 | gross_profit = cups_sold * cup_price 102 | 103 | # Display the results 104 | print("You sold " + str(cups_sold) + " cups of coffee today.") 105 | print("You made $" + str(gross_profit) + ".") 106 | 107 | # Add the profit to our coffers 108 | self.cash += gross_profit 109 | 110 | # Subtract inventory 111 | self.coffee_inventory -= cups_sold 112 | 113 | # Before we loop around, add a day 114 | self.increment_day() 115 | 116 | def simulate(self, temperature, advertising, cup_price): 117 | # Find out how many cups were sold 118 | cups_sold = self.daily_sales(temperature, advertising) 119 | 120 | # Save the sales data for today 121 | self.sales.append({ 122 | "day": self.day, 123 | "coffee_inv": self.coffee_inventory, 124 | "advertising": advertising, 125 | "temp": temperature, 126 | "cup_price": cup_price, 127 | "cups_sold": cups_sold 128 | }) 129 | 130 | # We technically don't need this, but why make the next step 131 | # read from the sales list when we have the data right here 132 | return cups_sold 133 | 134 | # Faux temp distributions. We'll do this better 135 | # later with a bell curve, but for now a quick hack 136 | 137 | def make_temp_distribution(self): 138 | # This is not a good bell curve, but it will do for now 139 | # until we get to more advanced mathematics 140 | temps = [] 141 | 142 | # First, find the average between TEMP_MIN and TEMP_MAX 143 | avg = (self.TEMP_MIN + self.TEMP_MAX) / 2 144 | # Find the distance between TEMP_MAX and the average 145 | max_dist_from_avg = self.TEMP_MAX - avg 146 | 147 | # Loop through all possible temperatures 148 | for i in range(self.TEMP_MIN, self.TEMP_MAX): 149 | # How far away is the temperature from average? 150 | # abs() gives us the absolute value 151 | dist_from_avg = abs(avg - i) 152 | # How far away is the dist_from_avg from the maximum? 153 | # This will be lower for temps at the extremes 154 | dist_from_max_dist = max_dist_from_avg - dist_from_avg 155 | # If the value is zero, make it one 156 | if dist_from_max_dist == 0: 157 | dist_from_max_dist = 1 158 | # Append the output of x_of_y to temps 159 | for t in x_of_y(int(dist_from_max_dist), i): 160 | temps.append(t) 161 | return temps 162 | 163 | def increment_day(self): 164 | self.day += 1 165 | 166 | def daily_stats(self, temperature): 167 | print("You have $" + str(self.cash) + 168 | " cash on hand and the temperature is " + str(temperature) + ".") 169 | print("You have enough coffee on hand to make " + 170 | str(self.coffee_inventory) + " cups.\n") 171 | 172 | def day_header(self): 173 | print("\n-----| Day " + str(self.day) + 174 | " @ " + self.shop_name + " |-----") 175 | 176 | def daily_sales(self, temperature, advertising): 177 | return int((self.TEMP_MAX - temperature) * (advertising * 0.5)) 178 | 179 | @property 180 | def weather(self): 181 | # Generate a random temperature between 20 and 90 182 | # We'll consider seasons later on, but this is good enough for now 183 | return random.choice(self.temps) 184 | 185 | 186 | # Print welcome message 187 | welcome() 188 | 189 | # Get name and store name 190 | t_name = prompt("What is your name?", True) 191 | t_shop_name = prompt("What do you want to name your coffee shop?", True) 192 | 193 | # Create the game object 194 | game = CoffeeShopSimulator(t_name, t_shop_name) 195 | 196 | # Run the game 197 | game.run() 198 | -------------------------------------------------------------------------------- /Snippet_CCS-12.py: -------------------------------------------------------------------------------- 1 | # Import needed modules 2 | import random 3 | import re 4 | import numpy 5 | from utilities import * 6 | 7 | 8 | class CoffeeShopSimulator: 9 | 10 | # Minimum and maximum temperatures 11 | TEMP_MIN = 20 12 | TEMP_MAX = 90 13 | 14 | # Length of temperature list 15 | # (higher produces more realistic curve) 16 | SERIES_DENSITY = 300 17 | 18 | # Faux temp distributions. We'll do this better 19 | # later with a bell curve, but for now a quick hack 20 | 21 | def __init__(self, player_name, shop_name): 22 | 23 | # Set player and coffee shop names 24 | self.player_name = player_name 25 | self.shop_name = shop_name 26 | 27 | # Current day number 28 | self.day = 1 29 | 30 | # Cash on hand at start 31 | self.cash = 100.00 32 | 33 | # Inventory at start 34 | self.coffee_inventory = 100 35 | 36 | # Sales list 37 | self.sales = [] 38 | 39 | # Possible temperatures 40 | self.temps = self.make_temp_distribution() 41 | 42 | def run(self): 43 | print("\nOk, let's get started. Have fun!") 44 | 45 | # The main game loop 46 | running = True 47 | while running: 48 | # Display the day and add a "fancy" text effect 49 | self.day_header() 50 | 51 | # Get the weather 52 | temperature = self.weather 53 | 54 | # Display the cash and weather 55 | self.daily_stats(temperature) 56 | 57 | # Get price of a cup of coffee (but provide an escape hatch) 58 | response = prompt( 59 | "What do you want to charge per cup of coffee? (type exit to quit)") 60 | if re.search("^exit", response, re.IGNORECASE): 61 | running = False 62 | continue 63 | else: 64 | cup_price = int(response) 65 | 66 | # Do they want to buy more coffee inventory? 67 | print("\nIt costs $1 for the necessary inventory to make a cup of coffee.") 68 | response = prompt( 69 | "Want to buy more so you can make more coffee? (ENTER for none or enter number)", False) 70 | 71 | if response: 72 | if not self.buy_coffee(response): 73 | print("Could not buy additional coffee.") 74 | 75 | # Get price of a cup of coffee 76 | print("\nYou can buy advertising to help promote sales.") 77 | advertising = prompt( 78 | "How much do you want to spend on advertising (0 for none)?", False) 79 | 80 | # Convert advertising into a float 81 | advertising = convert_to_float(advertising) 82 | 83 | # Deduct advertising from cash on hand 84 | self.cash -= advertising 85 | 86 | # Simulate today's sales 87 | cups_sold = self.simulate(temperature, advertising, cup_price) 88 | gross_profit = cups_sold * cup_price 89 | 90 | # Display the results 91 | print("\nYou sold " + str(cups_sold) + " cups of coffee today.") 92 | print("You made $" + str(gross_profit) + ".") 93 | 94 | # Add the profit to our coffers 95 | self.cash += gross_profit 96 | 97 | # Subtract inventory 98 | self.coffee_inventory -= cups_sold 99 | 100 | if self.cash < 0: 101 | print("\n:( GAME OVER! You ran out of cash.") 102 | running = False 103 | continue 104 | 105 | # Before we loop around, add a day 106 | self.increment_day() 107 | 108 | def simulate(self, temperature, advertising, cup_price): 109 | # Find out how many cups were sold 110 | cups_sold = self.daily_sales(temperature, advertising, cup_price) 111 | 112 | # Save the sales data for today 113 | self.sales.append({ 114 | "day": self.day, 115 | "coffee_inv": self.coffee_inventory, 116 | "advertising": advertising, 117 | "temp": temperature, 118 | "cup_price": cup_price, 119 | "cups_sold": cups_sold 120 | }) 121 | 122 | # We technically don't need this, but why make the next step 123 | # read from the sales list when we have the data right here 124 | return cups_sold 125 | 126 | def buy_coffee(self, amount): 127 | try: 128 | i_amount = int(amount) 129 | except ValueError: 130 | return False 131 | 132 | if i_amount <= self.cash: 133 | self.coffee_inventory += i_amount 134 | self.cash -= i_amount 135 | return True 136 | else: 137 | return False 138 | 139 | def make_temp_distribution(self): 140 | # Create series of numbers between TEMP_MIN and TEMP_MAX 141 | series = numpy.linspace( 142 | self.TEMP_MIN, self.TEMP_MAX, self.SERIES_DENSITY) 143 | 144 | # Obtain mean and standard deviation from the series 145 | mean = numpy.mean(series) 146 | std_dev = numpy.std(series) 147 | 148 | # Calculate probability density and return the list it creates 149 | return (numpy.pi * std_dev) * numpy.exp(-0.5 * ((series - mean) / std_dev) ** 2) 150 | 151 | def increment_day(self): 152 | self.day += 1 153 | 154 | def daily_stats(self, temperature): 155 | print("You have $" + str(self.cash) + 156 | " cash on hand and the temperature is " + str(temperature) + ".") 157 | print("You have enough coffee on hand to make " + 158 | str(self.coffee_inventory) + " cups.\n") 159 | 160 | def day_header(self): 161 | print("\n-----| Day " + str(self.day) + 162 | " @ " + self.shop_name + " |-----") 163 | 164 | def daily_sales(self, temperature, advertising, cup_price): 165 | # Randomize advertising effectiveness 166 | adv_coefficient = random.randint(20, 80) / 100 167 | 168 | # Higher priced coffee doesn't sell as well 169 | price_coefficient = int((cup_price * (random.randint(50, 250) / 100))) 170 | 171 | # Run the sales figures! 172 | sales = int((self.TEMP_MAX - temperature) * 173 | (advertising * adv_coefficient)) 174 | 175 | # If price is too high, we don't sell anything 176 | if price_coefficient > sales: 177 | sales = 0 178 | else: 179 | sales -= price_coefficient 180 | 181 | if sales > self.coffee_inventory: 182 | sales = self.coffee_inventory 183 | print( 184 | "You would have sold more coffee but you ran out. Be sure to buy additional inventory.") 185 | 186 | return sales 187 | 188 | @property 189 | def weather(self): 190 | # Generate a random temperature between 20 and 90 191 | # We'll consider seasons later on, but this is good enough for now 192 | return int(random.choice(self.temps)) 193 | -------------------------------------------------------------------------------- /coffee_shop_simulator.py: -------------------------------------------------------------------------------- 1 | import pickle 2 | import random 3 | import re 4 | import numpy 5 | 6 | class CoffeeShopSimulator: 7 | 8 | # Minimum and maximum temperatures 9 | TEMP_MIN = 20 10 | TEMP_MAX = 90 11 | 12 | # Length of temperature list 13 | # (higher produces more realistic curve) 14 | SERIES_DENSITY = 300 15 | 16 | # Save game file 17 | SAVE_FILE = "savegame.dat" 18 | 19 | # Faux temp distributions. We'll do this better 20 | # later with a bell curve, but for now a quick hack 21 | 22 | def __init__(self): 23 | 24 | # Get name and store name 25 | print("Let's collect some information before we start the game.\n") 26 | self.player_name = self.prompt("What is your name?", True) 27 | self.shop_name = self.prompt("What do you want to name your coffee shop?", True) 28 | 29 | # Current day number 30 | self.day = 1 31 | 32 | # Cash on hand at start 33 | self.cash = 100.00 34 | 35 | # Inventory at start 36 | self.coffee_inventory = 100 37 | 38 | # Sales list 39 | self.sales = [] 40 | 41 | # Possible temperatures 42 | self.temps = self.make_temp_distribution() 43 | 44 | def run(self): 45 | print("\nOk, let's get started. Have fun!") 46 | 47 | # The main game loop 48 | running = True 49 | while running: 50 | # Display the day and add a "fancy" text effect 51 | self.day_header() 52 | 53 | # Get the weather 54 | temperature = self.weather 55 | 56 | # Display the cash and weather 57 | self.daily_stats(temperature) 58 | 59 | # Get price of a cup of coffee (but provide an escape hatch) 60 | response = self.prompt("What do you want to charge per cup of coffee? (type exit to quit)") 61 | if re.search("^exit", response, re.IGNORECASE): 62 | running = False 63 | continue 64 | else: 65 | cup_price = int(response) 66 | 67 | # Do they want to buy more coffee inventory? 68 | print("\nIt costs $1 for the necessary inventory to make a cup of coffee.") 69 | response = self.prompt("Want to buy more so you can make more coffee? (ENTER for none or enter number)", False) 70 | 71 | if response: 72 | if not self.buy_coffee(response): 73 | print("Could not buy additional coffee.") 74 | 75 | # Get price of a cup of coffee 76 | print("\nYou can buy advertising to help promote sales.") 77 | advertising = self.prompt("How much do you want to spend on advertising (0 for none)?", False) 78 | 79 | # Convert advertising into a float 80 | advertising = self.convert_to_float(advertising) 81 | 82 | # Deduct advertising from cash on hand 83 | self.cash -= advertising 84 | 85 | # Simulate today's sales 86 | cups_sold = self.simulate(temperature, advertising, cup_price) 87 | gross_profit = cups_sold * cup_price 88 | 89 | # Display the results 90 | print("\nYou sold " + str(cups_sold) + " cups of coffee today.") 91 | print("You made $" + str(gross_profit) + ".") 92 | 93 | # Add the profit to our coffers 94 | self.cash += gross_profit 95 | 96 | # Subtract inventory 97 | self.coffee_inventory -= cups_sold 98 | 99 | if self.cash < 0: 100 | print("\n:( GAME OVER! You ran out of cash.") 101 | running = False 102 | continue 103 | 104 | # Before we loop around, add a day 105 | self.increment_day() 106 | 107 | # Save the game 108 | with open(self.SAVE_FILE, mode="wb") as f: 109 | pickle.dump(self, f) 110 | 111 | def simulate(self, temperature, advertising, cup_price): 112 | # Find out how many cups were sold 113 | cups_sold = self.daily_sales(temperature, advertising, cup_price) 114 | 115 | # Save the sales data for today 116 | self.sales.append({ 117 | "day": self.day, 118 | "coffee_inv": self.coffee_inventory, 119 | "advertising": advertising, 120 | "temp": temperature, 121 | "cup_price": cup_price, 122 | "cups_sold": cups_sold 123 | }) 124 | 125 | # We technically don't need this, but why make the next step 126 | # read from the sales list when we have the data right here 127 | return cups_sold 128 | 129 | def buy_coffee(self, amount): 130 | try: 131 | i_amount = int(amount) 132 | except ValueError: 133 | return False 134 | 135 | if i_amount <= self.cash: 136 | self.coffee_inventory += i_amount 137 | self.cash -= i_amount 138 | return True 139 | else: 140 | return False 141 | 142 | def make_temp_distribution(self): 143 | # Create series of numbers between TEMP_MIN and TEMP_MAX 144 | series = numpy.linspace(self.TEMP_MIN, self.TEMP_MAX, self.SERIES_DENSITY) 145 | 146 | # Obtain mean and standard deviation from the series 147 | mean = numpy.mean(series) 148 | std_dev = numpy.std(series) 149 | 150 | # Calculate probability density and return the list it creates 151 | return (numpy.pi * std_dev) * numpy.exp(-0.5 * ((series - mean) / std_dev) ** 2) 152 | 153 | def increment_day(self): 154 | self.day += 1 155 | 156 | def daily_stats(self, temperature): 157 | print("You have $" + str(self.cash) + " cash on hand and the temperature is " + str(temperature) + ".") 158 | print("You have enough coffee on hand to make " + str(self.coffee_inventory) + " cups.\n") 159 | 160 | def day_header(self): 161 | print("\n-----| Day " + str(self.day) + " @ " + self.shop_name + " |-----") 162 | 163 | def daily_sales(self, temperature, advertising, cup_price): 164 | # Randomize advertising effectiveness 165 | adv_coefficient = random.randint(20, 80) / 100 166 | 167 | # Higher priced coffee doesn't sell as well 168 | price_coefficient = int((cup_price * (random.randint(50, 250) / 100))) 169 | 170 | # Run the sales figures! 171 | sales = int((self.TEMP_MAX - temperature) * (advertising * adv_coefficient)) 172 | 173 | # If price is too high, we don't sell anything 174 | if price_coefficient > sales: 175 | sales = 0 176 | else: 177 | sales -= price_coefficient 178 | 179 | if sales > self.coffee_inventory: 180 | sales = self.coffee_inventory 181 | print("You would have sold more coffee but you ran out. Be sure to buy additional inventory.") 182 | 183 | return sales 184 | 185 | @property 186 | def weather(self): 187 | # Generate a random temperature between 20 and 90 188 | # We'll consider seasons later on, but this is good enough for now 189 | return int(random.choice(self.temps)) 190 | 191 | @staticmethod 192 | def prompt(display="Please input a string", require=True): 193 | if require: 194 | s = False 195 | while not s: 196 | s = input(display + " ") 197 | else: 198 | s = input(display + " ") 199 | return s 200 | 201 | @staticmethod 202 | def convert_to_float(s): 203 | # If conversion fails, assign it to 0 204 | try: 205 | f = float(s) 206 | except ValueError: 207 | f = 0 208 | return f 209 | 210 | @staticmethod 211 | def x_of_y(x, y): 212 | num_list = [] 213 | # Return a list of x numbers of y 214 | for i in range(x): 215 | num_list.append(y) 216 | return num_list -------------------------------------------------------------------------------- /Snippet_CCS-14.py: -------------------------------------------------------------------------------- 1 | import pickle 2 | import random 3 | import re 4 | import numpy 5 | 6 | 7 | class CoffeeShopSimulator: 8 | 9 | # Minimum and maximum temperatures 10 | TEMP_MIN = 20 11 | TEMP_MAX = 90 12 | 13 | # Length of temperature list 14 | # (higher produces more realistic curve) 15 | SERIES_DENSITY = 300 16 | 17 | # Save game file 18 | SAVE_FILE = "savegame.dat" 19 | 20 | # Faux temp distributions. We'll do this better 21 | # later with a bell curve, but for now a quick hack 22 | 23 | def __init__(self): 24 | 25 | # Get name and store name 26 | print("Let's collect some information before we start the game.\n") 27 | self.player_name = self.prompt("What is your name?", True) 28 | self.shop_name = self.prompt( 29 | "What do you want to name your coffee shop?", True) 30 | 31 | # Current day number 32 | self.day = 1 33 | 34 | # Cash on hand at start 35 | self.cash = 100.00 36 | 37 | # Inventory at start 38 | self.coffee_inventory = 100 39 | 40 | # Sales list 41 | self.sales = [] 42 | 43 | # Possible temperatures 44 | self.temps = self.make_temp_distribution() 45 | 46 | def run(self): 47 | print("\nOk, let's get started. Have fun!") 48 | 49 | # The main game loop 50 | running = True 51 | while running: 52 | # Display the day and add a "fancy" text effect 53 | self.day_header() 54 | 55 | # Get the weather 56 | temperature = self.weather 57 | 58 | # Display the cash and weather 59 | self.daily_stats(temperature) 60 | 61 | # Get price of a cup of coffee (but provide an escape hatch) 62 | response = self.prompt( 63 | "What do you want to charge per cup of coffee? (type exit to quit)") 64 | if re.search("^exit", response, re.IGNORECASE): 65 | running = False 66 | continue 67 | else: 68 | cup_price = int(response) 69 | 70 | # Do they want to buy more coffee inventory? 71 | print("\nIt costs $1 for the necessary inventory to make a cup of coffee.") 72 | response = self.prompt( 73 | "Want to buy more so you can make more coffee? (ENTER for none or enter number)", False) 74 | 75 | if response: 76 | if not self.buy_coffee(response): 77 | print("Could not buy additional coffee.") 78 | 79 | # Get price of a cup of coffee 80 | print("\nYou can buy advertising to help promote sales.") 81 | advertising = self.prompt( 82 | "How much do you want to spend on advertising (0 for none)?", False) 83 | 84 | # Convert advertising into a float 85 | advertising = self.convert_to_float(advertising) 86 | 87 | # Deduct advertising from cash on hand 88 | self.cash -= advertising 89 | 90 | # Simulate today's sales 91 | cups_sold = self.simulate(temperature, advertising, cup_price) 92 | gross_profit = cups_sold * cup_price 93 | 94 | # Display the results 95 | print("\nYou sold " + str(cups_sold) + " cups of coffee today.") 96 | print("You made $" + str(gross_profit) + ".") 97 | 98 | # Add the profit to our coffers 99 | self.cash += gross_profit 100 | 101 | # Subtract inventory 102 | self.coffee_inventory -= cups_sold 103 | 104 | if self.cash < 0: 105 | print("\n:( GAME OVER! You ran out of cash.") 106 | running = False 107 | continue 108 | 109 | # Before we loop around, add a day 110 | self.increment_day() 111 | 112 | # Save the game 113 | with open(self.SAVE_FILE, mode="wb") as f: 114 | pickle.dump(self, f) 115 | 116 | def simulate(self, temperature, advertising, cup_price): 117 | # Find out how many cups were sold 118 | cups_sold = self.daily_sales(temperature, advertising, cup_price) 119 | 120 | # Save the sales data for today 121 | self.sales.append({ 122 | "day": self.day, 123 | "coffee_inv": self.coffee_inventory, 124 | "advertising": advertising, 125 | "temp": temperature, 126 | "cup_price": cup_price, 127 | "cups_sold": cups_sold 128 | }) 129 | 130 | # We technically don't need this, but why make the next step 131 | # read from the sales list when we have the data right here 132 | return cups_sold 133 | 134 | def buy_coffee(self, amount): 135 | try: 136 | i_amount = int(amount) 137 | except ValueError: 138 | return False 139 | 140 | if i_amount <= self.cash: 141 | self.coffee_inventory += i_amount 142 | self.cash -= i_amount 143 | return True 144 | else: 145 | return False 146 | 147 | def make_temp_distribution(self): 148 | # Create series of numbers between TEMP_MIN and TEMP_MAX 149 | series = numpy.linspace( 150 | self.TEMP_MIN, self.TEMP_MAX, self.SERIES_DENSITY) 151 | 152 | # Obtain mean and standard deviation from the series 153 | mean = numpy.mean(series) 154 | std_dev = numpy.std(series) 155 | 156 | # Calculate probability density and return the list it creates 157 | return (numpy.pi * std_dev) * numpy.exp(-0.5 * ((series - mean) / std_dev) ** 2) 158 | 159 | def increment_day(self): 160 | self.day += 1 161 | 162 | def daily_stats(self, temperature): 163 | print("You have $" + str(self.cash) + 164 | " cash on hand and the temperature is " + str(temperature) + ".") 165 | print("You have enough coffee on hand to make " + 166 | str(self.coffee_inventory) + " cups.\n") 167 | 168 | def day_header(self): 169 | print("\n-----| Day " + str(self.day) + 170 | " @ " + self.shop_name + " |-----") 171 | 172 | def daily_sales(self, temperature, advertising, cup_price): 173 | # Randomize advertising effectiveness 174 | adv_coefficient = random.randint(20, 80) / 100 175 | 176 | # Higher priced coffee doesn't sell as well 177 | price_coefficient = int((cup_price * (random.randint(50, 250) / 100))) 178 | 179 | # Run the sales figures! 180 | sales = int((self.TEMP_MAX - temperature) * 181 | (advertising * adv_coefficient)) 182 | 183 | # If price is too high, we don't sell anything 184 | if price_coefficient > sales: 185 | sales = 0 186 | else: 187 | sales -= price_coefficient 188 | 189 | if sales > self.coffee_inventory: 190 | sales = self.coffee_inventory 191 | print( 192 | "You would have sold more coffee but you ran out. Be sure to buy additional inventory.") 193 | 194 | return sales 195 | 196 | @property 197 | def weather(self): 198 | # Generate a random temperature between 20 and 90 199 | # We'll consider seasons later on, but this is good enough for now 200 | return int(random.choice(self.temps)) 201 | 202 | @staticmethod 203 | def prompt(display="Please input a string", require=True): 204 | if require: 205 | s = False 206 | while not s: 207 | s = input(display + " ") 208 | else: 209 | s = input(display + " ") 210 | return s 211 | 212 | @staticmethod 213 | def convert_to_float(s): 214 | # If conversion fails, assign it to 0 215 | try: 216 | f = float(s) 217 | except ValueError: 218 | f = 0 219 | return f 220 | 221 | @staticmethod 222 | def x_of_y(x, y): 223 | num_list = [] 224 | # Return a list of x numbers of y 225 | for i in range(x): 226 | num_list.append(y) 227 | return num_list 228 | --------------------------------------------------------------------------------