I'm currently developing EV calculator using python and django. I get a key error exception
when trying to access a dictionary key in an if statement inside a function.
To break it down, my calculator function does the following, prompts the user for four input values, wager_amount, odd1, odd2 and odd_to_bet/back_odd
, based on values user has entered, the function will output expected value or ev
in jinja html. Something to note is, odd_to_bet/back_odd
must either be equal to odd1 or odd2
, if odd_to_bet/back_odd
is either not equal to odd1 or odd2
, the function has an else
block with a message to tell the user to Please, check the odds again for any typo error!
.
An example: lets say the user inputs the following values from html form
wager_amount = 10
odd1 = 1.54
odd2 = 2.47
odd_to_bet/back_odd = 1.54
This works fine, i'm able to display output without issues
the key error exception arises when the user inputs and submits odd_to_bet/back_odd
a value not either equal to odd1 or odd2
.
wager_amount = 10
odd1 = 1.54
odd2 = 2.47
odd_to_bet/back_odd = 1.52
My expected output should be "Please, check the odds again for any typo error!." displayed in the html.
My function code
def func_two_way(wager_amount, home_odd, away_odd, back_odd):
if back_odd == home_odd:
total_returns = home_odd * wager_amount
profit = total_returns - wager_amount
home_prob = 1/home_odd
away_prob = 1/away_odd
prob_not_occuring = away_prob
ev = (home_prob * profit)-(prob_not_occuring * wager_amount)
my_dict = {
'odd1': home_odd,
'odd2': away_odd,
'wager_amount': wager_amount,
'ev': round(ev, 2),
'back_odd': back_odd,
}
return my_dict
elif back_odd == away_odd:
total_returns = away_odd * wager_amount
profit = total_returns - wager_amount
home_prob = 1/home_odd
away_prob = 1/away_odd
prob_not_occuring = home_prob
ev = (away_prob * profit)-(prob_not_occuring * wager_amount)
my_dict = {
'odd1': home_odd,
'odd2': away_odd,
'wager_amount': wager_amount,
'ev': round(ev, 2),
'back_odd': back_odd,
}
return my_dict
else:
message = 'Please, check the odds again for any typo error!'
# print(user_res)
my_dict = {
'user_res': message,
}
return my_dict
my view in django
def two_way_ev(request):
if request.method == 'POST':
wager_amount = int(request.POST.get('wager_amount'))
odd1 = float(request.POST.get('odd1'))
odd2 = float(request.POST.get('odd2'))
back_odd = float(request.POST.get('back_odd'))
print(wager_amount)
my_func = func_two_way(wager_amount, odd1, odd2, back_odd)
print(my_func)
context = {
'wager_amount': my_func['wager_amount'],
'odd1': my_func['odd1'],
'odd2': my_func['odd2'],
'ev': my_func['ev'],
'back_odd': my_func['back_odd'],
'user_response': my_func['user_res'],
}
return render(request, 'two_way_ev.html', context)
else:
return render(request, 'two_way_ev.html', {})
html template
<div >
<p>Odd you are backing is {{back_odd}}</p>
<p>Your total wager amount is ${{wager_amount}}</p>
<p>Expected value is ${{ev}}</p>
<p>{{user_response}}</p>
</div>
the error message
KeyError at /blogapp/two_way_ev/
'wager_amount'
Request Method: POST
Request URL: http://127.0.0.1:8000/blogapp/two_way_ev/
Django Version: 4.0.2
Exception Type: KeyError
Exception Value:
'wager_amount'
Exception Location: C:\Users\Admin\Desktop\BERNIEBLOG\myblog\blogapp\views.py, line 88, in two_way_ev
Python Executable: C:\Users\Admin\.virtualenvs\BERNIEBLOG-Vx11UYiR\Scripts\python.exe
Python Version: 3.8.0
what am i doing wrong?
CodePudding user response:
From a quick look at your code I can determine that you Never initialize the key 'user_res'
in your dictionary unless an error occurs, so in some way nothing is going wrong and that is causing your crash.
Your django code tries to build the context
dictionary and is getting a KeyError
exception because the 'user_res'
key is simply not there!, a simple solution would be to initialize this key in all your dictionaries, for example like:
my_dict = {
'odd1': home_odd,
'odd2': away_odd,
'wager_amount': wager_amount,
'ev': round(ev, 2),
'back_odd': back_odd,
'user_res' : 'everything went fine!'
}
this would be sufficient in order for your application to work!
P.S, I must also add that it would be a slightly more elegant solution if you had your user simply pick the bet by entering a number (1 or 2 depending on the bet) rather than entering a long floating point value and being frustrated if he has a typo.