944,080 Members | Top Members by Rank

Ad:
  • Python Discussion Thread
  • Marked Solved
  • Views: 3715
  • Python RSS
Jan 6th, 2007
0

Sorting a File

Expand Post »
Hi,

I am trying to extend my "Student with the best GPA" program so that it allows the user to sort a file of students based on gpa, name, or credits. The program needs to prompt for the input and output files and also the field to sort on (gpa, name or credits).

The input file consists of students name, credits(hours) and quality points (gpa = quality points / hours)

I keep getting an error that global name "gpa" is not defined and I don't understand why. Can anyone steer me in the right direction as to where I am going wrong? Thank you!




This is what I have so far on my program:

Python Syntax (Toggle Plain Text)
  1. from p2gpa import Student, makeStudent
  2. def readStudents(filename):
  3. infile = open(filename, 'r')
  4. students = []
  5. for line in infile:
  6. students.append(makeStudent(line))
  7. infile.close()
  8. return students
  9.  
  10. def writeStudents(students, filename):
  11. outfile = open(filename, 'w')
  12. for s in students:
  13. outfile.write("%s\t%f\t%f\n" %
  14. (s.getName(), s.getHours(), s.getQPoints()))
  15. outfile.close()
  16. def cmpgpa(s1, s2):
  17. return cmp(s1.gpa(), s2.gpa())
  18. def cmpname(s1, s2):
  19. return cmp("s1.name()", "s2.name()")
  20. def cmpcredits(s1, s2):
  21. return cmp(s1.credits(), s2.credits())
  22.  
  23. def main():
  24. print "This program sorts student grade information"
  25. filename = raw_input("Enter the name of the data file: ")
  26. dfield = raw_input("Enter gpa, name, or credits to sort: ")
  27. filename = raw_input("Enter a name for the output file: ")
  28. data = readStudents(filename)
  29. if dfield == gpa:
  30. data.sort(cmpgpa)
  31. elif dfield == name:
  32. data.sort(cmpname)
  33. else:
  34. data.sort(cmpcredits)
  35. filename = raw_input("Enter a name for the output file: ")
  36. writeStudents(data, filename)
  37. print "The data has been written to", filename
  38. if __name__ == '__main__':
  39. main()



This is the p2gpa program that I imported:


Python Syntax (Toggle Plain Text)
  1. import string
  2. import math
  3. class Student:
  4. def __init__(self, name, hours, qpoints):
  5. self.name = name
  6. self.hours = float(hours)
  7. self.qpoints = float(qpoints)
  8. def getName(self):
  9. return self.name
  10. def getHours(self):
  11. return self.hours
  12. def getQPoints(self):
  13. return self.qpoints
  14. def gpa(self):
  15. return self.qpoints/self.hours
  16. def name(self):
  17. return self.name
  18. def makeStudent(infoStr):
  19. name, hours, qpoints = string.split(infoStr,"\t")
  20. return Student(name, hours, qpoints)
  21. def main():
  22. filename = raw_input("Enter name the grade file: ")
  23. infile = open(filename, 'r')
  24. best = makeStudent(infile.readline())
  25. for line in infile:
  26. s = makeStudent(line)
  27. if s.gpa() > best.gpa():
  28. best = s
  29. infile.close()
  30. print "The best student is:", best.getName()
  31. print "hours:", best.getHours()
  32. print "GPA:", best.gpa()
  33. if __name__ == '__main__':
  34. main()



This is the input file I want to sort (p2sortin.py):



Python Syntax (Toggle Plain Text)
  1. Computewell, Susan 100 400
  2. DibbleBit, Denny 18 41.5
  3. Jones, Jim 48.5 155
  4. Smith, Frank 37 125.33
  5. Adams, Henry 127 228


This is the error that I keep getting:

Python Syntax (Toggle Plain Text)
  1. This program sorts student grade information
  2. Enter the name of the data file: p2sortin.py
  3. Enter gpa, name, or credits to sort: gpa
  4. Enter a name for the output file: p2sortout.py
  5. Traceback (most recent call last):
  6. File "C:\Python23\p2sort.py", line 50, in ?
  7. main()
  8. File "C:\Python23\p2sort.py", line 40, in main
  9. if dfield == gpa:
  10. NameError: global name 'gpa' is not defined
  11. >>>




Thanks!
Similar Threads
Reputation Points: 10
Solved Threads: 0
Light Poster
babutche is offline Offline
34 posts
since Oct 2006
Jan 6th, 2007
0

Re: Sorting a File

Your initial problem is right here:
Python Syntax (Toggle Plain Text)
  1. def main():
  2. print "This program sorts student grade information"
  3. filename = raw_input("Enter the name of the data file: ")
  4. dfield = raw_input("Enter gpa, name, or credits to sort: ")
  5. filename = raw_input("Enter a name for the output file: ")
  6. data = readStudents(filename)
  7. ...
You are assigning the same variable 'filename' to both the input and output file.

Your next problem is here:
Python Syntax (Toggle Plain Text)
  1. if dfield == gpa:
  2. data.sort(cmpgpa)
The input function raw_input() returns a string, so this ought to be:
Python Syntax (Toggle Plain Text)
  1. if dfield == 'gpa':
  2. data.sort(cmpgpa)
Give your data file a name like in.dat, don't use .py (it is not Python code!).
Your next problem is here ( I added a test print):
Python Syntax (Toggle Plain Text)
  1. def makeStudent(infoStr):
  2. print string.split(infoStr,"\t") # test --> ['Computewell, Susan 100 400\n']
  3. name, hours, qpoints = string.split(infoStr,"\t")
  4. return Student(name, hours, qpoints)
The result of splitting a string is a list, not a tuple! Also the data file needs tabs at the right places to make this work!
Last edited by Ene Uran; Jan 6th, 2007 at 3:44 pm.
Reputation Points: 625
Solved Threads: 211
Posting Virtuoso
Ene Uran is offline Offline
1,704 posts
since Aug 2005
Jan 6th, 2007
0

Re: Sorting a File

Quote ...
File "C:\Python23\p2sort.py", line 40, in main
if dfield == gpa:
NameError: global name 'gpa' is not defined
I think you want "gpa" in quotes.
if dfield == "gpa":
A simple menu would be easier for the user, with 1=gpa, etc. In any case, you should have a list of correct responses, or be able to add something like 0 < number < 4, to check for a valid input.
Last edited by woooee; Jan 6th, 2007 at 9:29 pm.
Reputation Points: 741
Solved Threads: 692
Nearly a Posting Maven
woooee is offline Offline
2,307 posts
since Dec 2006
Jan 7th, 2007
0

Re: Sorting a File

I played with the code for a while and made these observations and corrections ...
python Syntax (Toggle Plain Text)
  1. # save as p2sort.py
  2. from p2gpa import Student, makeStudent
  3. def readStudents(filename):
  4. infile = open(filename, 'r')
  5. students = []
  6. for line in infile:
  7. students.append(makeStudent(line))
  8. infile.close()
  9. return students
  10.  
  11. def writeStudents(students, filename):
  12. outfile = open(filename, 'w')
  13. for s in students:
  14. print "%-20s %0.2f %0.2f" % (s.getName(), s.gpa(), s.getHours()) # test
  15. outfile.write("%s\t%0.2f\t%0.2f\n" %
  16. (s.getName(), s.getHours(), s.getQPoints()))
  17. outfile.close()
  18.  
  19. # for these compares s1 and s2 are class instances ...
  20. def cmpgpa(s1, s2):
  21. # low to high
  22. #return cmp(s1.gpa(), s2.gpa())
  23. # high to low
  24. return cmp(s2.gpa(), s1.gpa())
  25. def cmpname(s1, s2):
  26. #return cmp(s1.name(), s2.name()) # problems!!!?
  27. return cmp(s1.getName(), s2.getName())
  28. def cmpcredits(s1, s2):
  29. # low to high
  30. #return cmp(s1.getHours(), s2.getHours())
  31. # high to low
  32. return cmp(s2.getHours(), s1.getHours())
  33.  
  34. def main():
  35. print "This program sorts student grade information"
  36. # file has line format --> name tab hours tab qpoints
  37. file_in = raw_input("Enter the name of the data file: ")
  38. dfield = raw_input("Enter gpa, name, or credits to sort: ")
  39. # data is a list of Student class instances
  40. data = readStudents(file_in)
  41. if dfield == 'gpa':
  42. data.sort(cmpgpa)
  43. elif dfield == 'name':
  44. data.sort(cmpname)
  45. else:
  46. data.sort(cmpcredits)
  47. file_out = raw_input("Enter a name for the output file: ")
  48. writeStudents(data, file_out)
  49. print "The data has been written to", file_out
  50.  
  51. if __name__ == '__main__':
  52. main()
Here is the module file ...
python Syntax (Toggle Plain Text)
  1. # save this module file as p2gpa.py
  2. import string
  3. #import math
  4. class Student:
  5. def __init__(self, name, hours, qpoints):
  6. self.name = name
  7. self.hours = float(hours)
  8. self.qpoints = float(qpoints)
  9. def getName(self):
  10. return self.name
  11. def getHours(self):
  12. return self.hours
  13. def getQPoints(self):
  14. return self.qpoints
  15. def gpa(self):
  16. return self.qpoints/self.hours
  17. def name(self):
  18. return self.name
  19.  
  20. def makeStudent(infoStr):
  21. if '\t' in infoStr:
  22. #print string.split(infoStr,"\t") # test --> ['Computewell, Susan ', '100 ', '400\n']
  23. name, hours, qpoints = string.split(infoStr,"\t")
  24. return Student(name, hours, qpoints)
  25. def main():
  26. filename = raw_input("Enter name the grade file: ")
  27. infile = open(filename, 'r')
  28. best = makeStudent(infile.readline())
  29. for line in infile:
  30. s = makeStudent(line)
  31. if s.gpa() > best.gpa():
  32. best = s
  33. infile.close()
  34. print "The best student is:", best.getName()
  35. print "hours:", best.getHours()
  36. print "GPA:", best.gpa()
  37.  
  38. # test the module ...
  39. if __name__ == '__main__':
  40. main()
  41. #raw_input("Press Enter to go on ... ")
I also would recommend to use extension .dat or .txt for your data files, and make sure the text editor you use leaves the tab separator intact. Some editors replace tabs with spaces!

This little code will produce a correct sample data file called 'in.txt' ...
python Syntax (Toggle Plain Text)
  1. # this will create a sample data file with tab separators
  2. data = [['Computewell, Susan', 100, 400],
  3. ['DibbleBit, Denny', 18, 41.5],
  4. ['Jones, Jim', 48.5, 155],
  5. ['Smith, Frank', 37, 125.33],
  6. ['Adams, Henry', 127, 228]]
  7. fout = open("in.txt", "w")
  8. for line in data:
  9. text = "%s\t%s\t%s\n" % (line[0], line[1], line[2])
  10. print text,
  11. fout.write(text)
  12. fout.close()
Last edited by vegaseat; Jan 7th, 2007 at 3:56 pm. Reason: tab/space goof
Moderator
Reputation Points: 1333
Solved Threads: 1403
DaniWeb's Hypocrite
vegaseat is offline Offline
5,792 posts
since Oct 2004
Jan 7th, 2007
0

Re: Sorting a File

Thank you all very much for your input!! I will have to study this and see if I can figure out exactly what is going on (so I know what I am doing).

Now I see that one of my major problems was that I was trying to return:

return cmp(s1.name, etc..) instead of return cmp(s1.getName, etc...)
(same thing for Hours)

I have also fixed the other problem where I did not have my quotation marks in the

proper places.

Now I just have to fix a few more things in my files and I should be able to finish!!



Thank You For Helping!!
Last edited by babutche; Jan 7th, 2007 at 4:30 pm. Reason: Added Comments
Reputation Points: 10
Solved Threads: 0
Light Poster
babutche is offline Offline
34 posts
since Oct 2006

This thread is solved

Either the thread starter or a moderator has marked this thread as solved. You can most likely trust the responses and answers given. There is most likely no reason for any further responses to be posted here. If you have a related question, please start a new thread in this forum instead.

This thread is more than three months old

No one has posted to this discussion for at least three months. Please let old threads die and do not reply to them unless you feel you have something new and valuable to contribute that absolutely must be added to make the discussion complete. Otherwise, please start a new thread in this forum instead.
Message:
Previous Thread in Python Forum Timeline: break -- Not working properly
Next Thread in Python Forum Timeline: ValueError - Not Working





About Us | Contact Us | Advertise | Acceptable Use Policy
Forum Index | Build Custom RSS Feed


Follow us on Twitter


© 2011 DaniWeb® LLC