ValueError that should be caught and skipped, yet crashes program - python

What is the issue with:
try:
number = int((self.final_df_1[index1_name][i])[:first_space_a])
except TypeError or ValueError:
continue
For some background, that entry in the Dataframe is a string of an address. The argument of int() is simply the first "word," which in this case is the street number. The logic here is that I want to try to convert that street number into an integer, and if it happens to throw TypeError or ValueError, I want to skip to the next iteration of the for loop that this is nested within, ie, to the next row of the Dataframe. This is practical because the CSV's I'm parsing through contain thousands of addresses, and occasionally one will be formatted oddly (such as '74271/2,' which is one of the few entries that consistently throws this error in the test set).
I would expect this chunk of code to, during the attempt to convert to an integer, catch the error and, again, skip to the next iteration of the loop, but instead it does anything but what it's supposed to do.
Thanks in advance.

try doing
try:
number = int((self.final_df_1[index1_name][i])[:first_space_a])
except (TypeError,ValueError):
continue
instead of
try:
number = int((self.final_df_1[index1_name][i])[:first_space_a])
except TypeError or ValueError:
continue
This will check for both errors and the program won't crash. You can extend this to any amount of errors you want to check for.

Related

Python Repeat loop iteration on exception, supply new values

In my script, I have to hit an endpoint multiple times as there is a cap of the number of values that can be passed through. So I iterate through sublists which works. The problem is that there are times where a set of values in a sublist will be rejected by the endpoint, however, there is no way of knowing which ones will be rejected until I get the rejected list of values from the response. I can raise an exception in these scenarios, remove the invalid values, and hit the end point again (i.e. repeat the code in the exception as the first try).
However, I was curious to know if there is a better approach to do this. Something along the lines of when iteration breaks, I restart the same iteration but this time with the new values supplied. What is best practice? See examples below:
#repeat code in exception with newly created sublist. this works but repeat code
for sublist in sublists:
try:
#supply sublist to endpoint
except:
#create new sublist with erroneous values removed
#copy code in try here but supply new list
#restart same iteration after rejected but with new values. this doesnt work, but is there a way to make it work?
i=0
while i<len(sublists):
try:
#supply sublists[i] to endpoint
except:
#create new sublist[i] with erroneous values removed
#restart current iteration but this time with the newly created sublist[i]
i=i

How to print index (Row number) while conversion error during json.loads Panda Dataframe

I am using below code for Json load which works fine for valid json string, but for non valid it throws error.
orgdf['data'].apply(json.loads)
I just need to know for which index (row number) there is an invalid record for which Jason.loads giving error.
I know I can do it using dataframe enumeration (for loop), but looking for an efficient way to do that as it contains Million records.
It will be great if someone can help on the same.
You can create a custom function where you wrap the json.loads call in a try/except and then call this function inside apply. See also this answer.
def is_valid_json(s):
try:
json.loads(s)
except (json.JSONDecodeError, ValueError):
return False
return True
# Mark valid JSON strings
valid = orgdf['data'].apply(is_valid_json)
# Extract indices with _invalid_ strings
invalid_indices = valid[~valid].index

Having issues trying to store values into a tuple in Python [duplicate]

I'm telling my program to print out line 53 of an output. Is this error telling me that there aren't that many lines and therefore can not print it out?
If you have a list with 53 items, the last one is thelist[52] because indexing starts at 0.
From Real Python: Understanding the Python Traceback - IndexError:
IndexError
The IndexError is raised when you attempt to retrieve an index from a sequence, like a list or a tuple, and the index isn’t found in the sequence. The Python documentation defines when this exception is raised:
Raised when a sequence subscript is out of range. (Source)
Here’s an example that raises the IndexError:
test = list(range(53))
test[53]
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-6-7879607f7f36> in <module>
1 test = list(range(53))
----> 2 test[53]
IndexError: list index out of range
The error message line for an IndexError doesn’t give you great information. You can see that you have a sequence reference that is out of range and what the type of the sequence is, a list in this case. That information, combined with the rest of the traceback, is usually enough to help you quickly identify how to fix the issue.
Yes,
You are trying to access an element of the list that does not exist.
MyList = ["item1", "item2"]
print MyList[0] # Will work
print MyList[1] # Will Work
print MyList[2] # Will crash.
Have you got an off-by-one error?
The way Python indexing works is that it starts at 0, so the first number of your list would be [0]. You would have to print[52], as the starting index is 0 and
therefore line 53 is [52].
Subtract 1 from the value and you should be fine. :)
Yes. The sequence doesn't have the 54th item.
That's right. 'list index out of range' most likely means you are referring to n-th element of the list, while the length of the list is smaller than n.
Always keep in mind when you want to overcome this error, the default value of indexing and range starts from 0, so if total items is 100 then l[99] and range(99) will give you access up to the last element.
whenever you get this type of error please cross check with items that comes between/middle in range, and insure that their index is not last if you get output then you have made perfect error that mentioned above.
If you read a list from text file, you may get the last empty line as a list element.
You can get rid of it like this:
list.pop()
for i in list:
i[12]=....

Using User Input to Index List in Python

I can't understand what I am doing wrong with this method. It is called from another in class method as such:
def equip_menu(self): # this is not the actual method, but equip_choice is used only in the following lines
#snipped code
equip_choice = Input("Input the number of the item you want to equip:\n")
self.select_from_list_equip(equip_choice)
and this is the method throwing error:
def select_from_list_equip(self, equip_choice): # Trying to select item in list self.backpack
item_to_equip = self.backpack[equip_choice]
print("*DEBUG* Equip chosen:", item_to_equip.name)
playeritems.equip(item_to_equip)
I get the error:
"classes.py", line 109, in select_from_list_equip
item_to_equip = self.backpack[count]
TypeError: list indices must be integers or slices, not str"
So I tried making equip_choice an integer, even though I just try inputting digits without decimals and still get the error. I am in the opinion that I am not trying to use a string as list index, but obviously I am wrong. So I tried to force equip_choice to become an integer like this:
def select_from_list_equip(self, equip_choice):
int(equip_choice)
item_to_equip = self.backpack[equip_choice]
print("*DEBUG* Equip chosen:", item_to_equip.name)
playeritems.equip(item_to_equip)
But I still get the same identical error. Why can't I use the value of equip_choice as list index? I must be missing something very obvious and basic I am blind to?
Input() returns a string. You will need to use int() to convert to an integer.
input() resource

What are the necessary requirements for coding decimal to binary [Python]?

Okay, so I have had some help with some fellow users on this website and I found you can't just ask someone for code. I am not. I want to know some of the variables and stuff needed to code.
1) Need to have a raw_input so the user can type in their number.
- I have seen you type:
raw_input("Please insert a number: ") #This allows you the user to type in a number.
2) Need to have if, elif and else statements in my code to stop the user from typing in Anything but numerical values
-I think you need this:
if raw_input == '£' or '$' or '%' ETC
but I think that might take too long :( Need help to make my if statements
3) Need to stop the user from entering a value below 1 and above 256.
I think you need this:
if raw_input > 256:
return("Enter a value below 256")
elif raw_input < 1: return("Enter a value above 1")
4) Need to have the binary number presented as an '8 bit'
Example "00000111" same as "111".
Thanks, all information will be useful and I will try to reply to all of yous! Thanks!!!
First of all, welcome to StackOverflow. It looks like you've been burned on questions in the past, and probably rightly so. This site is not typically well-suited for rank amateurs, who are better suited looking up a tutorial or reading documentation.
That said, you seem earnest in your efforts and have phrased the question in a meaningful way, so let me try to help:
1) Need to have a raw_input so the user can type in their number
That's correct, the way you store user input in Python2 is raw_input, as such:
variable_name = raw_input("Prompt")
2 and 3) Input validation
Basically both these points are the same -- how do I make sure my user entered data that's appropriate? There's lots of schools of thought on this, and you should read the difference between EAFP and LBYL coding, as well as concepts like duck-typing and etc. For now, let me just show you what I would do.
number = raw_input("prompt")
try:
number = int(number)
except ValueError:
# the user entered a value that can't be converted
# to an integer, e.g. letters or a decimal number
# so you'd handle that here, maybe with...
print("Invalid number")
if 1 <= number <= 255:
# user has entered a number below 1 or above 256
# handle it as above, probably ending with:
return
4) Conversion and return of value
Once you've done all the steps above, your number is GUARANTEED to either have thrown an error or be an integer between 1-256. From this point on, it's smooth sailing, just return the binary representation of that number (which is done with the built-in bin)
else:
# number is now an integer between 1-256
return bin(number) # bin(x) returns the number in base 2
Clarification
There are some terms here you've never seen before, so let me explain.
try:
do_a_thing()
except Exception:
handle_exception()
This is called a try/except block, and you use them when you're expecting the thing you're doing inside the block might throw an exception. For instance I might do:
try:
f = open("path/to/a/file.txt", "r") # open a file in read mode
except (IOError,FileNotFoundError,PermissionError):
print("Can't open that file because of an error")
I know when I try to open a file, it might fail if another application has it open, or if I'm not able to access the drive it's on, or even if the file doesn't exist! I then specify underneath how my code should handle each situation, and could even do
try:
f = open("path/to/a/file.txt","r")
except IOError:
handle_IOError()
except FileNotFoundError:
make_file("path/to/a/file.txt")
except PermissionError:
get_permission('path/to/a/file.txt')
To handle multiple errors in different ways.
Final Product
If this were my code, I would write it like this:
def get_binary(value):
try:
value = int(value)
assert 1 >= value >= 255
except ValueError:
raise TypeError("Value must be an integer")
except AssertionError:
raise ValueError("Value must be between 1-255")
return bin(value)
user_in = raw_input("Enter a number between 1-255: ")
print "The number in binary is {}".format(get_binary(user_in)[2:])
The basic strategy is to see if you can cast your number appropriately to a float (or int, if you prefer). If you can, it's a valid number. If you can't, ask the user for another input.
while (True):
input = raw_input("Please enter a number: ")
try:
number = float(input)
if number < 1 or number > 256:
print("The number must be between 1 and 256 inclusive.")
continue
break
except ValueError:
pass
# do whatever you want with your number here
print(number)
To answer your questions:
"try" means do something that we think might not work quite right, such as making a number out of something the user is entering that isn't a number. If you do that, it causes a ValueError.
So, we "except" or "catch" this ValueError. This is where we could do some sort of error handling code, like print("I said a number!").
continue brings us back to the start of the while loop
break stops the while look and goes to the next line of code.

Categories

Resources