0
def transfer():
    print ("You've chosen to transfer money.")
    transAccFrom = int(input("From which account you want to transfer?\n1.Jack 2.Smith 3.Suzy 4.Craig 5.Vic :"))
    transMoney = float(input("How much you want to tranfer?"))
    transAccTo = int(input("To which account you want to transfer?\n1.Jack 2.Smith 3.Suzy 4.Craig 5.Vic :"))
#These are asked to know from which acc to to which acc the user wants to transefer.

    if (transAccFrom == 1):
        if (transMoney > c1.balance):
            print ("The process can't be done. Please check your account balance.")
        #Since balance of the account that is sending money from isn't enough, non process is being done.
        else:
            c1.balance = c1.balance - transMoney
            if (transAccTo == 1):
                c1.balance = c1.balance + transMoney
                print ("You have transfered money from Jack's Acc to Jack's Acc. Balance of Jack's Acc is "+str(c1.balance)+". Thank you for using our bank.")
            #After eliminate the amount of money that is determined to be transfered from, the amount of money is directly added to account that the money is supposed to be transfered to. Below steps are the same stages.
            elif (transAccto == 2):
                c2.balance = c2.balance + transMoney
                print ("You have transfered money from Jack's Acc to Smith's Acc. Remaining value of Jack's Acc is "+str(c1.balance)+". Balance of Smith's Acc is "+str(c2.balance)+" Thank you for using our bank.")

            elif (transAccTo == 3):
                c3.balance = c3.balance + transMoney
                print ("You have transfered money from Jack's Acc to Suzy's Acc. Remaining value of Jack's Acc is "+str(c1.balance)+". Balance of Suzy's Acc is "+str(c3.balance)+" Thank you for using our bank.")

            elif (transAccTo == 4):
                c4.balance = c4.balance + transMoney
                print ("You have transfered money from Jack's Acc to Craig's Acc. Remaining value of Jack's Acc is "+str(c1.balance)+". Balance of Craig's Acc is "+str(c4.balance)+" Thank you for using our bank.")

        elif (transAccTo == 5):
            c5.balance = c5.balance + transMoney
            print ("You have transfered money from Jack's Acc to Vic's Acc. Remaining value of Jack's Acc is "+str(c1.balance)+". Balance of Vic's Acc is "+str(c5.balance)+" Thank you for using our bank.")

            else:
                print ("You have input the wrong account to transfer money. Please check it again.")

I have created python code like this for my ATM machine code-transfering. Since I am not skilled at python, I created code one by one. (I have further codes that are to transfer from other users to transfer to another users.)

I have identified five users at the beginning of the code.

class Customer:
    def __init__ (self, name, birth, address, hkid, balance):
        self.name = name
        self.birth = birth
        self.address = address
        self.hkid = hkid
    self.balance = balance

#Assigning elements that are going to be in an array.
c1 = Customer ("Jack", "Jan, 10th, 1996", "430 Davis Ct., San Francisco", 
 "M8875895", 40000)
c2 = Customer ("Smith", "March 24th, 1997", "3-5 Tai Koo Shing, Hong Kong", "M3133242", 600)
c3 = Customer ("Suzy", "May 5th, 1995", "32 Clearwater Bay Ave. Hong Kong", "M8378644", 100000)
c4 = Customer ("Craig", "May 24th, 1993", "700 Powell Street, San Francisco", "M2314565", 70000)
c5 = Customer ("Vic", "September 21st, 1992", "1210 Freud Street, New York", "M1234569", 3400)

 #Appending customer information into the array
 CustomerList = []
CustomerList.append (c1)
CustomerList.append (c2)
CustomerList.append (c3)
CustomerList.append (c4)
CustomerList.append (c5)

But the problem is that I will have to add more users into the array that I've made. And based on transfer code that I've made, I can't do anything with new users that will be created.

