Random function with break command in Python - python

Write a function that accepts 3 numbers and calculates the average of the 3 numbers and raises the average to the second power (returns the average squared).
Write a loop that finds 3 random uniform numbers (0 to 1); sends the 3 numbers to the function and stops the loop when the value of the function is greater than 0.5625
I tried to figure out this 2 things but I am confused a little bit.
import random
a = random.random ()
b = random.random ()
c = random.random ()
def avenum(x1,x2,x3): # the average of the 3 numbers
z = (x1+x2+x3)/3.0
return z
y = avenum(a,b,c)
print 'the average of the 3 numbers = ',y
def avesec(x1,x2,x3): # the average of the second power
d = ((x1**2)+(x2**2)+(x3**2))/3.0
return d
y1 = avesec(a,b,c)
print 'the average of the second power = ',y1

The first question:
Write a function that accepts 3 numbers and calculates the average of the 3 numbers and raises the average to the second power (returns the average squared).
def square_of_average(x1, x2, x3):
z = (x1 + x2 + x3) / 3
return z ** 2 # This returns the square of the average
Your second question:
Write a loop that finds 3 random uniform numbers (0 to 1); sends the 3 numbers to the function and stops the loop when the value of the function is greater than 0.5625.
Assuming you want to write this in another function:
import random
def three_random_square_average():
z = 0 # initialize your answer
while(z <= 0.5625): # While the answer is less or equal than 0.5625...
# Generate three random numbers:
a, b, c = random.random(), random.random(), random.random()
# Assign the square of the average to your answer variable
z = square_of_average(a, b, c)
# When the loop exits, return the answer
return z
Another option:
import random
def three_random_squared_average():
while(True):
a, b, c = random.random(), random.random(), random.random()
z = square_of_average(a, b, c)
if(z > 0.5625):
break
return z
If you don't want a function:
import random
z = 0
while(z < 0.5625):
z = square_of_average(random.random(), random.random(), random.random())
print z

Firstly for 1) - you're raising the average to the second power... not each value. Otherwise you want the average of the second powers of the input values.
import random
a = random.random ()
b = random.random ()
c = random.random ()
def avenum1(x1,x2,x3): # the average of the 3 numbers
z = ((x1+x2+x3)/3.0)**2
return z
For 2): There are better ways but this is the most obvious.
def avenum1(x1,x2,x3): # the average of the 3 numbers
z = ((x1+x2+x3)/3.0)**2
return z
avg = 0:
while avg<0.5625:
a = random.random ()
b = random.random ()
c = random.random ()
avg = avenum1(a,b,c)
The better way:
avg = 0
while avg<0.5625:
list_ = [random.random() for i in range(3)]
avg = (sum(list_)/3.0)**2

Related

How to perform a ranking selection in this Genetic Algorithm

