How to fix the errors in my code for making a dictionary from a file

Viewed 926

This is what I am supposed to do in my assignment:

This function is used to create a bank dictionary. The given argument is the filename to load. Every line in the file will look like key: value Key is a user's name and value is an amount to update the user's bank account with. The value should be a number, however, it is possible that there is no value or that the value is an invalid number.

What you will do:

  • Try to make a dictionary from the contents of the file.
  • If the key doesn't exist, create a new key:value pair.
  • If the key does exist, increment its value with the amount.
  • You should also handle cases when the value is invalid. If so, ignore that line and don't update the dictionary.
  • Finally, return the dictionary.

Note: All of the users in the bank file are in the user account file.

Example of the contents of 'filename' file:

 Brandon: 115.5
 James: 128.87
 Sarah: 827.43
 Patrick:'18.9

This is my code:

bank = {}
with open(filename) as f:
    for line in f:
        line1 = line
        list1 = line1.split(": ")
        if (len(list1) == 2):
            key = list1[0]
            value = list1[1]
            is_valid = value.isnumeric()
            if is_valid == True
               value1 = float(value)
               bank[(key)] = value1

return bank

My code returns a NoneType object which causes an error but I don't know where the code is wrong. Also, there are many other errors. How can I improve/fix the code?

3 Answers

Try this code and let me explain everything on it because it depends on how much you're understanding Python Data structure:

Code Syntax

adict = {}
with open("text_data.txt") as data:
    """
        adict (dict): is a dictionary variable which stores the data from the iteration 
        process that's happening when we're separating the file syntax into 'keys' and 'values'. 
        We're doing that by iterate the file lines from the file and looping into them.
        The `line` is each line from the func `readlines()`. Now the magic happens here,
        you're playing with the line using slicing process which helps you to choose 
        the location of the character and play start from it. BUT, 
        you'll face a problem with how will you avoid the '\n' that appears at the end of each line. 
        you can use func `strip` to remove this character from the end of the file.
    """
    adict = {line[:line.index(':')]: line[line.index(':')+1: ].strip('\n')  for line in data.readlines()}
    print(adict)

Output

{' Brandon': '115.5', ' James': '128.87', ' Sarah': '827.43', ' Patrick': "'18.9"}

In term of Value Validation by little of search you will find that you can check the value if its a number or not

According to Detect whether a Python string is a number or a letter

a = 5
def is_number(a):
    try:
        float (a)
    except ValueError:
        return False
    else: 
        return True

By Calling the function

print(is_number(a))
print(is_number(1.4))
print(is_number('hello'))

OUTPUT

True
True
False

Now, let's back to our code to edit;

All you need to do is to add condition to this dict..

adict = {line[:line.index(':')]: line[line.index(':')+1: ].strip(' \n')  for line in data.readlines() if is_number(line[line.index(':')+1: ].strip('\n')) == True}

OUTPUT

{'Brandon': '115.5', 'James': '128.87', 'Sarah': '827.43'}

You can check the value of the dict by passing it to the function that we created

Code Syntax

print(is_number(adict['Brandon']))

OUTPUT

True

You can add more extensions to the is_number() function if you want.

You're likely hitting the return in the else statement, which doesn't return anything (hence None). So as soon as there is one line in your file that does not contain 2 white-space separated values, you're returning nothing.

Also note that your code is only trying to assign a value to a key in a dictionary. It is not adding a value to an existing key if it already exists, as per the documentation.

This should effectively do the job:

bank = {}
with open(filename) as file:
    for line in file:
        key, val = line.rsplit(": ", 1) # This will split on the last ': ' avoiding ambiguity of semi-colons in the middle
        # Using a trial and error method to convert number to float
        try:
            bank[key] = float(val)
        except ValueError as e:
            print(e)
return bank
Related