I have one problem. While drawing some sprites, why do I have a string named "undo" that goes to int()? (base 10)
import win32gui as w
import os as r
import time as t
import keyboard as kb
import random as ra
fw = w.GetForegroundWindow()
con = w.GetDC(fw)
r.system(f'mode con:cols={64} lines={32}')
r.system('color 07')
def CreateImag(readedlines,x,y):
for u in readedlines:
gg=u.split()
w.BitBlt(con,int(gg[0])+x,int(gg[1])+y,int(gg[2]),int(gg[3]),con,0,0,-1)
print('sprite draw')
t.sleep(2)
rl = []
r.system('cls')
while True:
print("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"+'='*64+"\n [from x from y f.x+x", end='')
print("f.y+y], for exit type \"exit\", for undo type \"undo\"")
if ag=='undo':
print(list.pop(-1))
break
ag = input('>>')
if ag=='exit':
file = open(f'image{ra.randint(0,100001)}.imag')
for aa in rl:
file.write(f'{aa}\n')
file.close()
rl.append(ag)
CreateImag(rl, 10, 10)
r.system('cls')
and then it gives this
Why is the string not appending?
I read the code and tried to understand the goal of the program, and here are the things I figured out that is done wrong. I stated them and provided solutions for them.
1
The reason why ag=input() is written after the if statement is because you cannot execute the undo command without doing anything. So, you need to do something first, and only then you can undo.
So, the error is caused, which is shown from the terminal pic is because, by you entering 'undo' as the first command, and since it didn't find any if statement, it appended the string 'undo' to rl (Which is not what we want).
Solution:
First, don't enter 'undo' as the first command in the program. (Although, it's the most easy fix but not recommended practice.)
Second, Shift the ag=input(">>") command directly under two print statements and change the code in the if statement as follows:
if ag=='undo':
if len(rl) > 0: # Condition to check if rl is not empty
print(rl.pop(-1))
break # Use continue instead?
I changed list.pop(-1 to rl.pop(-1) as recommended by #oluwafemi-sule
Advice/Recommendation: Usually, when we undo things we don't exit the program/loop. We generally don't break the loop. We skip the rest of the execution, so I fell you should use continue instead of break in the above code.
2
Suppose someone entered 'exit' instead of the required argument, hence the program performs the required steps before closing. Now, we want the program to terminate, and here in your code there is no termination statement.
If we don't terminate the program, 'exit' will be appended to the rl and again it'll cause an error. Hence, your other if statement should have a break statement. That would break the loop and hence complete the execution.
if ag=='exit':
file = open(f'image{ra.randint(0,100001)}.imag')
for aa in rl:
file.write(f'{aa}\n')
file.close()
break
Related
Slowly progressing with my learning with Python and would love a little hand with some code I've tried to create.
I previously had this program running with Global Variables to get a proof of concept to learn about passing variables between functions. Fully worked fine. However, rather than running the function and returning to the menu, it will just stop where I return the value and not progress back to the main menu I created. It is at the point of "return AirportDetailsGlobal".
I'm sure its a simple one, and as said - still learning!
Really appreciate any help on this!
Full code is on pastebin for further reference - pastebin 89VqfwFV
print("\nEnter airport code for overseas")
osCode = input()
airports = airData
for line in airports:
if osCode in line:
print (osCode, "Found\n\n")
print("Airport Name:",line[1])
OverseaCodeGlobal = osCode
x = int(line[2])
AirDataGlobal = x #changed here
return AirportDetailsGlobal
break
else:
print('Incorrect Choice')
menu()
menu()
If you do a return then your code goes back to where it was called from. If it wasn't called from anywhere (ie. you just ran that script directly) then calling return is in most ways equivalent to calling sys.exit(), ie. the program terminates. It'll never hit your break, leave the loop, or hit your call to menu().
Also, your indentation as given there isn't right, the else is at the same level as the for, not the if. I don't think that's the problem but you might hit it next. ;-)
The question I want to solve is to input two numbers and output the sum until the user finishes.(until the user inputs ctrl+d) Of course, I can solve the problem using sys.stdin, but I want to solve it using while.
The two codes below are my codes, the first one works well, but the second one doesn't work well. I don't know the difference between two codes. If anybody knows about the reason, please explain why..
from sys import stdin
# in this code, when I input ctrl d, program is finished
try:
while True:
a,b = map(int, stdin.readline().split())
print(a+b)
except:
exit()
from sys import stdin
# in this code, when I input ctrl d, 0 is printed out
try:
while 1:
print(sum(map(int, stdin.readline().split())))
except:
exit()
readline() doesn’t fail at EOF; it just returns an empty string. Splitting an empty string is fine. mapping int across an empty list is fine. Summing an empty iterable is fine (and results in zero).
In the first version, it’s the a, b unpacking that fails, but there’s no way to tell the difference when you throw away all the exception information and catch an overly broad class of exceptions at the same time.
Never use except; use except Exception to avoid catching low-level flow control exceptions. And if you feel the need to catch an exception you will otherwise ignore, consider logging the fact that you caught it for debugging purposes.
If you want to use sys.stdin, a for loop is better (line will continue to end with \n):
for line in stdin:
print(sum(map(int, line.split())))
If you want to use a while loop, input is better:
while True:
try:
line = input()
except EOFError:
break
print(sum(map(int, line.split())))
I wrote a Python script that executes an optimization and runs days to get a solution (due to the costly objective function). In all days work it will be sufficient to just stop the calculation at some point because the solution is good enough for me (but not for the optimization algorithm).
The problem is, I can always abort hitting Ctrl+C. But then there is no chance to nicely output the current best parameters, plot the data, save it etc. It would be great to stop the script in a controlled way after the next calculation of the objective function. So my thought was so question some variable (if user_stop=True) and programatically stop the optimization. But how to set such a variable? The python console is blocked during execution.
I thought about setting the content of a text file and reading it in each iteration but it's more than poor and hard to explain for other users of the script. Theoretically, I could also ask the user for an input but than the script won't run automatically (which it should until someone decides to stop).
Any ideas for my problem?
Basically that's it - stop the loop at some point but execute the print:
a = 0
while True:
a = a + 1
print(a)
If you poll your "variable" infrequently (say at most once every 20 seconds) then the overhead of testing for a file is negligible. Something like
import os
QUITFILE = "/home/myscript/quit_now.txt"
# and for convenience, delete any old QUITFILE that may exist at init time
... # days later
if os.path.isfile( QUITFILE)
# tidy up, delete QUITFILE, and exit
Then just echo please > home/myscript/quit_now.txt to tell your program to exit.
maybe you can use a do-while loop. holding your target in a varible
outside the loop and start looping the calculatio while <= your target calculation.
For Windows, I would use msvcrt.getch()
For example, this script will loop until a key is pressed, then, if it is q, prompt for the user to quit: (Note that the if statement uses 'short circuiting' to only evaluate the getch() - which is blocking - when we know that a key has been pressed.)
import msvcrt, time
while True: #This is your optimization loop
if msvcrt.kbhit() and msvcrt.getch() == 'q':
retval = raw_input('Quit? (Y/N) >')
if retval.lower() == 'y':
print 'Quitting'
break #Or set a flag...
else:
time.sleep(1)
print('Processing...')
If you place this if block at a point in the optimization loop where it will be frequently run, it will allow you to sop at a convenient point, or at least set a flag which you can check for at the end of each optimization run.
If you cannot place it somewhere where it will be frequently checked, then you can look at handling the KeyboardInterrupt raised by Ctrl-C
If you are running on Linux, or need cross-platform capability, have a look at this answer for getting the keypress.
I've written a simple console program in Python to perform basic logical calculations. However, when I use any of the single letters r,s,t or u (lower case) as variables, the console simply stalls. It doesn't produce an error or anything, and I end up having to Ctrl+C (Keyboard Interrupt in Linux). However, using any other letters in the alphabet aside from these four, my program runs fine.
Here is a snip of the exact moment where the console stalls:
And another snip of right after I Keyboard Interrupt after a stall, and a successful run of the program:
Here is the code segment referenced when I use a Keyboard Interrupt:
# Since my userExpression string is going
# to have a variable length, I had to
# initialize another variable to keep
# up with it and make sure that the while
# loop runs until the updated string ends.
truthList = truthMachine(propNum)
exprLength = len(userExpression)
while whileCounter < exprLength:
if userExpression[whileCounter] in varDict:
userExpression = userExpression.replace(userExpression[whileCounter],"truthList[i][" + str(varDict[userExpression[whileCounter]]) + "]")
exprLength = len(userExpression)
whileCounter += 1
This portion of the program is just supposed to switch the lower case letter variable with its value in a dictionary that I created. Again, it works with any other letter in the alphabet and I've thoroughly tested more complicated logical propositions and they all work if I'm not using r,s,t or u. Hopefully someone here has seen something similar.
I have my code and it does go run to infinity. What I want is that if on the unix command window if the user inputs a ctrl C, I want the program to finish the current loop it in and then come out of the loop. So I want it to break, but I want it to finish the current loop. Is using ctrl C ok? Should I look to a different input?
To do this correctly and exactly as you want it is a bit complicated.
Basically you want to trap the Ctrl-C, setup a flag, and continue until the start of the loop (or the end) where you check that flag. This can be done using the signal module. Fortunately, somebody has already done that and you can use the code in the example linked.
Edit: Based on your comment below, a typical usage of the class BreakHandler is:
ih = BreakHandler()
ih.enable()
for x in big_set:
complex_operation_1()
complex_operation_2()
complex_operation_3()
# Check whether there was a break.
if ih.trapped:
# Stop the loop.
break
ih.disable()
# Back to usual operation