i'm having trouble with ValueErrors in python

Question:

I’m trying to create a class "Hippocrates" with a function inside that lets me create a dictionary from a given text document (the content of the document is not important to my issue). When I try to return a value from the dictionary and the key does not exist in said dictionary, I want to raise a ValueError stating "invalid ICD-code". I then want the code to continue running since I need it to be able to keep returning values one after each other, but since I raise a ValueError the code stops.

I tried putting it inside a try except block but I’m not too familiar with it yet so I’m struggling.

Here’s what I have so far:

class Hippocrates:
    def __init__(self, location):
        self.file = open(location, "r")

    def description(self, code):
        answer = {}
        data = self.file.readline()
        while data:
            current = data.split()
            x = current.pop(0)
            current = ' '.join(current)
            answer[x] = answer.get(current, current)
            data = self.file.readline()

        try:
            return answer[code]
        except ValueError:
            print('invalid ICD-code')

When I try getting a value from it with an invalid key I get a KeyError. I don’t know why this would happen since it should just go straight to a ValueError.

I do get the correct value when I use a valid key.

Can someone help me figure this out please?

Asked By: Techtix

||

Answers:

You should except KeyError for invalid keys not ValueError

so just change the try/except to:

try:
    return answer[code]
except KeyError:
    print('invalid ICD-code')
Answered By: Hamza Sayyid

if you use dict[key]
then it will raise a KeyError if the key does not exist.
if you use dict.get(key) then it will return None if the key does not exist.

class Hippocrates:
    def __init__(self, location):
        self.file = open(location, "r")

    def description(self, code):
        answer = {}
        data = self.file.readline()
        while data:
            current = data.split()
            x = current.pop(0)
            current = ' '.join(current)
            answer[x] = answer.get(current, current)
            data = self.file.readline()

        try:
            return answer[code]
        except KeyError:
            print('invalid ICD-code')
Answered By: coolcoder613

The reason you’re receiving a KeyError rather than a ValueError is that Python raises a KeyError when you attempt to get data for a key which doesn’t exist in the dictionary. Therefore, no ValueError is raised and your catch block is never entered. The simple solution to this would be to change the type of exception you’re trying to catch to KeyError. However, using exception handling as execution flow is generally a bad practice so I would suggest checking if the key exists in the dictionary before retrieving it:

if code in answer:
    return answer[code]
else:
    raise ValueError('invalid ICD-code')

As an aside, I would suggest that you avoid having an open file as a field on your class. In general, it’s a good idea to open files, read them and close them as one operation. Also, your code is attempting to read the data in the file every time you try to access a code from the dictionary, so this will only work for the first code. Instead, you should try this:

class Hippocrates:
    def __init__(self, location):
        self.codes = {}
        file = open(location, "r")
        data = file.readline()
        while data:
            current = data.split()
            x = current.pop(0)
            current = ' '.join(current)
            self.codes[x] = current
            data = file.readline()
        file.close()

    def description(self, code):
        if code in self.codes:
            return self.codes[code]
        else:
            raise ValueError('invalid ICD-code')
Answered By: Woody1193
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.