def _find_discount_unit_wise(self, discount_str: str) -> int: """ Finds the discount on the basis of given unit. Args: discount_str: discount str Returns: discount on the basis of unit """ # fetch unit and discount unit = extract_required_data(data_str=discount_str, req_type=r'[a-zA-Z]+') discount = int( extract_required_data(data_str=discount_str, req_type=r'\d+')) # if a standard unit, return the same unit and price if StandardUnits.has_value(unit): return discount # if not a standard unit, convert the unit and discount discount *= units_mapping[unit]['std_equivalent_val'] # return the new discount unit wise return discount
def validate_units(part_a: str, part_b: str) -> bool: """ Validate the unit strings in the given data. Args: part_a: first part part_b: second part Returns: True if valid, else False """ # fetch the units str from both the parts criteria_unit = extract_required_data(part_a, req_type=r'\D+') qnty_unit = extract_required_data(part_b, req_type=r'\D+') # if no units data found if not criteria_unit or not qnty_unit: return False if criteria_unit not in units_mapping and not StandardUnits.has_value( criteria_unit): return False if qnty_unit not in units_mapping and not StandardUnits.has_value( qnty_unit): return False return True
def _find_item_unit(self, item_qnty_data: str, item_name: str, item_obj: Item) -> Any: """ Validates unit in the given string. Args: item_qnty_data: quantity data in which contains the unit item_name: name of the current item Returns: item's quantity and standard unit """ # check if quantity contains unit item_qnty_unit = extract_required_data(data_str=item_qnty_data, req_type=r'[a-zA-Z]+') # if no unit characters found, return None if not item_qnty_unit: print(f'Please specify the quantity for the item {item_name}') return None # if unit matches item's std unit if item_qnty_unit == item_obj.unit: return item_qnty_unit # if unit not found in the stored units, return None if item_qnty_unit not in units_mapping: print(f'Please add a valid unit for the item {item_name}') return None # if unit's equivalent std unit doesn't matches item's std unit if units_mapping[item_qnty_unit]['std_equivalent_unit'] != item_obj.unit: print(f'Please add a valid unit for the item {item_name}') return None return item_qnty_unit
def _extract_price_and_unit(self, price_str: str) -> tuple: """ Extract item price per unit from the price string. Args: price_str: price string Returns: price, unit """ # fetch the digits from the price string price = float( extract_required_data( data_str=price_str, req_type=r'[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)')[0]) # fetch the unit unit = price_str[price_str.index('/') + 1:] # if a standard unit, return the same unit and price if StandardUnits.has_value(unit): return price, unit # if not a standard unit, convert the unit and price price /= units_mapping[unit]['std_equivalent_val'] unit = units_mapping[unit]['std_equivalent_unit'] return price, unit
def validate_price(price_str: str) -> bool: """ Validates the price string for item. Args: price_str: string to be validated Returns: True, if valid, else False """ # if no digit is found, return false if not extract_required_data(data_str=price_str, req_type=r'\d+'): return False # if per('/') is not found, return false if '/' not in price_str: print("Please specify item price per ('/') units") return False # extract the unit from the price string unit = price_str[price_str.index('/') + 1:] # is unit not found in stored units, return false if not StandardUnits.has_value(unit) and unit not in units_mapping: return False return True
def validate_digits(part_a: str, part_b: str) -> bool: """ Validate the digits in the given data. Args: part_a: first part part_b: second part Returns: True if valid, else False """ # return false if no digit found in either part if not extract_required_data( part_a, req_type=r'[a-zA-Z]+') or not extract_required_data( part_b, req_type=r'[a-zA-Z]+'): return False return True
def _process_item_data(self, all_items_data: list) -> list: """ Process the data for all the input items and store the ones which are valid Args: all_items_data: list of all the input items Returns: list of valid items for which bill is to be generated """ # list to store the valid data for which bill needs to be generated processed_data = [] for item_data in all_items_data: # arguments must contain item name and quantity item_data = item_data.split(' ') if len(item_data) < 2: print('Invalid number of item arguments') continue # if len of arguments is greater than 2, take the last argument as quantity and rest as item name item_name = item_data[0] item_qnty_data = item_data[-1] if len(item_data) > 2: item_name = ' '.join(item_data[:-1]) # try to fetch the item's object from its corresponding entity type mapping item_obj = self.store_data[ITEM].get(item_name) # ignore the input if item not found if not item_obj: print(f'Sorry, the item {item_name} was not found') continue # check if quantity contains a digit item_qnty_digit = float( extract_required_data(data_str=item_qnty_data, req_type=r'[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)')[0]) # if no digit found, ignore the current item if not item_qnty_digit: print(f'Please specify the quantity in number for the item {item_name}') continue # find the unit item_qnty_unit = self._find_item_unit(item_qnty_data=item_qnty_data, item_name=item_name, item_obj=item_obj) if not item_qnty_unit: continue # if unit not a standard one, convert it and modify the item_quantity accordingly if item_qnty_unit in units_mapping: item_qnty_digit *= units_mapping[item_qnty_unit]['std_equivalent_val'] item_qnty_unit = units_mapping[item_qnty_unit]['std_equivalent_unit'] # store the item data for which bill needs to be generated processed_data.append( { 'item': item_obj, 'quantity': item_qnty_digit, 'unit': item_qnty_unit } ) # return the processed data return processed_data