5 Replies - 424 Views - Last Post: 09 September 2013 - 02:20 PM Rate Topic: -----

#1 CaseyJames22  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 23
  • Joined: 26-January 13

UnboundLocalError - local variable error - I/O file processing

Posted 09 September 2013 - 12:24 PM

I'll post my code and the error immediately following...
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# file grades.py
# Author: Casey

'''
This script reads an input .cvs file with:
    first name
    surname
    12 homework grades
    12 quiz scores (10 pts each)
     4 exam scores (100 pts each)
line at a time and reports
    first and surname
    averages for each category of score
    averall average and letter grade, per the schedule:
        homework - 40%; quizes - 10%; exams - 50%
        [100, 90] - A; (90, 80] - B; (80, 70] - C; (70, 60] - D; (60, 0] - F
'''

# Opens the input and output files
csvFile = open('grades.csv','r')
outFile = open('grades.grd','w')

# Stub function for setting up files for I/O
def setUpIO():
    return csvFile, outfile 
    # return inFile, outFile

def processStudent(data, possible):
    line=sum([0 if x == ',,' else int(x) for x in line[2:14]])/totals[hwtot]
    return ["James, Casey", 67, 23, 89, 99]

# Get the homework, quiz, and exam possible totals
line = csvFile.readline().rstrip('\n').split(',')
hwtot = sum([0 if x == ',,' else int(x) for x in line[2:14]])
qztot = sum([0 if x == ',,' else int(x) for x in line[14:26]])
extot = sum([0 if x == ',,' else int(x) for x in line[26:30]])
totals = [hwtot, qztot, extot]

gradelist = []

# For every line in the file, compute the averages and final grade
for line in csvFile:
    # process line and add it to the list of grades
    stuData = processStudent(line, totals)
    
    # Add student to grade list
    # Note: this next step could have been done much more elegantly, but
    #       I wanted you to see the formatting
    gradelist.append('{:<16}  {:8.2f}  {:8.2f}  {:8.2f}  {:8.2f}'.format\
                        (stuData[0], stuData[1], stuData[2], stuData[3],
                         stuData[4]))

# Sort list and provide a heading
gradelist.sort()
gradestr = '{:^16}' + 4 * '  {:>8}'
gradelist.insert(0, gradestr.format('Name', 'HWavg', 'QZavg', 'EXavg', 'Final'))

csvFile.close()
outFile.close()



bladowca@ubuntu:~/Documents/Asmt1$ python3 grades.py < grades.csv > grades.grd
Traceback (most recent call last):
File "grades.py", line 48, in <module>
stuData = processStudent(line, totals)
File "grades.py", line 33, in processStudent
line=sum([0 if x == ',,' else int(x) for x in line[2:14]])/totals[hwtot]
UnboundLocalError: local variable 'line' referenced before assignment

So, you can see I'm reading from grades.py processing it and sending it out to grades.grd ...now this local variable error stops the process and doesn't send anything (at all) to my output file...

Is This A Good Question/Topic? 0
  • +

Replies To: UnboundLocalError - local variable error - I/O file processing

#2 Valek  Icon User is offline

  • The Real Skynet
  • member icon

Reputation: 543
  • View blog
  • Posts: 1,713
  • Joined: 08-November 08

Re: UnboundLocalError - local variable error - I/O file processing

Posted 09 September 2013 - 12:31 PM

The line in processStudent() is a local version of the variable. It doesn't refereence the global version. If you want access to the global version, you have several options:

  • You can explicitly specify in processStudent() that line should refer to the global version (not recommended).
  • You can pass line to processStudent() as one of the arguments.
  • You can make a class to work with, make line a property of that class, and have processStudent() reference that (self.line, for instance).

This post has been edited by Valek: 09 September 2013 - 12:31 PM

Was This Post Helpful? 0
  • +
  • -

#3 CaseyJames22  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 23
  • Joined: 26-January 13

