I'm trying to use the values inside a .txt file to be able to use it in an equation

Viewed 135

I have a .txt file which has these values 10,20,30,40,50. It only has a single row but, with multiple columns. I'm having a hard time on how to use each column as a single value to be used in an equation.

I have the code below:

val = input('Enter the text file name: ')
print('Opening text file: ', val)

try:
    file = open(val + '.txt', 'r').readlines()

    for row in file:
        price_raw = row

except FileNotFoundError:
    print('File name not found.')

price = int(price_raw)
balanceA = 100
balanceB = 100
total_balance = (balanceA + balanceB) * price

print(total_balance)

I have tried converting row into an integer but, it prompts

ValueError: invalid literal for int() with base 10

I have tried to use print(type(row)) and the value I am getting from the file is a string.

How can I extract all the values in the .txt file and use them in the equation for total_balance?

For the first column on the .txt file, 10, e.g. total_balance = (100 + 100) * 10. Then the next column, which is 20, e.g. total_balance = (100 + 100) * 20

Is it possible for the total_balance to contains different values for each of the price value?

How would I approach on doing this?

3 Answers

You can easily read the line into an array of integers with the following snippet:

raw_prices = price_raw.split(",")
prices = list(map(int, raw_prices))

Some explanation:

  • The price_raw.split(",") breaks your input at every "," it finds and returns a list of strings with the numpers.
  • The map then converts this list to integer.
  • Finally, the list makes a list from the map object.

Problem:

Your textfile ends with a "\n" - when reading your last line is empty (aka "") - which can not be converted to integer.

int("")  # this is what happens in the last line

This produces:

=> Exception has occurred: ValueError, invalid literal for int() with base 10: ''

You can not convert empty lines - and need to fix that.

This

file = open(val + '.txt', 'r').readlines()

for row in file:
    price_raw = row

will open the file and loop through the list of lines of the file - price_raw will be reset to hold the value of each single line int turn ... and do nothing with it. The last value of a file content of 10,20,30,40,50\n will result in price_raw == "". int(price_raw) == int("") => produces your error.


Solutions:

# one number per line 
fn = "tata.txt"

with open (fn, "w") as f:
    f.write("10\n")
    f.write("30\n")

try:
    with open(fn) as f:
        lines = f.readlines()

    # converts all lines that do not strip down to nothing
    # to an integer
    numbers = map(int, (l.strip() for l in lines if l.strip()))


except ValueError as e:
    print(e)

balanceA, balanceB = numbers # decomposition

total_balance = (balanceA+balanceB)*42

print(total_balance)

Output:

1680

If you have multiple values per line, comma separated you need to split(",") each line into single things - see f.e.:

# multiple numbers per line - will also work for only a single line
fn = "tata.txt"

with open (fn, "w") as f:
    f.write("10,20\n")    # this will also work for only a single
    f.write("99,120\n")   # line .. 

try:
    with open(fn) as f:
        lines = f.readlines()

    # converts all lines that do not strip down to nothing
    # to an integer
    lines_with_numbers = [list(map(int, l.split(","))) for l in lines]

except ValueError as e:
    print(e)

for data in lines_with_numbers:

    balanceA, balanceB = data # decomposition

    total_balance = (balanceA+balanceB) * 42
    print("(" , balanceA, "+", balanceB, ") * 42 = ", total_balance)

Output:

( 10 + 20 ) * 42 =  1260
( 99 + 120 ) * 42 =  9198

Assuming your file has exactly one line with the following content:

10,20,30,40,50

When you:

file = open(val + '.txt', 'r').readlines()

The variable file with end up filled with ['10,20,30,40,50\n'].

When the loop below ends:

for row in file:
    price_raw = row

It will leave price_raw set with '10,20,30,40,50\n'.

So, when you do:

price = int(price_raw)

You are really saying:

price = int('10,20,30,40,50\n')

Which is obviously passing an invalid argument to int(), hence the error:

ValueError: invalid literal for int() with base 10: '10,20,30,40,50\n'

The solution, as pointed by @rammelmueller, is to split() the individual columns into single values and then convert each of them to int().

Even though it is not the case here, since you said you have exactly one line per file, it is a good practice to check if the line read is empty, as @PatrickArtner pointed.

With all that in mind, here is a possible solution for your problem:

filename = input('Enter the text file name: ')
print('Opening text file: ', filename)

balanceA = 100
balanceB = 100

try:
    # There are better ways of doing this, I'm leaving it as is just for clarity
    with open(filename + '.txt') as f:
        lines = f.readlines()
        # Process each line from the file
        for line in lines:
            # We are interested in non empty lines only
            if line.strip():
                # Split the columns and convert them to int()
                prices = [*map(int, line.split(','))]
                # Calculate the total_balance for each price
                for price in prices:
                    total_balance = (balanceA + balanceB) * price
                    print(total_balance)

except FileNotFoundError:
    print('File name not found.')

To completely understand the snippet above, it is recommended that you read the map() documentation, and Unpacking Argument Lists, to understand the meaning of the * in front of the map() call.

There is a lot of room for improvements but, I opted to leave the example as close as yours just for the sake of clarity.

Related