I'm building a Genetic Algorithm to maximize this function: x^5 - 10x^3 + 30x - y^2 + 21y.
The code must be in binary and the bounds for x and y are [-2.5, 2.5]. To generate the initial population I made a 16 bit string for both x and y where:
The first bit represents the signal [0 or 1]
The the second and third bit represents the integer part [00, 01 or 10]
The rest represents the float part
This is the function that generates the initial population:
def generate_population(n_pop):
population = list()
for _ in range(n_pop):
aux = list()
for _ in range(2):
signal = bin(randint(0, 1))[2:]
int_part = bin(randint(0, 2))[2:].zfill(2)
float_part = bin(randint(0, 5000))[2:].zfill(13)
aux.append((signal+int_part+float_part))
population.append(aux)
return population
I also made a function that returns the binary number into float:
def convert_float(individual):
float_num = list()
for i in range(2):
signal = int(individual[i][0])
int_part = int(individual[i][1:3], 2)
float_part = int(individual[i][3:], 2) * (10 ** -4)
value = round(int_part + float_part, 4)
if value > 2.5:
value = 2.5
if signal == 1:
value = value * (-1)
float_num.append(value)
return float_num
And lastly this function that calculate the fitness of each individual:
def get_fitness(individual):
x = individual[0]
y = individual[1]
return x ** 5 - 10 * x ** 3 + 30 * x - y ** 2 + 21 * y
This is my main function:
def ga(n_pop=10, n_iter=10):
population = generate_population(n_pop)
best_fitness_id, best_fitness = 0, get_fitness(convert_float(population[0]))
for i in range(n_iter):
float_population = [convert_float(x) for x in population]
fitness_population = [get_fitness(x) for x in float_population]
for j in range(n_pop):
if fitness_population[j] > best_fitness:
best_fitness_id, best_fitness = j, fitness_population[j]
print(f'--> NEW BEST FOUND AT GENERATION {i}:')
print(f'{float_population[j]} = {fitness_population[j]}')
selected_parents = rank_selection()
# childrens = list()
# childrens = childrens + population[best_fitness_id] # ELITE
After running the program I have something like this:
The population looks like: [['0000001100110111', '0000110111110101'], ['0010011111101110', '1000100101001001'], ...
The float population: [[0.0823, 0.3573], [1.203, -0.2377], ...
And the fitness values: [9.839066068044746, 16.15145434928624, ...
I need help to build the rank_selection() function, I've been stuck in this selection for 2 days. I know is something 1/N, 2/N etc and I've seen tons of examples in multiple languages but I could not apply any of them to this particular algorithm and it MUST be rank selecion.
I already know how to perform crossover and mutation.

Access 2D array slots by a number and vice versa

I want to map an array indices to a number, if this is an array:
grid2=[ ['a','b','c'],
['x','y','z']]
the number of 'a' is 1 and the number of 'b' is 2 and the number of 'c' is 3 and the number of 'x' is 4 and the number of 'y' is 5 and the number of 'z' is 6.
Here is my attempt, but it works only for squared arrays:
def i2d(r,c):
return r*height + c+1
here is the result which is not correct:
slot number of a=1 slot number of b=2 slot number of c=3
slot number of x=6 slot number of y=7 slot number of z=8
the correct result should be:
slot number of a=1 slot number of b=2 slot number of c=3
slot number of x=4 slot number of y=5 slot number of z=6
Also I want to write a convert method for mapping an integer to array index, here is my attempt:
def d2i(d):
r= int(d/height)-1
c= width - r
return (r,c)
but unfortunately, the final output is not correct. please help me in writing these two functions, I don't why my algorithm development aspect is turned off, maybe it is a side effect of using frameworks and libraries that they do the logic behind the scene, and I have used to call them.
Please tell me about the pythonish code if python has solved this by one of its operators or library functions, I want to learn it if such a thing exists.
Example : (input/output)
grid= [['a','b','c'],['x','y','z']]
#desired slot numbers=[1 ,2 ,3 ,4 ,5 ,6]
x = i2d(0,2)
#so x would be 3 if the we suppose number of a is 1
slot = d2i(3)
row=slot[0]
col=slot[1]
print(grid[row][col])
#the output is 'c'
Thanks in advance
UPDATE
I think calculation the slot number for an array index has different formula for when W=H and W>H and W<H:
def i2d(r,c,w,h):
if(h>w):
return r*h + c-r+1
if(h==w):
return r*h+c+1
if(h < w):
return r * w + c + 1
I cannot find any examples where this doesn't work.
def i2d(r, c, w):
return r * w + c + 1
def d2i(d, w):
div = int((d - 1) / w)
return (div, (d - 1) % w)
Is this what you're looking for? Outputs are commented throughout.
grid2 = [['a','b','c'], ['x','y','z']]
height = 2
width = 3
def i2d(r = None, c = None):
a = 1
if r is not None and c is not None:
for i in range(height):
for j in range(width):
if i == r and j == c:
return a
a += 1
print(i2d(0, 2)) # 3
def d2i(l, d):
for i in range(height):
for j in range(width):
if d == i2d(i, j):
return l[i][j]
print(d2i(grid2, 3)) # 'c'
Try this, it works for me :
width=3
height=3
def i2d(r,c):
return r*width + c+1
def d2i(d):
r= int(d/width)
#cover the h=w case
if (d%width==0 and width==height):
r=r-1
c= d%width-1
return (r,c)

Python Maclaurin series ln(x+1)

I have to write a program of Maclaurin series ln(x+1) on Python.
I need to use input function for two values: x, n. Then check if the values are legal and calculates the Maclaurin approximation (of order n) of the expression ln (1 + 𝑥) around the point x.
*Maclaurin series ln(x+1)= sum of ((-1)^n/n)*x^n
I stacked in the end when I calculate to expression, that what I wrote (after all the checks before):
for i in range(n + 1):
if i <= 1:
continue
else:
x = x + (((-1) ** (i + 1)) * (x ** i) / i)
When I input the test I get a number but it's a wrong answer.
Please help me understand what is wrong in this code.
Mathematically, the Maclaurin series is a bit beyond me, but I'll try to help. Two things.
First, you're storing all the successive values in x, as you calculate them; that means that the term for n = 5 (i = 5) is using a value of x which isn't the original value of the parameter x, but which has the successive results of the four previous computations stored in it. What you need to do instead is something like:
total = 0
for each value:
this term = some function of x # the value of x does not change
total = total + this term
Second, why aren't you interested in the term when i (or n) is equal to 1? The condition
if i <= 1:
continue
skips out the case when i equals 1, which evaluates to -x.
That should fix it, as far as I can see.
You are modifying the value of x in each iteration of the loop. Add and then store the partial sums in another variable.
def maclaurin_ln(x, n):
mac_sum = 0
for i in range(1, n + 1):
mac_sum += (((-1) ** (i + 1)) * (x ** i) / i)
return mac_sum
You can test this with the built-in function log1p to see how close they can get.
For ln(2) for different n,
from tabulate import tabulate
res = []
for n in [1, 10, 100, 1000, 10000]:
p = math.log1p(1)
q = maclaurin_ln(1, n)
res.append([1, n, p, q, q-p])
tabulate(res, headers=["x", "n", "log1p", "maclaurin_ln", "maclaurin_ln-log1p"])
x n log1p maclaurin_ln maclaurin_ln-log1p
--- ----- -------- -------------- --------------------
1 1 0.693147 1 0.306853
1 10 0.693147 0.645635 -0.0475123
1 100 0.693147 0.688172 -0.004975
1 1000 0.693147 0.692647 -0.00049975
1 10000 0.693147 0.693097 -4.99975e-05
For different x,
res = []
for x in range(10):
p = math.log1p(x/10)
q = maclaurin_ln(x/10, 100)
res.append([x/10, 1000, p, q, q-p])
tabulate(res, headers=["x", "n", "log1p", "maclaurin_ln", "maclaurin_ln-log1p"])
x n log1p maclaurin_ln maclaurin_ln-log1p
--- ---- --------- -------------- --------------------
0 1000 0 0 0
0.1 1000 0.0953102 0.0953102 1.38778e-17
0.2 1000 0.182322 0.182322 2.77556e-17
0.3 1000 0.262364 0.262364 -1.11022e-16
0.4 1000 0.336472 0.336472 0
0.5 1000 0.405465 0.405465 -1.11022e-16
0.6 1000 0.470004 0.470004 5.55112e-17
0.7 1000 0.530628 0.530628 -4.44089e-16
0.8 1000 0.587787 0.587787 -9.00613e-13
0.9 1000 0.641854 0.641854 -1.25155e-07

Turtle Graphics window not responding

I am attempting to translate a Julia set generator that I made previously to Python code. However, when the code is run, the turtle graphics window stops responding immediately and draws nothing. Have I done something horribly wrong or is there something I'm missing? Perhaps I'm asking too much of python to do in 1 frame. Please explain what is causing this to happen and how I can fix it. Thanks!
import turtle
import time
y_set = []
map_output = 0
iterations = 0
#turtle.hideturtle()
#turtle.speed(1)
generate a list of y-values
def y_set (r):
global y_set
y_set = []
for n in range ((360*2)+1):
y_set.append(n)
create a color value
def color (i, n):
output = map(i, 2, 10000, 0, 2500)
if output < 0:
output = 0
if output > 0:
output = 255
iterate on the x's
def repeat (n, r, i):
global iterations
global x
global y
aa = 0
ba = 0
ab = 0
a = 0
b = 0
for j in range (n):
iterations += 1
aa = a * a
bb = b * b
ab = 2 * a * b
a = ((aa - bb) + float(r))
b = (ab + float(i))
if (ab + bb) > 4:
break
turtle.setx(100 * x)
turtle.sety(100 * y)
color(iterations, n)
turtle.pendown()
turtle.penup()
Iterate on the y's
def Julia (s, r, i, d):
global iterations
global y_set
global x
global y
global a
global b
y_set(s)
while len(y_set) > 0:
y = y_set[0]/360
del y_set[0]
x = -1.5
for n in range (round((700/(float(r)+1))+1)):
a = x
b = y
iterations = 0
repeat(10**d, r, i)
x += ((1/240)*s)
user input
real = input('Real: ')
imag = input('Imaginary: ')
Julia (1, real, imag, 100)
turtle.done()
There are too many problems with this code to focus on an algorithm error. When I try to run it, I get, TypeError: 'int' object is not iterable. Specific issues:
The i argument here is being passed a number:
iterations += 1
...
color(iterations, n)
...
def color(i, n):
output = map(i, 2, 10000, 0, 2500)
but Python's map function (and Julia's) expects a function as its first argument:
map(func, *iterables)
and it returns a list of the results of applying func to iterables but you treat the result as a scalar value:
output = map(i, 2, 10000, 0, 2500)
if output < 0:
output = 0
if output > 0:
output = 255
The color() function never uses its second argument, and never returns anything!
The variables a & b here are being treated as globals, set but not used, as if prepared for use by repeat():
global a
global b
...
a = x
b = y
iterations = 0
repeat(10 ** d, r, i)
but the a & b used by repeat() are locals initialized to zero:
a = 0
b = 0
You have a function and global variable with the same name y_set!
And your globals are out of control.

Why my while loop failed (python)?

I'm a new learner of python programming. Recently I'm trying to write a "tool" program of "dynamic programming" algorithm. However, the last part of my programe -- a while loop, failed to loop. the code is like
import numpy as np
beta, rho, B, M = 0.5, 0.9, 10, 5
S = range(B + M + 1) # State space = 0,...,B + M
Z = range(B + 1) # Shock space = 0,...,B
def U(c):
"Utility function."
return c**beta
def phi(z):
"Probability mass function, uniform distribution."
return 1.0 / len(Z) if 0 <= z <= B else 0
def Gamma(x):
"The correspondence of feasible actions."
return range(min(x, M) + 1)
def T(v):
"""An implementation of the Bellman operator.
Parameters: v is a sequence representing a function on S.
Returns: Tv, a list."""
Tv = []
for x in S:
# Compute the value of the objective function for each
# a in Gamma(x), and store the result in vals (n*m matrix)
vals = []
for a in Gamma(x):
y = U(x - a) + rho * sum(v[a + z]*phi(z) for z in Z)
# the place v comes into play, v is array for each state
vals.append(y)
# Store the maximum reward for this x in the list Tv
Tv.append(max(vals))
return Tv
# create initial value
def v_init():
v = []
for i in S:
val = []
for j in Gamma(i):
# deterministic
y = U(i-j)
val.append(y)
v.append(max(val))
return v
# Create an instance of value function
v = v_init()
# parameters
max_iter = 10000
tol = 0.0001
num_iter = 0
diff = 1.0
N = len(S)
# value iteration
value = np.empty([max_iter,N])
while (diff>=tol and num_iter<max_iter ):
v = T(v)
value[num_iter] = v
diff = np.abs(value[-1] - value[-2]).max()
num_iter = num_iter + 1
As you can see, the while loop at the bottom is used to iterate over "value function" and find the right answer. However, the while fails to loop, and just return num_iter=1. As for I know, the while loop "repeats a sequence of statements until some condition becomes false", clearly, this condition will not be satisfied until the diff converge to near 0
The major part of code works just fine, as far as I use the following for loop
value = np.empty([num_iter,N])
for x in range(num_iter):
v = T(v)
value[x] = v
diff = np.abs(value[-1] - value[-2]).max()
print(diff)
You define value as np.empty(...). That means that it is composed completely of zeros. The difference, therefore, between the last element and the second-to-last element will be zero. 0 is not >= 0.0001, so that expression will be False. Therefore, your loop breaks.

Categories

Resources