I'm having a repeating try block issue - python

So i'm making a little app here, and I have try blocks (because I need to see if a file already exists or should be created). Although... my try block is repeating for some reason! I have ABSOLUTELY no idea why this is happening. Please help?
Also, the file is created fine :)
Code:
import sys
import time
Version = "V0.1"
def user():
PISBNdat = open("PISBN.dat", "w")
PISBNdat.write(Version)
cuser = raw_input("Please enter account username!")
for line in PISBNdat:
print "Test"
if cuser in line:
print("User already exists! Try again!")
user()
def start():
print "Hello and welcome to Plaz's PISBN!"
print "Opening file..."
time.sleep(0.8)
try:
fin = open("PISBN.dat", "r")
print "Success!"
fin.close()
user()
except:
time.sleep(0.5)
print "Did not recognize/find file!"
time.sleep(0.1)
print "Creating file!"
time.sleep(0.5)
try:
fout = open("PISBN.dat", "w")
print "Success!"
fout.close()
user()
except:
print "Failed!"
exit()
start()
And here's the output...:
Hello and welcome to Plaz's PISBN!
Opening file...
Did not recognize/find file!
Creating file!
Success!
Please enter account username! [This is what I entered: Plazmotech]
Failed!
Now obviously, since it said 'Failed!', it means its running my try block... because thats the only place it could output 'Failed!' So please help here!

Catch only the exceptions you want to handle. Note that printing "Failed!" and exiting is not handling an exception. Python's going to do that anyway, plus it's going to give you a buttload of information as to what happened, so why write extra code that does less and hides the cause of the problem?

As somebody (who just deleted his post) pointed out before, you call user() again in your user function, which is likely by mistake here.
I however believe your problems lie somewhere else. I assume you want "PISBN.dat" to contain a database where you look up for accounts. However, opening the file with only write permission will not help there. This causes your loop "for line in PISBNdat:" not working at all, so that the message "Test" did not appear.
It makes me think that "raw_input" failed and exception is caught. But as kindall pointed out, your code has some design flaws.

Here's an example of start() with correct try...except usage:
def start():
print "Hello and welcome to Plaz's PISBN!"
print "Opening file..."
time.sleep(0.8)
try: #try bloc contains minimum amount of code to catch the pertinent error.
f = open("PISBN.dat", "r")
print "Success!"
except IOError: #Only catch the exceptions you want to handle. IOError, in this case
f = None
if not f:
print "Did not recognize/find file!"
print "Creating file!"
try:
f = open("PISBN.dat", "w")
print "Success!"
except IOError:
print "Failed!"
exit()
f.close()
user() #Call user() after the file has been tested and/or created.

Related

Continue program even after assert fails

I want to continue even after the assert statement fails. Instead of saying "File not found" I would like to ignore it and continue my program. I am unable to figure out the syntax.
Overview of the script and problem faced :
This script is used for downloading pdf from urls which were written in a txt file. I had used assert to stop the program if the file wasn't found. It worked fine when all the urls in that txt file were working. The problem arose when there was a link which was dead and I didn't want the program to stop but instead continue to next link.
assert os.path.exists(of), "File not found at, " +str(of)
Program snippet :
for line in url_file:
stripped_line = line.split(',')
list_of_urls.append(stripped_line[2]+stripped_line[1])
driver.get(stripped_line[2]+stripped_line[1])
time.sleep(2)
of = download_dir+"/"+stripped_line[3]+".pdf"
fn = download_dir+"/"+stripped_line[0]+".pdf"
try:
assert os.path.exists(of), "File not found at, " +str(of)
except AssertionError:
pass
move(of, fn)
fns.append(stripped_line[0])
ofns.append(stripped_line[3])
status_file.write(stripped_line[0]+",File Downloaded\n")
url_file.close()
status_file.close()
driver.quit()
If you really want to use assert you can just us a try: except: block to catch the error thrown if the assertion is not True
try:
assert os.path.exists(of), "File not found at, " +str(of)
except AssertionError:
pass
However if your goal is just to print an error message if the file does not exist you can do:
if not os.path.exists(of):
print("File not found at, " +str(of))
if os.path.exists(of):
move(of, fn)
fns.append(stripped_line[0])
ofns.append(stripped_line[3])

Python Try with some Additional Logic

