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
Exemple #5
0
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
Exemple #6
0
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)
Exemple #7
0
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)
Exemple #8
0
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
Exemple #9
0
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
Exemple #10
0
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())
Exemple #12
0
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
Exemple #13
0
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())
Exemple #17
0
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)
Exemple #21
0
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
Exemple #24
0
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
Exemple #25
0
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
Exemple #27
0
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