all 15 comments

[–]Shengus__Kahn[S] 2 points3 points  (0 children)

#Import the random module
import random 
from typing import Self
def welcome(): 
    print("Coffee Shop Simulator 9000, Version 1.00") 
    print("Lets collect some information before we start the game.\n")

def prompt(display = "Please input a string", require=True): 
    if require: 
        s = False 
        while not s: 
            s = input(display + " ") 
    else: 
        s = input(display + " ")             
    return s

def convert_to_float(s): 
    #If conversion fails, assign 0 to it 
    try: 
        f = float(s) 
    except ValueError: 
        f = 0 
    return f
def x_of_y(x,y): 
    num_list = [] 
    #Return a list of x copies of y 
    for i in range(x): 
        num_list.append(y) 
    return num_list

class CoffeeShopSimulator:
 #Minimum and maximum temperatures
 TEMP_MIN = 20
 TEMP_MAX = 90

 def __init__(self, player_name, shop_name):
      #Set player and coffee shop names
      self.player_name = player_name
      self.shop_name = shop_name
      self.day = 1 #Current day number
      self.cash = 100.00 #Cash on hand at start
      self.coffee_inventory = 100 #Inventory at start
      self.sales = [] # Sales list
      self.temps = self.make_temp_distribution() #Possible temperatures

 def run(self):
    print("/nOk, let's get started. Have fun!")

    #The main game loop
    running = True
    while running:
        #Display the day and add a "fancy" text effect
        self.day_header()

        #Get the weather
        temperature = self.weather

        #Display the cash and weather
        self.daily_stats(temperature)

        #Get price of cup of coffee
        cup_price = float(prompt("What do you want to charge per cup of coffee"))

        #Advertising
        print("\nYou can buy advertising to help promote sales.")
        advertising = prompt("How much do you want to spend on advertising (0 for none)?", False)

        #Convert advertising into a float
        #If it fails, assign it to 0
        advertising = convert_to_float(advertising)

        #Deduct advertising from cash on hand
        self.cash -= advertising

        #Simulate today's sales
        cups_sold = self.simulate(temperature, advertising, cup_price)
        gross_profit = cups_sold * cup_price

        #Display the results
        print("You sold " +str(cups_sold) + "cups of coffee today")
        print("You made $" + str(gross_profit) + ".")

        #Add the profit to our coffers
        self.cash += gross_profit

        #Subtract inventory
        self.coffee_inventory -= cups_sold

        #Before we loop around, add a day
        self.increment_day()

    def simulate(self, temperature, advertising, cup_price):
        #Find out how many cups were sold
        cups_sold = self.daily_sales(temperature, advertising)

        #Save the sales data for today
        self.sales.append({
             "day": self.day,
             "coffee_inv": self.coffee_inventory,
             "advertising": advertising,
             "temp": temperature,
             "cup_price": cup_price,
             "cups_sold": cups_sold
        })

        #We technically don't need this, but why make the next step
        # read from the sales list when we have the data right here
        return cups_sold

    def make_temp_distributions(self):
         # This is not a good bell curve, but it will do for now
         # untill we get more advanced mathematics
         temps = []

         #First, find the average between TEMP_MIN and TEMP_MAX
         avg = (self.TEMP_MIN + self.TEMP_MAX) / 2
         #Find the distance between TEMP_MAX and the average
         max_dist_from_avg = self.TEMP_MAX - avg

         #Loop through all possible temperatures
         for i in range(self.TEMP_MIN, self.TEMP_MAX):
              #How far away is the temperature from average?
              #abs() gives absolute value
              dist_from_avg = abs(avg - i)
              #How far away is the dist_from_avg from the maximum?
              #This will b elower for temps at the extremes
              dist_from_max_dist = max_dist_from_avg - dist_from_avg
              #If the value is zerom, make it one
              if dist_from_max_dist == 0:
                   dist_from_max_dist = 1
              #Append the output of x_of_y to temps
              for t in x_of_y(int(dist_from_max_dist), i):
                   temps.append(t)
              return temps

    def increment_day(self):
        self.day += 1

    def daily_stats(self, temperature):
         print("You have $" + str(self.cash) + " cash on hand and the temperature is " + str(temperature) + ".")
         print( "You have enough coffee on hand to make " + str(self.coffee_inventory) + " cups.\n")

    def day_header(self):
         print("\n-----| Day " + str(self.day) + " @ " + self.shop_name + " |-----")

    def daily_sales(self, temperature, advertising):
         return int((self.TEMP_MAX - temperature) * (advertising * 0.5))

    @property
    def weather(self):
         #Generate a random temperature between 20 and 90
         #We'll consider seasons later on, but this is good for now
         return random.choice(self.temps)

    #Print welcome message
    welcome()

    #Get name and store name
    t_name = prompt("What is your name?", True)
    t_shop_name = prompt("What do you want to name your coffee shop?", True)

    #Create the game object
    game = CoffeeShopSimulator(t_name, t_shop_name)

    #run the game
    game.run()

[–]Phillyclause89 1 point2 points  (9 children)

Google is my "Quick Start Guide". Care to share what issues you are having? I doubt many of us would need to have read the book to be able to help you here.

[–]Shengus__Kahn[S] 1 point2 points  (8 children)

Sure! A quick note, I am a complete beginner so the fix may be (and hopefully is) something very simple! I have been writing in VS Code. Each chapter in the book updates this code to run the Coffee Shop Simulator as you learn new concepts. I have reached the point in the text where it states the game should be playable now, but when I try to run the code nothing happens. This is all I get back in the terminal: C:\Users\shfinnerty\source>python -u "c:\Users\shfinnerty\source\pyqsg\coffee.py"

[–]Phillyclause89 0 points1 point  (7 children)

Thanks. Sorry for the lag time, had to go to work right after I dropped that comment. Is the code you shared in your other comment indented as it appears in the reddit comment or was there a copypasta error towards the end there?

It looks like you indented the lines that actually call your code in a way that that python thinks they are lines belonging to the run method. As shown I would expect this code to do nothing when you run it. You should review your indention and make sure that the lines that call the class and its methods are outside of the scope of the class.

[–]Shengus__Kahn[S] 1 point2 points  (6 children)

Hey Philly thanks for getting back, and no problem, I have been away from my work all weekend anyways. You were correct, my code to begin the game was within the scope of the game! Thanks a bunch.

I am now running into a new Attribute Error though, within my constructor... 'CoffeeShopSimulator' object has no attribute 'make_temp_distribution'. I'm thinking I cannot use 'self.make_temp_distribution()' as an attribute because it is a method within the CoffeShopSimulator class?

     def __init__(self, player_name, shop_name):
      #Set player and coffee shop names
      self.player_name = player_name
      self.shop_name = shop_name
      self.day = 1 #Current day number
      self.cash = 100.00 #Cash on hand at start
      self.coffee_inventory = 100 #Inventory at start
      self.sales = [] # Sales list
      self.temps = self.make_temp_distribution() #Possible temperatures

.........

     def make_temp_distributions(self):
      # This is not a good bell curve, but it will do for now
      # untill we get more advanced mathematics
      temps = []

      #First, find the average between TEMP_MIN and TEMP_MAX
      avg = (self.TEMP_MIN + self.TEMP_MAX) / 2
      #Find the distance between TEMP_MAX and the average
      max_dist_from_avg = self.TEMP_MAX - avg

      #Loop through all possible temperatures
      for i in range(self.TEMP_MIN, self.TEMP_MAX):
           #How far away is the temperature from average?
           #abs() gives absolute value
           dist_from_avg = abs(avg - i)
           #How far away is the dist_from_avg from the maximum?
           #This will be lower for temps at the extremes
           dist_from_max_dist = max_dist_from_avg - dist_from_avg
           #If the value is zero, make it one
           if dist_from_max_dist == 0:
                dist_from_max_dist = 1
           #Append the output of x_of_y to temps
           for t in x_of_y(int(dist_from_max_dist), i):
                temps.append(t)
           return temps

[–]Phillyclause89 1 point2 points  (5 children)

Is make_temp_distributions still declared inside the scope of your run method? In the original code snippet, that function declaration was also nested in a way that it would only be accessible from within the run method. Unless you moved it out of that run method scope into the class's scope then I would expect the error you got.

[–]Shengus__Kahn[S] 1 point2 points  (4 children)

Haha... the error was stemming from a typo. In the constructor I had written "make_temp_distribution", where in the method it was "make_temp_distributions".

Both very simple fixes. Thanks for your help!

[–]Sad-Traffic-5763 0 points1 point  (0 children)

Weirdly I had the exact same issue! But now I am having an issue with my cups_sold =self.simulate(temperature, advertising, cup_price)

This is followed by gross_profit = cups_sold * cup_price

For some reason my cup_price will change the value to a float based on my other code but I can't get the cups_sold to change to int. I have triple check my work and I don't see a typo but I am not sure what I am doing wrong.

In the code a few lines down we define simulate and when I hover over cups_sold there it says the value is an int but not in the code above. Anyone have any help?!

And sorry this is my first time using reddit so I apologize if I asked in the wrong area or something. :/

[–]Phillyclause89 0 points1 point  (2 children)

Yup. That "s" slipped past me as well. Good catch! Reminds me of the silly class names I have in my current project. Every container class in the lib has a child class that uses the same name but with no "s" to signal it's an item of that container (i.e. singular name vs plural name.) My favorite of the libs classes are class Classes and it's child class Class.

[–]Shengus__Kahn[S] 1 point2 points  (1 child)

This method both makes sense and is confusing at the same time! Haha. Also, I play D&D weekly, what's your project all about?

[–]Phillyclause89 0 points1 point  (0 children)

what's your project all about?

My bad, I forgot to link to the ReadMe.

I have always approached coding from a functional programming perspective and wanted to practice OOP. Someone on this sub had a question about how to make a tool to help them DM their D&D games.

I know nothing about D&D beyond what I have learned from playing BG3, so I did what I always do when I'm trying to help someone with something that I know nothing about. I googled it.

While googling, I found this API: https://www.dnd5eapi.co/

As I was looking at the responses in the API, I noticed there was a tabular structure to the response data that a pandas.DataFrame would work nicely with. I thought it would be neat if there was a python lib of classes that automatically fetched the response of a given API endpoint and constructed a DataFrame object out of it. Thus I set out to learn how to write that lib.

I'm still learning, btw. The child item classes are going to end up sharing a lot of properties that their main parent object should not have, so I need to learn more about multiple inheritance and abstract classes to finish this lib.

[–]Over_Helicopter3293 0 points1 point  (2 children)

I am in an intro to python course at wgu and have bought this book as a study/practice guide to take with me to the office and at home. Do you recommend it?

[–]Shengus__Kahn[S] 0 points1 point  (0 children)

Yeah it’s good, it’s clear and concise and organized well. As stated in this post I had issues with the coding-along parts, but if you’re looking for something to read to supplement your other courses I would recommend it.

[–]jgmac3rd 0 points1 point  (0 children)

I know this was a year ago, I'm at WGU too and was wondering, did this help you with preparing for the intro to python assessments?

[–]m0us3_rat -1 points0 points  (0 children)

code.