Search code examples
pythonfunctionclassvariablesinstance-variables

How to reference a variable in second function in the same class?


How do I correctly define and call these functions?

I am trying to build an application that will prompt the main menu, go through a logon process, go to the next function, which would be the login menu and reference the inputs from the logon function so users do not have to input their card number and pin twice.

The issue I'm having is trying to be able to reference a variable in my second function, which is located in the same class. I'm being told by coworkers that using globals is bad and I shouldn't. Here is the code.

I've taken out some things as they aren't really important. I'd like to, for instance, use the elif choice ==3 statement to reference the original one_row.

p.s. I have changed def Login(self) to include the variables I'd like to reference, but then my main menu complains that the inputs have not been defined yet.

class LoginPrompt:
    def Login(self):
        while True:
            print(menu[1])
            self.Card_number=str(input('>>  '))
            print(menu[2])
            self.Character_PINs = getpass.getpass('>>  ')
            self.one_row = c.execute('SELECT * FROM {tn} WHERE {cn}=? and {cnn}=?'.\
                            format(tn=table_1, cn=column_1, cnn=column_3),    (self.Character_PINs, self.Card_number,))
        for row in self.one_row.fetchone():
                print('Welcome: ', row)
                return

        else:
            print('PIN incorrect; try again')

    def loginMenu(self):
        while True:
            print(menu[5])
            print("\n1 - Deposit funds")
            print("2 - Withdraw funds")
            print("3 - Check balance")
            print("4 - Reset Pin")
            print("5 - Exit")

            while True:
                try:
                    choice = int(input("Please enter a number: "))
                except ValueError:
                    print("This is not a number")
                if choice >= 1 and choice <=5:
                    if choice == 1:
                        amount = input("\nPlease enter the deposit amount: ")
                        if amount != '' and amount.isdigit():
                            int(amount)
                            amount = c.execute('UPDATE {tn} SET Balances = ? WHERE {cn}=?'.\
                                                format(tn=table_1, cn=column_2), (amount,))
                        else:
                            print("Please enter a valid number")
                            conn.commit()
                            conn.close

                    elif choice ==3:
                        print(Login.one_row)

                    elif choice ==5:
                        input('Enjoy your stay, and always remember to drink Nuka Cola! ')
                        return(mainMenu)
                else:
                    return


def mainMenu():
        print(menu[0])
        chosen=False
        while not chosen:
        opt=int(input('\n Please choose one of the options below:\n\n-> Register for a new account [1]\n-> Login to an existing account [2]\n\nPlease type a number...\n\n>>  '))
        if opt==1:
            userReg()
            chosen=True
        elif opt==2:
            login_Menu = LoginPrompt()
            login_Menu.Login()
            chosen=True
            login_Menu.loginMenu()
        else:
            print('\n\nPLEASE TYPE EITHER 1 OR 2...\n ')
    print(chosen)
if __name__ == "__main__":
        while True:
            mainMenu()

Solution

  • Here, you instantiated a single instance of LoginPrompt and called Login and loginMenu on it:

    login_Menu = LoginPrompt()
    login_Menu.Login()
    ...
    login_Menu.loginMenu()
    

    Since you assign an instance variable self.one_row in Login, you can access the same instance variable via self.one_row in loginMenu:

    class LoginPrompt:
        def Login(self):
            while True:
                ...
                self.one_row = ...
            ...
    
        def loginMenu(self):
            while True:
                ...
    
                while True:
                    ...
                    if choice >= 1 and choice <=5:
                        ...
    
                        elif choice == 3:
                            # print(Login.one_row)
                            print(self.one_row)
    

    You can read more about self and instance variables in the Python documentation: https://docs.python.org/3.8/tutorial/classes.html#class-and-instance-variables

    A note about code style

    In Python, the convention is to:

    • name functions consistently in lower_case_with_underscores (and classes in CapWords), and
    • name instances after the class name.
    login_prompt = LoginPrompt()
    login_prompt.login()
    ...
    login_prompt.login_menu()
    

    You can read more about naming conventions in the PEP 8 style guide for Python code: https://www.python.org/dev/peps/pep-0008/#prescriptive-naming-conventions