Python try-except-except - python

Im gonna include the description of the task this code is supposed to do in case someone needs it to answer me.
#Write a function called "load_file" that accepts one
#parameter: a filename. The function should open the
#file and return the contents.#
#
# - If the contents of the file can be interpreted as
# an integer, return the contents as an integer.
# - Otherwise, if the contents of the file can be
# interpreted as a float, return the contents as a
# float.
# - Otherwise, return the contents of the file as a
# string.
#
#You may assume that the file has only one line.
#
#Hints:
#
# - Don't forget to close the file when you're done!
# - Remember, anything you read from a file is
# initially interpreted as a string.
#Write your function here!
def load_file(filename):
file=open(filename, "r")
try:
return int(file.readline())
except ValueError:
return float(file.readline())
except:
return str(file.readline())
finally:
file.close()
#Below are some lines of code that will test your function.
#You can change the value of the variable(s) to test your
#function with different inputs.
#
#If your function works correctly, this will originally
#print 123, followed by <class 'int'>.
contents = load_file("LoadFromFileInput.txt")
print(contents)
print(type(contents))
When the code is tested with a file which contains "123", then everything works fine. When the website loads in another file to test this code, following error occurs:
[Executed at: Sat Feb 2 7:02:54 PST 2019]
We found a few things wrong with your code. The first one is shown below, and the rest can be found in full_results.txt in the dropdown in the top left:
We tested your code with filename = "AutomatedTest-uwixoW.txt". We expected load_file to return the float -97.88285. However, it instead encountered the following error:
ValueError: could not convert string to float:
So Im guessing the error occurs inside the first except statement, but i don't understand why. If an error occurs when the value inside a file is being converted to float, shouldnt the code just go to the second except statement ? And in the second except it would be converted to string, which will work anyway ? I'm guessing i misunderstand something about how try-except(specified error)-except(no specified error) works.
Sorry for long post.

shouldnt the code just go to the second except statement ?
Nope: this "flat" try/except statement works only for the first try block. If an exception occurs there, the except branches catch this exception and straight away evaluate the appropriate block. If an exception occurs in this block, it's not caught by anything, because there's no try block there.
So, you'd have to do a whole lot of nested try/except statements:
try:
do_this()
except ValueError:
try:
do_that()
except ValueError:
do_this()
except:
do_that_one()
except:
# a whole bunch of try/except here as well
You may need to add an extra level of nesting.
This is terribly inefficient in terms of the amount of code you'll need to write. A better option might be:
data = file.readline()
for converter in (int, float, str):
try:
return converter(data)
except:
pass
Note that if you do converter(file.readline()), a new line will be read on each iteration (or, in your case, in any new try/except block), which may not be what you need.

No, only one of those except blocks -- the first one matching the exception -- will be executed. The behavior you are describing would correspond to
except ValueError:
try:
return float(file.readline())
except:
return str(file.readline())

def load_file(filename):
file=open(filename, "r")
try:
val = file.readline()
return int(val)
except ValueError:
try:
return float(val)
except:
return str(val)
finally:
file.close()

Related

I'm doing a hash verification project, and after I store the hash, and want to verify it, it returns false after I check it against the new hash

I create a hash, and store it in a .txt file (will encrypt it later), but when I create a new hash and check against the stored one, It returns false even though the hashes are the exact same. Help?
Relevant code: `
def testHash(expectedHash, testHash):
try:
if expectedHash == testHash:
return True
else:
return False
except Exception as err:
print("Error, unkonwn if valid hash.")
print(f"Error: {err}")
return False
`
Here's the code to store the hash:
def storeHash(hash):
stored_hashes = open("storedHashes.txt", "a")
stored_hashes.write(hash+"\n")
stored_hashes.close()
And here's the code to get the stored hash:
def getHash(index):
stored_hashes = open("storedHashes.txt", "r+")
read_hash = stored_hashes.readlines(index)
clean_read_hash = ' '.join(read_hash) #required to remove the [] and \n
return clean_read_hash
Note: it returns no errors, but does not return True either.
Complete code can be found here: https://pastebin.com/2XpbmXaP
password: hashVerify
I know the file exertion on line 18 is .hs, that was a side track that led noewere, it should be .txt
Fun little fact, Windows and other OS's allow any file extension, and just use the things after the . if they don't know what it is as the type.
Note: the content of the testFile is "test for hashes"
It's hard to say for certain since you only define the functions and don't show the logic of calling them. But it looks like you just need to fix your call to stored_hashes.readlines. Change stored_hashes.readlines(index) to stored_hashes.readlines()[index]; as mentioned in a comment, the parameter accepted by stored_hashes.readlines (which returns a list, by the way) is not the index of the list but rather the total number of characters to allow to be read. That means, with your current code, you are always comparing the "test hash" to a list of every hash in your text file.

Ignoring KeyError while writing to file with dask.to_csv

I have a dataframe, which is not loaded into memory (and it should stay like that).
At some point in the script I apply a conversion with a dictionary to one of the dataframe columns in the following manner:
df['identifier'] = df.identifier.map(lambda identifier: alias_dict[str(identifier)],
meta=('identifier', str))
KeyError exceptions are not found out on this stage but just when I use to_csv so I try to handle them
try:
dd.to_csv(intersection_df, output, header=None, index=None, single_file=True, sep='\t')
except KeyError as err:
print(f'Unmatched key {err.args[0]}')
In case I encounter a KeyError, the writing to the file is stopped - is there a way to make the writing continue even if I get an exception at that stage?
The best thing to do, if you want to skip or remediate the failing lines but keep writing, is to put your try/except into the mapping function
def alias(identifier):
try:
return alias_dict[str(identifier)]
except KeyError:
return identifier
df['identifier'] = df.identifier.map(alias, meta=('identifier', str))
In this case, failures are passed through unchanged. You could turn them into None and filter them out in a second step, or the two steps could be combined with map_partitions.

python3 exception invalid syntax error

I recently started learning python3, and I am trying to write an exception.
I have this line, which is a list of words.
I want to match the word create to the list, sometimes it's there sometimes its not. When it's not there I get this error:
Traceback (most recent call last):
File "sub_process.py", line 17, in <module>
if (line.index("create")):
ValueError: 'create' is not in list
and I am fine with that. This is expected. So I thought if I wrote an exception to it the script could just continue on and keep doing stuff. So I an exception below and all its suppose to do is nothing. Catch the error and continue on.
line = line.split()
if line.index("create"):
print("basd");
except ValueError:
print("123");
But everytime i try to compile this I get syntax error at "except" and I am not sure why. It looks perfectly normal compared against all the tutorials that I could find.
Rather than using index, you should just be using the in operator, which returns a simple boolean:
if "create" in line:
print("basd")
else:
print("123")
This will not raise an exception so there is no need for try/except.
if/except is not a valid construct. Use try/except:
line = line.split()
try:
if line.index('create'):
print('basd')
except ValueError:
print("123")
Alternatively, you could avoid the exception and the try/except altogether:
line = line.split()
if 'create' in line:
print('basd')
else:
print("123")
You need to add try before the if statement:
line = line.split()
try: # added 'try'
if line.index("create"):
print("basd");
except ValueError:
print("123");
Also note, you don't need the semicolons at the end of statements, and it is generally frowned upon when they are used in that way.
As an alterintave to #Rosemans solution, you can do that all on one line:
print('basd') if "create" in line else print("123")
#use try block..
line = line.split()
try:
if line.index("create"):
print("basd")
except ValueError:
print("123")

Maya/Python - function which loops though text file except for some lines

