print values after each 1000 step - python

I want to print value after every certain interval (1000) on last line of code than every single value.
DARTS=200000
hits = 0
throws = 0
rangen = RanGenerator()
pi = 0
avg = 0
mu = 0
var = 0
dev = 1
for i in range (1, DARTS):
throws += 1
x = rangen.rand()
y = rangen.rand()
z = rangen.rand()
tt = x**2 + y**2 + z**2
dist = sqrt(tt)
if dist <= 1.0:
hits = hits + 1.0
pi = 6 * (hits / throws)
avg = avg + pi
mu = avg/throws
var = (var+(mu-pi)**2)/throws
dev = sqrt(var)
print("%d: %s" % (i,dev))

This is easy with the modulo operator - it will print the values only when i is divisible by 1000:
if i % 1000 == 0:
print("%d: %s" % (i,dev))

Related

Python Scipy fsolve function returns roots which are equal to starting points

I need to get all roots of a scalar equation. But fsolve can only return 1 root for each call. So I design a self-call function find_root_recursively of fsolve. This function will call itself until the new root is equal the previous root, which means fsovle has found all roots and no more new roots will be added. I use this logic to end self calling. But in some cases fsolve will return a root which is exactly the same as starting point. one_root = start always. Obviously this start is not a root. So the list_root is always adding new roots, it never ends.
min_value = df_group['strike'].min()
start_point = int(float(min_value) * 0.8)
def find_root_by_small_step(function, start_0, increment):
start = start_0
one_root = fsolve(function, start)
def get_transaction_data(self, expiry_date, df_group):
return df_group[df_group['expiration_date'] == expiry_date].loc[(df_group['type'] == 1) & (df_group['position'] == 1)], \
df_group[df_group['expiration_date'] == expiry_date].loc[(df_group['type'] == 1) & (df_group['position'] == 0)], \
df_group[df_group['expiration_date'] == expiry_date].loc[(df_group['type'] == 0) & (df_group['position'] == 1)], \
df_group[df_group['expiration_date'] == expiry_date].loc[(df_group['type'] == 0) & (df_group['position'] == 0)]
def calculate_one_payoff(self, stock_price, df_long_call, df_short_call, df_long_put, df_short_put):
# buy call
df_buy_call_executed = df_long_call[stock_price >= df_long_call['strike']]
if len(df_buy_call_executed) > 0:
buy_call_executed_sum = ((stock_price - df_buy_call_executed['breakeven_price']) * df_buy_call_executed['option_amount']).sum()
else:
buy_call_executed_sum = 0
df_buy_call_noExec = df_long_call[stock_price < df_long_call['strike']]
if len(df_buy_call_noExec) > 0:
buy_call_noExec_sum = (-1 * df_buy_call_noExec['option_price'] * df_buy_call_noExec['option_amount']).sum()
else:
buy_call_noExec_sum = 0
# sell call
df_sell_call_executed = df_short_call[stock_price >= df_short_call['strike']]
if len(df_sell_call_executed) > 0:
sell_call_executed_sum = ((df_sell_call_executed['breakeven_price'] - stock_price) * df_sell_call_executed['option_amount']).sum()
else:
sell_call_executed_sum = 0
df_sell_call_noExec = df_short_call[stock_price < df_short_call['strike']]
if len(df_sell_call_noExec) > 0:
sell_call_noExec_sum = (df_sell_call_noExec['option_price'] * df_sell_call_noExec['option_amount']).sum()
else:
sell_call_noExec_sum = 0
# buy put
df_buy_put_executed = df_long_put[stock_price < df_long_put['strike']]
if len(df_buy_put_executed) > 0:
buy_put_executed_sum = ((df_buy_put_executed['breakeven_price'] - stock_price) * df_buy_put_executed['option_amount']).sum()
else:
buy_put_executed_sum = 0
df_buy_put_noExec = df_long_put[stock_price >= df_long_put['strike']]
if len(df_buy_put_noExec) > 0:
buy_put_noExec_sum = (-1 * df_buy_put_noExec['option_price'] * df_buy_put_noExec['option_amount']).sum()
else:
buy_put_noExec_sum = 0
# sell put
df_sell_put_executed = df_short_put[stock_price < df_short_put['strike']]
if len(df_sell_put_executed) > 0:
sell_put_executed_sum = ((stock_price - df_sell_put_executed['breakeven_price']) * df_sell_put_executed['option_amount']).sum()
else:
sell_put_executed_sum = 0
df_sell_put_noExec = df_short_put[stock_price >= df_short_put['strike']]
if len(df_sell_put_noExec) > 0:
sell_put_noExec_sum = (df_sell_put_noExec['option_price'] * df_sell_put_noExec['option_amount']).sum()
else:
sell_put_noExec_sum = 0
one_stock_price_sum = buy_call_executed_sum + buy_call_noExec_sum + sell_call_executed_sum + sell_call_noExec_sum + \
buy_put_executed_sum + buy_put_noExec_sum + sell_put_executed_sum + sell_put_noExec_sum
one_stock_price_sum = float(one_stock_price_sum)
return one_stock_price_sum
df_long_call, df_short_call, df_long_put, df_short_put = self.get_transaction_data(expiry_date, df_group)
find_root_by_small_step(function=calculate_one_payoff, start=start_point, increment=increment)
ticker type position expiration_date strike option_price option_amount breakeven_price
AAPL 1 0 2021-11-19 145.0000 5.1700 2500.0000 150.1700
AAPL 0 1 2021-11-19 145.0000 2.9700 2500.0000 142.0300
AAPL 0 1 2021-11-19 145.0000 2.7000 5000.0000 142.3000
AAPL 1 1 2021-11-19 145.0000 5.8500 5000.0000 150.8500
AAPL 1 1 2021-11-19 155.0000 1.6000 1050.0000 156.6000
True root = 139.9 and 159.0

