0

わかりました、アドバイスをくれる時間があれば誰でも簡単にできるように、できるだけ多くの情報を提供しようと思います。

私は算術トレーニングのようなプログラムを書いています。プログラムの考え方は、ユーザーが「セッション」を作成し、必要な数学演算 (/、*、-、+)、方程式の量、数ジェネレータの範囲 (2 つの数、たとえば1 と 5 を指定すると、ランダム化される方程式のすべての数値がこの範囲になります)。

次に、セッションが生成され、ユーザーは方程式を完成させます。最後に、ユーザーは自分の答えを確認でき、正解率、セッションを完了するのにかかった時間、セッションが作成された正確な日時が表示されます。

プログラムはオブジェクト指向プログラミングで書かれており、各セッションはオブジェクトです。これらのオブジェクトは、ピクルされたリストに含まれています。ユーザーが以前のセッションに戻って、改善点などを追跡できるという考えです。

問題: 各オブジェクトを繰り返し処理し、そのすべてのデータを出力するのは不可能です。

私のプログラムのコードは次のとおりです。

import pickle,time,random

class Session:
    def __init__(self,amount,operation,numgen_range):
        start_time = [int(time.strftime('%M', time.gmtime())),int(time.strftime('%S', time.gmtime()))]
        ID = main.get_id() + 1
        accuracy = 0
        rights = 0
        equations_data = []
        duration = [0,0]
        datetime = time.strftime('%a, %d %b %Y %H:%M:%S', time.gmtime())
        self.session_data = [ID,amount,operation,numgen_range,datetime,accuracy,rights,equations_data,duration]
        main.save_id()

        if self.session_data[2] == '+':
            for i in range(self.session_data[1]):
                a = random.randint(self.session_data[3][0],self.session_data[3][1])
                b = random.randint(self.session_data[3][0],self.session_data[3][1])
                answer = a + b
                user_answer = int(input('{0} + {1} = '.format(a,b)))
                if answer == user_answer:
                    rightwrong = True
                    self.session_data[6] += 1
                else:
                    rightwrong = False
                eq_data = [a,self.session_data[2],b,answer,user_answer,rightwrong]
                self.session_data[7].append(eq_data)
        elif self.session_data[2] == '*':
            for i in range(self.session_data[1]):
                a = random.randint(self.session_data[3][0],self.session_data[3][1])
                b = random.randint(self.session_data[3][0],self.session_data[3][1])
                answer = a * b
                user_answer = int(input('{0} * {1} = '.format(a,b)))
                if answer == user_answer:
                    rightwrong = True
                    self.session_data[6] += 1
                else:
                    rightwrong = False
                eq_data = [a,self.session_data[2],b,answer,user_answer,rightwrong]
                self.session_data[7].append(eq_data)
        elif self.session_data[2] == '-':
            for i in range(self.session_data[1]):
                a = random.randint(self.session_data[3][0],self.session_data[3][1])
                b = random.randint(self.session_data[3][0],self.session_data[3][1])
                answer = a - b
                user_answer = int(input('{0} - {1} = '.format(a,b)))
                if answer == user_answer:
                    rightwrong = True
                    self.session_data[6] += 1
                else:
                    rightwrong = False
                eq_data = [a,self.session_data[2],b,answer,user_answer,rightwrong]
                self.session_data[7].append(eq_data)
        elif self.session_data[2] == '/':
            for i in range(self.session_data[1]):
                a = random.randint(self.session_data[3][0],self.session_data[3][1])
                b = random.randint(self.session_data[3][0],self.session_data[3][1])
                answer = a / b
                user_answer = int(input('{0} / {1} = '.format(a,b)))
                if answer == user_answer:
                    rightwrong = True
                    self.session_data[6] += 1
                else:
                    rightwrong = False
                eq_data = [a,self.session_data[2],b,answer,user_answer,rightwrong]
                self.session_data[7].append(eq_data)

        end_time = [int(time.strftime('%M', time.gmtime())),int(time.strftime('%S', time.gmtime()))]
        if start_time[0] >= end_time[0]:
            self.session_data[8][0] = start_time[0] - end_time[0]
        else:
            self.session_data[8][0] = end_time[0] - start_time[0]
        if start_time[1] >= end_time[1]:
            self.session_data[8][1] = start_time[1] - end_time[1]
        else:
            self.session_data[8][1] = end_time[1] - start_time[1]

        self.session_data[5] = (self.session_data[6] / self.session_data[1]) * 100
        print('You got {0} problems correct out of {1}, your accuracy percentage was {2}%.\nYou took {3} minutes and {4} seconds to complete the session.'.format(self.session_data[6],self.session_data[1],int(self.session_data[5]),self.session_data[8][0],self.session_data[8][1]))

        while True:
            try:
                i = int(input('Enter 1 to check answers or 2 to return to the menu: '))
                if i == 1:
                    main.util = True
                    for i in self.session_data[7]:
                        if i[5]:
                            rw = 'CORRECT'
                        else:
                            rw = 'INCORRECT'
                        print('{0} {1} {2} = {3} Your Answer: {4} - {5}\n'.format(i[0],i[1],i[2],i[3],i[4],rw))
                elif i == 2:
                    main.util = False
                    pass
                else:
                    raise ValueError
                break
            except ValueError:
                print(main.input_error_msg)
                continue

