power series expansion for sine function - python

import math
def sine_func(x):
power = 0
sine = x
add = (-1)**(power)*(x**(2*power+1))/(math.factorial((2*power+1)))
while math.fabs(add) > 1.0e-8:
sine += add
power += 1
add == (-1)**(power)*(x**2*power+1)/(math.factorial((2*power+1)))
return sine
print(sine_func(1))
Program is just running forever, any thoughts on where I made my error?

This line:
add_ == (-1)**(power_int)*(x**2*power_int+1))/(math.factorial((2*power_int+1)))
Neither refers to the previous variable ("add" != "add_") nor assigns any value - == is comparison in Python, not assignment. Try:
add = (-1)**(power_int)*(x**2*power_int+1))/(math.factorial((2*power_int+1)))

Your code is running fine for me (Python 3.3.3), after fixing the brackets and the initialization as sine=0.
import math
def sine_func(x):
power = 0
sine = 0
add = (-1)**(power)*(x**(2*power+1))/(math.factorial((2*power+1)))
while math.fabs(add) > 1.0e-8:
sine += add
power += 1
add = (-1)**(power)*(x**(2*power+1))/(math.factorial((2*power+1)))
return sine

Related

How to properly add gradually increasing/decreasing space between objects?

I've trying to implement transition from an amount of space to another which is similar to acceleration and deceleration, except i failed and the only thing that i got from this was this infinite stack of mess, here is a screenshot showing this in action:
you can see a very black circle here, which are in reality something like 100 or 200 circles stacked on top of each other
and i reached this result using this piece of code:
def Place_circles(curve, circle_space, cs, draw=True, screen=None):
curve_acceleration = []
if type(curve) == tuple:
curve_acceleration = curve[1][0]
curve_intensity = curve[1][1]
curve = curve[0]
#print(curve_intensity)
#print(curve_acceleration)
Circle_list = []
idx = [0,0]
for c in reversed(range(0,len(curve))):
for p in reversed(range(0,len(curve[c]))):
user_dist = circle_space[curve_intensity[c]] + curve_acceleration[c] * p
dist = math.sqrt(math.pow(curve[c][p][0] - curve[idx[0]][idx[1]][0],2)+math.pow(curve [c][p][1] - curve[idx[0]][idx[1]][1],2))
if dist > user_dist:
idx = [c,p]
Circle_list.append(circles.circles(round(curve[c][p][0]), round(curve[c][p][1]), cs, draw, screen))
This place circles depending on the intensity (a number between 0 and 2, random) of the current curve, which equal to an amount of space (let's say between 20 and 30 here, 20 being index 0, 30 being index 2 and a number between these 2 being index 1).
This create the stack you see above and isn't what i want, i also came to the conclusion that i cannot use acceleration since the amount of time to move between 2 points depend on the amount of circles i need to click on, knowing that there are multiple circles between each points, but not being able to determine how many lead to me being unable to the the classic acceleration formula.
So I'm running out of options here and ideas on how to transition from an amount of space to another.
any idea?
PS: i scrapped the idea above and switched back to my master branch but the code for this is still available in the branch i created here https://github.com/Mrcubix/Osu-StreamGenerator/tree/acceleration .
So now I'm back with my normal code that don't possess acceleration or deceleration.
TL:DR i can't use acceleration since i don't know the amount of circles that are going to be placed between the 2 points and make the time of travel vary (i need for exemple to click circles at 180 bpm of one circle every 0.333s) so I'm looking for another way to generate gradually changing space.
First, i took my function that was generating the intensity for each curves in [0 ; 2]
Then i scrapped the acceleration formula as it's unusable.
Now i'm using a basic algorithm to determine the maximum amount of circles i can place on a curve.
Now the way my script work is the following:
i first generate a stream (multiple circles that need to be clicked at high bpm)
this way i obtain the length of each curves (or segments) of the polyline.
i generate an intensity for each curve using the following function:
def generate_intensity(Circle_list: list = None, circle_space: int = None, Args: list = None):
curve_intensity = []
if not Args or Args[0] == "NewProfile":
prompt = True
while prompt:
max_duration_intensity = input("Choose the maximum amount of curve the change in intensity will occur for: ")
if max_duration_intensity.isdigit():
max_duration_intensity = int(max_duration_intensity)
prompt = False
prompt = True
while prompt:
intensity_change_odds = input("Choose the odds of occurence for changes in intensity (1-100): ")
if intensity_change_odds.isdigit():
intensity_change_odds = int(intensity_change_odds)
if 0 < intensity_change_odds <= 100:
prompt = False
prompt = True
while prompt:
min_intensity = input("Choose the lowest amount of spacing a circle will have: ")
if min_intensity.isdigit():
min_intensity = float(min_intensity)
if min_intensity < circle_space:
prompt = False
prompt = True
while prompt:
max_intensity = input("Choose the highest amount of spacing a circle will have: ")
if max_intensity.isdigit():
max_intensity = float(max_intensity)
if max_intensity > circle_space:
prompt = False
prompt = True
if Args:
if Args[0] == "NewProfile":
return [max_duration_intensity, intensity_change_odds, min_intensity, max_intensity]
elif Args[0] == "GenMap":
max_duration_intensity = Args[1]
intensity_change_odds = Args[2]
min_intensity = Args[3]
max_intensity = Args[4]
circle_space = ([min_intensity, circle_space, max_intensity] if not Args else [Args[0][3],circle_space,Args[0][4]])
count = 0
for idx, i in enumerate(Circle_list):
if idx == len(Circle_list) - 1:
if random.randint(0,100) < intensity_change_odds:
if random.randint(0,100) > 50:
curve_intensity.append(2)
else:
curve_intensity.append(0)
else:
curve_intensity.append(1)
if random.randint(0,100) < intensity_change_odds:
if random.randint(0,100) > 50:
curve_intensity.append(2)
count += 1
else:
curve_intensity.append(0)
count += 1
else:
if curve_intensity:
if curve_intensity[-1] == 2 and not count+1 > max_duration_intensity:
curve_intensity.append(2)
count += 1
continue
elif curve_intensity[-1] == 0 and not count+1 > max_duration_intensity:
curve_intensity.append(0)
count += 1
continue
elif count+1 > 2:
curve_intensity.append(1)
count = 0
continue
else:
curve_intensity.append(1)
else:
curve_intensity.append(1)
curve_intensity.reverse()
if curve_intensity.count(curve_intensity[0]) == len(curve_intensity):
print("Intensity didn't change")
return circle_space[1]
print("\n")
return [circle_space, curve_intensity]
with this, i obtain 2 list, one with the spacing i specified, and the second one is the list of randomly generated intensity.
from there i call another function taking into argument the polyline, the previously specified spacings and the generated intensity:
def acceleration_algorithm(polyline, circle_space, curve_intensity):
new_circle_spacing = []
for idx in range(len(polyline)): #repeat 4 times
spacing = []
Length = 0
best_spacing = 0
for p_idx in range(len(polyline[idx])-1): #repeat 1000 times / p_idx in [0 ; 1000]
# Create multiple list containing spacing going from circle_space[curve_intensity[idx-1]] to circle_space[curve_intensity[idx]]
spacing.append(np.linspace(circle_space[curve_intensity[idx]],circle_space[curve_intensity[idx+1]], p_idx).tolist())
# Sum distance to find length of curve
Length += abs(math.sqrt((polyline[idx][p_idx+1][0] - polyline[idx][p_idx][0]) ** 2 + (polyline [idx][p_idx+1][1] - polyline[idx][p_idx][1]) ** 2))
for s in range(len(spacing)): # probably has 1000 list in 1 list
length_left = Length # Make sure to reset length for each iteration
for dist in spacing[s]: # substract the specified int in spacing[s]
length_left -= dist
if length_left > 0:
best_spacing = s
else: # Since length < 0, use previous working index (best_spacing), could also jsut do `s-1`
if spacing[best_spacing] == []:
new_circle_spacing.append([circle_space[1]])
continue
new_circle_spacing.append(spacing[best_spacing])
break
return new_circle_spacing
with this, i obtain a list with the space between each circles that are going to be placed,
from there, i can Call Place_circles() again, and obtain the new stream:
def Place_circles(polyline, circle_space, cs, DoDrawCircle=True, surface=None):
Circle_list = []
curve = []
next_circle_space = None
dist = 0
for c in reversed(range(0, len(polyline))):
curve = []
if type(circle_space) == list:
iter_circle_space = iter(circle_space[c])
next_circle_space = next(iter_circle_space, circle_space[c][-1])
for p in reversed(range(len(polyline[c])-1)):
dist += math.sqrt((polyline[c][p+1][0] - polyline[c][p][0]) ** 2 + (polyline [c][p+1][1] - polyline[c][p][1]) ** 2)
if dist > (circle_space if type(circle_space) == int else next_circle_space):
dist = 0
curve.append(circles.circles(round(polyline[c][p][0]), round(polyline[c][p][1]), cs, DoDrawCircle, surface))
if type(circle_space) == list:
next_circle_space = next(iter_circle_space, circle_space[c][-1])
Circle_list.append(curve)
return Circle_list
the result is a stream with varying space between circles (so accelerating or decelerating), the only issue left to be fixed is pygame not updating the screen with the new set of circle after i call Place_circles(), but that's an issue i'm either going to try to fix myself or ask in another post
the final code for this feature can be found on my repo : https://github.com/Mrcubix/Osu-StreamGenerator/tree/Acceleration_v02

Problem with passing parameters and scopes, how can I fix this?

I'm making a password generator and strength checker (I'm new to coding), and my problem is that I can't get a function working that generates a password, calls the function that checks the strength, and have the strength checking function return back to the generating function.
Sorry if that was a bad explanation, please check the code for clarification.
Everything I've tried has partially worked or not worked at all, including using globals; even then I couldn't get it functioning properly.
import random
allchars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!$%^&*()_-=+"
def generatePassword():
generatedPass = ""
while points < 20:
for i in range(random.randint(8, 12)):
generatedPass += random.choice(allchars)
checkFunc(generatedPass)
points = 0
print(generatedPass)
def checkFunc(password):
numberofTriples = 0
consecChars = []
points = 0
allCrit = 0
(Redacted code that just calculates the points of the password)
(Redacted code that just calculates the points of the password)
return points
I want it to take the password it randomly generates, and check its strength, if it falls under a certain point threshold, to generate another until it is above the threshold, and print it.
Your generatedPassword function doesn't ever set the value of points in the while loop, thus it is never failing the condition of points < 20.
You'd want to change checkFunc(generatedPass) to points = checkFunc(generatedPass). This will properly set the value of points, and break from the loop.
So here are couple issues with your code:
import random
allchars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!$%^&*()_-=+"
def generatePassword():
#note you should have initiated ***points*** to 0 before using it in your while loop
generatedPass = ""
while points < 20:
for i in range(random.randint(8, 12)):
generatedPass += random.choice(allchars)
checkFunc(generatedPass)
points = 0 #points here has no value assignment you want to assign checkFunc()'s return value to points like this: points = checkFunc(generatedPass), or else you'll have an infinite loop.
print(generatedPass)
def checkFunc(password):
numberofTriples = 0
consecChars = []
points = 0
allCrit = 0
## (Redacted code that just calculates the points of the password)
## (Redacted code that just calculates the points of the password)
#Just be sure you have points variable here being updated according to the strength before you return it.
Here is an example of the same code but instead of strength, we are checking length:
import random
allchars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!$%^&*()_-=+"
def generatePassword():
generatedPass = ""
points = 0
while points < 20:
for i in range(random.randint(8, 12)):
generatedPass += random.choice(allchars)
points = checkLength(generatedPass)
print(generatedPass)
def checkLength(password):
return len(password)
Input:
generatePassword()
Output:
1Aid0%7tZYo0Ip(u_zeCQo=I
I hope you are doing great.
Here is a corrected code that should work:
Corrections done:
points was not declared before usage
points were not updated after call of checkFunc
N.B: to simulate the computing of the score, I used the random function.
Here is the full code:
import random
allchars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!$%^&*()_-=+"
def generatePassword():
generatedPass = ""
# We set points to 0 to start the while loop
points = 0
while points < 20:
for i in range(random.randint(8, 12)):
generatedPass += random.choice(allchars)
# We set points to the score computed by checkFunc to know if we need to trigger the generation of a new password.
points = checkFunc(generatedPass)
print(generatedPass)
def checkFunc(password):
numberofTriples = 0
consecChars = []
points = 0
allCrit = 0
# Simulating point computation
points = random.randint(10,30)
return points
I hope it helps,
Have a lovely day,
G

Python Filtering a Point Cloud with PhotoScan Based on a Threshold Value - basic python help needed

I'm trying to implement a filter with Python to sort out the points on a point cloud generated by Agisoft PhotoScan. PhotoScan is a photogrammetry software developed to be user friendly but also allows to use Python commands through an API.
Bellow is my code so far and I'm pretty sure there is better way to write it as I'm missing something. The code runs inside PhotoScan.
Objective:
Selecting and removing 10% of points at a time with error within defined range of 50 to 10. Also removing any points within error range less than 10% of the total, when the initial steps of selecting and removing 10% at a time are done. Immediately after every point removal an optimization procedure should be done. It should stop when no points are selectable or when selectable points counts as less than 1% of the present total points and it is not worth removing them.
Draw it for better understanding:
Actual Code Under Construction (3 updates - see bellow for details):
import PhotoScan as PS
import math
doc = PS.app.document
chunk = doc.chunk
# using float with range and that by setting i = 1 it steps 0.1 at a time
def precrange(a, b, i):
if a < b:
p = 10**i
sr = a*p
er = (b*p) + 1
p = float(p)
for n in range(sr, er):
x = n/p
yield x
else:
p = 10**i
sr = b*p
er = (a*p) + 1
p = float(p)
for n in range(sr, er):
x = n/p
yield x
"""
Determine if x is close to y:
x relates to nselected variable
y to p10 variable
math.isclose() Return True if the values a and b are close to each other and
False otherwise
var is the tolerance here setted as a relative tolerance:
rel_tol is the relative tolerance – it is the maximum allowed difference
between a and b, relative to the larger absolute value of a or b. For example,
to set a tolerance of 5%, pass rel_tol=0.05. The default tolerance is 1e-09,
which assures that the two values are the same within about 9 decimal digits.
rel_tol must be greater than zero.
"""
def test_isclose(x, y, var):
if math.isclose(x, y, rel_tol=var): # if variables are close return True
return True
else:
False
# 1. define filter limits
f_ReconstUncert = precrange(50, 10, 1)
# 2. count initial point number
tiePoints_0 = len(chunk.point_cloud.points) # storing info for later
# 3. call Filter() and init it
f = PS.PointCloud.Filter()
f.init(chunk, criterion=PS.PointCloud.Filter.ReconstructionUncertainty)
a = 0
"""
Way to restart for loop!
should_restart = True
while should_restart:
should_restart = False
for i in xrange(10):
print i
if i == 5:
should_restart = True
break
"""
restartLoop = True
while restartLoop:
restartLoop = False
for count, i in enumerate(f_ReconstUncert): # for each threshold value
# count points for every i
tiePoints = len(chunk.point_cloud.points)
p10 = int(round((10 / 100) * tiePoints, 0)) # 10% of the total
f.selectPoints(i) # selects points
nselected = len([p for p in chunk.point_cloud.points if p.selected])
percent = round(nselected * 100 / tiePoints, 2)
if nselected == 0:
print("For threshold {} there´s no selectable points".format(i))
break
elif test_isclose(nselected, p10, 0.1):
a += 1
print("Threshold found in iteration: ", count)
print("----------------------------------------------")
print("# {} Removing points from cloud ".format(a))
print("----------------------------------------------")
print("# {}. Reconstruction Uncerntainty:"
" {:.2f}".format(a, i))
print("{} - {}"
" ({:.1f} %)\n".format(tiePoints,
nselected, percent))
f.removePoints(i) # removes points
# optimization procedure needed to refine cameras positions
print("--------------Optimizing cameras-------------\n")
chunk.optimizeCameras(fit_f=True, fit_cx=True,
fit_cy=True, fit_b1=False,
fit_b2=False, fit_k1=True,
fit_k2=True, fit_k3=True,
fit_k4=False, fit_p1=True,
fit_p2=True, fit_p3=False,
fit_p4=False, adaptive_fitting=False)
# count again number of points in point cloud
tiePoints = len(chunk.point_cloud.points)
print("= {} remaining points after"
" {} removal".format(tiePoints, a))
# reassigning variable to get new 10% of remaining points
p10 = int(round((10 / 100) * tiePoints, 0))
percent = round(nselected * 100 / tiePoints, 2)
print("----------------------------------------------\n\n")
# restart loop to investigate from range start
restartLoop = True
break
else:
f.resetSelection()
continue # continue to next i
else:
f.resetSelection()
print("for loop didnt work out")
print("{} iterations done!".format(count))
tiePoints = len(chunk.point_cloud.points)
print("Tiepoints 0: ", tiePoints_0)
print("Tiepoints 1: ", tiePoints)
Problems:
A. Currently I'm stuck on an endless processing because of a loop. I know it's about my bad coding. But how do I implement my objective and get away with the infinite loops? ANSWER: Got the code less confusing and updated above.
B. How do I start over (or restart) my search for valid threshold values in the range(50, 20) after finding one of them? ANSWER: Stack Exchange: how to restart a for loop
C. How do I turn the code more pythonic?
IMPORTANT UPDATE 1: altered above
Using a better range with float solution adapted from stackoverflow: how-to-use-a-decimal-range-step-value
# using float with range and that by setting i = 1 it steps 0.1 at a time
def precrange(a, b, i):
if a < b:
p = 10**i
sr = a*p
er = (b*p) + 1
p = float(p)
return map(lambda x: x/p, range(sr, er))
else:
p = 10**i
sr = b*p
er = (a*p) + 1
p = float(p)
return map(lambda x: x/p, range(sr, er))
# some code
f_ReconstUncert = precrange(50, 20, 1)
And also using math.isclose() to determine if selected points are close to the 10% selected points instead of using a manual solution through assigning new variables. This was implemented as follows:
"""
Determine if x is close to y:
x relates to nselected variable
y to p10 variable
math.isclose() Return True if the values a and b are close to each other and
False otherwise
var is the tolerance here setted as a relative tolerance:
rel_tol is the relative tolerance – it is the maximum allowed difference
between a and b, relative to the larger absolute value of a or b. For example,
to set a tolerance of 5%, pass rel_tol=0.05. The default tolerance is 1e-09,
which assures that the two values are the same within about 9 decimal digits.
rel_tol must be greater than zero.
"""
def test_threshold(x, y, var):
if math.isclose(x, y, rel_tol=var): # if variables are close return True
return True
else:
False
# some code
if test_threshold(nselected, p10, 0.1):
# if true then a valid threshold is found
# some code
UPDATE 2: altered on code under construction
Minor fixes and got to restart de for loop from beginning by following guidance from another Stack Exchange post on the subject. Have to improve the range now or alter the isclose() to get more values.
restartLoop = True
while restartLoop:
restartLoop = False
for i in range(0, 10):
if condition:
restartLoop = True
break
UPDATE 3: Code structure to achieve listed objectives:
threshold = range(0, 11, 1)
listx = []
for i in threshold:
listx.append(i)
restart = 0
restartLoop = True
while restartLoop:
restartLoop = False
for idx, i in enumerate(listx):
print("do something as printing i:", i)
if i > 5: # if this condition restart loop
print("found value for condition: ", i)
del listx[idx]
restartLoop = True
print("RESTARTING LOOP\n")
restart += 1
break # break inner while and restart for loop
else:
# continue if the inner loop wasn't broken
continue
else:
continue
print("restart - outer while", restart)

How to run a calculation until true within a loop python

Hi so a quick question for spyder python 3.6
Say I have a simple while loop or if statement.
import random
from decimal import Decimal
usraccbal = (1000.01)
def rate():
ratecontents = (random.random() * (1.202 - 0.308) + 0.308)
return ratecontents
def newconvert(amount, rate):
a = (amount * rate)
return a, amount
b = rate()
rate1 = b
c = newconvert(usraccbal, rate1)
newcnvrt = (c[0])
prevusraccbal = (c[1])
#while or if here
if newcnvrt == prevusraccbal or newcnvrt < prevusraccbal:
#Continue calculating until newcnvrt > prevusraccbal
#then update values
else:
#Update values
usraccbal = newcnvrt
As you can see I would like to continue trying to get a newcnvrt which equals more than prevusraccbal either in an if or a while loop. So importantly it is constantly getting a new exchange rate and trying to use that.
The code is actually in a function normally which has root.after(3000,results) and is actioned by a button press
You should be able to replace .... < .... or .... == .... with .... <= .....
Just add a while with your condition. It executes until the condition is no longer True, and then the loop exits.
while newcnvrt <= prevusraccbal:
... # calculate until condition is false
usraccbal = newcnvrt

Attempting recursion in Python

I am attempting to make this program function in a recursive manner. The program takes in a csv file, calls on columns and takes the distance between the begin and end points. Within lengths of 10 miles, random samples are taken from the begin point and up to the end point. If the sample is still less than the end point - 2, a new sample is taken then miles down the road from varOut. It is my goal to have this program do this recursively. But im new to recursion. At this point the only output im getting is None, so im wondering what exactly is causing this to happen.
import csv
import math
import random as r
def yielderOut(length):
n = 0
rounder = 3
readerIn()
for col in csv.DictReader(open('2015_FILES_COMBINED.CSV')):
corridorRB = str(col['CORRIDOR_CODE_RB'])
begMi = float(col['FRFPOST'])
endMi = float(col['TRFPOST'])
dir_ = str(col['DIR'])
if abs(begMi - endMi) > length and dir_ == 'I':
varOut = round(r.uniform((math.ceil(begMi) + 1), (math.floor(begMi) + (length))), rounder)
if varOut < (endMi - 2):
return yielderOut(varOut + length), n + 1
else:
return corridorRB, round(begMi, rounder), round(endMi, rounder), 'Increasing', varOut, n
yielderOut(10)
data
CORRIDOR_CODE_RB FRFPOST TRFPOST DIR
C000001E 0 667.145996 I
C000001E 667.145996 0 D
C000003N 0 110.5 I
C000003N 110.5 0 D
It's hard to understand what your function does without any sample data...
But the reason you're getting None returned is that when the condition
abs(begMi - endMi) > length and dir_ == 'I'
is not true for any col then when the for loop is finished your function will return the default value of None.

Categories