Re: UnboundLocalError - local variable error - I/O file processing

Posted 09 September 2013 - 12:39 PM

can I have examples of these? :/ ...I'm very new when it comes to classes, would i pass line in as an argument or csvFile? and the first option may make most sense, as the process student is going through a list and must do line by line...

This post has been edited by andrewsw: 09 September 2013 - 12:52 PM
Reason for edit:: Removed previous quote

Was This Post Helpful? 0
  • +
  • -

#4 Valek  Icon User is offline

  • The Real Skynet
  • member icon

Reputation: 543
  • View blog
  • Posts: 1,713
  • Joined: 08-November 08

Re: UnboundLocalError - local variable error - I/O file processing

Posted 09 September 2013 - 01:06 PM

Actually, I took a closer look. I went through too quickly. Your problem here is simply a typo. You pass line to processStudent() as the first argument, so when you reference it inside that method, you would reference it as data in accordance with your method signature.

I'm confused, though, as to why you're doing the work of processing out what is in hwtot (totals[0]) when you've already done that. And then it's not being used in that method because you're passing back a static data set instead of what you're processing.

In addition, totals[hwtot] is going to fail unless hwtot is an integer between 0 and 2, because totals is a 3- element array, and you added hwtot to it as a value, which can be found at totals[0].

Also, at the time you're calling processStudent(), line hasn't been split on commas, so line 32 probably won't behave the way you expect it to.
Was This Post Helpful? 0
  • +
  • -

#5 CaseyJames22  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 23
  • Joined: 26-January 13

Re: UnboundLocalError - local variable error - I/O file processing

Posted 09 September 2013 - 01:27 PM

This...
def processStudent(data, possible):
    data=sum([0 if x == ',,' else int(x) for x in line[2:14]])/totals[hwtot]
    return ["James, Casey", 67, 23, 89, 99]

Throws...
Traceback (most recent call last):
File "grades.py", line 49, in <module>
stuData = processStudent(line, totals)
File "grades.py", line 32, in processStudent
data=sum([0 if x == ',,' else int(x) for x in line[2:14]])/totals[hwtot]
File "grades.py", line 32, in <listcomp>
data=sum([0 if x == ',,' else int(x) for x in line[2:14]])/totals[hwtot]
ValueError: invalid literal for int() with base 10: 'o'
bladowca@ubuntu:~/Documents/Asmt1$

However, what i'm trying to do is get the scores from [2:14],[14:26],[26:30] and divide them by each total...
So. maybe i need to add a few lines?
hw/total[0] qz/total[1]
and so fourth...?
Was This Post Helpful? 0
  • +
  • -

#6 Valek  Icon User is offline

  • The Real Skynet
  • member icon

Reputation: 543
  • View blog
  • Posts: 1,713
  • Joined: 08-November 08

Re: UnboundLocalError - local variable error - I/O file processing

Posted 09 September 2013 - 02:20 PM

That'd be the unexpected behavior I was talking about. Also, if you're trying to assign to data without using it, why are you even passing it in? You generally pass stuff in as arguments if you're going to do work on it. Are you sure you didn't mean to do something like this?

line = sum([0 if x == ',,' else int(x) for x in data[2:14]])/totals[0]

Granted, that doesn't fix your error, because you're still doing the same operation you did to get hwtot, but without this:

line = csvFile.readline().rstrip('\n').split(',')

So since it isn't split on the commas, it's reading it as a long string and grabbing characters 3 through 14 of it, instead of reading a list and grabbing elements 3 through 14. You also will likely have a dangling newline on the last element of the array when it's been split, so the rstrip() would still be necessary.

Also, if you're trying to get those totals for each student, you'll want to do the splitting on commas and line processing on a per line basis (perhaps inside processStudent()?).

This post has been edited by Valek: 09 September 2013 - 07:19 PM
Reason for edit:: Removed previous quote

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1