with open('data/saved_sessions.txt','rb') as file:
    saved_sessions = pickle.load(file)

class main:
    util = None
    input_error_msg = 'You entered an invalid input, try again.'

    def create():
        print('Create Session.')

        while True:
            try:
                amount = int(input('Enter the amount of equations you want: '))
                if amount < 1:
                    raise ValueError
                if amount > 50:
                    print('Sorry, the limit for equation amounts is 50, try again.')
                    continue
                break
            except ValueError:
                print(main.input_error_msg)
                continue

        while True:
            try:
                operation = input('Enter operation: ')
                if operation == '':
                    print('You must specify an operation for the session!')
                    continue
                if len(operation) != 1:
                    print(main.input_error_msg)
                    continue
                if "+" not in operation:
                    if "-" not in operation:
                        if "*" not in operation:
                            if "/" not in operation:
                                print("You failed to enter a valid equation type. Please try again.")
                                continue
                break
            except ValueError:
                print(main.input_error_msg)
                continue

        numgen_range = [0,0]
        while True:
            try:
                numgen_range[0] = int(input('Enter base range number: '))
                if numgen_range[0] < 0:
                    raise ValueError
                break
            except ValueError:
                print(main.input_error_msg)
                continue

        while True:
            try:
                numgen_range[1] = int(input('Enter ceiling range number: '))
                if numgen_range[1] < numgen_range[0]:
                    print('Sorry the ceiling range number cannot be larger than the base range number.')
                    continue
                break
            except ValueError:
                print(main.input_error_msg)
                continue

        while True:
            try:
                i = int(input('Enter 1 to generate this session or 2 to enter new specifications: '))
                if i == 1:
                    saved_sessions.append(Session(amount,operation,numgen_range))
                    main.pickle_sessions()
                    if main.util:
                        main.menu()
                    else:
                        main.menu(rmenu=True)
                elif i == 2:
                    main.create()
                else:
                    raise ValueError
                break
            except ValueError:
                print(main.input_error_msg)
                continue

    def get_id():
        try:
            with open('data/id_count.txt','rb') as file:
                count = pickle.load(file)
        except IOError:
            pass
        else:
            return count

    def save_id():
        try:
            with open('data/id_count.txt','wb') as file:
                pickle.dump(ID,file)
        except IOError:
            pass
        else:
            print('id count pickled.')

    def view_archive():
        print('View Session Archive')
        #view archive code to go here.    

    def menu(rmenu=False):
        if rmenu:
            while True:
                try:
                    i = int(input('Enter 1 to return to the menu: '))
                    if i == 1:
                        main.menu()
                    else:
                        raise ValueError
                    break
                except ValueError:
                    print(main.input_error_msg)
                    continue
        else:
            print('Menu -[1]Create Session.[2]View Session Archive.[3]Exit.')
            while True:
                try:
                    i = int(input('Enter choice: '))
                    if i == 1:
                        main.create()
                    elif i == 2:
                        main.view_archive()
                    elif i == 3:
                        quit()
                    else:
                        raise ValueError
                    break
                except ValueError:
                    print(main.input_error_msg)
                    continue

    def pickle_sessions():
        try:
            with open('data/saved_sessions.txt','wb') as file:
                pickle.dump(saved_sessions,file)
        except IOError:
            pass
        else:
            print('Sessions have been pickled.')

    def start():
        if __name__ == '__main__':
            main.menu()

main.start()

今私がやりたいことは、各オブジェクトを反復処理し、その session_data リストに移動し、これを反復処理してデータの各ビットを出力し、session_data リストの要素 7 である方程式_データ リストを反復処理することです。個々の方程式のデータを含むさらに多くのリストが取り込まれているので、それを繰り返したいと思います。

要約すると、各オブジェクトからすべてのデータを出力します。

I thought something like:
for i in saved_sessions:
    for y in i.session_data:
        #print out elements then loop over equations_data on line below
        for x in i.session_data[7]:
            #print out elements

ただし、これは機能しません。基本的に、self.session_data [7]であるequations_dataリスト内のリストにアクセスする方法を理解できませんが、これを反復しようとすると、インデックスエラーが返されます。

私がやりたいことを言ったように、次のように各セッションを 1 つずつ表示します。

ID: 1
Date: some date
Time: some time
Operation: +
Equations: 5
Right Answers: 5
Accuracy: 100%
Time Taken: 15 seconds

Equations:
1 + 5 = 6 Your Answer: 6
1 + 6 = 7 Your Answer: 7
1 + 7 = 8 Your Answer: 8
1 + 8 = 9 Your Answer: 9
1 + 9 = 10 Your Answer: 10

この問題に関するヘルプは大歓迎です。また、私のプログラミングのあらゆる側面について、非常に率直なフィードバックをお待ちしております。建設的な批判が奨励されます。

4

1 に答える 1

3

単一のリスト属性に変数を入れているのはなぜですか? 番号ではなく名前でアクセスできるように、それらをすべてクラス属性にしてみませんか? 例: 、self.equations_dataself.accuracyなど?

ネストされたループの問題は、ネストされすぎていることです。n 回繰り返していますi.session_data[7]。ここで、n は明らかに 9 であり、session_data の長さです。次のようなものが必要です。

for i in saved_sessions:
    for j in range(len(i.session_data)):
        if j!=7:
            y=i.session_data[j]
            # print out your elements here
    for x in i.session_data[7]:
        #print out elements

しかし、それをしないでください。その1つのリストに属性を保存しないように、アプローチを修正してください。少なくとも辞書に保存して、名前でアクセスできるようにします。さらに良いことに、それらをクラスの属性として保存します。

__str__(self)クラスの出力に関しては、メソッドを実装してSession、クラス インスタンスのデータを目的の形式の文字列に変換する必要があります。次に例を示します。

class Session(object):
    ...
    def __str__(self):
        out = 'ID:%s\nAMOUNT:%d ... '%(self.ID, self.amount, ...)   # And so on.
        return out

そうすれば、次のように実行できます。

for session in saved_sessions:
    print str(session)

以上です。なんてかわいいの!(参考までに、でループするときに変数名に説明的な単語を使用する方が Pythonicfor ... inです。)

その他の推奨事項

  1. @David Robinson が指摘しているように、クラスMainは思い通りに実行されません。Python クラスについて正しくない仮定をしているため、先に進む前にPython クラスについて読む必要があります。インスタンスなしでメソッドにアクセスしたい場合は、静的メソッドを宣言する必要があり@staticmethodます。これは非常に Pythonic ではないと思います。

2&3. reネストされたifステートメントの代わりに使用します。例:

if not re.search(r'[\*\-\+\/]', operation):
    # Invalid operation, you should raise an exception here
    raise ValueError

4 . Python のスタイル ガイドを確認し、コードを適切にフォーマットします。これにより、Python を使用して記述を開始できるようになり、コードがより明確で優れたものになります。

それらは私の目を引いたものでした

于 2012-04-24T05:41:01.923 に答える