Setting new variables in a while loop with calculations PYTHON - python

I'm running a population model, and the wrong numbers always come out because I'm setting the variables to new values, but then when I want to use the old variables, the loop automatically updates itself and uses the new ones.
juvenile_population = 10
adult_population = 10
senile_population = 1
juvenile_survival = 1
adult_survival = 1
senile_survival = 0
birth_rate = 2
generations = 5
counter = 0
while counter < generations:
juvenile_population = adult_population * birth_rate
adult_population = juvenile_population * juvenile_survival
senile_population = (adult_population * adult_survival) (senile_population * senile_survival)
total_population = juvenile_population + adult_population + senile_population
print("Juvenile: ",juvenile_population)
print("Adult: ",adult_population)
print("Senile: ",senile_population)
print("Total: ",total_population)
counter += 1
A friend said to set new named variables, but then after one loop, won't you get the same problem again? I want the variables to update, but only after they've been printed, if that makes sense.
Any suggestions?

You are overwriting the existing values with new values. With Python you can merge all four lines into one like this:
juvenile_population, adult_population, senile_population, total_population = adult_population * birth_rate, juvenile_population * juvenile_survival, (adult_population * adult_survival) (senile_population * senile_survival), juvenile_population + adult_population + senile_population
This will assign all the values at once, without overwriting them first.

Per #Selcuk, you could use variable unpacking directly, but even with nicer formatting it looks unwieldly:
juvenile_population, adult_population, senile_population, total_population = (adult_population * birth_rate,
juvenile_population * juvenile_survival,
(adult_population * adult_survival) (senile_population * senile_survival),
juvenile_population + adult_population + senile_population)
My suggestion would be to either write a helper function, and keep "like" values in a dictionary like so:
populations = {'juvenile': 10,
'adult': 10,
'senile': 1
}
survivals = {'juvenile': 1,
'adult': 1,
'senile': 0}
birth_rate = 2
generations = 5
def update_population(pops):
juvie = pops['adult'] * birth_rate
adults = pops['juvenile'] * survivals['juvenile']
seniles = pops['adult'] * survivals['adult'] + (pops['senile'] * survivals['senile'])
return {k:v for k,v in zip(['juvenile','adult','senile'],[juvie,adults,seniles])}
counter = 0
while counter < generations:
populations = update_population(populations.copy())
total_population = sum(populations.values())
print("Juvenile: ",populations['juvenile'])
print("Adult: ",populations['adult'])
print("Senile: ",populations['senile'])
print("Total: ",total_population)
counter += 1

Related

ErlangC Python Function

The objective of this is to increase Variable N by 1 until the result is equal to Variable SLT or just under SLT. I am new at python, but this is what I came up with:
from math import factorial
import math
{A = 10
N = 11
TGT = 20
SLT = .80
AHT = 180
}
def ErlangC():
if (N-A<=0):
return 1
else:
L = (A**N / factorial(N)) * (N / (N - A))
sum_ = 0
for i in range(N):
sum_ += (A**i) / factorial(i)
return (1 - (L / (sum_ + L)) * math.exp((-(N-A) * (TGT / AHT))))
ErlangC()
the idea behind it is making a while loop until the required service level is achieved, you can use pyworkforce which already has this function implemented, example:
Example:
from pyworkforce.queuing import ErlangC
erlang = ErlangC(transactions=100, asa=20/60, aht=3, interval=30, shrinkage=0.3)
positions_requirements = erlang.required_positions(service_level=0.8, max_occupancy=0.85)
print("positions_requirements: ", positions_requirements)
Output:
>> positions_requirements: {'raw_positions': 14,
'positions': 20,
'service_level': 0.8883500191794669,
'occupancy': 0.7142857142857143,
'waiting_probability': 0.1741319335950498}

Summing results from a monte carlo

