программа здравоохранения

В этой программе я собираюсь взять некоторую информацию о росте, весе и возрасте ученика и вернуть их среднее значение для сравнения. есть 2 класса для сравнения, и программа работает нормально, но я хочу знать, есть ли способ улучшить эту программу и сделать ее лучше?

information = []
for i in range(8):
    information.append(input().split())

information = [[int(x) for x in line] for line in information]



class Student_A:

    def __init__(self, age, height, weight, age_b, height_b, weight_b):
        self.age = age
        self.height = height
        self.weight = weight
        self.age_b = age_b
        self.height_b = height_b
        self.weight_b = weight_b

    def get_info(self):
        a = (sum(self.age) / len(self.age))
        b = (sum(self.height) / len(self.height))
        c = (sum(self.weight) / len(self.weight))
        e = (sum(self.age_b) / len(self.age_b))
        f = (sum(self.height_b) / len(self.height_b))
        g = (sum(self.weight_b) / len(self.weight_b))

        yield a
        yield b
        yield c  
        yield e  
        yield f
        yield g 

        if b == f and c == g:
            print('Same')
        elif b == f:
            if c < g:
                print('A')
            else:
                print('B')
        elif b > f:
            print('A')
        else:
            print('B')

class_a = Student_A(information[1], information[2], information[3], information[5], information[6], information[7])
class_a = class_a.get_info()
for item in class_a:
    print(item)

ввод должен быть таким:

# inputs must be entered line by line not every single number

5 # number of students
16 17 15 16 17
180 175 172 170 165
67 72 59 62 55
5
15 17 16 15 16
166 156 168 170 162
45 52 56 58 47

вывод должен быть таким:

16.2
172.4
63.0
15.8
164.4
51.6
A # the best class

2 ответа
2

Если я правильно понимаю, Student_A class — странное существо: (1) он хранит списки возрастов, роста и веса для двух групп учеников; (2) вычисляет средние значения возраста, роста и веса для каждой из групп; и (3) он имеет некоторую логику для сравнения средних значений. Если мы спросим, ​​какая значимая сущность реального мира Student_A экземпляр должен представлять, его нет. Это говорит о том, что есть проблема с дизайном.

Вот класс, который имеет смысл в реальном мире:

class StudentGroup:

    def __init__(self, ages, heights, weights):
        # Note the use of plural variable names.
        # Don't call it an "age" if it's really a list of ages.
        self.ages = ages
        self.heights = heights
        self.weights = weights

Каждый StudentGroup экземпляр будет содержать возраст, рост и вес для
одна группа. Программа создаст два экземпляра класса, а затем выполнит другие вычисления и сравнения.

Классу нужен способ получения средних значений. Это хороший вариант использования
@property и стандартная библиотека statistics модуль.

from statistics import mean

class StudentGroup:

    @property
    def avg_age(self):
        return mean(self.ages)

    # Do the same for height and weight.

Чтобы сравнить группы, вам просто нужно реализовать два метода в классе и включить total_ordering декоратор. Он позволяет вам напрямую сравнивать два экземпляра класса различными способами (<, <=, ==, >=, >), при условии, что вы реализуете два метода, показанных ниже.

from functools import total_ordering

@total_ordering
class StudentGroup:

    def __eq__(self, other):
        return (
            self.avg_height == other.avg_height and
            self.avg_weight == other.avg_weight
        )

    def __lt__(self, other):
        # You can implement this one. Return True if self < other.

Что касается синтаксического анализа ввода, я предлагаю вам организовать синтаксический анализ в соответствии с более крупной целью программы: не собирать 8 строк ввода; вместо этого дважды соберите 4 строки ввода. Кроме того, поместите весь свой код в функции:

def line_to_ints(line):
    # A utility function to parse one line of user input.
    return [int(x) for x in line.split()]

def main():
    # Create two StudentGroup instances.
    sgs = []
    for _ in range(2):
        # Get lines of input from user. Don't parse here.
        lines = [input() for _ in range(4)]

        # Parse the needed lines into a list-of-list of ints.
        params = [line_to_ints(line) for line in lines[1:]]

        # Create a new StudentGroup instance.
        sgs.append(StudentGroup(*params))

    # Compare them.
    msg = (
        'Same' if sgs[0] == sgs[1] else
        'A'    if sgs[0] >  sgs[1] else
        'B'
    )

    # Report.
    print(msg)

if __name__ == '__main__':
    main()

  • можно ли печатать внутри функции? потому что как только вы сказали печатать вне функции

    — Xus

  • 2

    @Xus Печать внутри функций — это хорошо — определенно лучший способ. Ключевой вопрос — что это за функция? Функции с вычислениями не должны печатать; они должны возвращать данные или изменять данные. Печать должна происходить во внешней оболочке программы внутри функции, которая не делает ничего сложного (обычно это означает main() функция). Чтобы просмотреть мой собственный код в ответе выше, можно утверждать, что большую часть работы следует делегировать двум вспомогательным функциям: get_user_input() и parse(). Но все же напечатайте main().

    — FMc


  • 1

    спасибо я понял

    — Xus


Важное правило, которое следует помнить о кодировании: если несколько ваших строк выглядят в основном одинаково, вы, вероятно, можете упростить свою программу с помощью циклов for.

Это верно и для вашего кода. Если вместо хранения всей информации в разных переменных вы просто храните их в одном кортеже для каждого учащегося, вы можете значительно сократить свой код с помощью циклов for.

information = []
for i in range(8):
    information.append(input().split())

information = [[int(x) for x in line] for line in information]



class Student_A:

    def __init__(self, age, height, weight, age_b, height_b, weight_b):
        self.student_a = (age, height, weight)
        self.student_b = (age_b, height_b, weight_b)

    def get_info(self):
        abc = []
        efg = []
        for i in range(len(self.student_a)): 
            abc.append(sum(self.student_a[i]) / len(self.student_a[i]))
            efg.append(sum(self.student_b[i]) / len(self.student_b[i]))

        for info in abc:
            yield info
        for info in efg:
            yield info

        if abc[1] == efg[1] and abc[2] == efg[2]:
            print('Same')
        elif abc[1] == efg[1]:
            if abc[2] < efg[2]:
                print('A')
            else:
                print('B')
        elif abc[1] > efg[1]:
            print('A')
        else:
            print('B')

class_a = Student_A(information[1], information[2], information[3], information[5], information[6], information[7])
class_a = class_a.get_info()
for item in class_a:
    print(item)

Обратите внимание, что for i in range(len(self.student_a)): работает только потому что self.student_a и self.student_b имеют одинаковую длину. Это просто sum / len расчет по каждому элементу информации.

Кроме того, вместо того, чтобы выдавать каждую переменную, теперь просто перебирайте abc и efg!

Последний сложный оператор if также должен использовать индексы вместо переменных, но благодаря моим информативным именам списков он должен быть простым для понимания.

Если есть еще что-то, что вы хотели бы уточнить, не стесняйтесь спрашивать меня!

Примечание. Если вы хотите еще больше сократить свой код, у вас может быть только 1 кортеж для обоих учеников. На мой взгляд, это не очень удобно для чтения.

    Добавить комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *