"""Main file.""" def find_next_valid_upc(upc: int, skip: int = 1) -> int: """Find next valid UPC based on an existing UPC value. Args: upc (int): A current UPC value to help generate the next valid UPC. skip_power (int): How far to advance the next found UPC. Returns: int: A valid UPC. """ if skip < 1: raise ValueError(f'{skip} must be >= 1') upc_found = False while not upc_found: upc = upc+(10 * skip) checksum = calculate_upc_checksum(upc) new_upc = str(upc)[0:-1] + str(checksum) upc_found = len(new_upc) == 12 return int(new_upc) def validate_upc(upc: int) -> bool: """Validates a upc. Args: upc (int): A UPC to validate. Returns: bool: Whether or not the UPC is valid. """ # UCP must be 12 characters long if len(str(upc)) != 12: raise ValueError('{upc} does not contain 12 characters.') # Checksum is last digit checksum = str(upc)[-1] if calculate_upc_checksum(upc) == int(checksum): return True return False def calculate_upc_checksum(upc: int) -> bool: """Calculates the checksum on a upc. Args: upc (int): A UPC to check. Returns: int: The checksum of the upc. """ if len(str(upc)) == 12: upc = str(upc)[0:-1] if len(str(upc)) != 11: raise ValueError(f'UPC value of length {len(str(upc))} is invalid.') even_items = [] odd_items = [] # Loop through UPC without checksum and store values for pos, num in enumerate(str(upc)): if (pos+1) % 2 == 0: even_items.append(int(num)) else: odd_items.append(int(num)) # Create the check for 6 odd values odd_check = sum(odd_items)*3 # Create the check for 5 even values even_check = sum(even_items) # Sum checks round up to nearest ten sum_of_checks = even_check + odd_check diff_from_ten = 10 - (sum_of_checks % 10) return diff_from_ten def report_upc_valid(upc: int) -> bool: """Report if a UPC is valid. Args: upc (int): A UPC to check. """ is_valid = validate_upc(upc) report_valid = 'is' if is_valid else 'is not' print(f'UPC {upc} {report_valid} valid.') return is_valid def main(): """Main method.""" upc = 193483736817 is_valid = report_upc_valid(upc) if not is_valid: print('Finding valid UPC...') new_upc = find_next_valid_upc(upc) print(f'Next valid UPC: \'{new_upc}\'') report_upc_valid(new_upc) if __name__ == '__main__': main()