I do not know why my simulation is so slow. I need to optimize my simulation and improve the way I use variables

This is a python program that does some sort of simulation,, I am looking for any type of optimization while keeping the same p[i] form, I have tried Pypy and I got an around 3x performance gain over python. Any suggestions are welcomed
import random
from time import perf_counter
infected, non_infected = 1, 99999
infectation_chance, infection_days, death_chance = 1/100, 2/1000, 2/100
population, population_list = infected + non_infected, non_infected * [0] + infected * [1]
place = 10
p = {i: [] for i in range(1,place + 1)}
day = 1
simulation_duration = 3
while 0 < simulation_duration:
print(f"Working on day {day}..")
time1 = perf_counter()
for person in population_list:
p[random.randint(1, place)].append(person)
time2 = perf_counter()
i = 0
while i < place:
tl = []
i += 1
for crowd in p[i]:
if crowd == 0:
if (random.random() < infectation_chance * str(p[i]).count("1")) - (infectation_chance/100 * str(p[i]).count("0")):
tl.append(1)
else:
tl.append(0)
if crowd == 1:
tl.append(1)
p[i] = tl
i = 0
population_list = []
while i < place:
i += 1
population_list.append(p[i])
simulation_duration -= 1
day += 1
print(f"Total time: {perf_counter() - time1} \nInfection time: {perf_counter() - time2} \nPlacing time: {time2-time1}")
print(str(population_list).count("1"), str(population_list).count("0"))
Even tho I received lots of help I still need more optimization.Any type of optimization as far as it doesn't change the results are welcomed.Since this is fully compatible with pypy I am using pypy, I can also use python if it means better performance. Current setup:
import random
import functools
from time import perf_counter
with open("results.txt", "w") as results:
results.seek(0)
results.write("")
results.close()
time1 = perf_counter()
#functools.lru_cache(maxsize=128)
def simulation():
infected, non_infected = 1, 99999999
infectation_chance_c, death_chance, recovery_chance, reinfectation_chance, incubation_time = 1.4, 1 - 0.03, 1 - 0.97, 1 - 1 / 150, 2
death_chance, recovery_chance = death_chance / incubation_time, recovery_chance / incubation_time
population_total, population_list = infected + non_infected, non_infected * [0] + infected * [1]
place = 1
day = 0
simulation_duration = 100000000
with open("results.txt", "a") as results:
print("Starting... \nPlease wait for results, this can take lots of time!")
while infected > 0 and simulation_duration > 0:
population = population_list.count(0) + population_list.count(-1) + population_list.count(1)
healthy = population_list.count(0) + population_list.count(-1)
recovered = population_list.count(-1)
infected = population_list.count(1)
died = population_total - len(population_list)
p = {i: [] for i in range(1,place + 1)}
results.write(f"Day {day}: Infected: {infected} Healthy: {healthy} p-Imune: {recovered} Alive: {population} Died: {died} \n")
print(f"Day {day}: Infected: {infected} Healthy: {healthy} p-Imune: {recovered} Alive: {population} Died: {died}")
for person in population_list:
p[random.randint(1, place)].append(person)
i = 0
while i < place:
i += 1
p_infected = p[i].count(1)
try:
infectation_chance = 1 - float(p_infected) / (float(len(p[i])) / infectation_chance_c)
except:
pass
for j, crowd in enumerate(p[i]):
if crowd == -1:
if random.random() > reinfectation_chance:
p[i][j] = 1
elif random.random() > reinfectation_chance:
p[i][j] = 0
elif crowd:
if random.random() > death_chance:
p[i].pop(j)
elif random.random() > recovery_chance:
if random.random() > 0.4:
p[i][j] = -1
else:
p[i][j] = 0
elif not crowd:
if random.random()>infectation_chance:
p[i][j] = 1
i = 0
population_list = []
while i < place:
i += 1
population_list.extend(p[i])
simulation_duration -= 1
day += 1
print(f"Total time: {perf_counter() - time1}")
simulation()
print(f"Simulation finishsed... \nProcessing time: {perf_counter()-time1}")
here is a corrected version in pure python, commented because there were some bugs. your major time loss was counting infected/non-infected inside the for loop, though the result is always the same. it could be optimized again with numpy if you wanna use a bigger population
import random
from time import perf_counter
infected, non_infected = 1, 99999
infectation_chance, infection_days, death_chance = 1/100, 2/1000, 2/100
population, population_list = infected + non_infected, non_infected * [0] + infected * [1]
place = 10
day = 1
simulation_duration = 3
while 0 < simulation_duration:
# p must be reset here or it will grow indefinitely
p = {i: [] for i in range(1,place + 1)}
print(f"Working on day {day}..")
time1 = perf_counter()
for person in population_list:
p[random.randint(1, place)].append(person)
time2 = perf_counter()
i = 0
while i < place:
i += 1
# if you need to, count infected/non-infected here
# not in your for loop where it has always the same value
# and don't cast to str, what's the point?
# pi_infected = p[i].count(1)
# pi_sane = p[i].count(0)
for j, crowd in enumerate(p[i]):
if crowd == 0:
# your formula was broken (a-b is always true)
# i used a generic one
if random.random()>(1-infectation_chance):
# change your list in place:
# no need for temp list, save lots of cycles
p[i][j] = 1
i = 0
population_list = []
while i < place:
i += 1
# it's extend, not append here or your population list
# will have a length of #place
population_list.extend(p[i])
simulation_duration -= 1
day += 1
print(f"Total time: {perf_counter() - time1} \nInfection time: {perf_counter() - time2} \nPlacing time: {time2-time1}")
print(population_list.count(1), population_list.count(0))
numpy version
import random
import numpy as np
from time import perf_counter
infected, non_infected = 1, 99999
infectation_chance, infection_days, death_chance = 1/100, 2/1000, 2/100
place = 10
population = infected + non_infected
group_size = population//place
population_list=np.zeros((population))
population_list[:infected]=1
day = 1
simulation_duration = 3
while 0 < simulation_duration:
print(f"Working on day {day}..")
time1 = perf_counter()
# shuffle is not recursive so we need to flatten population_list
population_list=population_list.flatten()
np.random.shuffle(population_list)
population_list=population_list.reshape((place, group_size))
time2 = perf_counter()
# we need to rebuild the pure python code with no loops
# first we create randoms for all pop
randoms = np.random.rand(population).reshape((place, group_size))
# list of infected by group: a list of all p[i].count(1)
nb_infected = np.count_nonzero(population_list, axis=1).reshape((place,1))
# compute (1-infectation_chance**p[i].count(1)) for all pop
infection_map=np.full((place, group_size), 1-infectation_chance)**nb_infected
# if randoms>infection_map and population_list==0
new_infected = np.bitwise_and(randoms>infection_map, population_list==0)
# then set to 1 in place
population_list[new_infected] = 1
simulation_duration -= 1
day += 1
print(f"Total time: {perf_counter() - time1} \nInfection time: {perf_counter() - time2} \nPlacing time: {time2-time1}")
total_infected=np.count_nonzero(population_list)
print(total_infected, population-total_infected)

