-1

I'm fairly new to python and can't solve this issue (I have already searched extensively)

My aim is to complete a shopping program where the user inputs the product which the program then reads the associated txt file and returns the items price.

This is my current code:

product_name_input = str(input("Please enter products name: "))

with open("products.txt") as text_file:    

    p_name  = [str(line.split(", ")[1]) for line in text_file]
    p_price = [float(line.split(", ")[2]) for line in text_file]

    while True:
        p_name == product_name_input
        print(p_price)
        break

    if product_name_input not in p_name:
        print("That product does not exist")

The current output i get if a product that is input that does exist in the file:

Please enter products name: shirt

[]

The current output i get if a product that is input that does not exist in the file:

Please enter products name: freezer

[]

That product does not exist

Any help on this is greatly appreciated!

Grismar
  • 27,561
  • 4
  • 31
  • 54
NMGITV
  • 1
  • 2
  • Welcome to Stack Overflow. What is the format of your lines? – ewokx Jun 02 '22 at 03:49
  • Welcome to Stack Overflow. The problem occurs because of https://stackoverflow.com/questions/3906137/why-cant-i-call-read-twice-on-an-open-file , but it seems like that is not enough to solve the problem for you. You should use a proper tool to read the file contents, such as the built-in standard library `csv` module. At any rate, please read [ask] and https://meta.stackoverflow.com/questions/284236, and make sure to **ask a specific question** when posting. "Any help on this is greatly appreciated!" does not qualify. – Karl Knechtel Jun 02 '22 at 04:27

3 Answers3

0

This line is a good start:

with open("products.txt") as text_file:   

It creates a handle to an open file (using a context manager with with, which is a good habit). You can iterate over the variable text_file to get each line from the file, one at a time. However, you can only do that once without reseting the file handle to the start of the file.

So in this code:

    p_name  = [str(line.split(", ")[1]) for line in text_file]
    p_price = [float(line.split(", ")[2]) for line in text_file]

The first line completely exhausts the file, and the second line results in an empty list because there are no more lines to read in the file.

One way to do it would be to go over the file once, but build both lists at the same time:

p_name = []
p_price = []
with open("products.txt") as text_file:
    for line in text_file:
        p_name.append(str(line.split(", ")[1]))
        p_price.append(float(line.split(", ")[2]))

An arguably more pythonic, but perhaps a bit harder to understand solution:

with open("products.txt") as text_file:
    p_name, p_price = zip(*[
        (str((parts := line.split(", "))[1]), float(parts[2]))
        for line in text_file
    ])

Readability is worth a lot, so you may prefer the first solution. The second solution can be better in some situations, but I don't think that's much of a concern for you right now.

What's different in the second solution:

  • the results are created all at once, without setup
  • the line is only split once and the result reused as parts
  • the results are collected in a list of tuples, which is then split into the two lists you need using zip() on the list (unpacked with *)

All this is assuming you're not actually interested in the first columnm, since [1] gets you the second and [2] gets you the third.

Grismar
  • 27,561
  • 4
  • 31
  • 54
  • Thank you for taking the time to help me, this didn't solve my problem exactly but greatly helped! – NMGITV Jun 02 '22 at 04:29
0

if your text file contain lines with delimited string, consider using csv module

import csv

product_name_input = str(input("Please enter products name: "))

with open("products.txt") as text_file:    
    lines = csv.reader( text_file, delimiter=',' )
    for line in lines:
        p_name, p_price = line
        if p_name == product_name_input:
           print(p_price)
           break # found
        print("That product does not exist")
Jupri
  • 345
  • 1
  • 6
0

In the below line, the text_file is read as an iterable and becomes empty once all the items in it are accessed

p_name  = [str(line.split(", ")[1]) for line in text_file]

A better approach would be to read all the lines into an list variable and then process them from there. Ideally construct a dictionary of name:price pairs and then query the dictionary to get the price for a product name.

product_name_input = str(input("Please enter products name: "))

with open("products.txt") as text_file:

    lines = text_file.readlines()

name_price_dict  = {str(line.split(", ")[1]):float(line.split(", ")[2]) for line in lines}

query_price = name_price_dict.get(product_name_input)

if query_price is not None:
    print(f"Price for {product_name_input} is {query_price}")
else:
    print(f"Price for {product_name_input} not found")
SigKill
  • 87
  • 5
  • 1
    Thank you so very much, this solved my problem! I appreciate the time you took to help a stranger! – NMGITV Jun 02 '22 at 04:28