def intro(): """ Prints the main menu and forwards to respective functions """ try: main_menu_list = [ '1. Create Customer', '2. Modify Customer', '3. Delete Customer', '4. Open Account', '5. Modify Account', '6. Close Account', '7. Transact', '8. Generate Report', '9. Add Branch', '10. View Branches', '11. About Us', '12. Exit', 'Press Ctrl + C to Force Exit' ] login_time = get_current_time() while True: clear_console() print_name() print() print('Login time: ' + login_time) print() print(27 * '=') print() for i in main_menu_list: print('\t' + i) print() inp = input('Command: ') print() if inp == '1': create_customer() elif inp == '2': modify_customer() elif inp == '3': delete_customer() elif inp == '4': open_account() elif inp == '5': modify_account() elif inp == '6': close_account() elif inp == '7': transact() elif inp == '8': generate_report() elif inp == '9': create_branch() elif inp == '10': view_branches() elif inp == '11': about() elif inp == '12': print('Goodbye!\nLogout time: ', get_current_time()) break else: print("Invalid entry!") # Pause before printing the menu again pause() except KeyboardInterrupt: print('Exiting!')
def __init__(self, formatfile_filepath, csv_filepath): self.validate_state = False self.validate_type = "" self.validate_message_title = "" self.validate_message_text = "" self.validate_message_detailed = "" self.format_file_file_path = formatfile_filepath self.csv_file_path = csv_filepath self.current_time = utility.get_current_time() self.username = utility.getuser() self.delimiter = "\t" self.validation_certificate_path = None self.format_file_path = utility.path_from_file_path( self.format_file_file_path) self.format_file_filename = utility.file_from_file_path( self.format_file_file_path) self.csv_path = utility.path_from_file_path(self.csv_file_path) self.csv_filename = utility.file_from_file_path(self.csv_file_path) self.csv_file = os.path.splitext(self.csv_filename)[0] self.csv_created_date = utility.get_file_date_time( self.csv_file_path, 0) self.csv_modified_date = utility.get_file_date_time( self.csv_file_path, 1) self.ff = FormatFile.FormatFile(self.format_file_file_path) if not self.ff.isValid: self.set_validate(False, "ERROR", "Error:", "Format File is invalid.") return else: self.dic_format_file = self.ff.get_fields() self.field_count = len(self.dic_format_file) self.list_csv = self.get_csv(self) self.validate_header(self) if self.validate_state: self.validate_content(self)
def modify_account(self): """ Modify function to modify an object of Account class """ modify_account_list = ['1. Modify Maximum Transaction Amount'] for i in modify_account_list: print('\t' + i) print() ch = input('Command: ') if ch == '1': while True: try: self.max_transaction_amount = int( input('New Maximum Transaction Amount: ')) break except ValueError: print('\nInvalid Value\n') global_transactions.append( Transaction( self.customer.customer_id, self.account_number, get_current_date(), get_current_time(), self.get_branch_code(), 0, self.balance, self.balance, 'Maximum Transaction Amount modified successfully!')) send_message( f'Greetings from Bank XXX!\nYour Customer ID {self.customer.customer_id}\nYour Account Number ' f'{self.account_number}.\nYour account has been modified successfully.', self.customer.phone_number)
def withdraw(self, amount): """ Withdraw function to withdraw money from account """ if int(amount) <= 0: # Validation rule: Amount is negative print( 'Invalid amount. Please enter positive values.\nTransaction aborted!' ) elif int(amount) > self.max_transaction_amount: # Validation rule: Amount is more than maximum set by the customer print( 'Amount entered is more than the maximum.\nTransaction aborted!' ) elif int(amount) > self.balance: # Validation rule: Amount is more than current balance print('Amount entered is more than balance.\nTransaction aborted!') else: self.balance -= int(amount) # Add withdrawal transaction to transactions log global_transactions.append( Transaction(self.customer.customer_id, self.account_number, get_current_date(), get_current_time(), self.get_branch_code(), amount, str(int(self.balance) + int(amount)), str(self.balance), f'{str(amount)} withdrawn successfully!')) send_message( f'Greetings from Bank XXX!\nYour Customer ID {self.customer.customer_id}.\nYou have withdrawn ' f'{str(amount)} from Account #{self.account_number}\nClosing Balance: INR{self.balance}', self.customer.phone_number)
def __init__(self, socketio): utility.create_directories("logs/") self.logger = utility.Logger("logs/" + utility.get_current_time()) sys.stderr = ErrorLogger(self.logger) self.currentState = CheckState(socketio, self.logger) msg = f"Current state : {self.currentState}." self.logger.write_and_flush(msg + "\n") print(msg)
def delete_customer(self): """ Delete function to delete an object of Customer class """ # Add deletion of customer to transactions log global_transactions.append( Transaction(self.customer_id, 'NA', get_current_date(), get_current_time(), 'NA', 'NA', 'NA', 'NA', f'Customer {self.customer_id} deleted successfully!')) # Delete individual accounts for i in self.active_accounts: self.active_accounts[i].delete_account(False) self.active_accounts.clear() print('Customer deleted successfully!') send_message( f'Greetings from Bank XXX!\nYour Customer ID {self.customer_id} has been deleted.\nSorry to see you go!', self.phone_number)
def input_customer(self): """ Input function to take values from the user and assign it to an object of Customer class """ self.first_name = input('First Name: ') self.last_name = input('Last Name: ') self.address.input_address() while True: self.phone_number = input( 'Phone Number (+<Country Code><Phone Number>): ') if validate_phone(self.phone_number): otp = generate_otp(self.phone_number) flag = False while not flag: otp_input = input(f'OTP sent on {self.phone_number}: ') if str(otp_input) == str(otp): flag = True if flag: break else: print( '\nInvalid Phone Number. Phone Numbers should follow +<Country Code><Phone Number>\n' ) while True: self.email = input('Email: ') if validate_email(self.email): break else: print('\nInvalid Email ID\n') self.customer_id = utility.global_customer_id utility.global_customer_id = str(int(utility.global_customer_id) + 1) utility.global_customer_id = '0' * ( 4 - len(utility.global_customer_id)) + utility.global_customer_id global_customer_map[self.customer_id] = self # Add creation of customer to transactions log global_transactions.append( Transaction(self.customer_id, 'NA', get_current_date(), get_current_time(), 'NA', 'NA', 'NA', 'NA', f'Customer {self.customer_id} created successfully!')) print( f'Customer created successfully! Customer ID: {self.customer_id}') send_message( f'Greetings from Bank XXX!\nWelcome {self.first_name} {self.last_name}!\nYour Customer ID ' f'{self.customer_id}.', self.phone_number)
def manual_photos_making(camera): draw_markup = input("Draw markup points on images? (y/n): ") draw_markup = draw_markup.lower() == "y" label = input("Please type label, which should be added to photos: ") sep = " " counter = 1 path_piece = OUTPUT_DIR + label + sep while True: action = input("Hit enter to get an image, type anything to stop: ") if action != "": break frame = camera.get_image() if draw_markup == "y": frame = markup_5_points(frame) cv.imwrite(path_piece + str(counter) + sep + utility.get_current_time() + ".jpg", frame) counter += 1
def delete_account(self, pop_from_list): """ Delete function to delete an object of Account class """ # Add deletion of account to transactions log global_transactions.append( Transaction( self.customer.customer_id, self.account_number, get_current_date(), get_current_time(), self.get_branch_code(), 'NA', self.balance, 0, f'Account {self.account_number} deleted successfully!')) self.customer.active_accounts_number -= 1 if pop_from_list: self.customer.active_accounts.pop(self.account_number) print( f'Account {str(self.account_number)} deleted successfully! Closing Balance: INR{str(self.balance)}' ) send_message( f'Greetings from Bank XXX!\nYour Customer ID {self.customer.customer_id}\nYour Account Number ' f'{self.account_number}.\nYour account has been deleted successfully.', self.customer.phone_number)
def run_performance_test(camera): label = input("Please type label, which should be added to photos: ") sep = " " counter = 1 path_piece = OUTPUT_DIR + label + sep saving_time_delta = "None" try: while True: frame = camera.get_image() cur_time = utility.get_current_time( ) # timestamp when frame was read saving_start_t = time.time() cv.imwrite( path_piece + str(counter) + sep + cur_time + sep + "(prev. imwrite time " + str(saving_time_delta) + " seconds).jpg", frame) saving_time_delta = time.time() - saving_start_t counter += 1 except KeyboardInterrupt: return
def start(): utility.connect() try: r_id=int(sys.argv[3]) hostname=sys.argv[4] port=int(sys.argv[5]) username=sys.argv[6] password=sys.argv[7] req_str=sys.argv[8] script=sys.argv[9] args=sys.argv[10] cmd_syntax=sys.argv[11] log.log_debug("%s %s %s %s %s %s %s %s %s" % (str(r_id), hostname, str(port), username, password, req_str, script, args, cmd_syntax), 2, -2) if script.lower().rfind(".c") > 0: script = script[:script.lower().rfind(".c")] else: if script.lower().rfind(".cpp") > 0: script = script[:script.lower().rfind(".cpp")] #print hostname+", "+str(port)+", "+username+", "+password+", "+req_str+", "+script+", "+args+", "+cmd_syntax+", "+str(r_id) if cmd_syntax == "NULL": if args == "NULL": cmd = script else: cmd = script + " " + args else: if args == "NULL": cmd = cmd_syntax + " " + script else: cmd = cmd_syntax + " " + script + " " + args cmd = cmd + ' ' + 'rid_' + str(r_id) log.log_debug("%s" % (cmd), 2, -2) client = ssh.SSHClient() client.set_missing_host_key_policy(ssh.AutoAddPolicy()) client.connect(hostname, port=port, username=username, password=password) utility.update_status('Running', r_id) #utility.update_time('start', r_id, utility.get_current_time()) stdin, stdout, stderr = client.exec_command(cmd) err = stderr.readlines() errStr = '' if len(err) > 0: # if failed to run script log.log_debug(err, 1, -2) log.log_debug("Failed to run script %s; Request:%s ID:%d" % (script, req_str, r_id), 1, -2) errStr = script + "\n" errStr += "Failed to run script. "+"\n" errStr += '; '.join(err) email_sender.send(r_id, req_str, errStr) utility.update_status('Failed', r_id) utility.update_time('end', r_id, utility.get_current_time()) else: # if process runs successfully output = stdout.readlines() # search for ERROR token for line in output: if line.lower().find("error")!=-1 or line.lower().find("fail")!=-1 or line.lower().find("failed")!=-1 or line.lower().find("exception")!=-1: errStr += "> " errStr += line + '\n' if len(errStr) > 0: # if error found while running script log.log_debug("Error found after running script; Request:%s, ID:%d" % (req_str, r_id), 2, -2) errStr = script + '\n' + errStr email_sender.send(r_id, req_str, errStr) utility.update_status('Error', r_id) utility.update_time('end', r_id, utility.get_current_time()) else: # no error found while running script utility.update_status('Done', r_id) utility.update_time('end', r_id, utility.get_current_time()) log.log_debug("No error found after running script; Request:%s, ID:%d" % (req_str, r_id), 2, -2) client.close() except Exception as err: log.log_debug(err, 1, -2) log.log_debug("Error in start(); Request:%s ID:%d" % (req_str, r_id), 1, -2) errStr = script + '\n' + str(err) email_sender.send(r_id, req_str, errStr) finally: utility.close_conn()
def input_account(self): """ Input function to take values from the user and assign it to an object of Account class """ while True: ch = input('Existing customer? (Y/N): ') # For existing customers, adds a new account to the customer.active_accounts dictionary if ch.upper() == 'Y': existing_customer_id = input('Existing Customer ID: ') if existing_customer_id in global_customer_map: print( f'Customer found. Adding account to customer ID #{existing_customer_id}' ) self.customer = global_customer_map[existing_customer_id] self.customer.active_accounts_number += 1 break else: print( 'Customer ID does not exist. Recheck ID or register as a new customer.' ) elif ch.upper() == 'N': # For new customers, creates a new customer then adds a new account to the customer.active_accounts # dictionary self.customer = Customer( '', '', Address('', '', '', '', '', '', '', ''), '', '', 0, '', {}) self.customer.input_customer() self.customer.active_accounts_number += 1 break while True: try: self.max_transaction_amount = int( input('Maximum Transaction Amount: ')) break except ValueError: print('\nInvalid Value\n') while True: try: self.balance = int(input('Initial Balance: ')) break except ValueError: print('\nInvalid Value\n') while True: branch_code = input('Branch Code: ') if branch_code in global_branches: break else: print('\nInvalid Branch Code\n') self.account_number = str(self.customer.customer_id + branch_code + str("%02d" % self.customer.active_accounts_number)) self.customer.active_accounts[self.account_number] = self print( f'Account created successfully! Account ID: {self.account_number}') # Add creation of account to transactions log global_transactions.append( Transaction( self.customer.customer_id, self.account_number, get_current_date(), get_current_time(), self.get_branch_code(), 'NA', 0, self.balance, f'Account {self.account_number} created successfully!')) send_message( f'Greetings from Bank XXX!\nYour Customer ID {self.customer.customer_id}\nYour Account Number ' f'{self.account_number}.\nBalance INR{self.balance}\nYour account has been created successfully.', self.customer.phone_number)
def main(): t = 0 utility.connect() while True: if not utility.db_lock(): try: utility.update_db_lock('active', 'monitor', 'start') n = utility.running_proc() if n < config.max_running_proc: new_requests = utility.get_new_requests() for item in new_requests: if n < config.max_running_proc: r_id=item[0] req_str=item[1].strip() args=item[2] if args == None or args == '': args = 'NULL' else: args = item[2].strip() host, port, script, username, password = utility.get_host_script_user_pass(req_str) if script != None: ext = script[script.rfind(".")+1:] cmd_syntax = utility.get_cmd(ext) if cmd_syntax == None or cmd_syntax == '': cmd_syntax="NULL" else: cmd_syntax=cmd_syntax.strip() utility.update_status('Starting', r_id) utility.update_time('start', r_id, utility.get_current_time()) log.log_debug("Starting Request:%s, ID:%d" % (req_str, r_id), 2, -1) os.system("./remote_process.py -thread -tid %s %s %s %s %s %s %s %s %s > /dev/null &" % (str(r_id), host, str(port), username, password, req_str, script, args, cmd_syntax)) n += 1 time.sleep(2) else: log.log_debug("No script entry found for Request:%s, ID:%d" % (req_str, r_id), 2, -1) else: log.log_debug("No more request can be handled....reached its max", 2, -1) else: log.log_debug("No more request can be handled....reached its max", 2, -1) except Exception as err: log.log_debug(err, 1, -1) log.log_debug("Error in main()", 1, -1) utility.rollback_conn() finally: utility.update_db_lock('inactive', 'monitor', 'end') t += 1 push_to_queue.push() # take active proc, both single and periodic, from process_list table and insert them to queue time.sleep(config.sleep_time) # Call th_check.py in every 20min approx. if t * config.sleep_time >= config.th_check_period: t = 0 th_check.check_runtime()
def main(): # check input dirs if not os.path.isfile(INPUT_JSON_FILE): print("Couldn't find json file:", INPUT_JSON_FILE) exit(0) if not os.path.isfile(INPUT_CLASSES_FILE_PATH): print("Couldn't find classes file:", INPUT_CLASSES_FILE_PATH) exit(0) if not os.path.exists(INPUT_DATASET_IMAGES_DIR): print("Couldn't find images directory:", INPUT_DATASET_IMAGES_DIR) exit(0) # define and create output dirs output_jpg_dir = OUTPUT_DATA_DIR + "jpg/" output_txt_dir = OUTPUT_DATA_DIR + "txt/" utility.create_directories(OUTPUT_DATA_DIR, output_jpg_dir, output_txt_dir) # statistics and report data img_processed = 0 regions_processed = 0 regions_converted = 0 unsupported_regions_count = 0 unsupported_regions_files = set() regions_outside_prec_area_count = 0 regions_outside_prec_area_files = set() missing_dataset_images_count = 0 missing_dataset_images_files = set() missing_json_region_types_count = 0 missing_json_region_types_files = set() missing_classes_count = 0 missing_classes = set() w_from = SCENE_CENTER_X - PRECISE_ZONE_LEFT w_to = SCENE_CENTER_X + PRECISE_ZONE_RIGHT h_from = SCENE_CENTER_Y - PRECISE_ZONE_TOP h_to = SCENE_CENTER_Y + PRECISE_ZONE_BOTTOM precise_zone = Polygon([[w_from, h_from], [w_to, h_from], [w_to, h_to], [w_from, h_to]]) output_jpg_dir = OUTPUT_DATA_DIR + "jpg/" # load json with open(INPUT_JSON_FILE, "r") as file: data = json.loads(file.read()) # load classes classes = detection.YoloOpenCVDetection.load_class_names( INPUT_CLASSES_FILE_PATH) # loop over images list in json cur_file_no = 1 for file_key in data["_via_img_metadata"]: if cur_file_no % 10 == 0: print("Processed", cur_file_no, "of", len(data["_via_img_metadata"]), "files.") cur_file_no += 1 file_name = data["_via_img_metadata"][file_key]["filename"] file_path = INPUT_DATASET_IMAGES_DIR + file_name # check if image jpg file exists and is not empty if os.path.isfile(file_path) and os.stat(file_path).st_size > 0: img = cv.imread(file_path) img_processed += 1 else: missing_dataset_images_count += 1 missing_dataset_images_files.add(file_name) continue reg_img_file_counter = 1 # loop over regions of current image file for region in data["_via_img_metadata"][file_key]["regions"]: regions_processed += 1 # check if region type is present if REGION_TYPE_KEY not in region["region_attributes"]: missing_json_region_types_count += 1 missing_json_region_types_files.add(file_name) continue region_type = region["region_attributes"][REGION_TYPE_KEY] # regions whitelist check if APPLY_REGIONS_WHITE_LIST and region_type not in REGIONS_WHITE_LIST: continue # check if type is present in yolo names file if region_type not in classes: missing_classes_count += 1 missing_classes.add(region_type) continue # get region info and convert to rect if needed if region["shape_attributes"]["name"] == "rect": crop_reg_left = int(region["shape_attributes"]["x"]) crop_reg_right = int(region["shape_attributes"]["x"] + region["shape_attributes"]["width"]) crop_reg_top = int(region["shape_attributes"]["y"]) crop_reg_bottom = int(region["shape_attributes"]["y"] + region["shape_attributes"]["height"]) reg_center_x = int(region["shape_attributes"]["x"] + region["shape_attributes"]["width"] / 2) reg_center_y = int(region["shape_attributes"]["y"] + region["shape_attributes"]["height"] / 2) elif region["shape_attributes"]["name"] == "circle": crop_reg_left = int(region["shape_attributes"]["cx"] - region["shape_attributes"]["r"]) crop_reg_right = int(region["shape_attributes"]["cx"] + region["shape_attributes"]["r"]) crop_reg_top = int(region["shape_attributes"]["cy"] - region["shape_attributes"]["r"]) crop_reg_bottom = int(region["shape_attributes"]["cy"] + region["shape_attributes"]["r"]) reg_center_x = int(region["shape_attributes"]["cx"]) reg_center_y = int(region["shape_attributes"]["cy"]) else: # print("Unsupported region shape '", region["shape_attributes"]["name"], "', THIS REGION WON'T BE SHIFTED. See info in file ", MISSED_REGIONS_FILE, sep="") unsupported_regions_count += 1 unsupported_regions_files.add(file_name) continue # precise zone check if APPLY_PRECISE_ZONE and not precise_zone.contains_point( [reg_center_x, reg_center_y]): regions_outside_prec_area_count += 1 regions_outside_prec_area_files.add(file_name) continue # reduce region sizes if allowed if APPLY_REGIONS_SIZE_REDUCING: yolo_reg_left = crop_reg_left + int( crop_reg_left * REGIONS_SIZE_REDUCING_PERCENT / 2) yolo_reg_right = crop_reg_right - int( crop_reg_right * REGIONS_SIZE_REDUCING_PERCENT / 2) yolo_reg_top = crop_reg_top + int( crop_reg_top * REGIONS_SIZE_REDUCING_PERCENT / 2) yolo_reg_bottom = crop_reg_bottom - int( crop_reg_bottom * REGIONS_SIZE_REDUCING_PERCENT / 2) else: yolo_reg_left = crop_reg_left yolo_reg_right = crop_reg_right yolo_reg_top = crop_reg_top yolo_reg_bottom = crop_reg_bottom # crop and save image region reg_img = img[crop_reg_top:crop_reg_bottom, crop_reg_left:crop_reg_right] reg_img_name = file_name[:-4] + " " + str( reg_img_file_counter) + file_name[-4:] cv.imwrite(output_jpg_dir + reg_img_name, reg_img) # convert region to yolo format reg_center_x = int( (yolo_reg_right - yolo_reg_left) / 2) # TODO: a bug - not int not none happens here reg_center_y = int((yolo_reg_bottom - yolo_reg_top) / 2) reg_width = yolo_reg_right - yolo_reg_left reg_height = yolo_reg_bottom - yolo_reg_top img_x_size = crop_reg_right - crop_reg_left img_y_size = crop_reg_bottom - crop_reg_top obj_class = classes.index(region_type) x_center = round(reg_center_x / img_x_size, 6) y_center = round(reg_center_y / img_y_size, 6) width = round(reg_width / img_x_size, 6) height = round(reg_height / img_y_size, 6) # <object-class> <x_center> <y_center> <width> <height> record_line = str(obj_class) + " " + str(x_center) + " " + str(y_center) + " " + str(width) + " " + \ str(height) + "\n" # save converted to yolo region into txt with open( output_txt_dir + file_name[:-4] + " " + str(reg_img_file_counter) + ".txt", "w") as txt_file: txt_file.write(record_line) reg_img_file_counter += 1 regions_converted += 1 current_time = utility.get_current_time() + " " # save passed unsupported regions info if len(unsupported_regions_files) > 0: with open(current_time + UNSUPPORTED_REGIONS_LIST_FILE, "w") as file: file.write( "These images are present in VIA's json project but their regions types are not supported:\n" ) for item in unsupported_regions_files: file.write(item + "\n") # save missing image files (present in json, absent in dir) if len(missing_dataset_images_files) > 0: with open(current_time + MISSING_DATASET_IMAGES_LIST_FILE, "w") as file: file.write( "These images are present in VIA's json project but absent in given images directory (images are required for conversion to YOLO format):\n" ) for item in missing_dataset_images_files: file.write(item + "\n") # save missing in json region types if len(missing_json_region_types_files) > 0: with open(current_time + MISSING_JSON_REGION_TYPES_LIST_FILE, "w") as file: file.write( "These images are added to VIA's json project but their regions have no information about region types:\n" ) for item in missing_json_region_types_files: file.write(item + "\n") # save missing classes in classes file if len(missing_classes) > 0: with open(current_time + MISSING_CLASSES_LIST_FILE, "w") as file: file.write( "These classes are present in given json, but absent in " + INPUT_CLASSES_FILE_PATH + " classes file:\n") for item in missing_classes: file.write(item + "\n") # save list of files with regions outside the precise area if len(regions_outside_prec_area_files) > 0: with open(current_time + REGIONS_OUTSIDE_PRECISE_ZONE_LIST_FILE, "w") as file: file.write( "List of files whose regions were outside of the precise zone (it's ok):\n" ) for item in regions_outside_prec_area_files: file.write(item + "\n") # show report print("Processed", img_processed, "images") print("Processed", regions_processed, "regions") print("Successfully converted", regions_converted, "regions") conversion_failed = False if unsupported_regions_count > 0: conversion_failed = True print("Passed", unsupported_regions_count, "regions due to unsupported shape. See'", UNSUPPORTED_REGIONS_LIST_FILE, "'file for details.") if missing_dataset_images_count > 0: conversion_failed = True print("Missing", missing_dataset_images_count, "images in given images directory. See'", MISSING_DATASET_IMAGES_LIST_FILE, "'file for details.") if missing_json_region_types_count > 0: conversion_failed = True print("Missing", missing_json_region_types_count, "regions types in given json file. See'", MISSING_JSON_REGION_TYPES_LIST_FILE, "'file for details.") if missing_classes_count > 0: conversion_failed = True print("Missing", missing_classes_count, "classes count in given classes file. See'", MISSING_CLASSES_LIST_FILE, "'file for details.") if regions_outside_prec_area_count > 0: print("Passed", regions_outside_prec_area_count, "regions which were outside of precise area (it's ok). See'", REGIONS_OUTSIDE_PRECISE_ZONE_LIST_FILE, "'file for details.") if conversion_failed: print( "Total: conversion is FAILED! See report files mentioned above for details." ) else: print("Total: conversion is SUCCESSFUL!")
def modify_customer(self): """ Modify function to modify an object of Customer class """ modify_customer_list = [ '1. First Name', '2. Last Name', '3. Address', '4. Phone Number', '5. Email' ] print('\n\tWhich parameter do you want to modify?') for i in modify_customer_list: print('\t' + i) print() ch = input('Command: ') if ch == '1': self.first_name = input('New First Name: ') global_transactions.append( Transaction(self.customer_id, 'NA', get_current_date(), get_current_time(), 'NA', 'NA', 'NA', 'NA', 'First name modified successfully!')) send_message( f'Greetings from Bank XXX!\nYour Customer ID {self.customer_id}.\nYour account has been modified ' f'successfully.', self.phone_number) elif ch == '2': self.last_name = input('New Last Name: ') global_transactions.append( Transaction(self.customer_id, 'NA', get_current_date(), get_current_time(), 'NA', 'NA', 'NA', 'NA', 'Last name modified successfully!')) send_message( f'Greetings from Bank XXX!\nYour Customer ID {self.customer_id}.\nYour account has been modified ' f'successfully.', self.phone_number) elif ch == '3': self.address.modify_address() global_transactions.append( Transaction(self.customer_id, 'NA', get_current_date(), get_current_time(), 'NA', 'NA', 'NA', 'NA', 'Address modified successfully!')) send_message( f'Greetings from Bank XXX!\nYour Customer ID {self.customer_id}.\nYour account has been modified ' f'successfully.', self.phone_number) elif ch == '4': while True: self.phone_number = input( 'New Phone Number (+<Country Code><Phone Number>): ') if validate_phone(self.phone_number): otp = generate_otp(self.phone_number) flag = False while not flag: otp_input = input(f'OTP sent on {self.phone_number}: ') if str(otp_input) == str(otp): flag = True if flag: break else: print( '\nInvalid Phone Number. Phone Numbers should follow +<Country Code><Phone Number>\n' ) global_transactions.append( Transaction(self.customer_id, 'NA', get_current_date(), get_current_time(), 'NA', 'NA', 'NA', 'NA', 'Phone number modified successfully!')) send_message( f'Greetings from Bank XXX!\nYour Customer ID {self.customer_id}.\nYour account has been modified ' f'successfully.', self.phone_number) elif ch == '5': while True: self.email = input('Email: ') if validate_email(self.email): break else: print('\nInvalid Email ID\n') global_transactions.append( Transaction(self.customer_id, 'NA', get_current_date(), get_current_time(), 'NA', 'NA', 'NA', 'NA', 'Email modified successfully!')) send_message( f'Greetings from Bank XXX!\nYour Customer ID {self.customer_id}.\nYour account has been modified ' f'successfully.', self.phone_number) else: print('Invalid entry!')