Hey guys,

I'm in desparate need of assistance with my A-Level project.
I'm writing a Banking system in Python and I'm being told by the idle log that a function hasn't been defined - even though that function is right above it!

My Full Code is:

    #'http://effbot.org/tkinterbook/tkinter-index.htm' <<< Tkinter Tutorials
    #Ignore the link above, it's for future reference

    import time
    import random

    class BankAccount():

      #Class Initialisation
        def __init__(self, firstName, lastName, accountNumber, pinNumber, balance=0):
            self.fn = firstName
            self.ln = lastName
            self.accNum = accountNumber
            self.pin = pinNumber
            self.bal = balance
            self.transactions = []

      #Class Functions
        def deposit(self, amount):
            self.bal += amount
            return self.bal

        def withdraw(self, amount):
            if self.bal - amount > 0:
                self.bal -= amount
                self.transactions.append(-amount)
                time.sleep(.25)
                print('\n[Your new balance is £{}]\n'.format(self.bal))
            else: 
                time.sleep(.25)
                print('\n[You must withdraw a number greater than zero]\n')

        def accinfo(self):
            print('\n')
            print('-'*50)
            print('                Account Information')
            print('-'*50)
            print('Account Holder: {} {}'.format(self.fn, self.ln))
            print('Account Balance: £{}'.format(self.bal))
            print('Account Number: {}'.format(self.accNum))
            print('Account Pin: {}\n'.format(self.pin))

      #Setters
        def setfn(self, firstName):
            self.fn = firstName
            print('\n[First Name Updated]\n')

        def setln(self, lastName):
            self.ln = lastName
            print('\n[Last Name Updated]\n')

        def setNewAccNum(self):
            self.accNum = random.randint(0000,9999)
            print('\n[Account Number: {}]\n'.format(self.accNum))

        def setNewPin(self):
            self.pin = random.randint(0000, 9999)
            print('\n[Pin Number: {}]\n'.format(self.pin))

        def login():
            time.sleep(.25)

            accNum = random.randint(0000, 9999)
            pinNum = random.randint(0000, 9999)
            bal = 1000

            firstName = input('Please enter your first name: ')
            lastName = input('Please enter your last name: ')
            password = input('Please enter your password: ')
            for line in open('credentials.txt','r').readlines():
                login_info = line.split()
                if firstName == login_info[0] and lastName == login_info[1] and password == login_info[2]:
                    acc = BankAccount(firstName, lastName, accNum, pinNum, bal)
                    print('Logging in...')
                    time.sleep(.25)
                    accinfo()
                else:
                    print('WRONG LOL GET LOST U NUB')
                    exit()

        def newAccount():
            time.sleep(.25)
            firstName = input('Please input your first name: ')
            lastName = input('Please input your last name: ')
            password = input('Please input a password: ')
            file = open('credentials.txt','a')
            file.write(firstName)
            file.write(' ')
            file.write(lastName)
            file.write(' ')
            file.write(password)
            file.write('\n')
            file.close()
            print('\nThe Bank has rewarded you with 1000 GBP for opening an account with us!\n')
            print('Account Opened! Now try logging on\n')
            mainloop()

        def mainloop():
            print('-'*50)
            print('              The Royal Mint Of Spain')
            print('-'*50+'\n')
            print('•  Enter Input [1-4]')
            print('1) Login')
            print('2) Open Account')
            print('3) Exit\n')
            choice = input('>>>')

            if choice == '1': login()
            elif choice == '2': newAccount()
            elif choice == '3': exit(time.sleep(.25))
            else:
                print('[Invalid Input]')
                mainloop()

        mainloop()

    test = BankAccount('Test','Testerson', 1234, 5678, 1000)

Idle is telling me the following:

Traceback (most recent call last):
  File "H:\My Documents\Computing\Python\Object Oriented Programming\Banking System\main.py", line 6, in <module>
    class BankAccount():
  File "H:\My Documents\Computing\Python\Object Oriented Programming\Banking System\main.py", line 114, in BankAccount
    mainloop()
  File "H:\My Documents\Computing\Python\Object Oriented Programming\Banking System\main.py", line 107, in mainloop
    if choice == '1': login()
NameError: global name 'login' is not defined

I would appreciate any help!

Thanks!

Start by taking mainloop out of the class. Make other methods (like login) actual class methods. Put your loop in the main line as

while True:
    print('-'*50)
    print('              The Royal Mint Of Spain')
    print('-'*50+'\n')
    print('  Enter Input [1-4]')
    print('1) Login')
    print('2) Open Account')
    print('3) Exit\n')
    choice = input('>>>')
    if choice   == '1': test.login()
    elif choice == '2': test.newAccount()
    elif choice == '3': sys.exit()
    else:
        print('[Invalid Input]')
commented: Much Appreciated, I'll try this later! I'll be sure to credit you in the final code +0

login() is declared uner the class, even though it is not a member of the class.

commented: Thanks very much for your help! +0