使用.format()获得完美的输出

时间:2016-03-13 04:03:01

标签: python file file-io

编写一个名为print_grades的函数,它接受文件名(字符串)作为输入参数。您的函数应该调用函数来读取文件并创建成绩字典。使用成绩词典,您的函数应使用下面显示的确切格式打印学生的姓名,成绩和平均值。请注意,您被要求编写一个函数(不是程序),该函数会打印成绩。打印成绩后,您的功能应返回无。

示例输入文件:

1000123456,Rubble,Test_3,80,Test_4,80,quiz,90
1000123210,Bunny,Test_2,100,Test_1,100,Test_3,100,Test_4,100
1000123458,Duck,Test_1,86,Test_5,100,Test_2,93,Test_4,94

你的程序输出应该是:

    ID     |       Name       | Test_1 | Test_2 | Test_3 | Test_4 |  Avg.  |
1000123210 | Bunny            |    100 |    100 |    100 |    100 | 100.00 |
1000123456 | Rubble           |      0 |      0 |     80 |     80 |  40.00 | 
1000123458 | Duck             |     86 |     93 |      0 |     94 |  68.25 |

注意:

  • 列标题全部居中

  • 打印输出根据学生ID

  • 按升序排序
  • 每列与相邻列分隔三个字符'| '(space vertical_bar space)。
  • ID始终为10个字符,并且左对齐(不计算边界字符)
  • 名称左对齐(最多16个字符,不包括边界字符)。
  • 等级和平均值是正确的。成绩和平均值的列宽为6个字符(不包括边界字符)。
  • 平均值在小数点后以两位精度对齐。

到目前为止开发的代码。请告诉我下一步该怎么做。

CODE:

def create_grades_dict(file_name):
my_dict={}
file_pointer=open(file_name, "r")
data = file_pointer.readlines()
for line in data:
    datalist = line.strip().split(',')
    if len(datalist) < 2: 
        continue
    stud_id, last_name = datalist[:2]
    namelist, gradelist = [], []
    for name in datalist[2::2]:
        namelist.append(name.strip())
    for grade in datalist[3::2]:
        gradelist.append(int(grade.strip()))
    namelist.append('avg')
    avg = sum(gradelist)/float(len(gradelist))
    gradelist.append(avg)

    newdict = dict(zip(namelist, gradelist))
    my_dict[stud_id]=[last_name, newdict]
    return my_dict 

ERROR:

Error in evaluating function:
ValueError at line 7
too many values to unpack

3 个答案:

答案 0 :(得分:1)

你应该记住一些事情:

  1. 您的输入行可能包含垃圾数据 - 您需要忽略的数据。
  2. 您的输入文件可能包含空行,您需要对其进行测试。
  3. 解包变量需要在=符号的左侧和右侧之间取得平衡;如果右边有太多东西,左边的变量太少,你会得到:

    >>> a,b,c = 1,2,3,4
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ValueError: too many values to unpack
    

    当然,如果 left 上有太多变量,那么你会得到一个不同的错误:

    >>> a,b,c = 1,2
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ValueError: need more than 2 values to unpack
    

    尝试阅读整行,并按,分割(正如您现在所做的那样)。然后,逐步执行返回的列表,然后分离您的值 - 而不是假设所有行都以正确的顺序具有正确的信息。

答案 1 :(得分:1)

正如Burhan向你解释的那样。你可以这样继续:

a = "1000123456,Rubble,Test_3,80,Test_4,80,quiz,90"
>>> my_val = a.split(",")
>>> my_val
['1000123456', 'Rubble', 'Test_3', '80', 'Test_4', '80', 'quiz', '90']
>>> id,name = my_val[0], my_val[1]
>>> id
'1000123456'
>>> name
'Rubble'
my_dict = dict(zip(my_val[2::2],my_val[3::2]))
>>> my_dict
{'Test_4': '80', 'Test_3': '80', 'quiz': '90'}

现在可以使用dict.get(key[,default])

>>> my_dict.get('Test_4',0)
'80'

答案 2 :(得分:0)

为了达到预期效果,您需要两个功能:

第一个功能:

def create_grades_dict(file_name):
    my_dictionary = {}
    file_pointer = open(file_name, 'r')
    data = file_pointer.readlines()
    for line in data:
        student_row = map(str.strip, line.strip().split(','))
        student_id = student_row.pop(0)
        student_lastname = student_row.pop(0)
        student_data = [student_lastname]
        for valid_test in ['Test_1', 'Test_2', 'Test_3', 'Test_4']:
            if valid_test in student_row:
                student_data.append(int(student_row[student_row.index(valid_test) + 1]))
            else:
                student_data.append(0)
        student_data.append(sum(student_data[-4: ])/4)        
        my_dictionary[student_id] = student_data
    return my_dictionary

第二功能:

def print_grades(file_name):
    # Call your create_grades_dict() function to create the dictionary
    grades_dict=create_grades_dict(file_name)
    print ("    ID     |       Name       | Test_1 | Test_2 | Test_3 | Test_4 |  Avg.  |")
    for key in sorted(grades_dict.keys()):
        print ("{0:<10} | {1:<16} | {2:>6} | {3:>6} | {4:>6} | {5:>6} | {6:>6.2f} |".format(key, grades_dict[key][0],  grades_dict[key][1],  grades_dict[key][2], grades_dict[key][3], grades_dict[key][4], grades_dict[key][5], ))

所以你看到第二个函数调用第一个函数,它给出了正确的输出:

 ID     |       Name       | Test_1 | Test_2 | Test_3 | Test_4 |  Avg.  |
1000123210 | Bunny            |    100 |    100 |    100 |    100 | 100.00 |
1000123456 | Rubble           |      0 |      0 |     80 |     80 |  40.00 |
1000123458 | Duck             |     86 |     93 |      0 |     94 |  68.25 |