3
\$\begingroup\$

The program is taken on the standard input a list of football team games with the result of the match and displays on the standard output a summary table of the results of all matches.

A team is awarded 3 points for a win, 0 for a loss, and 1 for a draw.

from collections import defaultdict

numberTeams = int(input())
dictTeams = defaultdict(list)

class Score:
    def __init__(self, number, dictTeams):
        self.number = number
        self.dictTeams = dictTeams
        self.lengthValue = 0
        self.total = 0
        self.win, self.draw, self.loss = 0, 0, 0
    def appendScore(self):
        for i in range(self.number):
            rez = input().split(';')
            self.dictTeams[rez[0]].append(3 if int(rez[1])>int(rez[3]) else 1 if int(rez[1])==int(rez[3]) else 0)
            self.dictTeams[rez[2]].append(3 if int(rez[1])<int(rez[3]) else 1 if int(rez[1])==int(rez[3]) else 0)
    def countScore(self):
        for letter, value in dictTeams.items():
            self.lengthValue = len(value)
            self.win, self.draw, self.loss = 0, 0, 0

            for i in value:
                if i==3: self.win+=1
                elif i==1: self.draw+=1
                elif i==0: self.loss+=1

            self.total = self.win*3+self.draw*1
            print(f"{letter}:{self.lengthValue} {self.win} {self.draw} {self.loss} {self.total}")

    

competition = Score(numberTeams, dictTeams)
competition.appendScore()
competition.countScore()

Possible input:

3 
Madrid;4;Spartak;5
Spartak;6;Chelsi;1
Chelsi;3;Madrid;3

Do I need to use classes there?

\$\endgroup\$
0

2 Answers 2

4
\$\begingroup\$

Layout

Place the class right after the imports. Having the class between other lines of code disrupts the natural flow of the code.

You should also add blank lines between the functions.

Lint check

I ran pylint, and it identified a few long lines of code. You could split those up into multiple lines.

Naming

Some of the variable names are not very meaningful, such as lengthValue. Consider changing some of the names. For example, I think numberTeams is better named as numberMatches. I'm not sure what rez stands for.

Output description

Add header text to the printed output so you know what the the numbers in the columns mean. Here is the output from your input example:

Madrid:2 0 1 1 1
Spartak:2 2 0 0 6
Chelsi:2 0 1 1 1

Users have no idea what the 5 numbers after the team name means.

Input

You should add text at the input prompt so that the user knows what is expected for input.

You should check the input values in case the user enters the wrong kind of value. For example, if the user enters a word like dog instead of the number of matches, the code dies badly. The pyinputplus module can help to check for valid input.

You should also add checking to make sure the scores are numbers, not words.

If you have a lot of data to input, doing so at the command line is cumbersome. Consider storing the input as a separate file, then reading the file instead of having the user input the data one line at a time at the command prompt. Entering data at the command line is error prone; it is much easier to fix typos in a file.

Documentation

It would be good to add some header comments at the top of the file to describe the purpose of the code, as well as the expected input and a description of the output.

Do I need to use classes there?

No, you don't need to use classes, but it is fine to do so.


Here is re-worked code with some of the above suggestions:

'''
The program is taken on the standard input a list of football team games with
the result of the match and displays on the standard output a
summary table of the results of all matches.

A team is awarded 3 points for a win, 0 for a loss, and 1 for a draw.
'''

from collections import defaultdict
import pyinputplus as pyip

class Score:
    def __init__(self, number, dictTeams):
        self.number = number
        self.dictTeams = dictTeams
        self.number_matches = 0
        self.total = 0
        self.win, self.draw, self.loss = 0, 0, 0

    def appendScore(self):
        for i in range(self.number):
            rez = input(f'Match {i+1}: ').split(';')
            self.dictTeams[rez[0]].append(3 if int(rez[1])>int(rez[3])
                                            else 1 if int(rez[1])==int(rez[3]) else 0)
            self.dictTeams[rez[2]].append(3 if int(rez[1])<int(rez[3])
                                            else 1 if int(rez[1])==int(rez[3]) else 0)

    def countScore(self):
        print("Team: matches win draw loss total")
        for team, values in dictTeams.items():
            self.number_matches = len(values)
            self.win, self.draw, self.loss = 0, 0, 0

            for i in values:
                if   i==3: self.win  += 1
                elif i==1: self.draw += 1
                elif i==0: self.loss += 1

            self.total = self.win*3 + self.draw*1
            print(f"{team}: {self.number_matches} {self.win} {self.draw} {self.loss} {self.total}")

numberMatches = pyip.inputInt("Enter the number of matches: ", min=1)
dictTeams = defaultdict(list)
competition = Score(numberMatches, dictTeams)
competition.appendScore()
competition.countScore()
\$\endgroup\$
2
\$\begingroup\$

These two lines:

self.dictTeams[rez[0]].append(3 if int(rez[1])>int(rez[3]) else 1 if int(rez[1])==int(rez[3]) else 0)
self.dictTeams[rez[2]].append(3 if int(rez[1])<int(rez[3]) else 1 if int(rez[1])==int(rez[3]) else 0)

are not very readable. Aside from your intention being unclear (e.g., what is rez and why do we care how big rez[1] is?), the lines are too long. Try this:

rez_1 = int(rez[1])
rez_3 = int(rez[3])
if rez_1 == rez_3:
    value_0 = 1
    value_2 = 1
elif rez_1 > rez_3:
    value_0 = 3
    value_2 = 0
else:
    value_0 = 0
    value_2 = 3

self.dictTeams[rez[0]].append(value_0)
self.dictTeams[rez[2]].append(value_2)

Even there, rez_1, rez_3, value_0, and value_2 should probably have more descriptive names.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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