简体   繁体   中英

Python - How do you replace a certain line in a text file with another string?

I am creating a quiz program with python. There are three text files, one for outputting the question (works), one for checking if the user input the correct (works) and one for updating mastery. The latter isn't working. A question is mastered when is answered correct three times. I want to update the mastery from the text file to go from zero to one (and so on).

When I run my program it replaces the first line with 1, however the two 0's below it go missing and I therefore recieve an index out of range error. I am open to trying other methods.

This is the code I am attempting to implement the code below into my own program:

with open('stats.txt', 'r') as file:
    # read a list of lines into data
    data = file.readlines()

print(data)
print("Your name: " + data[0])

x = "0"
# now change the 2nd line, note that you have to add a newline
data[1] = x + "\n"

# and write everything back
with open('stats.txt', 'w') as file:
    file.writelines(data)

My program:

    question_answered = 0  # sets number of questions answered to zero
    lineq = 6  # sets the number of lines to output from questions.txt
    linea = 0  # sets the number of linea to read from answers.txt

    with open("questions.txt", "r") as q:
        with open("answers.txt", "r") as a:
            answer_lines = a.readlines()

            while question_answered != 3:

                question_answered += 1

                for i in range(lineq):
                    line2 = (q.readline())
                    print(line2)

                response = input("answer:")

                if response not in answer_lines[linea]:
                    print("incorrect")
                    mastery = (update_mastery[linea])
                    mastery = int(mastery)
                    if mastery < 1:
                        print("mastery", mastery)
                    else:
                        mastery -= 1
                        print("mastery", mastery)
                else:
                    print("correct")
                    with open("mastery.txt", "r") as m:
                        update_mastery = m.readlines()

                    mastery = update_mastery[linea]
                    mastery = int(mastery) + 1
                    mastery = str(mastery)
                    update_mastery[linea] = mastery + "\n"

                    with open('mastery.txt', 'w') as m:
                        m.writelines(update_mastery[linea])

                linea += 1


questions()

questions.txt:

1)Define isotope
[A]Atoms of the same element with same number of protons and a different number of neutrons
[B]Atoms of the different element with same number of protons and a different number of neutrons
[C]Atoms of the same element with same number of neutrons and a different number of protons
[D]Atoms of the same element with same number of protons and a different number of electrons

2)Name the type of decay that occurs when, they have too many neutrons
[A]Gamma Radiation
[B]Alpha Decay
[C]Beta Plus Decay
[D]Beta Minus Decay

3)Define Coulomb
[A]1 coulomb is the quantity of charge carried past a given point if a steady current of 1 amp flows for 1 second
[B]1 coulomb is the quantity of charge carried past a given point if a steady voltage of 1 volts per 1 second
[C]1 coulomb is the quantity of current carried past a given point if a steady voltage of 1 volts per 1 second
[D]1 coulomb is the rate of flow of charge

answers.txt:

A
D
A

mastery.txt:

0
0
0

I believe it would be easier to keep track of the the mastery level using a dictionary stored in a pickle . It makes it very easy to handle program's state and is much faster to modify.
For a quick answer, I would load the pickle like this:

"""
We are loading the pickled mastery values by checking if the pickle file exists.
If it doesn't we define a default mastery level
"""
try:
    with open("mastery.p", "rb") as mastery_file:
        mastery = pickle.load(mastery_file)
except FileNotFoundError:
    mastery = {
        "1: Define isotope": 0,
        "2: Name the type of decay that occurs when, they have too many neutrons": 0,
        "3: Define Coulomb": 0,
    }

You can then use mastery as a regular dictionary and modify the values accordingly. When you are done, you can save the mastery state in the pickle again:

def save():
    with open("mastery.p", "wb") as m:
        pickle.dump(mastery, m)

Now for the entire program:

import pickle

"""
Here we defining the quesions and choices in a dictionary, but you could
load them from a normal text file, json file, or a pickle.
The questions are the keys to choices.
"""
q_and_a = {
    "1: Define isotope": [
        "[A]Atoms of the same element with same number of protons and a different number of neutrons",
        "[B]Atoms of the different element with same number of protons and a different number of neutrons",
        "[C]Atoms of the same element with same number of neutrons and a different number of protons",
        "[D]Atoms of the same element with same number of protons and a different number of electrons",
    ],
    "2: Name the type of decay that occurs when, they have too many neutrons": [
        "[A]Gamma Radiation",
        "[B]Alpha Decay",
        "[C]Beta Plus Decay",
        "[D]Beta Minus Decay",
    ],
    "3: Define Coulomb": [
        "[A]1 coulomb is the quantity of charge carried past a given point if a steady current of 1 amp flows for 1 second",
        "[B]1 coulomb is the quantity of charge carried past a given point if a steady voltage of 1 volts per 1 second",
        "[C]1 coulomb is the quantity of current carried past a given point if a steady voltage of 1 volts per 1 second",
        "[D]1 coulomb is the rate of flow of charge",
    ],
}

"""
The answers have been defined with the same scheme as the questions
Once again, you could load these from a file or add them as the last
item in the q_and_a and filter them out when giving the questions.
"""
answers = {
    "1: Define isotope": "a",
    "2: Name the type of decay that occurs when, they have too many neutrons": "b",
    "3: Define Coulomb": "a",
}

"""
We are loading the pickled mastery values by checking if the pickle file exists.
If it doesn't we define a default mastery level
"""
try:
    with open("mastery.p", "rb") as mastery_file:
        mastery = pickle.load(mastery_file)
except FileNotFoundError:
    mastery = {
        "1: Define isotope": 0,
        "2: Name the type of decay that occurs when, they have too many neutrons": 0,
        "3: Define Coulomb": 0,
    }

# Here, we are iterating over every question each session


def show_questions(q, choices):
    print(f"{q}:")  # Show the question
    print("\n".join(choices))  # Show the choices
    answer = input("You answer: ")  # wait for answer
    if answer.lower() != answers[q]:  # convert to lowercase (to match answerkey)
        print(f"wrong, answer is {answers[q]}")
        mastery[q] -= 1
        print(f"Your mastery decreased to {mastery[q]}\n")
        return False
    else:
        print("Correct!")
        mastery[q] += 1
        print(f"Your mastery increased to {mastery[q]}\n")
        return True


def save():
    with open("mastery.p", "wb") as m:
        pickle.dump(mastery, m)


def loop_all():
    """
    Loops through all qustions once
    """
    for q, choices in q_and_a.items():
        show_questions(q, choices)
        save()


def for_mastery(max_level=3):
    """
    Loops through each question till mastery is reached
    Mastery can be adjusted by passing it as an argument
    """
    for q, m in mastery.items():
        print(m)
        choices = q_and_a[q]
        while m < max_level:
            passed = show_questions(q, choices)
            if passed:
                m += 1
            else:
                m -= 1
            save()
        print("mastered!\n")


for_mastery()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM