Getting rid of global variables - How?

Thread Solved

Join Date: Nov 2008
Posts: 12
Reputation: hydrobat is an unknown quantity at this point 
Solved Threads: 0
hydrobat hydrobat is offline Offline
Newbie Poster

Getting rid of global variables - How?

 
0
  #1
Aug 27th, 2009
Hi!

I've made a small program for an assignment and it works as it should. There's just one problem; the code contains two global variables. I won't pass the course unless I get rid of them and it's been bugging me for weeks.

The program:
  1. ##This program simulates a series of shooting competitions with participants found in a text file.
  2.  
  3. #modules
  4. import random, time, sys
  5.  
  6. # classes
  7. class Participant(object):
  8. """person with statistics"""
  9.  
  10. # constructor
  11. def __init__(self, name, sigma, competitions, wins, wa_results):
  12. """Create participant with attributes"""
  13. self.name = name
  14. self.sigma = sigma
  15. self.competitions = competitions
  16. self.wins = wins
  17. self.wa_results = wa_results
  18. # methods
  19. def __str__(self):
  20. """String representation of the class."""
  21. return self.name + "/" + self.sigma + "/" + self.competitions + "/" + self.wins + "/" + self.wa_results
  22.  
  23. # functions
  24. def read_file(database):
  25. """takes the information from the textfile and returns a list"""
  26. file1=[]
  27. for line in database.readlines():
  28. stats = line.split('/')
  29. file1.append(stats)
  30. return file1
  31.  
  32. def make_object(file1):
  33. """makes an instance for each contestant and runs the shooting function"""
  34.  
  35. for h in file1:
  36. try:
  37. temp = Participant(h[0],h[1],h[2],h[3],h[4])
  38. shooting(h[0], h[1])
  39. except ValueError and IndexError:
  40. print "Wrong format."
  41. time.sleep(1)
  42. sys.exit()
  43.  
  44.  
  45.  
  46. def season(file1):
  47. """creates one season, uses the shooting method within read_file function"""
  48. while True:
  49. try:
  50. comps_amount = int(raw_input("How many competitions in a season?"))
  51.  
  52. if comps_amount > 0 and comps_amount < 101:
  53. break
  54. else:
  55. print "Must be at least 1 competition and at most 100."
  56. except ValueError:
  57. print "Try again with an integer this time..."
  58. winnerlist=[]
  59. print "======================================================="
  60. for comp in range(1, comps_amount+1):
  61. print "Competition nr:", comp, "\n"
  62. global old_leader
  63. old_leader=0
  64. global tiedshot
  65. make_object(file1)
  66. print "======================================================="
  67. if (comp+1)%3==True and comp!=1:
  68. time.sleep(4)
  69. winnerlist.append(leader)
  70.  
  71.  
  72.  
  73.  
  74. print "Statistics:"
  75. for word in set(winnerlist):
  76. """counts how many times a name appears in winnerlist"""
  77. wins=winnerlist.count(word)
  78. print word, "won", wins,
  79. if wins==1:
  80. print "competition."
  81. else:
  82. print "competitions."
  83.  
  84. def shooting(name, sigma):
  85. """creates one series of shots and results"""
  86. print name,
  87. shotlist=[]
  88. for x in range(10):
  89. try:
  90. p = (110 - abs(int(random.normalvariate(0, int(sigma)))))
  91. except ValueError:
  92. print "Wrong format."
  93. time.sleep(1)
  94. sys.exit()
  95. if p < 20:
  96. p=0
  97. elif p == 110:
  98. p=100
  99. shot = p/20
  100. shotlist.append(shot)
  101. print shot,
  102. shotlist.sort()
  103. del shotlist[0:2]
  104. shotsum = sum(shotlist)
  105. print "results =", shotsum
  106. global old_leader
  107. if shotsum > old_leader:
  108. global leader
  109. leader = name
  110. old_leader = shotsum
  111.  
  112.  
  113. def main():
  114. """main function"""
  115. while True:
  116. while True:
  117. print """
  118. 1. Simulate a season of shooting competitions.
  119. 2. Exit programme.
  120. """
  121. try:
  122. choice = int(raw_input("Enter your choice:"))
  123. except ValueError:
  124. choice=None
  125. if choice==1:
  126. break
  127. elif choice==2:
  128. print "Good bye."
  129. time.sleep(1)
  130. sys.exit()
  131. else:
  132. print "Choose 1 or 2..."
  133. try:
  134. database = open("participants.txt", 'r')
  135. file1= read_file(database)
  136. database.close()
  137.  
  138. season(file1)
  139. except IOError:
  140. print "Can't find participants.txt, exiting."
  141. time.sleep(1)
  142. sys.exit()
  143.  
  144.  
  145.  
  146.  
  147.  
  148. # start program
  149. main()
The txt-file that comes with, called participants.txt:
  1. Bob/25/0/0/0
  2. Bill/23/0/0/0
  3. Billy Bob/32/0/0/0
  4. Dick Cheney/34/0/0/0
  5. Lee Harvey/28/0/0/0

Any help with how to replace the two global variables leader and old_leader would be much appreciated.

/Hydobat
Reply With Quote Quick reply to this message  
Join Date: Nov 2008
Posts: 12
Reputation: hydrobat is an unknown quantity at this point 
Solved Threads: 0
hydrobat hydrobat is offline Offline
Newbie Poster

Re: Getting rid of global variables - How?

 
0
  #2
Aug 27th, 2009
I tried removing the global variable 'old_leader' and putting it as a parameter in every function that it involves but then it kept returning the value 0... Do you think something like that is the way to go?

By the way my presentation is due in 16 hours so some quick hints would mean a lot.
Reply With Quote Quick reply to this message  
Join Date: Jul 2008
Posts: 1,165
Reputation: Gribouillis is a jewel in the rough Gribouillis is a jewel in the rough Gribouillis is a jewel in the rough Gribouillis is a jewel in the rough 
Solved Threads: 284
Gribouillis's Avatar
Gribouillis Gribouillis is online now Online
Veteran Poster

Re: Getting rid of global variables - How?

 
0
  #3
Aug 27th, 2009
A standard design to avoid global variables is to define a class like this
  1. class Competitions(object):
  2. def __init__(self):
  3. self. old_leader = 0
  4. def read_file(self, database):
  5. ...
  6. def make_object(self, file1):
  7. ...
  8. etc
  9.  
  10. if __name__ == "__main__":
  11. Competitions().main()
Reply With Quote Quick reply to this message  
Join Date: Nov 2008
Posts: 12
Reputation: hydrobat is an unknown quantity at this point 
Solved Threads: 0
hydrobat hydrobat is offline Offline
Newbie Poster

Re: Getting rid of global variables - How?

 
0
  #4
Aug 27th, 2009
Thank you for replying! Just some questions.
Do I take every function and make it a method in the Competitions class? Even main()? Because that's what I've done now and the executer says "unbound method main() must be called with Competitions instance as first argument (got nothing instead)"
Last edited by hydrobat; Aug 27th, 2009 at 4:42 pm. Reason: Wrong quote
Reply With Quote Quick reply to this message  
Join Date: Jul 2008
Posts: 1,165
Reputation: Gribouillis is a jewel in the rough Gribouillis is a jewel in the rough Gribouillis is a jewel in the rough Gribouillis is a jewel in the rough 
Solved Threads: 284
Gribouillis's Avatar
Gribouillis Gribouillis is online now Online
Veteran Poster

Re: Getting rid of global variables - How?

 
0
  #5
Aug 27th, 2009
You don't need to put every function in the class, but it's the easiest thing to do. You must create an instance. If you replaced the call main() by Competitions().main() it should work (note that calling the class creates an instance).
Reply With Quote Quick reply to this message  
Join Date: Nov 2008
Posts: 12
Reputation: hydrobat is an unknown quantity at this point 
Solved Threads: 0
hydrobat hydrobat is offline Offline
Newbie Poster

Re: Getting rid of global variables - How?

 
0
  #6
