【问题标题】:Need help writing and reading files and storing data into lists需要帮助写入和读取文件以及将数据存储到列表中
【发布时间】:2018-04-12 04:05:48
【问题描述】:

我需要加权成绩计算器方面的帮助,我有计算数据和加权平均值所需的位。我的问题是导入数据并存储它。我想我需要使用列表,但我只是不确定如何分隔每个条目,我知道我可以使用 .split() 并且我可能会这样做。但我真正的问题是弄清楚如何存储这些值,然后写入输出文件。

这就是我使用“open("scores.txt","r")" 命令导入程序的输入的 .txt 文件的样子

Babbage, Charles
10.0   9.5    8.0  10.0
 9.5  10.0    9.0
85.0  92.0   81.0
Turing, Alan
10.0   8.0    6.0
10.0  10.0    9.0   9.5
90.0  92.0   88.5
Hopper, Grace
10.0  10.0    8.0
10.0  10.0    9.0   9.5
90.0  92.0   88.0
Van Rossum, Guido
 7.5   8.5
 7.5   8.5    6.0   9.0
68.0  81.0   70.0
Backus, John
 9.5   9.5   10.0   8.0   9.5  10.0
 7.5   8.5    6.0   9.0  10.0
99.0  93.0  100.0
Crawley, Bryan
 6.0
 7.5
70.0  60.0   55.5

我尝试使用 s.isdigit 和 s.isalpha,但并没有真正奏效。第一行是测验,第二行是项目,第三行是考试。测验和考试的数量是任意的,考试总是三个。

这是输出需要的样子:

Babbage, Charles      89.4   B
Turing, Alan          91.3   A
Hopper, Grace         92.7   A
Van Rossum, Guido     75.5   C
Backus, John          94.4   A
Crawley, Bryan        63.9   D

这是我的代码现在的样子:

quiz_scores = []

while True:
    score = float(input("Quiz #{} ----- ".format(len(quiz_scores)+1)))
    if score == -1:
        break
    quiz_scores.append(score)
quiz_total = sum(quiz_scores) - min(quiz_scores)
if len(quiz_scores)>1:
    quiz_avg =  (quiz_total/((len(quiz_scores))-1)*10)
else:
    quiz_avg = (quiz_total/(len(quiz_scores)*10)

print()

project_scores = []

while True:
    score2 = float(input("Project #{} -- ".format(len(project_scores)+1)))
    if score2 == -1:
        break
    project_scores.append(score2)

project_total = sum(project_scores)
project_avg = (project_total/(len(project_scores))*10)

print()

exam1 = float(input("Exam #1 ----- "))
exam2 = float(input("Exam #2 ----- "))


print()

final = float(input("Final Exam -- "))

average = ((quiz_avg*.15)+(project_avg*.20)+(exam1*.20)+(exam2*.20)+(final*.25))

print("Average ---- %.2f" % average)



if 90 <= average <= 100:
    print("Grade ------- A")
if 80 <= average < 90:
    print("Grade ------- B")
if 70 <= average < 80:
    print("Grade ------- C")
if 60 <= average < 70:
    print("Grade ------- D")
if 0 <= average < 60:
    print("Grade ------- F")

绝对希望在这里学习,而不仅仅是复制粘贴您的评论;所以,如果我有一些问题要问你,请多多包涵。

谢谢你们,这个社区非常有帮助。

【问题讨论】:

  • 您可能会发现Saving an Object (Data persistence) 的答案很有用。通过使用pickle 模块,您可以将您的数据列表直接保存到一个或多个文件中,稍后再读回。

标签: python list if-statement while-loop floating-point


【解决方案1】:

您可能想改用 .csv。通过导入 csv 或 pandas,您可以在 csv 文件中保存/加载数据。

查看官方文档了解更多详情。

【讨论】:

  • 不幸的是它需要是一个 .txt 文件
  • 这应该是评论,而不是答案
  • 你应该把它贴在他问题的 cmets 下,因为这不是对他的问题的回答,而是一个建议。别担心:]
  • 但是等我问这个问题的人哈哈
  • 哦,哈哈,我把我的评论指向了 Moyan!我现在正在处理您的代码,非常有趣。谢谢你的帖子!
【解决方案2】:

编辑:我已经删除了 NumPy 和 Pandas 的使用。如果您想更详细或更具体地回答您的问题,您应该更新您的原始问题或放入 cmets。

如果您无法像@martineau 建议的那样在输入数据之前选择数据输入的外观,您可以执行以下操作:

# Ordered dictionary will let us add keys to a dictionary {}, but if we
# access the keys, it will retain the order we added them, which is not
# the default behaviour of a normal dict.
from collections import OrderedDict

# Load the file and sequentially add lines for users. You can simplify
# if they always have 3 lines each
with open('scores.txt') as f:

    out_dict = OrderedDict()
    # Load in each line from the file
    for line in f.readlines():

        # remove commas, replace(), strip newline characters '\n', strip();
        # split the line on spaces '81 81 30' -> ['81', '81', '30']
        line_split = [i for i in line.strip().replace(',', '').split(' ') if i != '']

        # From your current format, we know that some lines start with a character when there is a name, or a digit if it is a number
        # float('4') will give 4
        # float('s') will raise a ValueError exception
        #

        try:
            # If we do not raise an exception, we know it is an integer/float
            vals = [float(i) for i in line_split]
            # We can keep adding the values to the last entry in our dictionary, i.e., to the last name we created
            # As we used OrderedDict, we do not have to worry that we will retrieve a random key.
            out_dict[[i for i in out_dict.keys()][-1]].extend(vals)
        except ValueError:
            # So, if we raise an exception, we know it is 'Charles Babbage'
            # A new name is a new key, so put a new key in out_dict, and make the value a list we can keep adding to
            out_dict[line.strip()] = []