Is there a way for me to simplifying transfering code using Customer ... so that I can add more new users into the array and do some banking works with those newly created users?

  • You already have a list: using the actual indices as indicators for comparisons etc (instead of `== 1`, `== 2` etc) is step 1 (probably the index + 1, since Python's lists are zero-indexed). The next step is to use use `dict`s instead: you can use either numbers as keys (ever increasing, thus unique) or customers names (these will not always be unique, but can be clearer in questions as at the top of your code). –  Feb 27 '18 at 03:16
  • 1
    The thing is, while the answer is fairly obvious, there are also multiple ways to handle this, and that may make question a bit too broad for a practical answer. It is, for example, more suited for something like the [Python tutor mailing list](https://mail.python.org/mailman/listinfo/tutor). –  Feb 27 '18 at 03:19

2 Answers2

1

In General:
Every time you see code repeating itself, ask yourself: "Tae, couldn't that be done in a loop?"

More Specific:

  • It is clearer if you assign each customer his very own number to identify him easily. Therefore you could add a class attribute which increments every time a new customer is created.

    class Customer:
        counter = 1
        def __init__ (self, name, birth, address, hkid, balance):
            self.name = name
            self.birth = birth
            self.address = address
            self.hkid = hkid
            self.balance = balance
    
            #assign customer index, starting at 1
            self.index = Customer.counter
            Customer.counter += 1
    
  • you can know add each customer to a dictionary instead of a list, to easily access each customer by his index.

    CustomerArchive = {}
    
    CustomerArchive[c1.index] = c1
    CustomerArchive[c2.index] = c2
    CustomerArchive[c3.index] = c3
    CustomerArchive[c4.index] = c4
    
  • now we can easily iterate through that dictionary, to make your user interface flexible. For example...

    transAccFrom = int(input("From which account you want to transfer?\n1.Jack 2.Smith 3.Suzy 4.Craig 5.Vic :"))
    

    ...becomes...

    question = "From which account do you want to transfer?\n"
    
    for index,customer in CustomerArchive.items():
    
        question = question + str(index) + ". " + str(customer.name)
    
    transAccFrom = int(input(question))
    
  • and the awful long elif part can be replaced by simply calling the specific customer:

    sender = CustomerArchive[transAccFrom]
    receiver = CustomerArchive[transAccTo]
    
    #...ongoing transaction stuff
    

EDIT

In case you want to keep your list rather than having a dictionary (for whatever reason...) nothing changes despite the part where you...

...add customers to your list (which is just as you've done it in your original question)

...try to get a specific customer from the list.

In order to get a specific CustomerObject from the list, you have to iterate through it and compare every single object with your aim index:

#The outer function defines the default customer_list source
def get_customer_from(cus_list):
    #The inner function finds&returns the customer matching the given index
    def wrapped(customer_index):
        for customer in cus_list:
            if customer.index == customer_index:
                return customer
    return wrapped

And here is the behaviour/how it works:

>>get_customer = get_customer_from(CustomerList)
>>get_customer(1).name
"Jack"
>>Suzy = get_customer(3)
>>Suzy.birth
"May 5th, 1995"

Note: That might not be that easy to understand if you are relatively new to python, but its a good way to achieve it and quite pythonic. You could of course instead use a single function and pass the full CusomerList on every time you call the function (simpler but not as elegant...).

NewNewton
  • 1,015
  • 1
  • 10
  • 22
  • Looks great to go with the dictionary instead of listing. But still, is there a way for me to use list? Can I pick a specific array from the listed elements? (e.g. I want to call Suzy's balance for printing. Is there any way to bring its value as c3[balance] or something like this? – Tae Min Kim Mar 01 '18 at 03:20
  • By array you mean object I suppose. Let me edit my answer real quick:) However, I don't see a point why a list would be of advantage in your case. – NewNewton Mar 01 '18 at 03:54
  • Really appreciate your help. Just by seeing your code, I think I do understand. So, if I place the define part at the beginning of the code or where my other define parts are at, then I can use it later through the command "get_customer(number).(name or whatever I need)"? +) Do I still need to use CustomerArchive and index? – Tae Min Kim Mar 02 '18 at 02:17
0

This can work:

def transfer(customers):
    print ("You've chosen to transfer money.")
    for i, customer in enumerate(customers):
        print("{}. {}".format(i, customer.name))
    i = int(input("Select the number of the account from which "
                  "you'd like to transfer money: "))
    fro = customers[i]
    amount = float(input("How much would you like to transfer: "))
    if fro.balance < amount:
        print ("The process can't be done. Please check your account balance.")
        return

    for i, customer in enumerate(customers):
        print("{}. {}".format(i, customer.name))
    i = int(input("Select the number of the account to which "
                  "you'd like to transfer money: "))        
    to = customers[i]

    fro.balance -= amount
    to.balance += amount
    print ("You have transfered money from {}'s account to {}'s account. "
           "The new balance of {}'s account is {}. ".format(
               fro.name, to.name, fro.name, fro.balance))

where the input argument customers is your CustomerList.

I've used fro instead of from, since from is a reserved word in Python.


As mentioned in my comment to the question itself, I think a dict would be better than a list, but since you're currently using a list, I went with a list as well, to stay closest to what you currently have.