My code is really simple:
import numpy
def f(x):
return x**2 +1
f_min=10
for x in numpy.arange(-1,10,0.1):
if f(x)<f_min :
f_min=f(x)
x_min=x
else:
print (x_min)
It gives me the correct result (x-->0) but not only once but alot of times. Why is that and how can I keep it from doing so?
Because you told it to. :-)
Your if statement reads:
if I have a new minimum, record the value and position;
otherwise, print the existing minimum.
Any time you don't find a new minimum, you print. Since this function has its minimum early in your range, you get a lot of output.
If you want the global minimum printed only once, then do it only once: move it outside of the loop.
for x in numpy.arange(-1,10,0.1):
if f(x)<f_min :
f_min=f(x)
x_min=x
print (x_min)
To fix this, move the print statement out of the for loop:
import numpy
def f(x):
return x**2 +1
f_min=10
for x in numpy.arange(-1,10,0.1):
if f(x)<f_min :
f_min=f(x)
x_min=x
print (x_min)
Why do this? Well, before, when you had the print statement in the for loop, each time the for loop went through, whenever the if statement was not true, it printed, so you got a bunch of printed things. Now, when you move it out of the for loop, it can only be printed once, and the program works as you expect.
Related
I might be asking a simple question. I have a python program that runs every minute. But I would like a block of code to only run once the condition changes? My code looks like this:
# def shortIndicator():
a = int(indicate_5min.value5)
b = int(indicate_10min.value10)
c = int(indicate_15min.value15)
if a + b + c == 3:
print("Trade posible!")
else:
print("Trade NOT posible!")
# This lets the processor work more than it should.
"""run_once = 0 # This lets the processor work more than it should.
while 1:
if run_once == 0:
shortIndicator()
run_once = 1"""
I've run it without using a function. But then I get an output every minute. I've tried to run it as a function, when I enable the commented code it sort of runs, but also the processing usage is more. If there perhaps a smarter way of doing this?
It's really not clear what you mean, but if you only want to print a notification when the result changes, add another variable to rembember the previous result.
def shortIndicator():
return indicate_5min.value5 and indicate_10min.value10 and indicate_15min.value15
previous = None
while True:
indicator = shortIndicator()
if previous is None or indicator != previous:
if indicator:
print("Trade possible!")
else:
print("Trade NOT possible!")
previous = indicator
# take a break so as not to query too often
time.sleep(60)
Initializing provious to None creates a third state which is only true the first time the while loop executes; by definition, the result cannot be identical to the previous result because there isn't really a previous result the first time.
Perhaps also notice the boolean shorthand inside the function, which is simpler and more idiomatic than converting each value to an int and checking their sum.
I'm guessing the time.sleep is what you were looking for to reduce the load of running this code repeatedly, though that part of the question remains really unclear.
Finally, check the spelling of possible.
If I understand it correctly, you can save previous output to a file, then read it at the beginning of program and print output only if previous output was different.
i have two functions with while loop, the results from the first loop is used in the second one as an until condition, but when calling the two functions in the main it execute only the first one and it doesn't even enter the second function it just give me the results of the first loop.
in the first function self.user_association() there is a linear optimization using PULP i though it is the one causing the problem but it was not because when calling the loop function block_estimated_access_link() in the second one it works just fine but my program does not work that way because as i said i use the results from the first loop in the second one. Here is the code, can someone tell me what am i doing wrong or what is the problem exactly?
def block_Estimation_ACCESS_LINK(self):
while (self.iteration < self.Iter_max):
self.User_association()
self.estimated_access_power()
self.calcul_alpha()
self.calcul_rate_am()
self.User_association()
self.iteration += 1
def block_bg_power_allocation(self):
EPS = 0.0000000000001
RamTot = 0
while (self.iteration < self.Iter_maxB):
self.calcul_power_backhaul()
print('backhaul Pok=', self.p_ok)
self.calcul_delta()
self.calcul_rok()
for i in self.station:
for j in self.users:
self.Ram = numpy.delete(self.Ram, self.Ram[0])
RamTot = sum(self.Ram)
if EPS <= (self.Rok[i] - sum(self.Ram[i])):
self.iteration += 1
def main(self):
self.block_Estimation_ACCESS_LINK()
self.block_bg_power_allocation()
In the first function you're doing this:
self.iteration += 1
And then, in the second function your stop condition is:
while (self.iteration < self.Iter_maxB):
So the first function would increment self.iteration to self.Iter_max. Now, if self.Iter_maxB is the same value as self.Iter_max, your second functions loop will never execute. I suspect that's what's happening here. Check those two varaibles.
Fix would be something like this if you want to execute both those loops the same number of time:
def main(self):
self.block_Estimation_ACCESS_LINK()
self.iteration = 0
self.block_bg_power_allocation()
Below is my code. Here, I am trying to read the variable gobs(x) from an input file and then I want to use it for other calculations, eg., computing error(x). But, I found, I can read it from input file properly within the loop, but when trying to use it outside the loop, only the first data is getting transferred. For all 100 data, which I read as gobs(x) inside the loop, it is showing the value of last data only, when I am using it outside the loop.
code started below
constant = 99
x0=50
z0=5
def gsyn (x):
return (constant*z0)/(z0**2+(x-x0)**2)
with open ('Grav_H_Cyln_v3_output.txt') as finp:
lines=finp.readlines()
for line in lines:
g=float(line)
x=line
def gobs (x):
return g
print (gobs(x)) # here, gobs(x) is printing properly
def error(x):
return (gsyn(x)-gobs(x))
for i in range (1, 100, 1):
x=i
print (error(x)) # here, only the first value of gobs(x) is coming
print ('stop')
This seems like a very odd solution to what is fundamentally a very simple problem. Make gobs a dictionary so you can set or retrieve gobs[x] at will.
gobs = dict()
with open ('Grav_H_Cyln_v3_output.txt') as finp:
lines=finp.readlines()
for line in lines:
g=float(line)
gobs[line] = g
print (gobs[line])
You could try creating a vector gobs[] outside the loop, and filling it up within the loop over lines.
That should do.
Instead of reassigning the value of x on each iteration of your loop, append i to a list that is declared outside of the if-block scope.
x = []
for i in range (1, 100, 1):
x.append(i)
print(x)
...
def splitMunipulation(p,threshold=5000):
runs=[];i=0
while i<len(p):
l=[];i+=1
print i,p[i]
while p[i]!=press(0,1,0):
l.append(p[i]);i+=1
else:
runs.append(l)#here i points to another (0,1,0)
return runs
...
record=splitMunipulation(record)
'''
Output:
1 <__main__.press instance at 0x046690A8>
File "H:\mutate.py", line 28, in splitMunipulation
while p[i]!=press(0,1,0):
IndexError: list index out of range
pressis a class
and since print p[i] works well,why p[i] is considered out of range?
Really don't get what's going on
'''
so, a few things..
Firstly, your code is very... unpythonic. This isn't C, so you don't need to use while loops for iteration, and don't use semicolons to separate multiple commands on one line in Python. Ever. Also, the while...else format is confusing and should be avoided.
If you look at the first few 'lines' of your while loop,
while i<len(p):
l=[];i+=1
You keep i below the length of p, but you immediately increase i's value by one. As such, when i=len(p) - 1, you will make i one larger, len(p). So when you try to access p[i], you are trying to access a value that doesn't exist.
Fixing those issues, you would get:
...
def splitMunipulation(p,threshold=5000):
runs=[]
for i in p:
l=[]
print i
if i != press(0,1,0):
runs.append(i)
return runs
...
record=splitMunipulation(record)
while p[i]!=press(0,1,0):
l.append(p[i]);i+=1
The variable i gets incremented in this loop until p[i]!=press(0,1,0). Since nothing is happening to make p longer, or to test that i is not greater than the length of p, it is easy to see how the index could get out of range.
len returns the length, not the last index. If l=[1,2,3], then len(l) returns 3, but l[3] is out of range.
so you should use
while i<len(p)-1
or better yet:
for i in range(len(p)):
def rot_dig(x):
y=''
output=[x]
listing=list(x)
for i in range(1,len(x)):
listing.append(listing[0])
del(listing[0])
for i in listing:
y=y+i
output.append(y)
y=''
return output
import math
def prime_is(x,prime):
for m in prime:
if m<=math.sqrt(x):
if x%m==0:
return False
else:
return True
prime=[2]
for x in range(3,1000000):
if prime_is(x,prime):
prime.append(x)
primestr=[]
for x in prime:
primestr.append(str(x))
sums=0
for x in primestr:
count=0
for y in rot_dig(x):
if y in primestr:
count+=1
if count==len(x):
sums+=1
else:
for y in rot_dig(x):
if y in primestr:
primestr.remove(y)
print sums
When run with the bold code the solutions miss the final rotation. So if it looks at say 1193, it includes 1193, 3119, 9311 but not 1931. I have spent a while trying to work out why but I don't get it.
I have since edited the code to make it much quicker and solved the problem I had by simply removing the block of code, but I can't understand why it happens since surely that block of code will only be executed on non circular primes.
It's probably because your outer loop is for x in primestr: and the marked code removes items from primestr. You don't want to change primestr while looping over it that way. You could use a loop like while i < len(primestr) instead.
Some other improvements would be to compute sqrt outside the loop; to use a list comprehension instead of a loop to create primestr; and especially to use string slicing in rot_dig, it's way more complicated than it needs to be.