getting list index out of range error when trying to add a a number from a list into a another list

Gudi = 0
gudi = []
Numbers = []
A = int(input("how many numbers are in the list"))
time.sleep(.5)
print ("Can you please enter the numbers?")
time.sleep(.3)
for i in range(A):
data = int(input())
Numbers.append(data)
# variables
median = sorted(Numbers)
ludi = int(A/2)
two = ludi - 1
One = median[ludi]
Two = median[two]
sum = (One + Two)
Ans = sum/2
cal = int((A - 1)/2 + 1) - 1
ans = median[cal]
def Median():
if A%2 == 0:
print ("The median is " + str(Ans))
else:
print ("The median is " + str(ans))
def sorlist():
print median
def Maximum():
print (median[-1])
def Minimum():
print (median[0])
def UQ():
if A%2 != 0:
global Gudi
global cal # the indice of the median
var = A - (cal - 1) # number of numbers that come after the median
Gudi += 1
for i in range(var):
cal += Gudi
gudi.append(median[cal])
Gudi += 1
UQ()
When I am trying to run the last function which is called UQ, I am getting this error: "IndexError: list index out of range on line 50 in main.py". I can't figure out what is wrong. I am trying to print the number of a list into a another list so then I can find the upper quartile.
The problem lies here
for i in range(var):
cal += Gudi
gudi.append(median[cal])
Gudi += 1
In each iteration
you are adding cal by Gudi
Gudi increases by 1
Suppose A = 10
cal = int((A - 1)/2 + 1) - 1 = 4
var = 10 - (4- 1) = 5
when
i=0, cal = cal + gudi = 4 + 1 = 5, Gudi = 2
i=1, cal = cal + gudi = 5 + 2 = 7, Gudi = 3
i=2, cal = cal + gudi = 7 + 3 = 10, Gudi = 4 --> out of bound

