简体   繁体   English

使用 while 循环更新多个函数中使用的分配变量 - PYTHON

[英]Update assigned variable used in multiple functions using a while loop - PYTHON

I completed an assignment for a scripting class I'm taking, and it worked fine, but I wanted to take it a step further, which has sent me down a rabbit hole.我完成了我正在接受的脚本 class 的作业,它运行良好,但我想更进一步,这让我陷入了困境。 The script is for an ATM transaction.该脚本用于 ATM 交易。

I added a while loop to give the user additional options, instead of just ending the program.我添加了一个 while 循环来为用户提供额外的选项,而不是仅仅结束程序。 But I found the my account_balance variable remained equal to the default value set initially (in this case 500.25).但我发现我的 account_balance 变量仍然等于最初设置的默认值(在本例中为 500.25)。 I've been trying to find ways to make this update as the user goes through the program, in theory it should go as follows:当用户通过程序时,我一直试图找到进行此更新的方法,理论上它应该 go 如下:

  1. User checks balance = $500.25 --------------> balance(account_balance)用户查看余额 = $500.25 --------------> balance(account_balance)
  2. User makes deposit = $500.00 ---------------> deposit(account_balance, amount)用户存款 = $500.00 ---------------> 存款(account_balance, amount)
  3. User checks balance again = $1,000.25 ---> program always returns with $500.25用户再次检查余额 = $1,000.25 ---> 程序总是返回 $500.25

To try and make this work, I made another function transactionGo(pin), and set all the other functions inside it, hoping this would update the variable account_balance, that didn't work either, and in fact caused more problems, I feel I'm going down a road I shouldn't.为了尝试使这项工作,我制作了另一个 function transactionGo(pin),并在其中设置了所有其他函数,希望这会更新变量 account_balance,这也不起作用,实际上引起了更多问题,我觉得我正在走一条我不应该走的路。

import sys

# -------------------------- DECLARE variables for balance, deposit, and withdrawal --------------------------

account_balance = float(500.25)                                                 # Starting balance indicated by Codio
#balance = 100
amount = 0
#deposit_amount = 0                                                              # Declare variable 'deposit_amount'
#withdrawal_amount = 0                                                           # Declare variable 'withdrawal_amount'
pin = ''

# -------------------------- DEFINE FUNCTIONS - balance, withdrawal, and deposit -----------------------------
def transactionGo (pin):
  pin = int(input("Please enter your 5 digit pin number:\n"))
  
  def balance(account_balance):                                                   # Define balance function
    print("Your current balance is $%.2f" % (account_balance))                    # Prints the current available balance

  def deposit(account_balance, amount):                                           # Define DEPOSIT function with parameters account_balance and amount
    amount = float(input("How much would you like to deposit today?\n"))          # Accept user input for the deposit amount, in float format
    balance = account_balance + amount                                            # This addition assigns the updated value of the account balance, to the variable 'account_balance'
    print("Deposit was $%.2f , your new current balance is $%.2f" % (amount, balance))  # Prints deposit amount and account balance
    return balance                                                                # Return records the new value of account_balance to reflect accordingly in other transactions
    

  def withdrawal(account_balance, amount):                                        # Define WITHDRAWAL function with parameters account_balance and withdrawal_amount
    amount = float(input("How much would you like to withdraw today?\n"))         # Accept user input for the withdrawal amount, in float format
    if amount > account_balance:                                                  # Checking to see if the amount requested, is greater than the amount available
      print("Insufficient funds, $%.2f is greater than your account balance of $%.2f" % (amount, account_balance)) # If the amount requested is greater than the account balance, there are insufficient funds
    else:                                                                         # Sufficient amount of funds are available, the function continues
      balance = account_balance - amount                                          # Variable 'balance' is assigned to reflect the new available balance
      print ("Withdrawal amount was $%.2f, your new current balance is $%.2f" % (amount, balance))  # Prints withdrawal amount and account balance
      return balance                                                              # Return records the new value of balance to reflect accordingly in other transactions
  
# Lines 18 and 20 compose a conditional statement with the withdrawal function
# Line 18 => if the requested withdrawal amount is greater than the account balance, the conditional statement stops, and prints to the user there are insufficient funds
# Line 20 => if there are sufficient funds available, the conditional statement continues, updates the 'balance', and outputs to the user their withdrawal amount and new available balance

# ------------------------------------ ACCEPT USER INPUT - D, B, W, or Q -------------------------------------
userAccess = input ("Welcome to Tom & Kate Banking, if you would like to sign into your account, please press (C)ontinue, or (E)xit\n").upper()
if userAccess == 'C':
  transactionGo (pin)

  userChoice = 'go'                                                               # Setting the variable 'userChoice' to 'go', so we can implement a while loop

  # Step ONE => Create a WHILE loop to offer the user additional options after they have completed a transaction
  while userChoice != 'E':                                                        # As long as the user does not select 'E' (Exit), the program will keep looping with user choices
    
  # Step TWO =>  Ask user what action they would like to proceed with, user input is accepted and assigned to the variable 'userchoice'
    userChoice = input ("Would you like to check your (B)alance, make a (D)eposit, (W)ithdraw cash, or (E)xit?\n").upper()

  # Step THREE => conditional statement begins based on the value of variable 'userchoice' from user input
  # Four branches utilizing if / elif for DEPOSIT, BALANCE, WITHDRAWAL, EXIT
    if (userChoice == 'D'):                                                       # Accepts input D and proceeds with function 'deposit'
      deposit (account_balance, amount)                                           # DEPOSIT function is called with parameters 'balance' and 'amount'

    elif (userChoice == 'B'):                                                     # Accepts input B and proceeds with function 'balance'
      balance (account_balance)                                                   # BALANCE function is called with parameter 'balance'

    elif (userChoice == 'W'):                                                     # Accepts input D and proceeds with function 'withdrawal'
      withdrawal (account_balance, amount)                                        # WITHDRAWAL function is called with parameters 'balance' and 'amount'

    elif (userChoice == 'E'):                                                     # Accepts input E for EXIT
      print("Thank you for banking with us.")                                     # There is no function for EXIT, and therefore the user has a printed message ending their session

else:
  print("We hope to see you again soon, have a nice day!")



When I run this, the first function runs - transactionGo(pin), but when I go into the other transaction functions, IDLE tells me my variables are undefined.当我运行它时,第一个 function 运行 - transactionGo(pin),但是当我 go 进入其他事务函数时,IDLE 告诉我我的变量未定义。

PROBLEM: The scope of the account_balance variable and the functions within transactionGo are different to how you are using them.问题:account_balance 变量的 scope 和 transactionGo 中的函数与您使用它们的方式不同。 For example, if you wish to modify a variable outside of a function you need to declare it global at the top of your function definition.例如,如果您希望修改 function 之外的变量,则需要在 function 定义的顶部将其声明为全局变量。

Furthermore, the functions within transactionGo cannot be accessed anywhere in the file except for the transactionGo function itself as the scope of the functions is just within the transactionGo function and not anywhere else.此外,除了 transactionGo function 本身之外,不能在文件中的任何位置访问 transactionGo 中的函数,因为函数的 scope 就在 transactionGo ZC1C425268E68385D1AB5074C17A94F14 中,而不是其他任何地方。 This is why IDLE tells you the functions are undefined, because they are not a part of the file but a part of the transactionGo function and inside of that function only.这就是为什么 IDLE 告诉你函数是未定义的,因为它们不是文件的一部分,而是 transactionGo function 和 function 内部的一部分。 So in your code those functions are never called所以在你的代码中,这些函数永远不会被调用

SOLUTIONS: You need to ensure you understand scope in python.解决方案:您需要确保您了解 python 中的 scope。 The following link is an amazing explanation of what is meant by scope:以下链接是对 scope 含义的惊人解释:

https://www.w3schools.com/python/python_scope.asp https://www.w3schools.com/python/python_scope.asp

