Nathan Leow
Nathan Leow

Reputation: 83

Interrupt loop python after a certain string have been printed

I have a bicycle list like this :

fmnewlist = [
    ['Bike No.', 'Purchase Date', 'Batt %', 'Last Maintenance', 'KM since Last', 'Reason/s'], 
    ['T101', '10/4/2016', '55', '10/1/2017', '25.08', 'No service'], 
    ['T102', '1/7/2016', '10', '15/5/2017', '30.94', 'No service'], 
    ['T103', '15/11/2016', '94', '13/6/2017', '83.16', 'KM'], 
    ['T104', '25/4/2017', '58', '10/1/2017', '25.08', 'No service'], 
    ['T105', '24/5/2017', '5', '20/6/2017', '93.8', 'Batt & KM']
]

and I want to check for certain elements in each of the inner lists and then print a string out like this without it looping. Here's my code, why doesn't it work?

lens=len(fmnewlist)
biketocheck=(input("Bike No.:"))
countertwo=1

while countertwo < (lens+1):
    a=fmnewlist[countertwo]
    if biketocheck in a[0] and a[5]!="No service":
        print("Bike serviced.")
    elif biketocheck in a[0] and a[5]=="No service":
        print("Bicycle not due for servicing")
    elif biketocheck not in fmnewlist:
        print("No such bicycle")
    else:
        print(" ")
    countertwo+=1
    if countertwo==lens:
        break

expected output when T123 is entered:

Bike No.:T123
No such bicycle

real output:

Bike No.:T123
No such bicycle
No such bicycle
No such bicycle
No such bicycle
No such bicycle

expected output when input is T102:

Bicycle not due for servicing

real output:

Bike No.:T102 No such bicycle Bicycle not due for servicing No such bicycle No such bicycle No such bicycle

expected output when input is T103:

Bike serviced Real output:

Bike No.:T103 No such bicycle No such bicycle Bike serviced. No such bicycle No such bicycle

Upvotes: 0

Views: 75

Answers (3)

OMY
OMY

Reputation: 412

Use for instead of while, remove the else part. Then you can use the else statement for for:

for bicycle in fmnewlist[1:]:  # Don't use the first line
    # previous statements except else, it should have a `break` too.
    if biketocheck in a[0]:
        if a[5]!="No service":
            print("Bike serviced.")
        # compare is either != or == so there's no need to write the whole elif 
        else:
            print("Bicycle not due for servicing")
        break
else:
    print("No such bicycle")

else will only be used if for was completed without a break in it. So it means no bicycle was found. What you are doing is checking each line for the needed bicycle and of course it doesn't exist in that element.

P.S: You can use else with while too. But you have to be certain that the condition returns False after awhile or else clause won't work. It's easier with for to do it.

Upvotes: 0

user94559
user94559

Reputation: 60153

Here's my best guess as to what the program is supposed to do:

  1. Look through the list of bikes for a row where the first element matches a user-specified ID.
  2. If the bike is not found, print "No such bicycle."
  3. If the bike is found, print out either "Bicycle not due for servicing" or "Bike serviced" depending on the value of the 6th element.

Given those assumptions, I believe this code should do what you want:

fmnewlist = [
    ['Bike No.', 'Purchase Date', 'Batt %', 'Last Maintenance', 'KM since Last', 'Reason/s'], 
    ['T101', '10/4/2016', '55', '10/1/2017', '25.08', 'No service'], 
    ['T102', '1/7/2016', '10', '15/5/2017', '30.94', 'No service'], 
    ['T103', '15/11/2016', '94', '13/6/2017', '83.16', 'KM'], 
    ['T104', '25/4/2017', '58', '10/1/2017', '25.08', 'No service'], 
    ['T105', '24/5/2017', '5', '20/6/2017', '93.8', 'Batt & KM']
]

biketocheck=(input("Bike No.:"))

found = False
for bike in fmnewlist[1:]:
    if bike[0] == biketocheck:
        found = True

        if bike[5] == "No service":
            print("Bicycle not due for servicing")
        else:
            print("Bike serviced.")
        break

if not found:
    print("No such bicycle")

EDIT

Using a dict instead, which makes the logic a little easier:

bikes = { bike[0]:bike[1:] for bike in fmnewlist[1:] }

biketocheck=(input("Bike No.:"))

if biketocheck in bikes:
    if bikes[biketocheck][4] == "No service":
        print("Bicycle not due for servicing")
    else:
        print("Bike serviced.")
else:
    print("No such bicycle")

Upvotes: 2

zwer
zwer

Reputation: 25809

Why not just create a lookup map of your list and do quick if .. in comparisons, something like:

fmnewlist = [
    ['Bike No.', 'Purchase Date', 'Batt %', 'Last Maintenance','KM since Last', 'Reason/s'], 
    ['T101', '10/4/2016', '55', '10/1/2017', '25.08', 'No service'], 
    ['T102', '1/7/2016', '10', '15/5/2017', '30.94', 'No service'], 
    ['T103', '15/11/2016', '94', '13/6/2017', '83.16', 'KM'], 
    ['T104', '25/4/2017', '58', '10/1/2017', '25.08', 'No service'], 
    ['T105', '24/5/2017', '5', '20/6/2017', '93.8', 'Batt & KM']
]

bike_iter = iter(fmnewlist)  # create an iterator for easier handling
next(bike_iter)  # skip the first item (header)
bike_nos = {bike[0]: bike[5] for bike in bike_iter}  # create bike_no: reason map

biketocheck = input("Bike No.: ")  # get the input

if biketocheck in bike_nos:  # check if the bike exists
    if bike_nos[biketocheck] == "No service":  # if it exists, check for status...
        print("Bicycle not due for servicing")
    else:
        print("Bike serviced.")
else:  # bike doesn't exist...
    print("No such bicycle")

And if you test it:

Bike No.: T103
Bike serviced.

Bike No.: T102
Bicycle not due for servicing

Bike No.: T123
No such bicycle

Upvotes: 2

Related Questions