Is there a way to let Python generate multiple if statements? - python

I just need to add +30 to every number in every if statement. I need 36 of these, is there a way to let turtle make more if statements or something similar? I'm really stuck and the manual way would be crazy.
For example:
if 0 <= x <=30 and 0 <= y <= 30:
turtle.drawsstuff
if 30 <= x <=60 and 0 <= y <= 60:
etc.

Use a for loop.
for n in range(0, 36 * 30, 30):
if n <= x <= n + 30 and 0 <= y <= n + 30:
pass #do something

for n in range(0, 36 * 30, 30):
if n <= x <= (n+30) and n <= y <= (n+30):
pass # (do stuff)
range can take an optional third argument for the "step" value. For reference, see Python's documentation on range.

Related

Code simplification. Between positive and negative conditions

I have a question, how to simplify this code? I have the impression that it can be done in 3 conditional instructions and not in 6 ...
if (PID > 10 and self.last_pid > 0):
if (PID >= self.last_pid):
self.setKp(self.Kp+self.increase_val)
self.increase_val = self.increase_val*2
else:
percent_last = PID/self.last_pid*100
self.increase_val + (percent_last/100*self.increase_val)
self.setKp(self.Kp+self.increase_val)
if (PID < -10 and self.last_pid < 0):
if (PID <= self.last_pid):
self.setKp(self.Kp+self.increase_val)
self.increase_val = self.increase_val*2
else:
percent_last = PID/self.last_pid*100
self.increase_val + (percent_last/100*self.increase_val)
self.setKp(self.Kp+self.increase_val)
(Which might be simplified to:)
if A > 10 and B > 0:
if A >= B:
# do block A
else:
# do block B
if A < -10 and B < 0:
if A <= B):
# do block A
else:
# do block B
This should be equivalent to your two cases for positive and negative values:
if abs(A) > 10 and A * B > 0:
if abs(A) >= abs(B):
# do block A
else:
# do block B
Explanation:
abs(A) corresponds to A > 10 and A < -10 respectively
A * B > 0 means that both have the same sign and B != 0
abs(A) >= abs(B) means A <= B if both are < 0 and A => B if both are > 0
Now that's shorter and less repetitive, but whether it's easier to understand is for you to decide. In any case, you should add a comment explaining the code and that it is supposed to do.
With your original variables and procedures, this would be:
if abs(PID) > 10 and PID * self.last_pid > 0:
if abs(PID) >= abs(self.last_pid):
self.setKp(self.Kp+self.increase_val)
self.increase_val = self.increase_val*2
else:
percent_last = PID/self.last_pid*100
self.increase_val + (percent_last/100*self.increase_val)
self.setKp(self.Kp+self.increase_val)
Some more points that I just noticed:
your line self.increase_val + (percent_last / 100 * self.increase_val) does not do anything. I guess the + should be = or +=?
it is kind of pointless to first * 100 to get percent just to then / 100 again
it's odd how in one case you add increase_val to KP before increasing it, but after increasing it in the other case; is this intentional?
In fact, I think that this could be further simplified to this, provided that the inner if is used to cap the increase to the increase_val; not sure whether it should be added to Kp before or after being increased itself, though, or if that should actually depend on the case.
if abs(PID) > 10 and PID * self.last_pid > 0:
self.setKp(self.Kp + self.increase_val)
self.increase_val *= 1 + min(PID/self.last_pid, 1)
It's a bit long, but it takes less lines:
if (A > 10 and B > 10 and A>=B) or (A < -10 and B < 0 and A<= B):
#do block a
else:
#do block b
If you don't like it being so long, I would recommend turning each side of the or on the first line into a boolean variable and then using said variable in the if statement. Like so:
condA = A > 10 and B > 10 and A>=B
condB = A < -10 and B < 0 and A<= B
if condA or condB:
#do block a
else:
#do block b

Python - problem with changing values to groups