I've found some pieces of answers here and there but I can't figure the exact way to build what I want. Thank you by advance if you can help.
I have multiple text files, all built the same way but with different informations in each one of them. I'd like to loop over each file and return the infos in it line by line. On the other hand I have some booleans which define if one specific line in the file has to be skipped or not. For example: "if boolean1 is true and lineInTheCorrespondingFile = 40, then skip that line, else, read it but skip line 36 and 37 instead".
The thing is I don't know how to proceed for the function knows which file is opened and which line is read and if the it has to skip it or not. Knowing that I need each line to be returned independently at the end of the function.
And here is my code so far:
def locatorsDatas (self):
preset = cmds.optionMenu ("presetMenu", q = 1, v = 1)
rawFile = presetsDir + preset.lower() + ".txt"
with open(rawFile) as file:
file.seek (0)
for lineNum, line in enumerate(file, start = 1):
if lineNum > 8 : # Skip header
locator = eval (line)
locName = locator[0]
xVal = locator[1]
yVal = locator[2]
zVal = locator[3]
locScale = locator[4]
locColor = locator[5]
if locator == "":
break
return (locName, xVal, yVal, zVal, locScale, locColor)
I don't know what values I should pass into the function to make it skip the lines I want, knowing that I can't write it directly into it since each file doesn't break at the same lines.
Oh, and it only return one line of the file instead of each separately.
Hope it's clear and you can help me, thanks again.
I see a number of issues with your code.
To start with, you're always returning the data from line 8 and never any other data. If you have many values you want to extract from the file, you might want to make your function a generator by using a yield statement rather than a return. Then the calling code can access the data with a for loop or pass the generator to list or another function that accepts any iterable.
def locatorsDatas(self):
# ...
lineNum, line in enumerate(file, start=1):
# ...
yield results
If you can't use a generator but need your function to return successive lines, you'll need to save the file iterator (or perhaps the enumerate iterator wrapped around it) somewhere outside the function's scope. That means you won't need to reopen the file every time the function is called. You could do something like:
def __init__(self):
preset = cmds.optionMenu ("presetMenu", q = 1, v = 1)
rawFile = presetsDir + preset.lower() + ".txt"
self.preset_file_enumerator = enumerate(open(rawFile)) # save the iterator on self
def locatorsDatas(self):
try:
lineNum, line = next(self.preset_file_enumerator) # get a value from the iterator
# do your processing
return results
except StopIteration:
# do whatever is appropriate when there's no more data in the file here
raise ValueError("no more data") # such as raising an exception
The next issue I see is how you're processing each line to get the separate pieces of data. You're using eval which is a very bad idea if the data you're processing is even slightly entrusted. That's because eval interprets its argument as Python code. It can do anything, including deleting files from your hard drive! A safer version is available as ast.literal_eval, which only allows the string to contain Python literals (including lists, dictionaries and sets, but not variable lookups, function calls or other more complicated code).
You also have an error check that I don't think will do what you intend. The if locator == "" test is probably placed too late to avoid errors from the earlier lines extracting data from the eval'd line. And the break statement you run will cause the function to exit without returning anything more. If you just want to skip blank lines, you should put the check at the top of the loop and use continue rather than break.
Now finally we can get to the issue you're asking about in the title of the question. If you want to skip certain lines based on various flags, you just need to check those flags as you're looping and do a continue to skip past the lines you don't want to read. I don't entirely understand what you were asking about regarding how the flags are passed, but assuming you can give them as arguments, here's a sketch of how the code could look:
def locatorsDatas(self, skip_40=False, skip_50=True):
# open file, ...
for lineNum, line in enumerate(file, start = 1):
if (not line or
lineNum < 8 or
skip_40 and lineNum == 40 or
skip_50 and lineNum == 50):
continue
# parse the line
yield result
Obviously you should use your own flag names and logic rather than the ones I've made up for my example code. If your logic is more complicated, you might prefer using separate if statements for each flag, rather than packing them all into one lone conditional like I did.

Python trying to write and read class from file but something went horribly wrong

