How do I assign dynamic key values in a dictionary in Python? - python

Environment:
Zipline 1.3.0
miniconda3
windows OS
I am trying to iterate S in data. S.symbol has like 15 values.
When iterating in data for 1 symbol, say ‘spy’ as in below code; i want to create 2keys
(S.symbol + “c”) —-> spyc to hold current value
(S.symbol + “s”) —→ spys to hold a float value.
def before_trading_start(context,data):
print("*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#")
print("Get DateTime: ",get_datetime())
#context is a dictionary
for S in data:
if(S.symbol == 'SPY'):
arr = list(range(1,91))
hist = data.history(S,"price",90,"1d")
price_list = np.log(hist.tolist())
context.spyc = data.current(S,"price")
context.spys = Slope(arr, price_list)
print (context.spyc)
print (S.symbol, context.spys)
else:
continue
############### My failed Version of dynamic naming
def before_trading_start(context,data):
print("*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*")
print("Get DateTime: ",get_datetime())
for S in data:
arr = list(range(1,91))
hist = data.history(S,"price",90,"1d")
price_list = np.log(hist.tolist())
context[S.symbol + "c"] = data.current(S,"price")
context[S.symbol+"s"] = Slope(arr, price_list)
print (context[S.symbol + "c"])
print (S.symbol, context[S.symbol + "s"])
S.symbols = ["Spy","AAPl",'xom','L','T','CSCO','MSFT'..]

Related

Why does my python loop return Key Error : 0 when I change the input dataframe?

I'm trying to do iterative calculation that will store the result of each iteration by append into a dataframe
however when I try to change the input dataframe into something else, I got the key error : 0
here are my complete code
d = []
df_it = df_ofr
i = 0
last_col = len(df_it.iloc[:,3:].columns) - 1
print("User Group : " + df_it[['user_type'][0]][0] + " " + df_it[['user_status'][0]][0])
for column in df_it.iloc[:,3:]:
if i > 0 :
if i < last_col: # 1 step conversion
convert_baseline = df_it[[column][0]][0]
convert_variant_a = df_it[[column][0]][1]
elif i == last_col: # end to end conversion
convert_baseline = df_it[[column][0]][0]
convert_variant_a = df_it[[column][0]][1]
lead_baseline = step_1_baseline
lead_variant_a = step_1_variant_a
#perform proportion z test
test_stat, p_value = proportions_ztest([convert_baseline,convert_variant_a], [lead_baseline,lead_variant_a], alternative='smaller')
#perform bayesian ab test
#initialize a test
test = BinaryDataTest()
#add variant using aggregated data
test.add_variant_data_agg("Baseline", totals=lead_baseline, positives=convert_baseline)
test.add_variant_data_agg("Variant A", totals=lead_variant_a, positives=convert_variant_a)
bay_result = test.evaluate(seed=99)
#append result
d.append(
{
'Convert into': column,
'# Users Baseline': lead_baseline,
'# Users Variant A': lead_variant_a,
'% CVR Baseline' : convert_baseline / lead_baseline,
'% CVR Variant A' : convert_variant_a / lead_variant_a,
'Z Test Stat' : test_stat,
'P-Value' : p_value,
'Prob Baseline being the Best' : bay_result[0]['prob_being_best'],
'Prob Variant A being the Best' : bay_result[1]['prob_being_best']
}
)
elif i == 0:
step_1_baseline = df_it[[column][0]][0]
step_1_variant_a = df_it[[column][0]][1]
i = i+1
lead_baseline = df_it[[column][0]][0]
lead_variant_a = df_it[[column][0]][1]
pd.DataFrame(d)
the one that I'm trying to change is this part
df_it = df_ofr
thanks for your help, really appreciate it
I'm trying to do iterative calculation that will store the result of each iteration by append into a dataframe

display ";" separated values in table format with python