然后,您可以随心所欲地使用这本词典。你也可以让get_scoreget_grade 随心所欲地工作,现在我只是取平均值,因为我没有完全理解你的意图....

# Some functions to define how the score and grading works
def get_score(scores):
    return sum(scores)/(1.0*len(scores))

def get_grade(score):
    if 90 <= score <= 100:
        return 'A'
    if 80 <= score < 90:
        return 'B'
    if 70 <= score < 80:
        return 'C'
    if 60 <= score < 70:
        return 'D'
    if 0 <= score < 60:
        return 'E'

for key, item in out_dict.items():
    print(key, get_score(item), get_grade(get_score(item)))

输出将如下所示:

Babbage, Charles 32.4 E
Turing, Alan 33.3 E
Hopper, Grace 33.65 E
Van Rossum, Guido 29.5555555556 E
Backus, John 27.8214285714 E
Crawley, Bryan 39.8 E

【讨论】:

  • dang,我不完全确定它是如何工作的,我打算使用一些诊断输出来跟踪它,因为我不熟悉很多功能,但它甚至无法通过 import numpy as np
  • 如果你想让它运行,你需要安装 numpy。我已经删除了 numpy 和 pandas 并放置了一些内联 cmets 来帮助您理解。如果您需要更多指导,请在 cmets/OP 中提出更具体的问题。
【解决方案3】:

希望您能了解这里所做的一切。如果您有任何问题,请告诉我。

gradebook={}
input_name = input("Enter input file:")
output_name = input("Enter input file:")

with open(input_name,"r") as file:
    for line in file:
        if line[0].isalpha():
            gradebook[line.strip()] = {'quizzes':next(file).strip().split(' '), 
                                        'projects':next(file).strip().split(' '), 
                                        'tests':next(file).strip().split(' ')
                                        }
for student, values in gradebook.items():
    quizzes = []
    projects = []
    tests = []
    for category, grades in values.items():
        for grade in grades:
            if grade != '':
                exec("%s.append(float(grade))"% category)
                # ^^^ THIS IS THE SAME AS THE FOLLOWING 
                #if category == 'quizzes':
                #   quizzes.append(float(grade))
                #if category == 'projects':
                #   projects.append(float(grade))
                #if category == 'tests':
                #   tests.append(float(grade))

    quiz_total = sum(quizzes) - min(quizzes)

    if len(quizzes)>1:
        quiz_avg =  (quiz_total/((len(quizzes))-1)*10) 
    else:
        quiz_avg = (quiz_total*10) #no reason to divide by len(quizzes) if it is 1

    project_total = sum(projects)
    project_avg = (project_total/(len(projects))*10)

    exam1 = tests[0]
    exam2 = tests[1]
    final = tests[2]

    average = ((quiz_avg*.15)+(project_avg*.20)+(exam1*.20)+(exam2*.20)+(final*.25))

    if 90 <= average <= 100:
        final_grade = "A"
    if 80 <= average < 90:
        final_grade = "B"
    if 70 <= average < 80:
        final_grade = "C"
    if 60 <= average < 70:
        final_grade = "D"
    if 0 <= average < 60:
        final_grade = "F"

    with open(output_name,"a") as file:
        file.write("{0:20} {1:0.1f} {2:>4}\n".format(student, average, final_grade))

这会输出以下内容:

Babbage, Charles     89.4    B
Turing, Alan         91.3    A
Hopper, Grace        92.7    A
Van Rossum, Guido    75.5    C
Backus, John         94.3    A
Crawley, Bryan       54.9    F

不确定为什么 Bryan Crawley 的成绩低于您的预期?

【讨论】:

  • 不打印输出,您能帮我弄清楚如何将其发送到名为“results.txt”的文本文件吗?
  • 这太棒了,有没有办法将其更改为用户定义要写入的文件的位置?这是我在顶部编辑输入的内容,因此用户可以指定他们希望他们的文件被称为imgur.com/a/WRb5q
  • 如果这就是全部,请继续并通过单击问题旁边的灰色复选标记来标记已接受的答案,当您这样做时它应该变为绿色.. 感谢您的问题,我比较新也适用于 python,所以代码写起来很有趣!
  • 它修复了输入标题,但输出仍然停留在“output.txt”。无论如何我们可以做到“output_name”是输出文件的名称imgur.com/a/WRb5q
  • 那是完美的人。我不熟悉其中一些功能,因此如果您想进一步解释某些内容,我可能会稍后添加评论以获取一些见解。 (希望有一种方法可以在此站点上向人们发送消息。)如果没有 - 不用担心!真的谢谢你,我整个星期都在摸索这个问题。继续并用绿色检查标记您,再次感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-04-10
  • 2019-10-12
  • 1970-01-01
  • 2011-06-14
  • 1970-01-01
  • 2018-10-25
  • 2021-11-24
相关资源
最近更新 更多