Considering this is only for my homework I don't expect much help but I just can't figure this out and honestly I can't get my head around what's going wrong. Usually I have an idea where the problem is but now I just don't get it.
Long story short: I'm trying to create a valid looking telephone number within a class and then loading it onto an array or list then later on save all of them as string into a folder. When I start the program again I want it to read the file and re-create my class and load it back into the list. (Basically a very simple repository).
Problem is even though I evaluate the stored phone number in the exact same way I validate it as input data ... I get an error which makes no sens.
Another small problem is the fact that when I re-use the data for some reason it creates white spaces in the file which in turn messes my program up badly.
Here I validate phone numbers:
def validateTel(call_ID):
if isinstance (call_ID, str) == True:
call_ID = call_ID.replace (" ", "")
if (len (call_ID) != 10):
print ("Telephone numbers are 10 digits long")
return False
for item in call_ID:
try:
int(item)
except:
print ("Telephone numbers should contain non-negative digits")
return False
else:
if (int(item) < 0):
print ("Digits are non-negative")
After this I use it and other non-relevant (to this discussion) data to create an object (class instance) and move them to a list.
Inside my class I have a load from string and a load to string. What they do is take everything from my class object so I can write it to a file using "+" as a separator so I can use string.split("+") and write it to a file. This works nicely, but when I read it ... well it's not working.
def load_data():
f = open ("data.txt", "r")
ch = f.read()
contact = agenda.contact () # class object
if ch in (""," ","None"," None"):
f.close()
return [] # if the file is empty or has None in some way I pass an empty stack
else:
stack = [] # the list where I load all my class objects
f.seek(0,0)
for line in f:
contact.loadFromString(line) # explained bellow
stack.append(deepcopy(contact))
f.close()
return stack
In loadFromString(line) all I do is validate the line (see if the data inside it at least looks OK).
Now here is the place where I validate the string I just read from the file:
def validateString (load_string):
string = string.split("+")
if len (string) != 4:
print ("System error in loading from file: Program skipping segment of corrupt data")
return False
if string[0] == "" or string[0] == " " or string[0] == None or string[0] == "None" or string[0] == " None":
print ("System error in loading from file: Name field cannot be empty")
try:
int(string[1])
except:
print("System error in loading from file: ID is not integer")
return False
if (validateTel(str(string[2])) == False):
print ("System error in loading from file: Call ID (telephone number)")
return False
return True
Small recap:
I try to load the data from file using loadFromString(). The only relevant thing that does is it tries to validate my data with validateString(string) in there the only thing that messes me up is the validateTel. But my input data gets validated in the same way my stored data does. They are perfectly identical but it gives a "System error" BUT to give such an error it should have also gave an error in the validate sub-program but it doesn't.
I hope this is enough info because my program is kinda big (for me any way) however the bug should be here somewhere.
I thank anyone brave enough to sift trough this mess.
EDIT:
The class is very simple, it looks like this:
class contact:
def __init__ (self, name = None, ID = None, tel = None, address = None):
self.__name = name
self.__id = ID
self.__tel = tel
self.__address = address
After this I have a series of setters and getters (to modify contacts and to return parts of the abstract data)
Here I also have my loadFromString and loadToString but those work just fine (except maybe they cause a small jump after each line (an empty line) which then kills my program, but that I can deal with)
My problem is somewhere in the validate or a way the repository interacts with it. The point is that even if it gives an error in the loading of the data, first the validate should print an error ... but it doesn't -_-
You said I just can't figure this out and honestly I can't get my head around what's going wrong. I think this is a great quote which sums up a large part of programming and software development in general -- dealing with crazy, weird problems and spending a lot of time trying to wrap your head around them.
Figuring out how to turn ridiculously complicated problems into small, manageable problems is the hardest part of programming, but also arguably the most important and valuable.
Here's some general advice which I think might help you:
use meaningful names for functions and variables (validateString doesn't tell me anything about what the function does; string tells me nothing about the meaning of its contents)
break down problems into small, well-defined pieces
specify your data -- what is a phone number? 10 positive digits, no spaces, no punctuation?
document/comment the input/output from functions if it's not obvious
Specific suggestions:
validateTel could probably be replaced with a simple regular expression match
try using json for serialization
if you're using json, then it's easy to use lists. I would strongly recommend this over using + as a separator -- that looks highly questionable to me
Example: using a regex
import re
def validateTel(call_ID):
phoneNumberRegex = re.compile("^\d{10}$") # match a string of 10 digits
return phoneNumberRegex.match(call_ID)
Example: using json
import json
phoneNumber1, phoneNumber2, phoneNumber3 = ... whatever ...
mylist = [phoneNumber1, phoneNumber2, phoneNumber3]
print json.dumps(mylist)
For starters, don't name your variables after reserved keywords. Instead of calling it string, call it telNumber or s or my_string.
def validateString (my_string):
working_string= my_string.split("+")
if len (working_string) != 4:
print ("System error in loading from file: Program skipping segment of corrupt data")
return False
The next line I don't really get - what is this If chain for? Accounting for bad data or something? Probably better to check for good data; bad data can come in infinite variety.
if working_string[0] == "" or working_string[0] == " " or working_string[0] == None or working_string[0] == "None" or string[0] == " None":
print ("System error in loading from file: Name field cannot be empty")
try:
int(string[1])
except:
print("System error in loading from file: ID is not integer")
return False
if (validateTel(str(working_string[2])) == False):
print ("System error in loading from file: Call ID (telephone number)")
return False
return True
Also, to give you a hint - you may want to look into regular expressions.
wow - many problems maybe connected to your problem, also as I commented - I suspect your problem is with turning the telnumber object to string.
f is is file object it won't be equal to anything. if you want to check if the file exists you should just do try /except around the file creation block. like:
try:
f = open ('data.txt','r') #also could call c=f.read() and check if c equals to none.. not really needed because you can cover an empty file in the next part iterating over f
except:
return
for line in f:
all sorts of stuff
return stack
don't use string reserved word and checking with negative numbers is very strange -is this part of the homeework? and why check by turning to int? this could also break your code - since the rest is a string.
all that said - I still suspect your main problem is with the way you turning the object into string data, It would never remain an instance of unless you used json/pickle/something else to strigfy. an object instance isn't just the class str.
and another thing - keep it simple, python is (also) about elegent and simple coding and you are trying to throw brute force with everything you know at a simple problem. focus, relax and rewrite the program.
I don't perceive all the logic.
For the moment , I can say you that you should correct the code of load_data() as follows:
def load_data():
f = open ("data.txt", "r")
ch = f.read()
contact = agenda.contact () # class object
if ch in (""," ","None"," None"):
f.close()
return [] # if the file is empty or has None in some way I pass an empty stack
else:
stack = [] # the list where I load all my class objects
f.seek(0,0)
for line in f:
contact.loadFromString(line) # explained bellow
stack.append(deepcopy(contact))
f.close()
return stack
I don't see how the file-like handler f could ever have a value None or string, so I think you want to test the content of the file -> f.read()
But then, the file's pointer is at its end and must be moved back to the start -> seek(0,0)
I will progressively add complementing considerations when I will understand more the problem.
edit
To test if a file is empty or not
import os.path
if os.path.isfile(filepath) and os.path.getsize(filepath):
.........
If the file with path filepath doesn't exist, getsize() raises an error. So the preliminary test if os.path.isfile() is necessary to avoid the second condition test to be evaluated.
But if your file can contain the strings "None" or " None" (really ? !), the getsize() will return 4 or 5 in this case.
You should avoid to manage with files containing these kinds of useless data.
edit
In validateTel(), after the instruction if isinstance (call_ID, str) == True: you are sure that call_ID is a string. Then the iteration for item in call_ID: will produce only item being ONE character long, hence it's useless to test if (int(item) < 0): , it will never happen; it could be possible that there is a sign - in the string call_ID but you won't detect it with this last condition.
In fact, as you test each character of callID, it is enough to test if it is one of the digits 0,1,2,3,4,5,6,7,8,9. If the sign - is in calml_ID, it will be detected as not being a digit.
To test if all the character in call_ID, there's an easy way provided by Python: all()
def validateTel(call_ID):
if isinstance(call_ID, str):
call_ID = call_ID.replace (" ", "")
if len(call_ID) != 10:
print ("A telephone number must be 10 digits long")
return False
else:
print ("Every character in a telephone number must be a digit")
return all(c in '0123456789' for c in call_ID)
else:
print ("call_ID must be a string")
return False
If one of the character c in call_ID isn't a digit, c in '0123456789' is False and the function all() stop the exam of the following characters and returns False; otherwise, it returns True

Categories