def status_process_for_tank() -> dict: """ This gets the status of the current tanks in process. :return: """ errorLogger.info("Retrieving the status of the tanks.") return tank_status()
def tank_status() -> dict: """ Gets the TANKS' status. :return: a dictionary of the TANKS. """ errorLogger.info("Getting the tanks' status.") return TANKS
def status_process_for_beer_stock() -> dict: """ This gets the status of the current beer stock in process. :return: """ errorLogger.info("Retrieving the status of the current beers in " "stock.") return beer_stock_status()
def beer_stock_status(): """ Getting the beer stock status. :return beer_stock: a dictionary of the beer stock. """ errorLogger.info("Retrieving the status of the beer stock.") return beer_stock
def total_beers_qty(period: datetime, beer_qty: dict) -> dict: """ This gets the total quantity of beer depending on the date. :param period: a datetime containing the date at which the beers were ordered in the csv file. :param beer_qty: a dictionary where the quantity of beer is stored to. :return beer_qty: a dictionary with the quantity of beer. """ errorLogger.info("Calculating the current total quantity of beer " "for a given period.") for beer in beers: if beer not in beer_qty: beer_qty.update({beer: 0}) try: tmp_qty = beer_qty[beer] + \ sales_data[period][beer]["quantity"] temp_total = beer_qty["total"] + \ sales_data[period][beer]["quantity"] except KeyError: errorLogger.error("KeyError") tmp_qty = beer_qty[beer] + 0 temp_total = beer_qty["total"] + 0 beer_qty.update({beer: tmp_qty}) beer_qty.update({"total": temp_total}) return beer_qty
def add_bear_name(beer_name: str): """ This method add new beers to the beers list. :param beer_name: a string containing beer's name. """ errorLogger.info("Adding new beer to the beers list.") if beers.count(beer_name) == 0: beers.append(beer_name)
def load_barnabys_sales_csvfile(file_name: str): """ This functions open and read the csv file and stores to a formatted dictionary. :param file_name: a string with the csv file name. """ errorLogger.info("Loading the sales csv file.") # opening csv file try: csvfile = open(file_name, 'rt') except IOError: errorLogger.error("IOError") return None else: with csvfile: # reading the csv file csvfile_reader = csv.reader(csvfile) next(csvfile_reader) for row in csvfile_reader: recipe = row[3].strip() gyle = int(row[4].strip()) quantity = int(row[5].strip()) # stores the date from the csv file as a datetime # object. date_obj = datetime.strptime(row[2].strip(), "%d-%b-%y") beers_obj = get_value_by_key(sales_data, date_obj) if not beers_obj: sales_data.update({date_obj: {}}) beers_obj = sales_data[date_obj] beer_key = recipe beer_obj = get_value_by_key(beers_obj, beer_key) if not beer_obj: beer = {"gyle_number": gyle, "quantity": 0} beers_obj.update({beer_key: beer}) beer_obj = beers_obj[beer_key] highest_gyle_number_for_beers.update({beer_key: gyle}) tmp_qty = beer_obj["quantity"] + quantity beer_obj.update({"quantity": tmp_qty}) beers_obj.update({beer_key: beer_obj}) # Calculate day sales sale_qty_day = get_value_by_key(beers_obj, SALES_PER_DAY) if not sale_qty_day: sale_qty_day = 0 sale_qty_day = sale_qty_day + quantity beers_obj.update({SALES_PER_DAY: sale_qty_day}) sales_data.update({date_obj: beers_obj}) # Calculate year sales update_sales_summary(date_obj, quantity, beer_key) add_bear_name(beer_key)
def calculate_average(array_obj: list) -> float: """ This method finds the average value from the list of elements. :param array_obj: a list of elements. :return average: a float of the average growth rate. """ errorLogger.info("Calculating the average.") average = 0 for element in array_obj: average += element average = average / len(array_obj) # finding the average return average
def get_value_by_key(obj: dict, key: str): """ This function gets the value by the key. :param obj: a dictionary object. :param key: a string containing a key for dictionary object. """ errorLogger.info("Getting value by a key.") try: return obj[key] except: errorLogger.error("The given obj or key doesn't exist.") return None
def get_periods() -> list: """ This function gets all the period in the csv file. :return periods: a list containing all the periods in the csv file. """ errorLogger.info("Retrieving all the period group(such as months " "and weeks) that was present in the csv file.") periods = [] for month in months: periods.append(month) for week in weeks: periods.append(week) return periods
def remove_process_for_beer(gyle_no: int, beer_name: str, quantity: int): """ This function allow the process to remove the process to the next state. :param gyle_no: an integer of the batch number. :param beer_name: a string containing the name of the beer. :param quantity: an integer representing the quantity of the beer. """ errorLogger.info("Removing a given beer in the brewing process.") beer_obj = find_process_for_beer(gyle_no, beer_name, quantity) if beer_obj: beers_producer_queue.remove(beer_obj) eventLogger.critical("@state : @%s", store_beer_process_data())
def total_month_beers_qty(month_name: str) -> dict: """ This gets the total quantity of beers for a given month. :param month_name: a string of the given month. :return month_beer_qty: a dictionary all beers for a given month. """ errorLogger.info("Retrieving the current total quantity of beer " "for given month.") month_beer_qty = {} month_beer_qty.update({"total": 0}) for element in sales_data: if element.strftime('%B') == month_name: month_beer_qty = total_beers_qty(element, month_beer_qty) return month_beer_qty
def update_recommended_sales(recommended_sales: dict, beer_name: str, quantity: int): """ Updating recommended sales dictionary. :param recommended_sales: a dictionary of the recommended sales. :param beer_name: a string representing the name of the beer. :param quantity: an integer of the beer quantity. """ errorLogger.info("Updating recommended sales dictionary.") recommended_sales.update( {beer_name: (recommended_sales[beer_name] - quantity)}) if recommended_sales[beer_name] <= 0: recommended_sales.update({beer_name: 0}) eventLogger.critical("@recommended : @%s", recommended_sales)
def find_process_for_beer(gyle_no: int, beer_name: str, quantity: int): """ This method finds the beer which is taking part in a process. :param gyle_no: an integer of the batch number. :param beer_name: a string containing the name of the beer. :param quantity: an integer representing the quantity of the beer. """ errorLogger.info("Finding a given beer from the brewing process.") for beer_obj in beers_producer_queue: if beer_obj.gyle_no == gyle_no and \ beer_obj.bear_name == beer_name and \ beer_obj.quantity == quantity: return beer_obj return None
def update_tank_used_capacity(tank_name: str, volume: int): """ This method updates the used_capacity in the TANKS dictionary. :param tank_name: a string containing the name of the tank. :param volume: an integer of the tank's volume. """ errorLogger.info("Updating the used capacity in the TANKS " "dictionary.") TANKS.update({ tank_name: { "volume": TANKS[tank_name]["volume"], "capability": TANKS[tank_name]["capability"], "used_capacity": volume } }) eventLogger.critical("@tanks : @%s", TANKS)
def move_process_to_next_state(gyle_no: int, beer_name: str, quantity: int): """ This function allow the process to move the process to the next state. :param gyle_no: an integer of the batch number. :param beer_name: a string containing the name of the beer. :param quantity: an integer representing the quantity of the beer. """ errorLogger.info("Moving a given beer in the brewing process to " "the next stage.") beer_obj = find_process_for_beer(gyle_no, beer_name, quantity) if beer_obj: beer_obj.set_move_next() time.sleep(0.2) eventLogger.critical("@state : @%s", store_beer_process_data())
def total_week_beers_qty(week_name: str) -> dict: """ This gets the total quantity of beers for a given week. :param week_name: a string of the given week. :return week_beer_qty: a dictionary all beers for a given week. """ errorLogger.info("Retrieving the current total quantity of beer " "for given week.") week_beer_qty = {} week_beer_qty.update({"total": 0}) for element in sales_data: if SALES_PER_WEEK.format(wk=element.isocalendar()[1]) == \ week_name: week_beer_qty = total_beers_qty(element, week_beer_qty) return week_beer_qty
def get_tank_for_capability(capability: str, volume: int) -> str: """ This method gets the capability of a tank. :param capability: a string of the capability. :param volume: an integer of the tank's volume. :return tank: a string of the tank's name. """ errorLogger.info("Getting a tank that is compatible with the " "capability.") for tank in TANKS: if capability in TANKS[tank]["capability"]: if volume <= TANKS[tank]["volume"] and \ TANKS[tank]["used_capacity"] == 0: update_tank_used_capacity(tank, volume) return tank return None
def release_tank(tank: str): """ This allow to release tank. :param tank: a string representing the tank's name. :return: boolean """ errorLogger.info("Releasing a tank.") TANKS.update({ tank: { "volume": TANKS[tank]["volume"], "capability": TANKS[tank]["capability"], "used_capacity": 0 } }) eventLogger.critical("@tanks : @%s", TANKS) return True
def update_beer_stock(beer_name: str, quantity: int): """ This method updates the current beer stock. :param beer_name: a string of the beer name. :param quantity: an integer representing the quantity of beer. :return: """ errorLogger.info("Updating the beer stock.") temp = 0 try: if beer_stock[beer_name]: temp = beer_stock[beer_name] + quantity except: temp = quantity beer_stock.update({beer_name: temp}) eventLogger.critical("@stock : @%s", beer_stock)
def update_sales_summary(date_obj: datetime, qty: int, beer: str): """ This function updates the sales_summary dictionary. :param date_obj: a datetime of the date of the invoice order. :param qty: an integer representing number of bottle. :param beer: a string representing the beer. """ errorLogger.info("Updating the sales summary list.") # Calculate year sales sale_qty_year = get_value_by_key(sales_summary, SALES_PER_YEAR) if not sale_qty_year: sale_qty_year = 0 sale_qty_year = sale_qty_year + qty sales_summary.update({SALES_PER_YEAR: sale_qty_year}) # Calculate each month sales month = date_obj.strftime('%B') sale_qty_month = get_value_by_key(sales_summary, month) if not sale_qty_month: sales_summary.update({month: {}}) sale_qty_month = sales_summary[month] months.append(month) sale_beers_qty_month = get_value_by_key(sale_qty_month, beer) if beer not in sale_qty_month: sale_qty_month.update({beer: 0}) sale_beers_qty_month = sale_qty_month[beer] tmp_qty = sale_beers_qty_month + qty sale_qty_month.update({beer: tmp_qty}) sales_summary.update({month: sale_qty_month}) # Calculate each week sales # gets the week number from the date week_no = date_obj.isocalendar()[1] # formatting the week string week = SALES_PER_WEEK.format(wk=week_no) sale_qty_week = get_value_by_key(sales_summary, week) if not sale_qty_week: sales_summary.update({week: {}}) sale_qty_week = sales_summary[week] weeks.append(week) sale_beers_qty_week = get_value_by_key(sale_qty_week, beer) if beer not in sale_qty_week: sale_qty_week.update({beer: 0}) sale_beers_qty_week = sale_qty_week[beer] tmp_qty = sale_beers_qty_week + qty sale_qty_week.update({beer: tmp_qty}) sales_summary.update({week: sale_qty_week})
def create_process_for_beer(gyle_no: int, beer_name: str, quantity: int): """ This create brew process for a beer. :param gyle_no: an integer showing the batch number. :param beer_name: a string representing the name of the beer. :param quantity: an integer of the beer quantity. """ errorLogger.info("Creating a brewing process for a given batch of " "beer.") if not find_process_for_beer(gyle_no, beer_name, quantity): with lock: beers_producer_queue.append( BrewingProcess(gyle_no, beer_name, quantity, {}, False, "start", "start")) eventLogger.critical("@state : @%s", store_beer_process_data()) else: errorLogger.warning("Beer process already exists")
def allocate_tank(capability: str, quantity: int) -> str: """ This function allocates tanks for a given capability. :param capability: a string of the tank's capability. :param quantity: an integer of the beer quantity. :return: a string of the tank. """ errorLogger.info("Allocating a tank.") volume = quantity * 0.5 if capability == "hot_brew": return "Kettle" elif capability == "fermentation": return get_tank_for_capability("fermenter", volume) elif capability == "conditioning": return get_tank_for_capability("conditioner", volume) elif capability == "bottling": return "bottling" return None
def predict_week_beer_qty(week_name: str) -> dict: """ This predicts the quantity of beers for a given week. :param week_name: a string of the given week. :return month_beer_qty: a dictionary all beers for a given week. """ errorLogger.info("Retrieving the predicted total quantity of beer " "for given week.") week_beer_qty = total_week_beers_qty(week_name) beer_week_growth_rate = calculate_growth_rate(weeks) total = 0 for beer in beers: temp_qty = math.ceil(week_beer_qty[beer] * (1 + beer_week_growth_rate[beer])) total += temp_qty week_beer_qty.update({beer: math.ceil(temp_qty)}) week_beer_qty.update({"total": total}) return week_beer_qty
def get_recommended_sales() -> dict: """ Getting the recommended sales. :return recommended_sales: a dictionary of the recommended sales. """ errorLogger.info("Getting the recommended sales.") recommended_sales = {} current_month = datetime.now().strftime('%B') current_month_index = months.index(current_month) temp = 0 for x in range(3): month_prediction = predict_month_beer_qty(months[current_month_index + x]) for beer in beers: try: if recommended_sales[beer]: temp = recommended_sales[beer] + month_prediction[beer] except: temp = month_prediction[beer] recommended_sales.update({beer: temp}) return recommended_sales
def status_process_for_beer() -> dict: """ This gets the status of the current beers in process. """ errorLogger.info("Retrieving the status of a given beer in the " "brewing process.") with lock: beer_queue = {} for beer_obj in beers_producer_queue: key = beer_obj.bear_name + ":" + str(beer_obj.gyle_no) + \ ":" + str(beer_obj.quantity) tmp = { key: { "gyle_no": beer_obj.gyle_no, "beer_name": beer_obj.bear_name, "quantity": beer_obj.quantity, "process_tank": beer_obj.process_tanks, "is_allocate": beer_obj.is_allocate } } beer_queue.update(tmp) return beer_queue
def calculate_growth_rate(array_obj: list) -> dict: """ This calculates the growth rate for each period. :param array_obj: a list of periods :return beer_growth_rate: a dictionary representing the growth rate for each period. """ errorLogger.info("Calculating the growth rates.") beer_growth_rate = {} for beer in beers: growth = [] for index in range(1, len(array_obj)): try: growth_rate = (sales_summary[array_obj[index]][beer] - sales_summary[array_obj[index - 1]] [beer]) / \ sales_summary[array_obj[index - 1]][beer] growth.append(growth_rate) except KeyError: errorLogger.error("KeyError") growth.append(0) average_growth = calculate_average(growth) beer_growth_rate.update({beer: round(average_growth, 2)}) return beer_growth_rate