how do i read the next line after finding a variable in a text file?

126 Views Asked by At

I am trying to make an app for electric vehicle drivers and i'm using a text file to store the data the way it works is i have the name of the electric vehicle and the the line under the name contains the miles it can get per 1%, i've got it so it can find the specific car but i can't find the range of the vehicle using that number.

MG MG4 EV Long Range
2.25
BMW iX1 xDrive30
2.3
Kia Niro EV
2.4
Tesla Model Y Long Range Dual Motor
2.7
BMW i4 eDrive40
3.2
with open('cars.txt', 'r')as cars:
    check = input("Enter full name of car: ")
    car = cars.read()
    percentage = cars.readline()
    if check in car:
        print("Found")
    total = range
    print(percentage)

this is what i have but every time it finds the car it won't find the range after it.

4

There are 4 best solutions below

0
Andrej Kesely On

I'd suggest to read the file into a dictionary, then use that dictionary to find the car, e.g.:

data = []
with open("cars.txt", "r") as f_in:
    for line in map(str.strip, f_in):
        if line == "":
            continue
        data.append(line)

data = dict(zip(data[::2], data[1::2]))

name = input("Enter full name of car: ")
print(data.get(name, "Not Found"))

Prints:

Enter full name of car: Kia Niro EV
2.4
0
S.B On

You can do the following:

target_car = "Kia Niro EV"

with open("temp.txt") as f:
    for line in f:
        if line.rstrip() == target_car:
            range_ = float(next(f))
            break
    else:
        range_ = "Not Found"
print(f"range is: {range_}")

f is a consumable iterator. You iterate over it until you find your car, then the next item in that iterator is what you're looking for.

Also note that you don't store the whole file in the memory in case you're dealing with a huge file. (In that case why wouldn't you use a proper database?)

0
Jeevan ebi On

Here are some other approach you can try:

check = input("Enter full name of car: ")
found = False

with open('cars.txt', 'r') as cars:
    for line in cars:
        if check in line:
            found = True
        elif found:
            # Once the car is found, the next line contains the range in miles per 1%
            percentage = float(line.strip())  # Convert the percentage to a floating-point number
            print(f"Found: {check}")
            print(f"Range per 1%: {percentage} miles")
            break

if not found:
    print("Car not found in the file.")

Sample Input :

Enter full name of car: Tesla Model Y Long Range Dual Motor

Output:

Found: Tesla Model Y Long Range Dual Motor
Range per 1%: 2.7 miles
0
tripleee On

The immediate problem is that read() reads all the remaining data from the file into memory; you can then no longer read() or readline() from the same file handle, because it is already at the end of the file.

You could traverse the entire list in memory and print the entry after the one which matched, using readlines() which similarly reads the entire file, but conveniently returns the lines as a list of strings.

    ...
    carlist = cars.readlines()
    for car in range(0, len(carlist), 2):
        if check in carlist[car]:
            print(carlist[car+1])

However, to avoid reading a potentially large amount of text into memory just to immediately discard it, perhaps only read one line at a time, and stop as soon as you find a match.

check = input("Enter full name of car: ")
found = False
with open('cars.txt', 'r') as cars:
    car_line = 1
    for line in cars:
        if car_line:
            if check in line:
                found = True
        else:
            if found:
                print(line, end="")
                break
        car_line = 1 - car_line

This takes a bit of thinking to wrap your head around if you haven't seen code like this before. Basically, we are examining a line at a time, and keeping a couple of state variables to keep track of what we have done on previous lines.

  • car_line keeps track of whether this is an odd line (the start of a new record, i.e. information about a new car) or an even line (meaning it belongs with the previous car line)
  • found keeps track of whether we have found the car we are looking for.

So, read a line. If it's not the car we are looking for, just update the car_line to remind us of what we just did. Then read another line. This is not a car_line so we take the else, and it was not found, so we do nothing with it. Read the next line again. Repeat until the car line matches. At this point, set found to remind us to print and exit after the next line. And then, finally, when you read the next line after that, you see that it is not a car line, and that the information we need is now found, so print and exit.

The assignment car_line = 1 - car_line implements a toggle. If car_line is 1, the new value will be 0; and if it is 0, the new value will be 1. (This generalizes nicely to toggling between two arbitrary states.)

A much better solution is to rewrite your data into a properly machine-readable format, like CSV or JSON, or perhaps a SQLite database, and then take it from there.

The logic above can be used for that, too, with fairly minor modifications. Here is a CSV converter.

with open('cars.txt', 'r') as cars, open('cars.csv', 'w') as outfile:
    car_line = 1
    writer = csv.writer(outfile)
    car = []
    for line in cars:
        data = line.rstrip('\n')
        if car_line:
            car = [data]
        else:
            car.append(float(data))
            writer.writerow(car)
        car_line = 1 - car_line

Searching the resulting CSV file is then somewhat more straightforward and convenient. If you need to manipulate the data more than just a few times, probably save it in a database instead, and index the field you want to search on.