I'm having the following function which picks results from a results.txt file and displays it to the user, the first row comes out nicely but the rest of the results are not well-aligned. I'm not sure what's causing this. here's the function
def show_result():
'''prints the score list'''
file_exist()
print_whole_list = []
print("Results")
print("*"*41)
result = open("results.txt","r")
res = result.readlines()
print("Name: Lap1: Lap2: Lap3: In total: Average:")
for i in res:
temp_list = i.split(";")
total = int(temp_list[1]) + int(temp_list[2]) + int(temp_list[3])
average = int(total) / 3.0
average = round(average, 2)
temp_list.insert(4, total)
temp_list.insert(5, average)
print_whole_list.extend(temp_list)
for row in print_whole_list:
print("{0:{width}}".format(row, width=10), end=' ')
result.close()
The records in the text file:
Kembos;23;43;23;
Moses;42;51;43;
Ben;43;23;21;
You can use tabulate instead to populate your data in a tabular format in python
from tabulate import tabulate
result = open("results.txt","r")
res = result.readlines()
final = []
for line in res:
temp_list = line.split(';')[:-1]
total = int(temp_list[1]) + int(temp_list[2]) + int(temp_list[3])
average = round(int(total) / 3.0, 2)
temp_list.append(total)
temp_list.append(average)
final.append(temp_list)
print(tabulate(final, headers=["Name", "Lap1", "Lap2", "Lap3", "In Total", "Average"]))
Above code will give the following output:

How do I update a value in a dataframe in a loop?

I am trying to update a rating row by row. I have one dataframe of players, that all start with the same rating. For each match, I want the rating to change. Another dataframe contains results of each match.
import pandas as pd
gamesdata = [['paul','tom'],['paul','lisa'],['tom','paul'],['lisa','tom'],['paul','lisa'],['lisa','tom'],['paul','tom']]
games = pd.DataFrame(gamesdata, columns = ['Winner', 'Looser'])
playersdata= ['lisa','paul','tom']
players = pd.DataFrame(playersdata, columns = ['Name'])
mean_elo = 1000
elo_width = 400
k_factor = 64
players['elo'] = mean_elo
def update_elo(winner_elo, loser_elo):
expected_win = expected_result(winner_elo, loser_elo)
change_in_elo = k_factor * (1-expected_win)
winner_elo += change_in_elo
loser_elo -= change_in_elo
return winner_elo, loser_elo
def expected_result(elo_a, elo_b):
expect_a = 1.0/(1+10**((elo_b - elo_a)/elo_width))
return expect_a
for index, row in games.iterrows():
winnername = row['Winner']
losername = row['Looser']
web = players['elo'].loc[players['Name'] == winnername].values[0]
wIndex = players.loc[players['Name'] == winnername]
#I want to return just the index, so I can update the value
print(wIndex)
leb = players['elo'].loc[players['Name'] == losername].values[0]
print('Winner Elo before: ' + str(web))
winner_elo, looser_elo = update_elo(web, leb)
print('Winner Elo after: ' + str(winner_elo))
#here I want to update value
#players.at[wIndex,'elo']=winner_elo
I am trying to update the value in the players table using
players.at[wIndex,'elo']=winner_elo
but i struggle to get the index with this code:
wIndex = players.loc[players['Name'] == winnername]
Found a sollution:
wIndex = players.loc[players['Name'] == winnername].index.values
Can't believe i missed that

How can I initialize dictionary in Python where key is an object?