In the following methods used to solve this issue, I will assume you want the functions themselves to change and modify the banking variables themselves.在用于解决此问题的以下方法中,我将假设您希望函数本身更改和修改银行变量本身。

Method #1 : Using the 'global' keyword and fixing the functions scopes方法#1 :使用'global'关键字并修复函数范围

# Describe the problem
# How to learn more about the problem
# Full solutions explained.

import sys

# -------------------------- DECLARE variables for balance, deposit, and withdrawal --------------------------

account_balance = float(500.25)                                                 # Starting balance indicated by Codio
#balance = 100
amount = 0
#deposit_amount = 0                                                              # Declare variable 'deposit_amount'
#withdrawal_amount = 0                                                           # Declare variable 'withdrawal_amount'
pin = ''

# -------------------------- DEFINE FUNCTIONS - balance, withdrawal, and deposit -----------------------------
def transactionGo (pin):
  pin = int(input("Please enter your 5 digit pin number:\n"))
  
def balance(account_balance):                                                   # Define balance function
  print("Your current balance is $%.2f" % (account_balance))                    # Prints the current available balance

def deposit():                                           # Define DEPOSIT function with parameters account_balance and amount
  global account_balance  # Using the 'global' keyword allows you to edit and modify the value of account_balance
  amount = float(input("How much would you like to deposit today?\n"))          # Accept user input for the deposit amount, in float format
  account_balance += amount                                           # This addition assigns the updated value of the account balance, to the variable 'account_balance'
  print("Deposit was $%.2f , your new current balance is $%.2f" % (amount, account_balance))  # Prints deposit amount and account balance                                                               # Return records the new value of account_balance to reflect accordingly in other transactions
    

def withdrawal():                                        # Define WITHDRAWAL function with parameters account_balance and withdrawal_amount
  global account_balance
  amount = float(input("How much would you like to withdraw today?\n"))         # Accept user input for the withdrawal amount, in float format
  if amount > account_balance:                                                  # Checking to see if the amount requested, is greater than the amount available
    print("Insufficient funds, $%.2f is greater than your account balance of $%.2f" % (amount, account_balance)) # If the amount requested is greater than the account balance, there are insufficient funds
  else:                                                                         # Sufficient amount of funds are available, the function continues
    account_balance -= amount                                          # Variable 'balance' is assigned to reflect the new available balance
    print ("Withdrawal amount was $%.2f, your new current balance is $%.2f" % (amount, account_balance))  # Prints withdrawal amount and account balance
    return balance                                                              # Return records the new value of balance to reflect accordingly in other transactions
  
# Lines 18 and 20 compose a conditional statement with the withdrawal function
# Line 18 => if the requested withdrawal amount is greater than the account balance, the conditional statement stops, and prints to the user there are insufficient funds
# Line 20 => if there are sufficient funds available, the conditional statement continues, updates the 'balance', and outputs to the user their withdrawal amount and new available balance

# ------------------------------------ ACCEPT USER INPUT - D, B, W, or Q -------------------------------------
userAccess = input ("Welcome to Tom & Kate Banking, if you would like to sign into your account, please press (C)ontinue, or (E)xit\n").upper()
if userAccess == 'C':
  transactionGo (pin)

  userChoice = 'go'                                                               # Setting the variable 'userChoice' to 'go', so we can implement a while loop

  # Step ONE => Create a WHILE loop to offer the user additional options after they have completed a transaction
  while userChoice != 'E':                                                        # As long as the user does not select 'E' (Exit), the program will keep looping with user choices
    
  # Step TWO =>  Ask user what action they would like to proceed with, user input is accepted and assigned to the variable 'userchoice'
    userChoice = input ("Would you like to check your (B)alance, make a (D)eposit, (W)ithdraw cash, or (E)xit?\n").upper()

  # Step THREE => conditional statement begins based on the value of variable 'userchoice' from user input
  # Four branches utilizing if / elif for DEPOSIT, BALANCE, WITHDRAWAL, EXIT
    if (userChoice == 'D'):                                                       # Accepts input D and proceeds with function 'deposit'
      deposit ()                                           # DEPOSIT function is called with parameters 'balance' and 'amount'

    elif (userChoice == 'B'):                                                     # Accepts input B and proceeds with function 'balance'
      balance (account_balance)                                                   # BALANCE function is called with parameter 'balance'

    elif (userChoice == 'W'):                                                     # Accepts input D and proceeds with function 'withdrawal'
      withdrawal ()                                        # WITHDRAWAL function is called with parameters 'balance' and 'amount'

    elif (userChoice == 'E'):                                                     # Accepts input E for EXIT
      print("Thank you for banking with us.")                                     # There is no function for EXIT, and therefore the user has a printed message ending their session

else:
  print("We hope to see you again soon, have a nice day!")

Method #2: Making a BankAccount class to store these methods and attributes方法 #2:创建一个 BankAccount class 来存储这些方法和属性

BankAccount.py银行账户.py

# This file will contain the class, to keep our project organised
class BankAccount:
    def __init__(self, account_balance, pin):
        self.account_balance = account_balance  # The account_balance is a class attribute
        self.pin = pin  # Class attribute

    def __repr__(self):
        return f'Account Balance: {self.account_balance}, Pin: {pin}'

    def check_pin(self):
        number_of_tries = 3  # Number of pin tries the user gets
        for i in range(number_of_tries, 0, -1):  # Counts backwards from the number_of_tries to the last digit 0
            print(f'Number of attempts remaining: {i}')
            while True:
                try:
                    inputted_pin = input('Please enter your 5 digit pin number:\n')

                    if len(inputted_pin) != 5:  # Checks and then handles whether or not the pin is 5 digits
                        incorrect_pin_length_error_message = 'Please ensure the pin you enter is 5 digits long\n\n'
                        print(incorrect_pin_length_error_message)

                    inputted_pin = int(inputted_pin)

                    if inputted_pin == self.pin:  # If the valid pin is the actual pin of this bank account
                        return True  # Allows the user to enter

                    else:
                        break  # Breaks out of the while loop making onto the next iteration of the for loop

                except ValueError:  # If the pin entered contains any character that is not a number then this except block will be hit when int(inputted_pin) is called
                    did_not_enter_all_numbers_error_message = 'Please ensure that you have entered pin number.\n\n'
                    print(did_not_enter_all_numbers_error_message)

                # If there is an error in the way a pin was entered it does not count as an attempt
                # Only when the pin is valid does it use up an attempt

        return False  # Returns False if the user fails to input the correct pin in the number of tries given

    def check_balance(self):
        """
        Prints the balance of the bank account.
        """
        print('Your current balance is $%.2f\n' % self.account_balance)

    def make_deposit(self):
        try:
            amount_to_deposit = input('How much would you like to deposit today?\n')
            try:
                if len(amount_to_deposit.split('.')[1]) != 2:  # Checks whether or not the user inputted two decimal places and two decimals only
                    more_than_two_decimal_place_error_message = 'Please ensure that your deposit is to two decimal places only.\n\n'
                    print(more_than_two_decimal_place_error_message)
                else:
                    if amount_to_deposit.count('.') > 1:  # Ensures that there is not more than one decimal point in the given input
                        multiple_decimal_points_error_message = 'Please ensure that the amount you wish to withdraw does not have multiple decimal points.\n\n'
                        print(multiple_decimal_points_error_message)
                    else:
                        self.account_balance += float(amount_to_deposit)  # Adds the amount once validated
                        self.check_balance()  # Prints out the current balance of the user

            except IndexError:  # Occurs if the user does not enter a decimal point
                did_not_enter_two_decimal_places_error_message = 'Please ensure that you enter exactly two decimal places in your deposit.\n\n'
                print(did_not_enter_two_decimal_places_error_message)

        except ValueError:  # Ensures that the input are all numbers
            did_not_enter_number_error_message = 'Please ensure that you enter a numerical amount.\n\n'

    def make_withdrawal(self):
        try:
            amount_to_withdraw = input('How much would you like to withdraw today?\n')
            if len(amount_to_withdraw.split('.')[1]) != 2:  # Ensures that there are two decimal places inputted and hta
                more_than_two_decimal_place_error_message = 'Please ensure that your withdrawal is to two decimal places only.\n\n'
                print(more_than_two_decimal_place_error_message)
            else:
                if amount_to_withdraw.count('.') > 1:  # Ensures that there is not more than one decimal point in the given input
                    multiple_decimal_points_error_message = 'Please ensure that the amount you wish to withdraw does not have multiple decimal points.\n\n'
                    print(multiple_decimal_points_error_message)
                else:
                    amount_to_withdraw = float(amount_to_withdraw)
                    if amount_to_withdraw > self.account_balance:  # Ensures that the user has enough funds to withdraw money from
                        insufficient_funds_message = 'Insufficient funds, $%.2f is greater than your account balance of $%.2f' % (amount_to_withdraw, self.account_balance)
                    else:
                        self.account_balance -= amount_to_withdraw  # Once validated withdraws the amount from the account
                        self.check_balance()  # Prints the user's balance


        except ValueError:  # Ensures that the input is only numbers
            did_not_enter_number_error_message = 'Please ensure that you enter a numerical amount.\n\n'

    def exit_transaction():
        exit_message = 'Thank you for banking with us.'
        print(exit_message)

    def do_transaction():
        # The main loop that you defined in your original code.
        if self.check_pin():

            while True:
                user_choice = input('Would you like to check your (B)alance, make a (D)eposit, (W)ithdraw cash, or (E)xit?\n').upper()

                if user_choice == 'B':
                    self.check_balance()

                elif user_choice == 'D':
                    self.make_deposit()

                elif user_choice == 'W':
                    self.make_withdrawal()

                elif user_choice == 'E':
                    self.exit_transaction()

        else:
            unsuccessful_pin_error_message = 'It seems like you ran out of pin tries, please try again later.'
            print(unsuccessful_pin_error_message)