Python returns ints when one of variable inside function is active

The main idea is:
searchindex() - repeat binary search algorithm over the list of random data with looking back and with fix.(variable counter1 should save number of occurences)
occur() - just assumning total number of occurences.
Please help to find a problem.
I always get counter1 = 0 after running a code.
def searchindex(searchlist, secs, x):
ts = calendar.timegm(time.gmtime())
delta_minute_ts = (ts - (ts % 60)) - secs
last_minute = datetime.datetime.fromtimestamp(delta_minute_ts).strftime('%Y-%m-%d %H:%M')
start = 0
end = len(searchlist) - 1
counter1 = 0
while (start <= end):
mid = (start + end) // 2
if (searchlist[mid] == last_minute):
counter1 = int(mid)
if x == 1:
end = mid - 1
else:
start = mid + 1
elif (last_minute < searchlist[mid]):
end = mid - 1
else:
start = mid + 1
return counter1
def occur():
start_result = searchindex(new1, 60, 1)
end_result = searchindex(new1, 60, 2)
if start_result is None:
return 'no results'
else:
end_result - start_result + 1

Function that calculates change

I want to write a function that calculates the change a machine has to give a customer. The function receives the cost of the product, the sum of money the customer gave and a dictionary that has the money the machine has in it.
The function should give the smallest set of coins and bills and take into account the money available.
It should also avoid running out of any one kind of money; for example, if it has 2 of 10€ and 8 of 5€ it should not use the 2 of 10€ in the same change.
This is my dictionary:
d = {0.01: 10,
0.02: 5,
0.05: 2,
0.1: 10,
0.2: 5,
0.5: 2,
1: 5,
2: 5,
5: 2,
10: 4,
20: 5,
50: 1,
100: 0,
200: 0,
500: 0,
}
and this is my code so far:
def change(cost, given, d):
last_change = 0
change = given - cost #calculates how much we own the customer
if change == 0: #if we don't own the customer anything
return change
else:
if change in d and d[change] != 0: #if change is in the dictionary and its value is not 0 we can give it to the customer
return change
else:
euro = int(change)
cent = change - euro #calculates if we have to give any cents
if cent == 0: #if we only have to give bills
for item in d:
if item > last_change and item < change and d[item] != 0: #biggest bill we can give the customer
last_change = item
I don't know what to do next.
from math import *
dict1 = {0.01: 10,
0.02: 5,
0.05: 2,
0.1: 10,
0.2: 5,
0.5: 2,
1: 5,
2: 5,
5: 2,
10: 4,
20: 5,
50: 1,
100: 0,
200: 0,
500: 0,
}
def change(cost, given, dict1):
last_change = 0
change = given - cost
if change == 0:
print change
else:
if change in dict1 and dict1[change] != 0:
print change
else:
if change >= 500 and dict1[change] != 0:
a = floor( change / 500 )
print a, " --500 's"
change = change - ( a * 500 )
if change >= 200 and dict1[change] != 0:
b = floor( change / 200 )
print b, " --200 's"
change = change - ( b * 200 )
if change >= 100 and dict1[change] != 0:
c = floor( change / 100 )
print c, " --100 's"
change = change - ( c * 100 )
if change >= 50 and dict1[change] != 0:
d = floor( change / 50 )
print d, " --50 's"
change = change - ( d * 50 )
if change >= 20 and dict1[change] != 0:
e = floor( change / 20 )
print e, " --20 's"
change = change - ( e * 20 )
if change >= 10 and dict1[change] != 0:
f = floor( change / 10 )
print f, " --10 's"
change = change - ( f * 20 )
if change >= 5 and dict1[change] != 0:
g = floor( change / 5 )
print g, " --5 's"
change = change - ( g * 5 )
if change >= 2 and dict1[change] != 0:
h = floor( change / 2 )
print h, " --2 's"
change = change - ( h * 2 )
if change >= 1 and dict1[change] != 0:
i = floor( change / 1 )
print i, " --1 's"
change = change - ( i * 1 )
if change >= 0.5 and dict1[change] != 0:
j = floor( change / 0.5 )
print j, " --0.5 's"
change = change - ( j * 0.5 )
if change >= 0.2 and dict1[change] != 0:
k = floor( change / 0.2 )
print k, " --0.2 's"
change = change - ( k * 0.2 )
---------------------------
---------------------------
---------------------------
---------------------------
implement similar steps for 0.1,0.05,0.02,0.01
Output will be like this:
1 - 500 's
2 - 200 's
2 - 100 's
1 - 20 's
Here is some pseudo-code - there are some details you have to fill in:
amount = ... the input amount ...
change = {}
for denomination in [500, 200, 100, 50, ...]:
if amount == 0:
break
n = ... number of coins of this denomination to use
change[denomination] = n # store it
amount = amount - n*denomination # subtract from amount
# the dictionary change contains how to make the change

Categories