Aug 27th, 2009
I'm all for easy . I'm probably missing something, but I can't see what. This is what I did so far:

  1. #modules
  2. import random, time, sys
  3.  
  4. class Competitions(object):
  5.  
  6. def __init__(self):
  7.  
  8. self. old_leader = 0
  9.  
  10. def read_file(self, database):
  11. file1=[]
  12. for line in database.readlines():
  13. stats = line.split('/')
  14. file1.append(stats)
  15. return file1
  16.  
  17.  
  18. def make_object(self, file1):
  19. """makes an instance for each contestant and runs the shooting function"""
  20.  
  21. for h in file1:
  22. try:
  23. shooting(h[0], h[1])
  24. except ValueError and IndexError:
  25. print "Wrong format."
  26. time.sleep(1)
  27. sys.exit()
  28.  
  29. def season(self, file1):
  30. """creates one season, uses the shooting method within read_file function"""
  31. while True:
  32. try:
  33. comps_amount = int(raw_input("How many competitions in a season?"))
  34.  
  35. if comps_amount > 0 and comps_amount < 101:
  36. break
  37. else:
  38. print "Must be at least 1 competition and at most 100."
  39. except ValueError:
  40. print "Try again with an integer this time..."
  41. winnerlist=[]
  42.  
  43. print "======================================================="
  44. for comp in range(1, comps_amount+1):
  45. print "Competition nr:", comp, "\n"
  46. #global old_leader
  47. make_object(file1)
  48. print "======================================================="
  49. if (comp+1)%3==True and comp!=1:
  50. time.sleep(4)
  51. winnerlist.append(leader)
  52.  
  53. print "Statistics:"
  54. for word in set(winnerlist):
  55. """counts how many times a name appears in winnerlist"""
  56. wins=winnerlist.count(word)
  57. print word, "won", wins,
  58. if wins==1:
  59. print "competition."
  60. else:
  61. print "competitions."
  62.  
  63. def shooting(self, name, sigma):
  64. """creates one series of shots and results"""
  65. print name,
  66. shotlist=[]
  67. for single in range(10):
  68. try:
  69. p = (110 - abs(int(random.normalvariate(0, int(sigma)))))
  70. except ValueError:
  71. print "Wrong format."
  72. time.sleep(1)
  73. sys.exit()
  74. if p < 20:
  75. p=0
  76. elif p == 110:
  77. p=100
  78. shot = p/20
  79. shotlist.append(shot)
  80. print shot,
  81. shotlist.sort()
  82. del shotlist[0:2]
  83. shotsum = sum(shotlist)
  84. print "results =", shotsum
  85. #global old_leader
  86. if shotsum > old_leader:
  87. global leader
  88. leader = name
  89. old_leader = shotsum
  90.  
  91. def main(self):
  92. """main function"""
  93. while True:
  94. while True:
  95. print """
  96. 1. Simulate a season of shooting competitions.
  97. 2. Exit programme.
  98. """
  99. try:
  100. choice = int(raw_input("Enter your choice:"))
  101. except ValueError:
  102. choice=None
  103. if choice==1:
  104. break
  105. elif choice==2:
  106. print "Good bye."
  107. time.sleep(1)
  108. sys.exit()
  109. else:
  110. print "Choose 1 or 2..."
  111. try:
  112. database = open("participants.txt", 'r')
  113. file1= read_file(database)
  114. database.close()
  115. season(file1)
  116. except IOError:
  117. print "Can't find participants.txt, exiting."
  118. time.sleep(1)
  119. sys.exit()
  120.  
  121.  
  122.  
  123.  
  124.  
  125.  
  126.  
  127.  
  128.  
  129.  
  130. if __name__ == '__main__':
  131.  
  132. Competitions.main()
Reply With Quote Quick reply to this message  
Join Date: Jul 2008
Posts: 1,165
Reputation: Gribouillis is a jewel in the rough Gribouillis is a jewel in the rough Gribouillis is a jewel in the rough Gribouillis is a jewel in the rough 
Solved Threads: 284
Gribouillis's Avatar
Gribouillis Gribouillis is online now Online
Veteran Poster

Re: Getting rid of global variables - How?

 
0
  #7
Aug 27th, 2009
The last line should be
  1. Competitions().main()
Your mission is to understand why. Also, the word 'global' should not appear in your code.
Last edited by Gribouillis; Aug 27th, 2009 at 6:06 pm.
Reply With Quote Quick reply to this message  
Join Date: Nov 2008
Posts: 12
Reputation: hydrobat is an unknown quantity at this point 
Solved Threads: 0
hydrobat hydrobat is offline Offline
Newbie Poster

Re: Getting rid of global variables - How?

 
0
  #8
Aug 27th, 2009
I feel stupid. Why brackets? Because it's syntax for calling a class method in python I guess. I have now gotten rid of the globals.

New problem arrives. "'Competitions' object is not iterable"

I googled it and found this:

  1. #required iterable elements
  2. def __iter__(self):
  3. return self.data.__iter__()
  4.  
  5. def __len__(self):
  6. return len(self.data)
  7.  
  8. def __contains__(self, v):
  9. return v in self.data
  10.  
  11. def __getitem__(self, v):
  12. return self.data[v]
I don't really understand it, is it necessary for my code?
Reply With Quote Quick reply to this message  
Join Date: Jul 2008
Posts: 1,165
Reputation: Gribouillis is a jewel in the rough Gribouillis is a jewel in the rough Gribouillis is a jewel in the rough Gribouillis is a jewel in the rough 
Solved Threads: 284
Gribouillis's Avatar
Gribouillis Gribouillis is online now Online
Veteran Poster

Re: Getting rid of global variables - How?

 
0
  #9