main.py主文件

from BankAccount import BankAccount

person1_bank_account = BankAccount(account_balance=500.25, pin=12345)
person2_bank_account = BankAccount(account_balance=1100.00, pin=54321)
# As many as you want

# Perform any functions on them
person1_bank_account.make_deposit()

person2_bank_account.make_withdrawal()

# Print values
print(person1_bank_account.account_balance)

print(person2_bank_account.pin)

This way your code is more flexible, clean, and scalable.这样,您的代码就更加灵活、简洁和可扩展。 For example in your class you can add ass many methods as you want in whatever way you want, and every instance of that class gains that functionality on top of being easy to manage.例如,在您的 class 中,您可以以任何您想要的方式添加任意数量的方法,并且该 class 的每个实例除了易于管理之外还获得了该功能。 You can handle any exception you want in whatever way you want.你可以用任何你想要的方式处理你想要的任何异常。 So this is what I would suggest.所以这就是我的建议。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Python - 使用 While 循环,如何更新要在函数中使用的变量字符串 - Python - Using a While Loop, how can I update a variable string to be used in a function Python While 循环 - 变量未跨函数更新 - Python While Loop - Variable Not Updating across Functions while循环崩溃中的多个python附加函数 - Multiple python append functions in while loop crashing Python:在while语句内部使用先前使用的变量创建循环,直到将该变量设置为所需的值为止 - Python: Using a variable previously used, inside of a while statement to create a loop until the variable is set to something required 在 While 循环中更新变量 - Python - Update variable within a While loop - Python python 如何while循环while true,一起运行多个函数 - python How to while loop while true , run multiple functions together 我正在尝试将分配的变量添加到python上的列表中,它处于while循环中,因此我希望它继续添加变量 - I am trying to add an assigned variable to a list on python, it is in a while loop so I want it to keep adding the variable 使用 for 循环定义多个函数 - Python - Using for loop to define multiple functions - Python 在 Python 中使用循环调用多个函数 - Call multiple functions using loop in Python 使用for循环在Python中定义多个函数? - Using for loop to define multiple functions in Python?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM