Как правильно использовать double для циклов? - PullRequest
0 голосов
/ 14 января 2019

Британская система оценок GSCE недавно изменилась и стала запутанной, и она просто не работает. Я только что получил свои оценки и не знал, что хорошо, а что нет. Чтобы избежать путаницы, я решил что-то сделать, чтобы сохранить, конвертировать и редактировать свои оценки. Чтобы сделать мой код более аккуратным, я решил использовать два цикла for, чтобы он просто выводил их все. Когда я попробовал это, выглядело, как будто это работает, но он просто напечатал «Для английского языка, вы получили 6с», затем, когда он перешел к тому, что предполагалось, чтобы быть английской литературой, он просто напечатал «Для английского языка, вы получили 6с», я действительно получил 6с, но предмет не на английском языке. То же самое произойдет, если я переставлю порядок циклов for, только оценки будут одинаковыми, но уроки были нормальными.

Все, что я сделал, это перестроил циклы for. Ничто не похоже на работу. Вот код:

            import time

            with open('lessons.txt', 'r') as f:
                english_language = str(f.readline().strip('\n'))
                english_lit = str(f.readline().strip('\n\n'))
                maths = str(f.readline().strip('\n\n\n'))
                chemistry = str(f.readline().strip('\n\n\n\n'))
                physics = str(f.readline().strip('\n\n\n\n\n'))
                biology = str(f.readline().strip('\n\n\n\n\n\n'))
                re = str(f.readline().strip('\n\n\n\n\n\n\n'))
                business = str(f.readline().strip('\n\n\n\n\n\n\n\n'))
                computer_science = str(f.readline().strip('\n\n\n\n\n\n\n\n\n'))
                french = str(f.readline().strip('\n\n\n\n\n\n\n\n\n\n'))
                geography = str(f.readline().strip('\n\n\n\n\n\n\n\n\n\n\n'))

            lessons = []
            lessons.extend((english_language, english_lit, maths, chemistry, physics, biology, re, business, computer_science, french, geography))
            lesson_name = ["English langauge", "English liturature", "Maths", "Chemistry", "Physics", "Biology", "R.E", "Business studies", "Computer science", "French", "Geography"]

            print("What do you want to do? Read your grades, edit your grades, convert your grades or read and convert your grades.")
            option = input("Say read to read your grades or edit to edit your grades: ")

            if option == "read":
                for i in lessons:
                    for name in lesson_name:
                        print("For", name, "you got",i)
                        time.sleep(3)
                        break

            elif option == "convert":
                import converter.py

            elif option == "edit":
                print("HIIIIIIIIIIIIIIIIIIII")

В файлах оценки от 5B, самый низкий показатель, который я получил, до 7B самый высокий показатель, который я получил.

То, что я ожидаю, это спросить вас, что вы хотите сделать, что он и делает. Затем, если вы введете «читать», будет написано «Для английского языка, вы получили 6с» и повторять, пока не дойдете до географии.

1 Ответ

0 голосов
/ 14 января 2019

Два цикла for не имеют смысла - разрыв тоже странный:

for i in lessons:
    for name in lesson_name:
        print("For", name, "you got",i)
        time.sleep(3)     # 
        break             # this breaks after the first name every time

Вы можете повторить оба списка одновременно, используя что-то вроде:

nums = [1,2,3]
for idx,value in enumerate(["A","B","C"]):
     print("For", value, "you got", nums[idx])

или лучше, сжав его - см. Ниже для фиксированной обработки данных и постобработки.


Вы можете значительно упростить чтение, игнорируя символы новой строки, а затем преобразовать оставшиеся оценки в словарь, используя zip () :

Создать файл с новыми строками в нем (и слишком много значений) :

import random

gr = [ f'{num}{let}' for num in range(1,10) for let in "ABC"]

with open('lessons.txt', 'w') as f:
    for k in random.choices(gr,k=20):
        f.write(k+"\n\n\n")

Чтение файла и декомпозиция списка

with open('lessons.txt', 'r') as f:
    # read all lines, remove newlines, create a list of results
    grades = [x.strip() for x in f.readlines() if x.strip()]

# there are 20 scores in the file *_ takes all that are not named decomps: 

english_language, english_lit, maths, chemistry, physics, biology, re, \
business, computer_science, french, geography, *remainder = grades

print(english_language, english_lit, maths, chemistry, physics, biology, re, \
      business, computer_science, french, geography )

Выход (3 прогона):

3C 6A 9B 7B 8B 5A 2B 8C 7B 3A 9B
1C 8A 5A 1C 3A 9B 7C 9A 7B 7A 1A
4C 1A 4C 8B 9A 3C 2C 7B 7C 5B 2A

Создание справочника поиска для уроков и оценок:

Вы можете связать оценки с lesson_name, используя zip():

# order the same as in the 
lesson_name = ["English langauge", "English liturature", "Maths", "Chemistry",
               "Physics", "Biology", "R.E", "Business studies", "Computer science", 
               "French", "Geography", "Remainder"]

# dict comprehension to build the dictionary mapping lesson names to grades
grades = {k:v for k,v in zip(
    lesson_name,
    [english_language, english_lit, maths, chemistry, physics, biology, re,  
     business, computer_science, french, geography, remainder])}

print (grades) 

Выход:

{'English langauge': '4B', 'English liturature': '3C', 'Maths': '1C', 
 'Chemistry': '8C', 'Physics': '6B', 'Biology': '2B', 'R.E': '6C',
 'Business studies': '8C', 'Computer science': '4B', 'French': '3A', 
 'Geography': '2A', 
 'Remainder': ['7B', '1A', '1C', '3B', '2B', '8B', '5B', '6B', '8C']}

Вы можете использовать dict для поиска оценок по имени:

print(grades["English langauge"]) # 4B

Чтобы напечатать все вещи:

for name, grade in grades.items():
    print("For", name, "you got", grade) 
    # do not break here- this will end the loop!

Некоторые пояснения:

grades = [x.strip() for x in f.readlines() if x.strip()]

Компонент весь список читает все строки вашего файла, отбрасывает пустые строки и строки, состоящие только из пробелов (пробел, табуляции, новые строки, ..) - остальные строки помещаются в список grades, но сначала удаляются так, у них нет начальных / конечных пробелов.

  • zip () принимает несколько итераций и объединяет их в кортежи - до тех пор, пока самая короткая итерация равна:

k = zip( [1,2,3],["a","b"],"!$&(=" )  #  [(1, 'a', '!'), (2, 'b', '$')]

Результат:

(1, 'a', '!')   # every 0th element
(2, 'b', '$')   # every 1st element and nothing more because ["a","b"] has no 2nd element

Применяя это к вашим данным, я собираю список ваших единичных оценок и "строк" lecture_names, чтобы получить:

[('English langauge', '5B'), ('English liturature', '8B'), ('Maths', '1C'), 
 ('Chemistry', '4B'), ('Physics', '4C'), ('Biology', '9A'), ('R.E', '6B'), 
 ('Business studies', '8A'), ('Computer science', '1A'), ('French', '8C'), 
 ('Geography', '9B'), 

 ('Remainder', ['7A', '4C', '6C', '5B', '3B', '9C', '3B', '1A', '3B'])]

и использовать это в словесном понимании для создания словаря:

grades = {k:v for k,v in zip(
    lesson_name,
    [english_language, english_lit, maths, chemistry, physics, biology, re,  
     business, computer_science, french, geography, remainder])}

k и v - это декомпозиции одного zip-result-tuple - из их словарных пониманий создается словарь:

ex = {k:v for k,v in [ ("a",1), ("b",2) ] }  # simplified example

возвращает ex в качестве словаря {"a":1, "b":2}.

НТН

...