Split long conditional expressions to lines - python

I have some if statements like:
def is_valid(self):
if (self.expires is None or datetime.now() < self.expires)
and (self.remains is None or self.remains > 0):
return True
return False
When I type this expressions my Vim automatically moves and to new line with this same indent as if line . I try more indent combinations, but validating always says thats invalid syntax. How to build long if's?

Add an additional level of brackets around the whole condition. This will allow you to insert line breaks as you wish.
if (1+1==2
and 2 < 5 < 7
and 2 != 3):
print 'yay'
Regarding the actual number of spaces to use, the Python Style Guide doesn't mandate anything but gives some ideas:
# No extra indentation.
if (this_is_one_thing and
that_is_another_thing):
do_something()
# Add a comment, which will provide some distinction in editors
# supporting syntax highlighting.
if (this_is_one_thing and
that_is_another_thing):
# Since both conditions are true, we can frobnicate.
do_something()
# Add some extra indentation on the conditional continuation line.
if (this_is_one_thing
and that_is_another_thing):
do_something()

put the linebreaks inside brackets
if ((....) and (...)):

You could invert the tests and return False on sub-sets of the test:
def is_valid(self):
if self.expires is not None and datetime.now() >= self.expires:
return False
if self.remains is not None and self.remains <= 0:
return False
return True
This way you can break up the long line of tests and make the whole thing a lot more readable.
Yes, you can use additional parentheses around your boolean tests to allow for newlines in the test, but readability suffers greatly when you have to go across multiple lines.

Related

syntax error using "if and elif" in python

I'll try to make a python program, convert roman to number. I believe my logic for the program is correct, but I get syntax error. maybe someone want's help me to fixed my program.
this my whole program:
bil = int(input())
if(bil<1 or bil>99):
print("no more than 3999")
else:
while(bil>=1000):
print("M")
bil-=1000
if(bil>=500):
elif(bil>500):
elif(bil>=900):
print("CM")
bil-=900
else:
print("D")
while(bil>=100):
if(bil>=400):
print("CD")
bil-400
else:
bil-=100
if(bil>=50):
elif(bil>=90):
print("XC")
bil-=90
else:
print("L")
bil-=50
while(bil>=10):
if(bil>=40):
print("XL")
bil-=40
else:
print("X")
bil-=10
if(bil>=5):
elif(bil==9)
print("IX")
bil-=9
else:
print("V")
bil-=5
while(bil>=1):
if(bil==4):
print("V")
bil-=4
else:
print("I")
bil-=1
I got syntax error in line :
elif(bil>500):
I need your opinion, thank you.
It shouldn't be elif, it should if bil>500. Because, you are trying to create a nested if condition and not an if/elif/else condition. So the final code in that block should be:
if(bil>=500):
if(bil>500):
if(bil>=900):
print("CM")
bil-=900
Also, I don't understand why you are comparing bil>500 two times at the same time. You could remove one if statement there
And there are many such if/elif blocks out there. You need to replace elif with if, if there is an indentation or you need to remove indentation for elif condition and write a condition for the if block too

Why do we need to add a "sleep" method to make a constant time attack succeed?