I am trying to sum the values in the 'Callpayoff' list however am unable to do so, print(Callpayoff) returns a vertical list:
0
4.081687878300656
1.6000410648454846
0.5024316862043037
0
so I wonder if it's a special sublist ? sum(Callpayoff) does not work unfortunately. Any help would be greatly appreciated.
def Generate_asset_price(S,v,r,dt):
return (1 + r * dt + v * sqrt(dt) * np.random.normal(0,1))
def Call_Poff(S,T):
return max(stream[-1] - S,0)
# initial values
S = 100
v = 0.2
r = 0.05
T = 1
N = 2 # number of steps
dt = 0.00396825
simulations = 5
for x in range(simulations):
stream = [100]
Callpayoffs = []
t = 0
for n in range(N):
s = stream[t] * Generate_asset_price(S,v,r,dt)
stream.append(s)
t += 1
Callpayoff = Call_Poff(S,T)
print(Callpayoff)
plt.plot(stream)
Right now you're not appending values to a list, you're just replacing the value of Callpayoff at each iteration and printing it. At each iteration, it's printed on a new line so it looks like a "vertical list".
What you need to do is use Callpayoffs.append(Call_Poff(S,T)) instead of Callpayoff = Call_Poff(S,T).
Now a new element will be added to Callpayoffs at every iteration of the for loop.
Then you can print the list with print(Callpayoffs) or the sum with print(sum(Callpayoffs))
All in all the for loop should look like this:
for x in range(simulations):
stream = [100]
Callpayoffs = []
t = 0
for n in range(N):
s = stream[t] * Generate_asset_price(S,v,r,dt)
stream.append(s)
t += 1
Callpayoffs.append(Call_Poff(S,T))
print(Callpayoffs,"sum:",sum(Callpayoffs))
Output:
[2.125034975231003, 0] sum: 2.125034975231003
[0, 0] sum: 0
[0, 0] sum: 0
[0, 0] sum: 0
[3.2142923036024342, 4.1390018820809615] sum: 7.353294185683396

Python randomly generated walks give same outcome when graphed

from pylab import *
no_steps = 10000
number = random()
position = zeros(no_steps)
position[0] = 0
time = zeros(no_steps)
time[0] = 0
for i in range(1, no_steps):
time[i] = time[i-1] + 1
if number >= 0.5:
position[i] = position[i-1] + 1
number = random()
else:
position[i] = position[i-1] - 1
number = random()
plot(time, position)
number2 = random()
position2 = zeros(no_steps)
position2[0] = 0
time2 = zeros(no_steps)
time2[0] = 0
for t2 in range(1, no_steps):
time2[t2] = time[t2-1] + 1
if number2 >= 0.5:
position2[t2] = position2[t2-1] + 1
number2 = random()
else:
position2[t2] = position[t2-1] - 1
number2 = random()
plot(time2,position2)
This is supposed to generate random walks by generating a random number each time and checking the conditions. Therefore I assumed that if it works for one walk I can just add more of the same and put them all on the same graph at the end. However, apparently that's not how this works and the graphs that do end up being plotted are extremely similar with the difference in the positions being one of -2 for some reason. The code if I run the blocks separately from their own program will generate two completely different walks, it's just when I put them together that it stops working as intended. What exactly am I missing?
You've accidentally reused variables from the first plot:
for t2 in range(1, no_steps):
time2[t2] = time[t2-1] + 1
^^^^^ ^^^^
if number2 >= 0.5:
position2[t2] = position2[t2-1] + 1
number2 = random()
else:
position2[t2] = position[t2-1] - 1
^^^^^^^^^ ^^^^^^^^
number2 = random()
plot(time2,position2)
I would generate the random walk with a function so you don't have to worry about renaming variables like this:
import numpy
from pylab import *
no_steps = 10000
def random_walk(no_steps):
# 2 * [0, 1] - 1 -> [0, 2] - 1 -> [-1, 1]
directions = 2 * numpy.random.randint(0, 2, size=(1, no_steps)) - 1
positions = numpy.cumsum(directions)
positions -= positions[0] # To make it start from zero
return positions
time1 = numpy.arange(0, no_steps)
plot(time1, random_walk(no_steps))
savefig('1.png')
clf()
time2 = numpy.arange(0, no_steps)
plot(time2, random_walk(no_steps))
savefig('2.png')

Creating histogram bins from Django queries

