В этой программе я собираюсь взять некоторую информацию о росте, весе и возрасте ученика и вернуть их среднее значение для сравнения. есть 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 ответа
Если я правильно понимаю, 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()
Важное правило, которое следует помнить о кодировании: если несколько ваших строк выглядят в основном одинаково, вы, вероятно, можете упростить свою программу с помощью циклов 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 кортеж для обоих учеников. На мой взгляд, это не очень удобно для чтения.

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