In this website: http://elijahcaine.me/remote-timing-attacks/ the author describes well what is a constant time attack and how to protect against this type of vulnerability.
But in the code that the author have done:
# secret.py
from time import sleep # Used to exaggerate time difference.
from sys import argv # Used to read user input.
def is_equal(a,b):
"""Custom `==` operator"""
# Fail if the strings aren't the right length
if len(a) != len(b):
return False
for i in range(len(a)):
# Short-circuit if the strings don't match
if a[i] != b[i]:
return False
sleep(0.15) # This exaggerates it just enough for our purposes
return True
# Hard-coded secret globals FOR DEMONSTRATIONS ONLY
secret = 'l33t'
# This is python for "If someone uses you as a script, do this"
if __name__ == '__main__':
try:
# The user got it right!
if is_equal(str(argv[1]), secret):
print('You got the secret!')
# The user got it wrong
else:
print('Try again!')
# The user forgot to enter a guess.
except IndexError:
print('Usage: python secret.py yourguess\n' \
+'The secret may consist of characters in [a-z0-9] '\
+'and is {} characters long.'.format(len(secret)))
I don't understand why we have to add this line to make the constant time attack succeed:
sleep(0.15) # This exaggerates it just enough for our purposes
In the website, the author says :
it exaggerates the time it takes to evaluate the is_equal function.
I've tried it, and we need a "sleep" method to make this attack succeed. Why we need to exaggerate the time?
Edit 1:
Why we need to exagerate the time ?
We need to exaggerate the time to showcase the time difference when two characters match and when they don't. So in this case, if the first character of a and b match, the method sleeps, then if the second characters don't match the function returns. This took 1 comparasion time + sleep(0.15) + 1 comparasion time.
On the other hand, if the first characters don't match, the functions returns in 1 comparasion time, so the attacker can see, if they match any character or not. The example uses this sleep to demonstrate this time difference.
For this to not happen, the is_equal function should be implemented in a way, that the response time of the function is static.
Using the example you provided:
def is_equal(a,b):
_is_equal = True
if len(a) != len(b):
return False
for i in range(len(a)):
if a[i] != b[i]:
_is_equal = False
return _is_equal
There is a built-in function in the secrets module which solves this problem.
compare_digest()
There are two possible paths to take in the "match" loop:
for i in range(len(a)):
# Short-circuit if the strings don't match
if a[i] != b[i]:
return False
sleep(0.15) # This exaggerates it just enough for our purposes
return True
if a[i] != b[i] evaluates as True - no match, exit from the function.
if a[i] != b[i] evaluates as False - match, continue to Sleep(0.15) before leaving function.
Sleep(0.15) if characters match adds significant time difference between these two paths. This in turn allows to simply use max of all attempts to identify correct character of the secret. Without this exaggeration you need to look for statistically significant differences in matching times.
Author mentioned this here:
Most important [for the author] we don't need to use StatisticsTM to
figure the secret, evaluating each input multiple times and
collecting/processing that timing data, it already takes about one
magnitude longer to evaluate a matching letter than it does to
evaluate a non-matching letter.
Use debug lines to see how times are different with and without sleep.
# Uncomment the following line for fun debug output
print('max {} min {}'.format(max(guess_times), min(guess_times)))
# Add this line to see full guess_times list
print(['{:.2f}'.format(elem) for elem in guess_times])

python boolean quest. for if statement

I tried this... but it doesn't work
question = input("do you want the program to start? Type Y/y to start: ")
y = TRUE
Y = TRUE
if(question == TRUE):
run statements
else:
what am i doing wrong? this doesn't work.
To answer your specific question, it is not working because of these issues:
TRUE is not a defined variable in python. True is.
question == TRUE won't work. See 1.
run statements isn't real code.
You need to put something in your else: block.
EDIT:
question can never become True in this code. – #adsmith
NOTE:
Just trying to be comprehensive with my coverage.
The boolean is True in Python, not true or TRUE. In any case, this doesn't do what you expect it to. This is what I'd do.
question = input("...")
if question.lower() == 'y': # or `question in ('y','Y'):` or `question.upper() == "Y":` or `question.casefold() == 'y':` or................
do_things
else:
handle_it
What you had written assigns the variables y and Y to some (undefined) variable TRUE. This will trigger a NameError since there is no such variable TRUE. If you had done:
y = True
Y = True
It still wouldn't have done what you wanted, since your input (fed into the variable question) is a string and those are variables. You could have done that with if globals()[question] but that's really bad practice, and COMPLETELY unnecessary in this situation.
As a side note -- there's never a reason to type == True. if foo will evaluate to True or False, which will fulfill the conditional on its own. It just does a needless compare :)
I think you probably want to use code something along these lines:
answer = raw_input("Do you want the program to start? Type Y/y to start: ")
if answer[0].lower() != "y": # first character not a "Y" or "y"?
exit()
rest of program...
1) You have five (5) spaces indenting your if clause. Should follow Generally Accepted Python Practices (GAPP) ;) (Yes, I just made this up. It may or may not become a thing :p) you should use four (4) spaces.
2) Try adding pass after else:
else:
pass
3) In Python, case matters. As such, boolean testing must be True or False (or 1/0 :p)
4) Don't you mean Y/N? Not Y/y?

Else statement executing even the IF statement is TRUE