I have a dataset that has different attributes. One of these attributes is temperature. My temperature range is from about -30 to about 30 degrees. I want to do a machine learning study and I wanted to group the temperature into different groups. On a principle: below -30: 0, -30 to -10: 1 and so on. I wrote the code below, but it doesn't work the way I want it to. The data type is: int32, I converted it with float64.
dane = [treningowy_df]
for zbior in dane:
zbior['temperatura'] = zbior['temperatura'].astype(int)
zbior.loc[ zbior['temperatura'] <= -30, 'temperatura'] = 0
zbior.loc[(zbior['temperatura'] > -30) & (zbior['temperatura'] <= -10), 'temperatura'] = 1
zbior.loc[(zbior['temperatura'] > -10) & (zbior['temperatura'] <= 0), 'temperatura'] = 2
zbior.loc[(zbior['temperatura'] > 0) & (zbior['temperatura'] <= 10), 'temperatura'] = 3
zbior.loc[(zbior['temperatura'] > 10) & (zbior['temperatura'] <= 20), 'temperatura'] = 4
zbior.loc[(zbior['temperatura'] > 20) & (zbior['temperatura'] <= 30), 'temperatura'] = 5
zbior.loc[ zbior['temperatura'] > 30, 'temperatura'] = 6
For example: before the code is executed, record 1 has a temperature: -3, and after the code is applied, record 1 has a temperature: 3. why? A record with a temperature before a change: 22 after the change: 5, i.e. the assignment was executed correctly.
it looks like you're manipulating a dataframe. have you tried using the apply function?
Personally I would go about this as such (in fact, with a new column).
1. Write a function to process the value
def _check_temperature_range(x):
if x <= -30:
return 0
elif x <= -10:
return 1
# so on and so forth...
2. Apply the function onto the column of the dataframe
df[new_column] = df[column].apply(lambda x: _check_temperature_range(x))
The results should then be reflected in the new_column or old column should you use back the same column
I think your code is applying multiple times on the same row.
With you're exemple with the first line :
temp = -3 gives 2
but then temp = 2 gives 3
So I recommend to create a new column in your dataframe
I believe it has to do with the sequence of your code.
A record with temperature -3, gets assigned as 2 -
zbior.loc[(zbior['temperatura'] > -10) & (zbior['temperatura'] <= 0), 'temperatura'] = 2
Then in the next line, it is found again as being between 0 and 10, and so assigned again as 3 -
zbior.loc[(zbior['temperatura'] > 0) & (zbior['temperatura'] <= 10), 'temperatura'] = 3
One solution is to assign a number that doesn't make you "jump" a category.
So, for -3, I'd assign 0 so it sticks around.
After that you can do another pass, and change to the actual numbers you wanted, eg 0->3 etc.
If zbior is a pandas.DataFrame, you can use the map function
def my_func(x):
if x <= -30:
return 0
elif x <= -10:
return 1
elif x <= 0:
return 2
elif x <= 10:
return 3
elif x <= 20:
return 4
elif x <= 30:
return 5
else:
return 6
zbior.temperatura=zbior.temperatura.map(my_func)

Why is <= throwing an invalid syntax error in Python

I am very new to Python.
I'm trying to create a loop that compares int, between a range.
while counter < N:
x = randn()
if x >= 0 and <=1:
print('0-1')
counter = counter + 1
elif x < 0 and < -1
print("0- -1")
counter = counter + 1
I keep getting a syntax error on the <=
File "<ipython-input-35-1d74b6e80ea0>", line 9
if x >= 0 and <=1:
^
SyntaxError: invalid syntax
Any help on what I am missing would be greatly appreciated
The correct syntax is:
if x >= 0 and x <= 1:
The reason for your confusion is because you're writing it out as you would explain it to a person. X has to larger or equal to zero and smaller or equal to one.
In python however, these are two separate conditions, which need to be written out in full: x >= 0 and also x <= 1.
Alternatively, you have the option of combining the operators into a single condition like so:
if 0 <= x <= 1
Merging them this way turns the inequality into a single (compound) condition.
You should try writing it as if x >= 0 and x <= 1:. The and connects two separate statements, so you need to write the comparisons separately.

ForLoop in Python - iterator should augment by a multiplier factor of 100

I'm just trying to figure out how something like this (written in C) :
for (long long i = 100; i <= pow(10,length); i = i * 100){}
would be translated into Python 3.
As the last part, where the iterator should multiply itself by 100, is the point where I got stuck.
Any assistance would be appreciated.
Use a while loop instead:
i = 100
while i <= 10 ** length:
# ....
i *= 100
or use a generator function:
def powerranger(start, end, mult):
val = start
while val <= end:
yield val
val *= mult
and
for i in powerranger(100, 10 ** length, 100):
# ...
Rather than using a for loop, this C-type loop would be better translated using a while loop:
i = 100
while i <= pow(10, length):
# Use the value of `i` here.
i *= 100
Import lots of things:
from itertools import takewhile, count
for i in (100 ** x for x in takewhile(lambda y: y <= length // 2, count(1))):
# do something useful here
j = 100
for i in range(length):
j *= 100
print j # or other use of j
Not too pythonic but it works.

Chained comparison number range in Python

I have the following function:
def InRange(number):
return 5 <= number >= 1
I want this to say false if the number is not within the range of 1 to 5 using a chain comparison, but cannot seem to get this right.
Any suggestions?
You want it like this:
def InRange(number):
return 1 <= number <= 5
Note that you could also do:
def InRange(number):
return 0 < number < 6
Use this:
1 <= number <= 5
From docs:
x < y <= z is equivalent to x < y and y <= z, except that y is
evaluated only once (but in both cases z is not evaluated at all when
x < y is found to be false).
Your (incorrect)expression is actually equivalent to:
number >=5 and number >= 1
So, it is going to be True for any number between 1 to infinity:
Alternatively you can do (it seemed appropriate based on the function's name):
def InRange(number):
return number in range(1, 6)
For large numbers you should use:
def InRange(number):
return number in xrange(1, 10000000)

Categories

Resources