I have a complex project and I will try to simplify one of the main problem of the project. So there is the simplification:
We can Imagine a while loop like this:
while(condition):
statement1
statement2
statement3
...
statementn
In this loop there n statements, and each statement can be whatever(function, loop, if statement,...) and there is a condition in the loop, this condition i want to check it BEFORE the while loop do it. Because if the condition is respect since the first statement I have to wait until the end of the while to check if the condition is respect... So there is my question is possible to check the condition BEFORE the loop without have a check-function between EACH statements of the whileloop ?
Because in fact, it's work... BUT the code isn't clear, I really think this way we pollute my code and i want to work more efficiently and with a beautiful code, so how can I solve my problem without this constraint ?
PS: I think about event listener like javascript but i found poor information about them on python, but if there is a tool which act like event listener it would be great !
It sounds like you want to clean up all your if-then-break statements into a single function that handles the "checking" of the value of a. For that purpose you could use exceptions:
import random
class ItIsFiveException(Exception): pass
def check(a):
if a == 5:
raise ItIsFiveException
try:
a = 0
while(a != 5):
a = random.randint(1,5); check(a)
a = random.randint(1,5); check(a)
a = random.randint(1,5); check(a)
a = random.randint(1,5); check(a)
except ItIsFiveException:
print("I saw a five!")
You just have to define your own python Exception as a class, and the raise it in your manually-defined check(a) function. Then you can wrap your entire while loop in a try-except block and catch your exception.
I am not sure if I understand you right, but this is what I'd do:
flag = False
while not flag:
for i in range(4):
a = random.randint(1, 5)
if a == 4:
flag = True
break
I don't know exactly what it happens with "a" but if if you can chain the conditions and will stop when the first one fails
while(checkRandom()):
...
def checkRandom(a):
return random.randint(1,5) == 5 and random.randint(1,5)....
If you can loop the generation of random values you can use
while(a!=5):
for item in range(1, 5):
a=random.randint(1,5)
if a==5:
break
Related
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
I'm trying to learn python and while learning I've come across a bit of a problem.
import time
import pyautogui
def SendScript():
time.sleep(2)
with open('script.txt') as f:
lines = f.readlines()
for line in lines:
time.sleep(2)
pyautogui.typewrite(line.strip())
pyautogui.press('enter')
SendScript()
I'm trying to print something to the screen every second time the 'enter' key has been pressed, but I'm an extreme beginner so I really don't know how to do that. Could someone help me accomplish this task?
You could create a new boolean variable to track if the enter key has been pressed before. That way, every time the for loop iterates, the value of pressed switches and only when the value of pressed is True will it print something.
import time
import pyautogui
def SendScript():
pressed = False
time.sleep(2)
with open('script.txt') as f:
lines = f.readlines()
for line in lines:
time.sleep(2)
if pressed:
print("Something")
pressed = not pressed
pyautogui.typewrite(line.strip())
pyautogui.press('enter')
SendScript()
From a more step-back approach, you could do:
events=['event1', 'event2', 'event3', 'event4', 'event5', 'event6', 'event7', 'event8']
counter = 0
for event in events:
counter += 1
if counter % 2 == 0: # ie do stuff when divisible by 2, ie when its even
print('print what you want to be printed every second time')
else:
pass
Of course you are not looping through events like I do in this example. The point is counting the events and only doing stuff when this count is even.
As indicated in another answer already, a simple toggle can be implemented with a bool and then code which toggles it every time something happens:
thing = False
:
if happens(something):
thing = not thing
This is fine for toggling between two states. A more general approach which allows for more states is to use a numeric variable and a modulo operator:
times = 0
maxtimes = 12
:
if happens(something):
times += 1
if times % maxtimes == 1:
print("ding dong")
The modulo could be compared to 0 instead if you want to print on the 12th, 24th etc iterations instead of the first, the 13th, etc, or of course any other offset within the period if that's what you want.
Another useful trick is to flip-flop between zero and some other value.
value = 0
othervalue = 1234
:
if happens(something):
value = othervalue - value
Of course, you can flip-flop between any two values actually; subtract the current value from their sum to get the other one.
Needless to say, just toggling or flip-flopping isn't very useful on its own; you'd probably add some (directly or indirectly) user-visible actions inside the if happens(something): block too.
You could use a generator for this:
def everySecondTime():
while True:
yield "hi"
yield "not hi"
mygen = everySecondTime()
print(next(mygen))
print(next(mygen))
print(next(mygen))
print(next(mygen))
This prints
hi
not hi
hi
not hi
I'm sure it's clear to you how you could adapt this to do some other actions instead.
Whether this approach is better than just using a boolean is highly debatable, but I thought I'd leave it here so you could learn about generators (the yield keyword) if you want to.
The loop I created runs smoothly while asking which class to add and when dropping a class. However whenever I try to add a class after dropping one the program just ends instead of going back to the loop to add a class. Where did I go wrong in the program. Below is the code.
RegisteredCourses=[]
Registration=raw_input('Enter A to add a course, D to drop a course and E to exit.')
while Registration=='a':
Course=raw_input('What course do you want to add?')
RegisteredCourses.append(Course)
print RegisteredCourses
Registration=raw_input('Enter A to add a course, D to drop a course and E to exit.')
while Registration=='d':
DropCourse=raw_input('What course do you want to drop?')
RegisteredCourses.remove(DropCourse)
print RegisteredCourses
Registration=raw_input('Enter A to add a course, D to drop a course and E to exit.')
while Registration=='e':
print 'bye'
There isn't 1 outer loop to ask for user input, there are 3 inner loops. Which is wrong.
once selected, the option remains forever, because the while loop, once entered, loops forever (the value of the condition doesn't change within the loop)
Instead, make an infinite loop and change your while by if/elif, and ask the question only once:
RegisteredCourses=[]
while True:
Registration=raw_input('Enter A to add a course, D to drop a course and E to exit.')
if Registration=='a':
Course=raw_input('What course do you want to add?')
RegisteredCourses.append(Course)
print RegisteredCourses
elif Registration=='d':
DropCourse=raw_input('What course do you want to drop?')
RegisteredCourses.remove(DropCourse)
print RegisteredCourses
elif Registration=='e':
print 'bye'
break # exit the loop
Effectively...Registration as a variable doesn't change beyond its first input statement. This means that you're going to be stuck with whatever value you gave it when you started running this code.
Since it seems like you want menu-like functionality, a simpler way to accomplish this would be to split everything up into methods.
def add_course():
Course=raw_input('What course do you want to add?')
RegisteredCourses.append(Course)
print RegisteredCourses
# Other methods for other functions
Inside of the main crux of your application, you have a simple while True loop instead.
while True:
registration = raw_input('Enter A to add a course, D to drop a course and E to exit.')
if registration == 'a':
add_course()
# Other methods
if registration == 'e':
print 'bye'
break
Sorry about the title, this is a bit of a tough question to phrase. I'm using Python. Basically, I want the program to check a variable indefinitely. If the variable goes above 100 for example, I want code block A to run only once, and then I want the program to do nothing until the variable goes back below 100, then run code block B, and wait again until the variable goes back above 100, and then run block A again, and repeat.
The current setup I've written is as follows:
while on = True:
if value_ind >= 100:
open_time = time()
else:
close_time = time()
calculate_time_open(open_time, close_time)
The obvious problem here is that whichever if/else code block is true will run itself indefinitely, and create multiple entries in my lists for only one event. So, how would I make the code blocks run only once and then wait for a change instead of repeating constantly while waiting for a change? Thanks in advance.
You can use a state machine: your program is in one of two state: "waiting for a high/low value" and behaves appropriately:
THRESHOLD = 100
waiting_for_high_value = True # False means: waiting for low value
while True: # Infinite loop (or "while on", if "on" is a changing variable)
if waiting_for_high_value:
if value_ind >= THRESHOLD:
open_time = time()
waiting_for_high_value = False
else: # Waiting for a low value:
if value < THRESHOLD:
close_time = time()
calculate_time_open(open_time, close_time)
waiting_for_high_value = True
Now, you do need to update you test value value_ind somewhere during the loop. This is best done through a local variable (and not by changing a global variable as an invisible side effect).
PS: The answer above can be generalized to any number of states, and is convenient for adding some code that must be done continuously while waiting. In your particular case, though, you toggle between two states, and maybe there is not much to do while waiting for a change, so Stefan Pochmann's answer might be appropriate too (unless it forces you to duplicate code in the two "wait" loops).
How about this?
while True:
# wait until the variable goes over 100, then do block A once
while value_ind <= 100:
pass
<block A here>
# wait until the variable goes below 100, then do block B once
while value_ind => 100:
pass
<block B here>
This solves your repetition issue. You might better actually wait rather than constantly checking the variable, though, although it depends on what you're actually doing.
Added: Here it is with the actual blocks A and B from your code and using not, which maybe makes it nicer. One of them with parentheses which maybe highlights the condition better. (And with pass not on an extra line... I think that's ok here):
while True:
while not value_ind > 100: pass
open_time = time()
while not (value_ind < 100): pass
close_time = time()
calculate_time_open(open_time, close_time)
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?