I have a problem in Python language that is described in a title.
for slovo in slova:
if pygame.mouse.get_pressed()[0] and slovo["rect"].collidepoint(pygame.mouse.get_pos()):
for i in range (len(randRijec)):
if slovo["name"] in randRijec[i]:
if i == 0:
slovo1 = randRijec[i].upper()
prvoSlovo = 1
...
...
else:
pogresnoBrojac += 1
slova.remove(slovo)
So, even this IF statement is true, ELSE statement is being executed! However, else statement should be skipped if the if statement is fulfilled.
How to fix this issue?
p.s. I've had this problem few times before and I was not able to solve it...
You have a mixture of tabs and spaces in your code:
Running cat -A test.py (on Unix) yields
for slovo in slova:$
if pygame.mouse.get_pressed()[0] and slovo["rect"].collidepoint(pygame.mouse.get_pos()):$
for i in range (len(randRijec)):$
if slovo["name"] in randRijec[i]:$
if i == 0:$
slovo1 = randRijec[i].upper()$
prvoSlovo = 1$
^I^I^I^I^I^I...$
^I^I^I^I^I^I...$
else:$
pogresnoBrojac += 1$
slova.remove(slovo)$
The ^I indicate tabs.
Thus, the else block is not being interpreted as being at the indentation level on which it appears to be.
Your python code should never mix tabs and spaces for indentation. You can check that your script is not mixing tabs and spaces by running python -t script.py.
In Python you must commit to using either only spaces or only tabs for indentation. PEP8 recommends spaces-only indentation.
You can convert tabs to spaces using the reindent.py program.
So, even this IF statement is true, ELSE statement is being executed!
I can assure you that this is not what happens.
I notice that in the outline of your code the if is inside a for loop. Make sure that in your actual code the else is not accidentally lined up with the for instead of the if. I've seen this mistake more than once.
In Python, for-else is a valid construct. For example, the following is perfectly valid Python:
for i in range(10):
if i < 100:
pass
else:
print 'In else clause'
When run, this prints out In else clause.
Contrast this with the following, which doesn't print anything when run:
for i in range(10):
if i < 100:
pass
else:
print 'In else clause'
It's a question from a long time ago and I stumbled upon it as I was troubleshooting the very same issue - the solution was actually pretty silly and most probably was also the case - as it's a for loop it iterates through every list element, if even one of those elements doesn't fulfill the if condition, it will automatically trigger the else - pretty self-evident but easy to miss for beginners.
Well at least that was the problem in my case :)
Next solution fixed my problem:
for slovo in slova:
if pygame.mouse.get_pressed()[0] and slovo["rect"].collidepoint(pygame.mouse.get_pos()):
xy = 0
for i in range (len(randRijec)):
if slovo["name"] in randRijec[i]:
xy = 1
if i == 0:
slovo1 = randRijec[i].upper()
prvoSlovo = 1
break
if i == 1:
slovo2 = randRijec[i].upper()
drugoSlovo = 1
break
slova.remove(slovo)
if xy == 0:
pogresnoBrojac += 1
...
...
...
xy = 1
pygame.display.update()
time.tick(value)
So, I have just added that xy counter that makes my code work how it should work. When IF statement is met, xy becomes 1, if IF statement isn't fulfilled, xy is set to 0 and then this "else" statement executes. At the end of the code, xy is set to 1 again to prevent executing this "else" (if xy == 0) block.

error in binary search program in python

hi I m wrtng a very simple Python Program to implement Binary Search.
tup=input("enter tup:")
start=0
length=len[tup]
end=tup[length-1]
mid=(int(start)+int(end))/2
key=input("enter value to search")
def search(start,end,key):
if key==tup[mid]
print mid
else if key<tup[mid]
search(start,mid,key)
else if key>tup[mid]
search(mid,end,key)
else
return(-1)
I get an error as
File "binsearch.py", line 8
if key==tup[mid]
^
SyntaxError: invalid syntax
I believe I m missing something trivial but unable to figure out.! Let me know if u feel there are any other errors. thanks :)
if key==tup[mid]
^
needs a : at the end
|
v
if key==tup[mid]:
Same problem in the rest of the statement:
else if key<tup[mid]
^
search(start,mid,key)
else if key>tup[mid]
^
Aside:
Instead of else if consider using Python's neat elif construct, e.g.,
elif key<tup[mid]:
etc.
You need to end all statements that begin a new block with : (i.e. the statements where you increase the indentation level in the next line)
You need to replace else if X with elif X:
You should use raw_input instead of input as the latter evals whatever the user entered.
return is a statement, not a function, so you do not need () around the return value.

Categories

Resources