Aug 27th, 2009
No, you probably entered something different from what I said above. Now good luck for your presentation, I can't help you more because it's very late here. bye.
Reply With Quote Quick reply to this message  
Join Date: Nov 2008
Posts: 12
Reputation: hydrobat is an unknown quantity at this point 
Solved Threads: 0
hydrobat hydrobat is offline Offline
Newbie Poster

Re: Getting rid of global variables - How?

 
0
  #10
Aug 27th, 2009
You were probably right, I got that working now. Thank you so much for helping.

Now the first problem seem to almost repeat itself.

  1. #modules
  2. import random, time, sys
  3.  
  4. class Competitions(object):
  5.  
  6. def __init__(self):
  7.  
  8. self.old_leader = 0
  9. self.leader = 0
  10.  
  11.  
  12. def read_file(self, database):
  13. file1=[]
  14. for line in database.readlines():
  15. stats = line.split('/')
  16. file1.append(stats)
  17. return file1
  18.  
  19.  
  20. def make_object(self, file1):
  21. """makes an instance for each contestant and runs the shooting function"""
  22.  
  23. for h in file1:
  24. try:
  25. Competitions().shooting(h[0], h[1])
  26. except ValueError and IndexError:
  27. print "Wrong format."
  28. time.sleep(1)
  29. sys.exit()
  30.  
  31. def season(self, file1):
  32. """creates one season, uses the shooting method within read_file function"""
  33. while True:
  34. try:
  35. comps_amount = int(raw_input("How many competitions in a season?"))
  36.  
  37. if comps_amount > 0 and comps_amount < 101:
  38. break
  39. else:
  40. print "Must be at least 1 competition and at most 100."
  41. except ValueError:
  42. print "Try again with an integer this time..."
  43. winnerlist=[]
  44.  
  45. print "======================================================="
  46. for comp in range(1, comps_amount+1):
  47. print "Competition nr:", comp, "\n"
  48. Competitions().make_object(file1)
  49. print "======================================================="
  50. if (comp+1)%3==True and comp!=1:
  51. time.sleep(4)
  52. winnerlist.append(leader)
  53.  
  54. print "Statistics:"
  55. for word in set(winnerlist):
  56. """counts how many times a name appears in winnerlist"""
  57. wins=winnerlist.count(word)
  58. print word, "won", wins,
  59. if wins==1:
  60. print "competition."
  61. else:
  62. print "competitions."
  63.  
  64. def shooting(self, name, sigma):
  65. """creates one series of shots and results"""
  66. print name,
  67. shotlist=[]
  68. for single in range(10):
  69. try:
  70. p = (110 - abs(int(random.normalvariate(0, int(sigma)))))
  71. except ValueError:
  72. print "Wrong format."
  73. time.sleep(1)
  74. sys.exit()
  75. if p < 20:
  76. p=0
  77. elif p == 110:
  78. p=100
  79. shot = p/20
  80. shotlist.append(shot)
  81. print shot,
  82. shotlist.sort()
  83. del shotlist[0:2]
  84. shotsum = sum(shotlist)
  85. print "results =", shotsum
  86. if shotsum > old_leader:
  87. leader = name
  88. old_leader = shotsum
  89.  
  90. def main(self):
  91. """main function"""
  92. while True:
  93. while True:
  94. print """
  95. 1. Simulate a season of shooting competitions.
  96. 2. Exit programme.
  97. """
  98. try:
  99. choice = int(raw_input("Enter your choice:"))
  100. except ValueError:
  101. choice=None
  102. if choice==1:
  103. break
  104. elif choice==2:
  105. print "Good bye."
  106. time.sleep(1)
  107. sys.exit()
  108. else:
  109. print "Choose 1 or 2..."
  110. try:
  111. database = open("participants.txt", 'r')
  112. file1= Competitions().read_file(database)
  113. database.close()
  114. Competitions().season(file1)
  115. except IOError:
  116. print "Can't find participants.txt, exiting."
  117. time.sleep(1)
  118. sys.exit()
  119.  
  120. if __name__ == '__main__':
  121.  
  122. Competitions().main()

When I run it, it says :

"in shooting
if shotsum > old_leader:
UnboundLocalError: local variable 'old_leader' referenced before assignment" (line 86.)

I thought old_leader was assigned in the constructor? Does anyone see what's wrong?
Reply With Quote Quick reply to this message  
Reply

This thread has been marked solved.
Perhaps start a new thread instead?
Message:




Views: 684 | Replies: 17
Thread Tools Search this Thread



Tag cloud for Python
About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2010 DaniWeb® LLC