Droxbot
Droxbot

Reputation: 53

Iterating over lines in a file to check for correct values(Python)

The file takes the format:

Britany     6.06 5.31 4.34 8.60 4.14 3.12 3.53 5.16
Eula        6.46 9.84 7.17 4.89 6.24 8.82 4.31 9.08
Georgianna  0.52 6.95 6.67 5.54 8.27 0.57 8.42 2.76
Emilee      2.66 5.73 3.29 1.27 2.66 9045 1.16 2.81
Serina      3.07 9.22 3.59 0.89 3.91 9.79 6.48 7.81

What I need to do is create a function that will check if each score for each contestant is between 0 and 10. If all scores of a contestant are acceptable, the contestant and his/her scores are written to the clean data file, if not, the contestant is eliminated and his/her data are not written to the clean data file. The names and scores of eliminated contestants should be stored in a list.

Here is my code so far:

def cleanData(userIn,userOut):
    fileIn = open(userIn,'r',encoding = 'UTF8')
    fileOut = open(userOut,'w',encoding = 'UTF8')
    eliminated=[]
    for line in fileIn:
        tempList= line.rsplit(maxsplit=-9)
        for num in tempList:
            if num in range(0,11):
                userOut.write(line)
            else:
                eliminated.append(line)

What I am attempting to do is read the line in the file and split it into a list so I can iterate over the numbers. Then I am trying to check if each number meets the criteria for a valid score and if all the numbers meet this goal write that line to the output file. Otherwise I want to append the line to the empty list eliminated for later use. I am not sure if I am using maxsplit properly, but I believe that I am starting from the right most index of -1 and wan to finish at -8, which would create a list of only the numbers.

Upvotes: 1

Views: 114

Answers (5)

Irshad Bhat
Irshad Bhat

Reputation: 8709

Problem is in the the below code line in your script:

if num in range(0,11):

It wiil create a list [0,1,2,3,4,5,6,7,8,9,10] and your given numbers doesn't lie in this list, so this if condition will never produce a True value and nothing is written to userOut file. So replace this line with:

if all([0 <= float(x) <= 10 for x in tempList]):

Upvotes: 0

friedi
friedi

Reputation: 4360

I fixed your code. These are the things I changed:

  • used codecs.open instead of open (working with utf8 is easy with this library)
  • used line.split()[1:] instead of line.rsplit(...)
  • cast every unicode string to a float number
  • check for every number if it is in the range with if num < 0 or num > 10:
  • fixed typo: fileOut.write instead of userOut.write
  • moved the else block from if...else to for...else

Here is the result:

import codecs

def cleanData(userIn,userOut):
    fileIn  = codecs.open(userIn, 'r', encoding='UTF8')
    fileOut = codecs.open(userOut, 'w', encoding='UTF8')
    eliminated = []
    for line in fileIn:
        tempList = line.split()[1:]
        for item in tempList:
            num = float(item)
            if num < 0 or num > 10:
                eliminated.append(line)
                break
        else: # no break
            fileOut.write(line)

Upvotes: 0

Joe Chavez
Joe Chavez

Reputation: 41

The line: if num in range(0,11): only checks if the number is an integer in that range.
i'd use a for/else in this example:

for line in fileIn:
    scores = line.split()[1:]
    for score in scores:
        if not 0 < float(score) < 10:
            eliminated.append(line)
            break
    else:
        userOut.write(line)

The else clause is only hit after the for clause is exhausted without hitting the break statement.

Upvotes: 0

Padraic Cunningham
Padraic Cunningham

Reputation: 180550

splitting the line and using spl[1:] will let you access each score, all will check if every score falls within the threshold.

with open(in) as f,open(out,"w") as f1:
    eliminated = []
    for line in f:
        spl = line.split() # split line into name and individual scores
        if all(0 <= x <= 10 for x in [float(x) for x in spl[1:]]): # compare spl[1:] which are all the floats/scores
            f1.write(line)  
        else:
            eliminated.append(line)

In a function:

def clean_data(user_in,user_out):
    with open(user_in) as f,open(user_out,"w") as f1:
        eliminated = []
        for line in f:
            spl = line.split()
            if all(0 <= x <= 10 for x in [float(x) for x in spl[1:]]):
                f1.write(line)
            else:
                eliminated.append(line)
    return eliminated

Upvotes: 0

Paul Becotte
Paul Becotte

Reputation: 9997

templist = line.split()[1:] 

would give you all of the values after the name.

if all([0 <= float(x) <= 10 for x in tempList]):

is a good way to check what you want. You don't want to check

for num in tempList:

because that will write the line if the first value is good (and again on each subsequent value that is good!)

Upvotes: 1

Related Questions