I have a for loop that goes through a list of cities as well as their broad variables (safety, affordability, transit, etc). If there's a match between the city's broad&specific variable and the broad&specific variable the user selects on the page then it assigns a weighted value else the value is 0. I am trying to add the values for each broad variable in the list but I get the error
local variable 'city_variable1_value' referenced before assignment
When I reference city_variable1_value and city_variable2_value as 0 before the first if statement then my
total_city_value = city_variable1_value city_variable2_value
equals 0 when it should be 0.24 for example. The code is below!
views.py
# list of each variable's broad category
broad_variable_list = ["safety", "affordability", "transit", "language", "attractions"]
# weighting of each variable ranking
weight_variable1 = 0.33
weight_variable2 = 0.24
weight_variable3 = 0.17
weight_variable4 = 0.14
weight_variable5 = 0.12
def get_ranking(request):
# if this is a POST request we need to process the form data
if request.method == 'POST':
# create a form instance and populate it with data from the request:
form = RankingForm(request.POST)
# check whether it's valid:
if form.is_valid():
# process the data in form.cleaned_data as required
specific_variable1 = form.cleaned_data['specific_variable1']
specific_variable2 = form.cleaned_data['specific_variable2']
broad_variable1 = form.cleaned_data['broad_variable1']
broad_variable2 = form.cleaned_data['broad_variable2']
# loop through each city in the database
for cities in City.objects.values_list('city', flat=True):
print(cities)
# loop through each broad variable in the list at the top of this page
for broad_variable in broad_variable_list:
# check if the current broad variable is equal to the first broad variable the user chose
if broad_variable == broad_variable1:
# if the city's specific variable is equal to the specific variable the user chose get the value of it based on it's ranking weight
if City.objects.values_list(broad_variable, flat=True).filter(city=cities).first() == specific_variable1:
city_variable1_value = 1 * weight_variable1
print(city_variable1_value)
# else assign a value of 0
else:
city_variable1_value = 0
print(city_variable1_value)
# check if the current broad variable is equal to the second broad variable the user chose
if broad_variable == broad_variable2:
# if the city's specific variable is equal to the specific variable the user chose get the value of it based on it's ranking weight
if City.objects.values_list(broad_variable, flat=True).filter(city=cities).first() == specific_variable2:
city_variable2_value = 1 * weight_variable2
print(city_variable2_value)
# else assign a value of 0
else:
city_variable2_value = 0
print(city_variable2_value)
total_city_value = city_variable1_value city_variable2_value
print(total_city_value)
# if a GET (or any other method) we'll create a blank form
else:
form = RankingForm()
return render(request, 'project/home.html', {'form': form})
CodePudding user response:
Your program reached the total_city_value = city_variable1_value city_variable2_value
line without ever assigning a value to city_variable1_value
. This is possible if the condition broad_variable == broad_variable1
was never true in the for loop which assigns to city_variable1_value
.
For a minimal example, if you did this,
def f():
if False:
a = 10
print(a)
f()
you would get the same error UnboundLocalError: local variable 'a' referenced before assignment
.
To fix this, just assign a default value to your variables before the if statement which potentially prevents the assignment from happening. For instance,
city_variable1_value = 0
if broad_variable == broad_variable1:
...
city_variable2_value = 0
if broad_variable == broad_variable2:
...