0

私はコンピューター サイエンスに興味がある高校の初心者プログラマーです。私は、Mike Dawson の本、Learning to program for the全くの初心者のための Python、第 3 版を使用して、Python でプログラミングすることを独学しています。. 新たに習得した OOP の知識を実践するためのプログラムを作成しています。このプログラムは、プレーヤーが銀行口座を開設したり、現金を引き出し/入金したり、為替レートを取得したり、ある口座から別の口座に送金したり、その他の機能を実行できる銀行をシミュレートします。ユーザーがアクセスできる複数のアクセス可能なアカウントがあるという事実をシミュレートするプログラムの主要部分として、プログラムに深刻な問題があります。どうすればよいのか、それが正しい方法なのかはわかりましたが、all_accounts という空のリストであるクラス属性を作成してみました。アカウントがインスタンス化されるたびに、インスタンスがリストに追加されます。プレーヤーが現金の引き出し/入金などのメニュー オプションを選択したときに、オブジェクトの属性 (残高など) を変更できるように、リスト内のインスタンスにアクセスできるようにしたいと考えています。これを行う方法がわかりません.3日間ほど答えを探していましたが、何も見つかりませんでした. 私は初心者のプログラマーなので、私のコードはおそらく不十分に書かれていると見なされることに注意してください。コードがどのように動作し、機能するかを人々が完全に理解する必要があると感じているため、コード全体を以下に掲載します。また、私のコードに正しくない点や改善できる点があれば、遠慮なくお知らせください。私は常に学習に対してオープンです。私のコードに正しくない点や改善できる点があれば、遠慮なくお知らせください。私は常に学習に対してオープンです。私のコードに正しくない点や改善できる点があれば、遠慮なくお知らせください。私は常に学習に対してオープンです。

class Account(object):
    """An interactive bank account"""
    wallet = 0
    all_accounts = []

    # initial
    def __init__(self, ID, bal):
        self.ID = ID
        self.bal = bal
        print("A new account has been opened!")
        Account.all_accounts.append(self)                       

    def withdraw(self, w_input):
        if w_input < self.bal  or w_input == 0:
            print("That is not a valid amount. Sending you back to menu.\n")
            Menu()
        else:
            self.bal = self.bal - w_input
            print("You withdrew $" + str(w_input) + ".\n")
            wallet += w_input
            print("You wallet now contains $" + Account.wallet)
            Menu()

    def deposit(self):
        # Whatever



def Menu():
    print(
        """
0 - Leave the Virtual Bank
1 - Open a new account
2 - Withdraw money
3 - Deposit money
4 - Transfer money from one account to another
5 - Get exchange rates(Euro, Franc, Pounds, Yuan, Yen)
"""
        ) # Add more if necessary
    choice = input("What would you like to do?: ")
    while choice != "0":
        if choice == "1":
            account_name = input("What is your account's ID?: ")
            account_bal = float(input("How much money would you like to put into the account?(USD): "))
            account_name = Account(ID = account_name, bal = account_bal)
            Menu()

        elif choice == "2":
            account_choice = input("What is your account ID?: ")
            if account_choice in instance.Account.all_account:
                withdraw_choice = input("How much money would you like to withdraw?: ")
                account_choice.withdraw(w_input = withdraw_choice)
            else:
                print("Nope.")



    if choice == "0":
        print("\nThank you for visiting the virtual bank!")
        input("Press the [ENTER] key to exit the program.")


Menu()
4

2 に答える 2

0

ACEfanatic02が言ったように、ユーザーインターフェイスをアプリケーションの本質から切り離しておくようにしてください。

アカウントに必要なものについて考えてください。

  • 一意の識別子
  • バランス
  • (の)クライアント
  • トランザクションのリスト

これらはインスタンス属性です。

また、それが何ができなければならないかについて考えてください

  • アカウントにお金を入金する
  • アカウントから撤退する
  • 別のアカウントに転送する

これらはメソッドです。

アカウントのテキスト表現を印刷する方法も必要になる場合があります。これは、クラスにマジックメソッドを提供することで実行できます__str__

簡単な例:

def _checkamount(a):
    if a < 0:
        raise ValueError('amount must be >0')


class Account(object):

    maxnum = 0

    def __init__(self, client):
        self.client = client
        self.balance = 0.0
        self.transactions = []
        Account.maxnum = Account.maxnum + 1
        self.number = Account.maxnum

    def __str__(self):
        "Generate a human-readable representation of the Account."
        rv = 'Accountnumber: ' + str(self.number) + '\n'
        rv += 'Client: ' + str(self.client) + '\n'
        rv += 'Balance: ' + str(self.balance) + '\n'
        return rv

    def withdraw(self, amount):
        _checkamount(amount)
        if self.balance < amount:
            raise ValueError('overdraft!')
        self.balance -= amount
        self.transactions.append(("withdraw", amount))

    def deposit(self, amount):
        _checkamount(amount)
        self.balance += amount
        self.transactions.append(("deposit", amount))

    def transfer(self, amount, other):
        _checkamount(amount)
        self.balance -= amount
        self.transactions.append(("transfer", amount, other.number))
        other.balance += amount
        other.transactions.append(("transfer", amount, self.number))

このコードをというファイルに保存しましたaccount.py

インタラクティブテスト(Ipythonを使用、インタラクティブな実験に強くお勧めします):

In [1]: from account import Account

In [2]: a = Account('myself')

In [3]: b = Account('someoneelse')

In [4]: a.deposit(200)

In [5]: a.withdraw(10)

In [6]: b.deposit(50)

In [7]: a.transfer(25, b)

In [8]: print a.transactions
[('deposit', 200), ('withdraw', 10), ('transfer', 25, 2)]

In [9]: print b
Accountnumber: 2
Client: someoneelse
Balance: 75.0

In [10]: print b.transactions
[('deposit', 50), ('transfer', 25, 1)]

In [11]: print a
Accountnumber: 1
Client: myself
Balance: 165.0

In [12]: a.withdraw(1000)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-12-ffc10f6333fe> in <module>()
----> 1 a.withdraw(1000)

/home/rsmith/tmp/account.py in withdraw(self, amount)
     24         _checkamount(amount)
     25         if self.balance < amount:
---> 26             raise ValueError('overdraft!')
     27         self.balance -= amount
     28         self.transactions.append(("withdraw", amount))

ValueError: overdraft!

このテストでは、文字列をとして使用していますclient。Pythonの動的な性質により、後でこれをたとえばクラスに変更できます。クライアントにメソッドClientがあれば、コードは引き続き機能します。__str__

于 2013-03-23T21:11:02.347 に答える
0

通常、呼び出しコードをクラスの内部動作から分離する必要があります。すべてのアカウントを保持しているリストをMenu()関数に直接チェックさせるのは柔軟性がなく、後で問題が発生します (データベース ストレージのリストを交換するとどうなるでしょうか?)

代わりに、AccountManagerクラスのようなものがより良いアイデアかもしれません:

class AccountManager(object):
    def __init__(self):
        self.accounts = []

    def create_account(self, id, balance):
        # You may want to check for uniqueness of id's here as well
        account = Account(id, balance)
        self.accounts.append(account)

    def get_account(self, id):
        for account in self.accounts:
            if account.id == id:
                return account
        return None # or a default value, or raise an exception

これで、呼び出し元のコードはAccountManager、アカウントの作成と取得を指示するだけで済み、アカウントがどのように保存されているかは気にしなくなりました。

于 2013-03-23T19:28:00.947 に答える