Another local variable referenced before assignment - Python
我先说:我知道这是一个经常被问到的问题。我读过其他答案,排除了:
我没有用+=来完成任务;
我尝试显式地分配函数中的每个变量,以确保它们不为空,以防函数的其他工作失败;
它们不是全局变量,我不希望它们是-它们只是内部变量,我用它们来计算我最终返回的内容。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 | ## Gets the data from external website - refreshes whenever the programme is called. ## Urllib2 required module ## csv to make life easier handling the data import urllib2 import csv import sys import math # import sqlite3 #don't need this just now, will probably run Django with MySQL when it comes to it # import MySQLdb Likewise, don't need this just now. #python3 import atexit from time import time from datetime import timedelta def secondsToStr(t): return str(timedelta(seconds=t)) line ="="*40 def log(s, elapsed=None): print(line) print(secondsToStr(time()), '-', s) if elapsed: print("Elapsed time:", elapsed) print(line) print() def endlog(): end = time() elapsed = end-start log("End Program", secondsToStr(elapsed)) def now(): return secondsToStr(time()) start = time() atexit.register(endlog) log("Start Program") def open_external_source(): # Checks if the core file's been modified since the last time we used it - if it hasn't, then we skip all of the file reading stuff. #need to change this to just pull the headers the first time. master_data_file = urllib2.urlopen("http://www.football-data.co.uk/mmz4281/1213/E0.csv","GET") print master_data_file headers = master_data_file.info() last_mod = headers["last-modified"] settings = open ("settings.csv","r+") historic_last_mod = settings.readline() #this only works when the setting is a 1 line file print"Local file version:" + historic_last_mod print"Server file version:" +last_mod if last_mod == historic_last_mod : print"It's the same, file not loaded" return true else : return false settings.close() #the if statement's commented out because it was messing up the variables into the function #if open_external_source == False: master_data_file = urllib2.urlopen("http://www.football-data.co.uk/mmz4281/1213/E0.csv","GET") data = list(tuple(rec) for rec in csv.reader(master_data_file, delimiter=',')) print len(data) print"printing full file" print data league_list = ["Arsenal","Chelsea","Liverpool","Man City","Man United","Newcastle","Newcastle","Norwich","Reading","Southampton","Stoke","Sunderland","Swansea","Tottenham","West Brom","West Ham","Wigan"] league_stats = league_list #for teams in league_list: - come back to this, will do this as a split and append. #call the next set of functions to skip the data reading stuff #This is the data reading section, that puts the data into our system #If we do proceed, then we redo all of the calculations, and read the data file in again, in case of any corrections, etc. #Column references: #Home Goals 4 #Away Goals 5 #Full Time Result 6 #Home Shots 10 #Away Shots 11 #Home Shots on Target 12 #Away Shots on Target 13 #Calculates the average for a given team at home, columns are 4 Home Goals, 5 Away Goa def CalcAverageHome(team, column, data): total = 0 count = 0 n=0 for row in data: if data[count][2] == team: total += int(data[count][column]) n+=1 count += 1 try: average = float(total) / n except ZeroDivisionError: average = 'Not played' return average def CalcAverageAway(team, column, data): total = 0 count = 0 n=0 for row in data: if data[count][3] == team: total += int(data[count][column]) n+=1 count += 1 try: average = float(total) / n except ZeroDivisionError: average = 'Not played' return average home_team ="Chelsea" away_team ="Newcastle" print"Here's the Average number of goals scored Home" home_goals = CalcAverageHome(home_team, 4, data) away_goals = CalcAverageAway(home_team, 5, data) home_conceded = CalcAverageHome(home_team, 5, data) away_conceded = CalcAverageAway(away_team, 4, data) adjusted_home = home_goals * away_conceded adjusted_away = away_goals * home_conceded print home_team, home_goals, home_conceded, adjusted_home print away_team, away_goals, away_conceded, adjusted_away print"starting to try and work the league averages out here." def poisson_probability(actual, mean): # naive: math.exp(-mean) * mean**actual / factorial(actual) # iterative, to keep the components from getting too large or small: p = math.exp(-mean) for i in xrange(actual): p *= mean p /= i+1 return p for i in range (10): print str((100*poisson_probability(i,adjusted_home)))+"%" league_list = ["Arsenal","Chelsea","Liverpool","Man City","Man United","Newcastle","Newcastle","Norwich","Reading","Southampton","Stoke","Sunderland","Swansea","Tottenham","West Brom","West Ham","Wigan"] # just assign the league list to the stats for now - # eventually each team entry will become the first column of a new sublist def LeagueAverages(data,column): total = 0 n = 0 for row in data : string = row[column] if string.isdigit() == True: total = total + int(row[column]) n += 1 league_average = float(total) / n return league_average print"League home goals average is:", LeagueAverages(data, 4) print"League away goals average is:", LeagueAverages(data, 5) print"finished that loop..." league_stats = [] test_team ="Arsenal" # Function iterates through the league teams and calculates the averages # and places them in one long list. for team in league_list: league_stats.append(team) league_stats.append(CalcAverageHome(team, 4, data)) print CalcAverageHome(team, 4, data) league_stats.append(CalcAverageHome(team, 5, data)) CalcAverageHome(team, 5, data) league_stats.append(CalcAverageHome(team, 7, data)) CalcAverageHome(team, 7, data) league_stats.append(CalcAverageHome(team, 8, data)) CalcAverageHome(team, 8, data) league_stats.append(CalcAverageHome(team, 10, data)) CalcAverageHome(team, 10, data) league_stats.append(CalcAverageHome(team, 11, data)) CalcAverageHome(team, 11, data) league_stats.append(CalcAverageHome(team, 12, data)) CalcAverageHome(team, 12, data) league_stats.append(CalcAverageHome(team, 13, data)) CalcAverageHome(team, 13, data) # This function should chunk the 'file', as when we run the above code, # we'll end up with one incredibly long list that contains every team on the same line def chunker(seq, size): return (seq[pos:pos + size] for pos in xrange(0, len(seq), size)) chunker (league_stats, 9) final_stats = [] for group in chunker(league_stats, 9): print repr(group) final_stats.append(repr(group)) #retrieve a particular value from the final stats array """ for row in final_stats: if data[count][2] == team: total += int(data[count][column]) n+=1 count += 1 """ def create_probability_table(hometeam, awayteam, final_stats): #reads in the home and away sides, calculates their performance adjusted #ratings and then calculates the likelihood of each team scoring a particular #number of goals (from 0-10) #those likelihoods are then combined to provide an 11x11 matrix of probabilities poisson_array = [] poisson_list_home = [] poisson_list_away = [] goals_home = 0 conceded_home = 0 goals_away = 0 conceded_away = 0 for team in final_stats: if team == hometeam: goals_home = team[1] conceded_home = team [3] print"home Goals, Home Conceded" print goals_home, conceded_home elif team == awayteam: goals_away = team[2] conceded_away = team[4] print"Away Goals, Away Conceded" print goals_away, conceded_away, else: pass adjusted_goals_home = goals_home * conceded_away adjusted_goals_away = goals_away * conceded_home #this section creates the two probability lists for home and away num goals scored for i in range (10): poisson_list_home.append = (100*poisson_probability(i,adjusted_goals_home)) poisson_list_away.append = (100*poisson_probability(i,adjusted_goals_away)) print poisson_list_home print poisson_list_away for number in poisson_list_home: for number in poisson_list_away: probability_table.append(poisson_list_home[number] * poisson_list_away[number]) return probability_table create_probability_table("Arsenal","Chelsea", final_stats) #and this section cross multiplies them into a new list # for i in range (10): # print data_frame [0:100] prints to console to provide visual check master_data_file.close() |
当我运行它时,它抛出一个
1 2 | line 272, in create_probability_table adjusted_goals_home = goals_home * conceded_away UnboundLocalError: local variable 'conceded_away' referenced before assignment |
错误-我不明白为什么!它是在函数开始时定义和分配的。这不是全球性的。
我看过这些问题,他们似乎没有回答:局部(?)赋值前引用的变量从父函数赋值给变量:"赋值前引用的局部变量"这是如何"在分配前引用的"?UnboundLocalError:分配前引用的本地变量"核心价"
你拼错了"承认":
1 2 | condeded_away = 0 ^ |
此外,您可能希望对
1 2 3 4 5 | teams = { 'team1': [...], 'team2': [...], ... } |
然后您可以更快地查找团队的统计数据:
1 | stats = teams['team2'] |