Hello I am trying to make 'try' only work under one condition:
try:
print "Downloading URL: ", url
contents = urllib2.urlopen(url).read()
except:
message = "No record retrieved."
print message
return None
I do not want the above code to work if the kwarg nodownload is True.
So I have tried the following:
try:
if nodownload:
print "Not downloading file!"
time.sleep(6)
raise
print "Downloading URL: ", url
contents = urllib2.urlopen(url).read()
except:
message = "No record retrieved."
print message
return None
The above always downloads no matter if the --nd argument is passed in the command line. The below always skips the file rather the argument is passed or not.
if not nodownload:
print "Not downloading file!"
time.sleep(6)
raise
print "Downloading URL: ", url
contents = urllib2.urlopen(url).read()
except:
message = "No record retrieved."
print message
return None
No download is input at the command line:
parser.add_argument('--nodownload', dest='nodownload', action='store_true',
help='This doesn't work for some reason')
You can use raise to cause an exception when you need to, thus making the try fail.
As others have mentioned, one can raise an exception.
Apart from using predefined exceptions, you may also use your own:
class BadFriend(Exception):
pass
class VirtualFriend(Exception):
pass
class DeadFriend(Exception):
pass
try:
name = raw_input("Tell me name of your friend: ")
if name in ["Elvis"]:
raise DeadFriend()
if name in ["Drunkie", "Monkey"]:
raise BadFriend()
if name in ["ET"]:
raise VirtualFriend()
print("It is nice, you have such a good friend.")
except BadFriend:
print("Better avoid bad friends.")
except VirtualFriend:
print("Whend did you shake hands with him last time?")
except DeadFriend:
print("I am very sorry to tell you, that...")
You can even pass some data via raised exception, but be careful not to abuse it too far (if
standard structures are working, use simpler ones).

Python password protection code not writing to file

I have attempted to get this code working in Python 3.5.1 but I am having problems with it not writing the hashed password and username to the file specified. Is there something I'm doing wrong?
import sys
import hashlib
import getpass
def main():
print ('\nUser & Password Storage Program v.01\n')
if input('The file will be modieifed if it exists.\nDo you wish to continue (Y/N): ') not in ('Y','y'):
sys.exit('\nChanges were not recorded\n')
user_name = input(str('Please Enter a User Name: '))
pwdinput = input("Now enter a password:").encode('utf-8')
password = hashlib.sha224(pwdinput).hexdigest()
try:
f = open(passfile.txt,'a+')
f.write(user_name + '\n')
f.write(password + '\n')
f.close()
except:
sys.exit('There was a problem writing to the file!')
print ('\nPassword safely stored in passfile.txt.\n')
main()
You don't have a variable called passfile.txt, and that is making the open call fail. It would be correctly opening the file if you surrounded it in quotes, like 'passfile.txt'
The reason this syntax error isn't obvious is because you have a catch all, and your program will just print 'There was a problem writing to the file!' instead.
Rather than catch all exceptions using except:, use the syntax except IOError:, as that will be thrown whenever there is an actual error in writing to the file.
The error is that your open() function is taking an object as a parameter, but you probably meant to use it as a string.
Also, you generally should use a with block when opening files.
try:
with open("passfile.txt",'a+') as f:
f.write("{}\n{}\n".format(user_name, password))
except Exception as e: # Use other exceptions for more accurate results
sys.exit('There was a problem writing to the file!\nError: {}'.format(str(e)))

Python: Reverse sentence and write it in another file

I'm trying to reverse the sentence and write it in another file but when I run it, it creates an empty reversed.txt file.
The following two lines are in file input:
Hello World
How is everyone doing?
The file output will have the lines:
dlroW olleH
?gniod enoyreve si woH
My code:
#!/usr/local/bin/python
name = raw_input("Enter name of file: ")
def Reverse(name):
try:
input_file=open(name,"r")
reversed = "reversed.txt"
output_file=open(reversed,"w")
list=input_file.readlines()
for i in range(0,len(list)):
d = int(len(list) - i)
output_file.write(list[d])
except IOError:
print("Cannot open file")
except:
print("Other errors")
else:
print("success")
finally:
print("prints always")
input_file.close()
output_file.close()
#returns reversed
Reverse(name)
When I run this it prints "Other errors". It creates the new file reversed.txt but it`s empty.
There are a couple of things wrong with your code snippet. But this should work better:
#!/usr/local/bin/python
name = raw_input("Enter name of file: ")
def Reverse(name):
try:
input_file=open(name,"r")
reversed = "reversed.txt"
output_file=open(reversed,"w")
for line in input_file.readlines():
output_file.write(line[-2::-1] + "\n")
except IOError:
print("Cannot open file")
except:
print("Other errors")
else:
print("success")
finally:
print("prints always")
input_file.close()
output_file.close()
#returns reversed
Reverse(name)
Here we iterate over the read lines and then use the fact that strings can be viewed as arrays to reverse each line.
EDIT
By using line[-2::-1] we avoid having the ending new line at the start of the line we write to the file. Then we append the "\n" so that each line is properly separated by the new line character.
You can try something like this:
lines=input_file.readlines()
for line in lines:
line = ''.join(list(reversed(line)))
output_file.write(line)
If I were to tell you what's wrong, without improving your implementation (which is definitely possible ;) ) I'd like to suggest a few things:
Indents are super important:
In your code just after the def you have a blank line. This means your function ends before it starts, and your try excepts are just 'floating'.
Your excepts aren't very helpful: You just print small information when catching exceptions. You have no idea why the exception is thrown. A better way to do this is print the exception with your own custom message. Something like:
try:
someCode()
except IOError as ioE:
print "Can't open file! - ", ioE # Change to print() for py3.x
except Exception as otherE:
print "Unknown error! - ", otherE
Initialize variables you intend to use: If you are using a variable, define it! Make sure any flow of loops/try-excepts will end up initializing your vairables. When in doubt, initialize as None (and check for None when using it). In your code, input_file is being used in finally. But if the input_file=open(name,"r") raises an exception, input_file will remain uninitialized causes another exception in finally.
Other than that your implementation can be improved from the other answers.
Hope this helps!

Writing Pythons Errors to a txt file

I am having trouble getting this to work correctly (obviously) - I am ALMOST there, and I have a good idea of WHY it is not working - just not sure how to make it work.
This is suppose to attempt to read a file into memory, if it fails it goes to the "except" clause of the block of code (that part is 'duh'). The error file prints: "<main.DebugOutput instance at 0x04021EB8>". What I want it to do is print the actual Error. Like a FileIOError or TraceBackError or whatever it is to that error file. This is just the beginning stages and I plan to add things like date stamps and to have it append, not write/create - I just need the actual error printed to the file. Advice?
import os, sys
try:
myPidFile = "Zeznadata.txt"
myOpenPID_File = open(myPidFile, "r") #Attempts to open the file
print "Sucessfully opened the file: \"" + myPidFile + "\"."
except:
print "This file, \"" + myPidFile + "\", does not exist. Please check the file name and try again. "
myFileErr = open("PIDErrorlog.txt", "w")
myStdError = str(sys.stderr)
myFileErr.write(myStdError)
myFileErr.close()
print "\nThis error was logged in the file (and stored in the directory): "
First, you should use a logging library. It will help you deal with different logging levels (info/warn/error), timestamps and more.
http://docs.python.org/library/logging.html
Second, you need to catch the error, and then you can log details about it. This example comes from the Python documentation.
import sys
try:
f = open('myfile.txt')
s = f.readline()
i = int(s.strip())
except IOError as (errno, strerror):
print "I/O error({0}): {1}".format(errno, strerror)
except ValueError:
print "Could not convert data to an integer."
except:
print "Unexpected error:", sys.exc_info()[0]
raise
See how it catches an IOError and assigns the error number and error message to variables? You can have an except block for each type of error you want to deal with. In the last (generic error) block, it uses sys.exc_info()[0] to get the error details.
http://docs.python.org/tutorial/errors.html
the problem is here:
myStdError = str(sys.stderr)
myFileErr.write(myStdError)
sys.stderr is a file-like interface defined in POSIX standards, called standard error, not "error text" that you can write to a file. So what you (probably) wanted to do is:
sys.stderr = myFileErr
This is the python equivalent to python your_python_sctipt.py 2> PIDErrorLog.txt in unix shell.
Use the logging module. The logging module have exception formatters that will help you print exceptions in a pretty way.
http://docs.python.org/library/logging.html
Like Kimvais says, your problem is:
myStdError = str(sys.stderr)
myFileErr.write(myStdError)
sys.stderr is a file handle to stderr (stdout is what print writes to).
You should do something like:
try:
...open file...
except IOError as (errno, strerror):
...open errfile...
errfile.write(strerror)
errfile.close()
Alison's answer is also very good and well written.

Categories