3
\$\begingroup\$

I have a code to get riders from certain teams and calculate the number of riders in those teams in that category:

valid_clubs = []
with open("validclubs.txt") as f:
    for line in f:
        valid_clubs.append(line)


disqualification_reasons = ["WKG", "UPG", "ZP", "HR", "HEIGHT", "ZRVG", "new", "AGE", "DQ", "MAP", "20MINS", "5MINS"]


with open("results.csv", 'rt', encoding='UTF-8',errors='ignore') as file:  # open results file to get breakdown of results
    reader = csv.reader(file, skipinitialspace=True, escapechar='\\')
    # each variable is current number of riders in the category
    A = B = C = D = E = Q = W = 0  # setting all values to 0 so we can work out number of riders in each category
    for row in reader:
        try:
            category = row[0]
            if row[4] in valid_clubs:
                if row[7] == "0":  # if club is in valid_clubs.txt and gender = female
                    W = W + 1  # each time this condition is met increase value of W by 1, where W is the amount of women
                if "A" == category:  # if club is in valid_clubs.txt and category is A
                    A = A + 1  # each time this condition is met increase value of A by 1
                if "B" == category:  # if club is in valid_clubs.txt and category is B
                    B = B + 1  # each time this condition is met increase value of B by 1
                if "C" == category:  # if club is in valid_clubs.txt and category is C
                    C = C + 1  # each time this condition is met increase value of C by 1
                if "D" == category:  # if club is in valid_clubs.txt and category is D
                    D = D + 1  # each time this condition is met increase value of D by 1
                if category in disqualification_reasons:  # all the possible DQ reason
                    Q = Q + 1  # each time this condition is met increase value of Q by 1, where Q is the number of riders DQ'ed
                if "E" == category:  # if club is in valid_clubs.txt and category is E
                    E = E + 1  # each time this condition is met increase value of E by 1
        except IndexError:  # ignore errors where row is empty
            pass
        total = str(A + B + C + D + E + Q)
print("There were", total, "riders", W, " were women:", "\nCat A:", A, "\nCat B:", B, "\nCat C:",
      C, "\nCat D:", D, "\nCat E:", E, "\nDisqualified:", Q)

It is a really repetitive code and I'm sure could be cleaned up. I would appreciate some advice on how you would do this.

Here is an example CSV:

Category.Position,Name,Time,Team,RandomInt1,RandomInt2,Male?
A,1,Person 4,00:54:12.92,2281,343,4.4,1
A,2,Person 3,00:54:13.29,10195,310,4.2,1
A,3,Person 2,00:54:19.19,84,334,5.0,1
A,4,Person 1,00:54:19.33,7535,297,4.9,1

Category would change as you go down the CSV

The Male? column is 1 when the person is male and 0 when they are female, Validclubs is a list of the team numbers which I want to use, imported from a txt file, RandomInt1/RandomInt2 are irrelevant for now

I would appreciate any advice on reducing the code so it is cleaner/shorter.

I want to use built-in libraries so not pandas.

\$\endgroup\$
4
  • \$\begingroup\$ not pandas - why not? \$\endgroup\$ – Reinderien Jul 2 '20 at 19:55
  • \$\begingroup\$ Please include your code that loads valid_clubs. \$\endgroup\$ – Reinderien Jul 2 '20 at 19:56
  • \$\begingroup\$ @Reinderien I have added now, on Pandas I have never worked with them, I have no knowledge of them so if I put this in and I want to make changes to my code I would not fully understand what it is doing \$\endgroup\$ – PythonIsBae Jul 2 '20 at 20:00
  • \$\begingroup\$ It's a useful thing to learn :) For small projects and datasets stock Python is fine, but you'll quickly run into performance issues when you try to scale. \$\endgroup\$ – Reinderien Jul 2 '20 at 20:02
3
\$\begingroup\$

Set membership

valid_clubs = []
with open("validclubs.txt") as f:
    for line in f:
        valid_clubs.append(line)

should be

with open("validclubs.txt") as f:
    valid_clubs = {line.strip() for line in f}

Lines coming back from a file handle in Python include their line ending, which you have to strip yourself; and you should be using a set, not a list. Set membership lookups will be much faster than list lookups.

Consider DictReader

The csv module has a reader that gives you back a dictionary based on the headings, so that you do not have to write row[0], but rather row['Category'].

Use Counter

Your list of category ifs can be condensed to a one-liner; read about Counter. This will be easier to use and perform better.

Empty rows

Based on # ignore errors where row is empty, this should be done up-front. Rather than hitting your face on an IndexError and having to ignore it, simply check for an empty row:

if row:
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.