I am trying to rephrase the implementation found here. This is what I have so far:
import csv
import math
import random
training_set_ratio = 0.67
training_set = []
test_set = []
class IrisFlower:
def __init__(self, petal_length, petal_width, sepal_length, sepal_width, flower_type):
self.petal_length = petal_length
self.petal_width = petal_width
self.sepal_length = sepal_length
self.sepal_width = sepal_width
self.flower_type = flower_type
def __hash__(self) -> int:
return hash((self.petal_length, self.petal_width, self.sepal_length, self.sepal_width))
def __eq__(self, other):
return (self.petal_length, self.petal_width, self.sepal_length, self.sepal_width) \
== (other.petal_length, other.petal_width, other.sepal_length, other.sepal_width)
def load_data():
with open('dataset.csv') as csvfile:
rows = csv.reader(csvfile, delimiter=',')
for row in rows:
iris_flower = IrisFlower(float(row[0]), float(row[1]), float(row[2]), float(row[3]), row[4])
if random.random() < training_set_ratio:
training_set.append(iris_flower)
else:
test_set.append(iris_flower)
def euclidean_distance(flower_one: IrisFlower, flower_two: IrisFlower):
distance = 0.0
distance = distance + math.pow(flower_one.petal_length - flower_two.petal_length, 2)
distance = distance + math.pow(flower_one.petal_width - flower_two.petal_width, 2)
distance = distance + math.pow(flower_one.sepal_length - flower_two.sepal_length, 2)
distance = distance + math.pow(flower_one.sepal_width - flower_two.sepal_width, 2)
return distance
def get_neighbors(test_flower: IrisFlower):
distances = []
for training_flower in training_set:
dist = euclidean_distance(test_flower, training_flower)
d = dict()
d[training_flower] = dist
print(d)
return
load_data()
get_neighbors(test_set[0])
Currently, print statements in the following code block:
def get_neighbors(test_flower: IrisFlower):
distances = []
for training_flower in training_set:
dist = euclidean_distance(test_flower, training_flower)
d = dict()
d[training_flower] = dist
print(d)
return
will have outputs similar to
{<__main__.IrisFlower object at 0x107774fd0>: 0.25999999999999945}
which is ok. But I do not want to create the dictionary first, and then append the key value, as in:
d = dict()
d[training_flower] = dist
So this is what I am trying:
d = dict(training_flower = dist)
However, it does not seem like the dist method is using the instance, but rather a String, because what I see printed is as follows:
{'training_flower': 23.409999999999997}
{'training_flower': 16.689999999999998}
How do I create the dictionary by using the object as key in one statement?
In your snippet, where you write d = dict(training_flower=dist), "training_flower" is a keyword argument for dict function and not an object. It is equivalent to writing d = {'training_flower': dist}. The only way to create a dictionary with an object as a key is to use the latter syntax:
d = {training_flower: dist}
To directly create a dict with a key which is not a valid keyword, use the {} syntax like:
Code:
d = {training_flower: 'a_value'}
Test Code:
training_flower = 'a key'
d = {training_flower: 'a_value'}
print(d)
Results:
{'a key': 'a_value'}
to initialize a dictionary with an object as a key, (edit: and the string in Stephen's example is an object anyway)
class Flower:
def __repr__(self):
return 'i am flower'
flower1 = Flower()
d = {flower1: 4}
print(d)
outputs
{i am flower: 4}
this is my first post here, and I know I'm late, sorry if it's a duplicate solution. just to show it works with an object.
would upvote Stephen's answer but I can't yet.

Append column field name with date range operator dynamically in django?

This is the code I'm using :
where_con=''
#loop on model name
# getting all info for one model
where_con = {}
for k in model_k_j:
type_val = type(model_k_j[k])
if type_val== dict:
print "dictonary type"
"""
for model_field_dict in model_k_j[k]:
start= model_k_j[k][model_field_dict]
end= model_k_j[k][model_field_dict]
where_con[k] = medical_home_last_visit__range=[start,end ]
break
"""
else:
col_name.append(k)
where_con[k] = model_k_j[k]
# covert data type
# **where_con {unpack tuple}
# where_con =str(where_con)
# print where_con
qs_new = model_obj.objects.filter(**where_con)
The field medical_home_last_visit is not static, it is coming dynamically.
How do I append it ? I have tried something like:
colname_variable = medical_home_last_visit
where_con[k] = colname_variable + __range=[start,end ]
but it is not working properly, and gives this error :
where_con[k] = colname_variable + __range=[start,end ]
^
SyntaxError: invalid syntax
where_con is dict and key name should be equal colname_variable__range:
#k = 'medical_home_last_visit__range'
where_con[k] = (start, end)
qs_new = model_obj.objects.filter(**where_con)
it is equal to:
model_obj.objects.filter(medical_home_last_visit__range=(start, end))
and any other filter args should be keys in where_con, for example:
#k = 'some_date__lte'
where_con[k] = datetime.datetime.now()

Categories