I'm trying to create bins with the count of prices to be used for a histogram.
I want the bins to be 0-1000, 1000-2000, 2000-3000 and so forth. If I just do group by I get way to many different bins.
The code I've written seems to end in a infinite loop (or at least the script is still running after an hour). I'm not sure how to do it correctly. Here is the code I wrote:
from itertools import zip_longest
def price_histogram(area_id, agency_id):
# Get prices and total count for competitors
query = HousePrice.objects.filter(area_id=area_id, cur_price__range=(1000,30000)).exclude(agency_id=agency_id)
count = query.values('cur_price').annotate(count=Count('cur_price')).order_by('cur_price')
total = query.count()
# Get prices and total count for selected agency
query_agency = HousePrice.objects.filter(area_id=area_id, agency_id=agency_id, cur_price__range=(1000,30000))
count_agency = query_agency.values('cur_price').annotate(count=Count('cur_price')).order_by('cur_price')
total_agency = query_agency.count()
# Make list for x and y values
x_comp = []
y_comp = []
x_agency = []
y_agency = []
bin_start = 0
bin_end = 1000
_count_comp = 0
_count_agency = 0
for row_comp, row_agency in zip_longest(count, count_agency, fillvalue={}):
while bin_start < int(row_comp['cur_price']) < bin_end:
_count_comp += row_comp['count']
_count_agency += row_agency.get('count', 0)
bin_start += 1000
bin_end += 1000
x_comp.append(str(bin_start) + "-" + str(bin_end) + " USD")
x_agency.append(str(bin_start) + "-" + str(bin_end) + " USD")
y_comp.append(_count_comp/total)
y_agency.append(_count_agency/total_agency)
return {'x_comp': x_comp, 'y_comp': y_comp, 'x_agency': x_agency, 'y_agency': y_agency}
I'm using Python 3.5 and Django 1.10.
I'm a little late, but maybe the django-pivot library does what you want.
from django_pivot.histogram import histogram
query = HousePrice.objects.filter(area_id=area_id, cur_price__range=(1000,30000)).exclude(agency_id=agency_id
hist = histogram(query, cur_price, bins=[1000:30000:1000])

Python: create permutation of variables and operators

It's about a quite simple dice game with the following rules:
Chose a number between 1 and 100
Role three dices at once
Get as close as possible to the chosen number with the rolled points and the following options:
addition, subtraction, multiplication and/or
multiply the points with 10
Example 1:
Dice1 = 2, Dice2 = 3, Dice3 = 1, Chosen number = 5
Possible calculations:
2 + 3 * 1 = 5 or
2 * 3 - 1 = 5
Example 2:
Dice1 = 6, Dice2 = 2, Dice3 = 2, Chosen number = 42
Possible calculation:
(6*10) - (2*10) + 2 = 42
Goal of my program is to find the best possible ways for combining points and operators.
What I have so far:
import sys
import operator
a = int (sys.argv[1]) # Dice 1
b = int (sys.argv[2]) # Dice 2
c = int (sys.argv[3]) # Dice 3
d = int (sys.argv[4]) # Number to reach
class Calc():
def __init__(self):
self.resultsdict = dict()
self.werte = dict()
permutations = [[a,b,c], [a,c,b], [b,a,c], [b,c,a], [c,a,b], [c,b,a]]
for p in permutations:
aa = int(p[0])
bb = int(p[1])
cc = int(p[2])
self.compute(aa,bb,cc, d)
self.getBest(d, a, b, c)
def compute(self, a,b,c,d):
func = [a+b+c, a+b-c, a+b*c, (a+b)*c, (a-b)+c, a-(b+c), a-b-c, a-b*c, (a-b)*c, a*b+c, a*(b+c), a*b-c, a*(b-c), a*b*c]
func1 = ["a+b+c", "a+b-c", "a+b*c", "(a+b)*c", "(a-b)+c", "a-(b+c)", "a-b-c", "a-b*c", "(a-b)*c", "a*b+c", "a*(b+c)", "a*b-c", "a*(b-c)", "a*b*c"]
i = 0
while i < len(func):
dictkey = str(a)+str(b)+str(c)+ ", " +str(func1[i])
if not func[i] < 0 :
self.resultsdict[dictkey] = abs(d-func[i])
self.werte[dictkey] = func[i]
i += 1
def getBest(self, d, d1, d2, d3):
self.bestresults = dict()
keys = self.resultsdict.keys()
minval = 1000000000
for k in keys:
if int(self.resultsdict[k]) <= int(minval):
minval = int(self.resultsdict[k])
print("THE BEST COMBINATION FOR REACHING " + str(d) + " WITH " + str(d1) + ", " + str(d2) + ", " + str(d3) + " HAS BEEN GAINED WITH REST: " + str(minval))
for k in keys:
if int(self.resultsdict[k]) == int(minval):
ergebnis = self.werte[k]
print('\t' + "Combination: " + str(k) + ", Result: " + str(ergebnis))
t = Calc()
In func I hardcoded part of possible combinations.
Now I'm looking for an algorithm that generates these combinations automatically so I don't have to write them all down manually.
How would you do that?
You can use
python "itertools"
http://docs.python.org/2/library/itertools.html
to genrate all combinations of ['+','-','*','a','b','c',10]
So that you can get all possible combinations and then just filter out the valid expressions.
but it won't generate paranthesis.
You can include ['(',')']
but it will take more time.

Categories

Resources