Dictionaries and the Robo-Advisor¶
One helpful trick with dictionaries is to use them to store data with names.
Consider the robo-advisor tool below.
def get_age():
need_age = True
while need_age:
age = input('What is your age? Enter it as a numberic argument (e.g. "50", not "fifty")\n')
try:
age = int(age) # this will break (raise an exception) if age is not numeric
need_age = False
except Exception as e:
print('Please try entering your age again')
return age
def get_risk_preference():
need_preference = True
while need_preference:
response = input("On a scale of 1-5, how much do you dislike risk? 1=not bothered by risk, 5=extremely worried about risk.\n")
try:
response = int(response) # this will break if response is not 1-5
need_preference = False
except Exception as e:
print('Please try entering your preference again')
return response
def get_allocation():
age = get_age()
# apply rule of 100
equity_weight = 100-int(age)
# get user's risk preference
preference = get_risk_preference()
# shift the allocation according to the user's preference
if preference == 1:
equity_weight += 10
elif preference == 2:
equity_weight += 5
elif preference == 4:
equity_weight -= 5
elif preference == 5:
equity_weight -= 10
# correct weights to stick within 0-100
equity_weight = min(equity_weight, 100)
equity_weight = max(equity_weight, 0)
debt_weight = 100-equity_weight
print('I would recommend', equity_weight, 'percent stocks and ', debt_weight, 'percent bonds')
return [equity_weight, debt_weight]
---------------------------------------------------------------------------
StdinNotImplementedError Traceback (most recent call last)
<ipython-input-2-19454c49e5b0> in <module>
----> 1 get_allocation()
<ipython-input-1-bbc80d1b0c91> in get_allocation()
23 def get_allocation():
24
---> 25 age = get_age()
26
27 # apply rule of 100
<ipython-input-1-bbc80d1b0c91> in get_age()
2 need_age = True
3 while need_age:
----> 4 age = input('What is your age? Enter it as a numberic argument (e.g. "50", not "fifty")\n')
5 try:
6 age = int(age) # this will break (raise an exception) if age is not numeric
/mnt/software/anaconda3/lib/python3.8/site-packages/ipykernel/kernelbase.py in raw_input(self, prompt)
855 """
856 if not self._allow_stdin:
--> 857 raise StdinNotImplementedError(
858 "raw_input was called, but this frontend does not support input requests."
859 )
StdinNotImplementedError: raw_input was called, but this frontend does not support input requests.
The block of code where where shift the equity_weight variable is a bit tedious to look at.
A more convenient way to store that information is via a dictionary like so:
def get_allocation():
age = get_age()
# apply rule of 100
equity_weight = 100-int(age)
# get user's risk preference
preference = get_risk_preference()
# shift the allocation according to the user's preference
shift = {1: 10, 2: 5, 3: 0, 4: -5, 5: -10}
equity_weight += shift[preference]
# correct weights to stick within 0-100
equity_weight = min(equity_weight, 100)
equity_weight = max(equity_weight, 0)
debt_weight = 100-equity_weight
print('I would recommend', equity_weight, 'percent stocks and ', debt_weight, 'percent bonds')
return [equity_weight, debt_weight]
So, why does this work? Well, recall that we asked the user to state their risk preference. This risk preference was given as an integer between 1 and 5. So, we can think of the integers 1-5 as “names” for preferences. That is, a person who is a 1 is very risk-tolerant/risk-loving. A person who is a 5 is very risk-averse.
Each of these five types of people has a “shift” to the rule of thumb equity weight. For instance, a very risk-averse person receives a shift of -10 to their recommended equity weight.
The dictionary:
records the person type as the key and the corresponding shift-value as the value in the dictionary.
Any person can then be referenced by their risk preference and their corresponding shift value is returned.
Dictionaries are frequently used in this manner. That is, a programmer specifies a dictionary with a set of key-value pairs, and then later uses the dictionary by providing a key to receive the corresponding value.
Let’s consider another example of a dictionary in action.
This dictionary uses sector names as keys and stock tickers as values.
Suppose the robo-advisor asks a user what sector they are interested in learning more about. For now, we don’t have enough tools in our toolkit to provide the user with a detailed response (though we will shortly!). Instead, let’s give the robot a bit of personality.
def fave_sector():
need_fave = True
while need_fave:
fave = input('''What is your favorite sector?\n
\t Materials\n
\t Communications\n
\t Energy\n
\t Financial\n
\t Healthcare\n
\t Industrials\n
\t Technology\n
\t Utilities\n''')
if fave in sectors.keys():
need_fave = False
print("That's cool,", sectors[fave],"is my favorite stock")