Лаборанты проводят эксперимент и запросили разработку системы обработки данных. Результатами эксперимента должны стать пары рациональных чисел.
Для работы им требуются функции:
enter_results(first, second, ...)
— добавление данных одного или нескольких результатов (гарантируется, что количество параметров будет чётным);get_sum()
— возвращает пару сумм результатов экспериментов;get_average()
— возвращает пару средних арифметических значений результатов экспериментов.
Все вычисления производятся с точностью до сотых.
Примечание
В решении не должно быть вызовов требуемых функций.
Пример
Ввод
enter_results(1, 2, 3, 4, 5, 6)
print(get_sum(), get_average())
enter_results(1, 2)
print(get_sum(), get_average())
Вывод
(9, 12) (3.0, 4.0)
(10, 14) (2.5, 3.5)
Ввод
enter_results(3.5, 2.14, 45.2, 37.99)
print(get_sum(), get_average())
enter_results(5.2, 7.3)
print(get_sum(), get_average())
enter_results(1.23, 4.56, 3.14, 2.71, 0, 0)
print(get_sum(), get_average())
Вывод
(48.7, 40.13) (24.35, 20.07)
(53.9, 47.43) (17.97, 15.81)
(58.27, 54.7) (9.71, 9.12)
Решение
Достаточно простая задача. Придется вспомнить как расширять список несколькими значениями, и решить для себя будете вы пересчитывать сумму четных и нечетных элементов каждый раз или сделаете один раз при добавлении новых элементов.
Первый вариант решения – добавление чисел в список и пересчет суммы и среднего каждый раз, когда приходит запрос.
Второй вариант решения – накопление суммы по мере накопления чисел, расчет среднего по запросу.
В комментариях упоминается еще один способ решения, но он более сложный и трудозатратный – его реализация интересна только с точки зрения вопроса как всегда иметь вычисленное среднее значение без фактического накопления суммы чисел.
Посмотреть код
Решение
data = []
odds = []
evens = []
def enter_results(*numbers):
global data, odds, evens
data.extend(list(numbers))
odds = data[::2]
evens = data[1::2]
def get_sum():
return round(sum(odds), 2), round(sum(evens), 2)
def get_average():
return round(sum(odds) / len(odds), 2), round(sum(evens) / len(evens), 2)
Решение
is_even = True
odds_counter = 0
evens_counter = 0
odds_sum = 0
evens_sum = 0
def enter_results(*numbers):
global is_even, odds_counter, evens_counter, odds_sum, evens_sum
for number in numbers:
if is_even:
evens_counter += 1
evens_sum += number
else:
odds_counter += 1
odds_sum += number
is_even = not is_even
def get_sum():
return round(evens_sum, 2), round(odds_sum, 2)
def get_average():
return round(evens_sum / evens_counter, 2), round(odds_sum / odds_counter, 2)
Я выбрал путь каждый раз считать заново сумму и как мне кажется это хорошо потому что я как минимум ушел от ошибки
Пока писал нашел комментарий в группе что округлять не надо было чтобы пройти тесты
дела…..
“””В эфире рубрика «Эксперименты»”””
left = ()
right = ()
def enter_results(*args: float) -> tuple:
global left, right
new_left = list(args[::2])
a = list(args[::])
a.insert(0, 0)
new_right = list(a[::2])
new_right.pop(0)
left = list(left)
left.extend(new_left)
right = list(right)
right.extend(new_right)
return right, left
def get_sum() -> tuple:
sum_left = sum(map(float, left))
sum_right = sum(map(float, right))
return sum_left, sum_right
def get_average() -> tuple:
from statistics import mean
avg_left = float(mean(left))
avg_right = float(mean(right))
return avg_left, avg_right
Эту задачу можно решать не накапливая сами значения, а считая напрямую среднее арифметическое. Но его реализация будет немного сложнее представленного варианта.
Основная идея в том, что если мы знаем сколько чисел мы уже учли в нашем среднем, мы можем легко восстановить сумму всех чисел умножив среднее арифметическое на количество учтенных чисел. Остается прибавить к сумме наше число и поделить уже на новое количество чисел.
average = (average * counter + number)/(counter + 1)
где counter – количество уже учтенных элементов.
действительно интересное решение
спасибо
я думал что оно будет проще
Реализовал еще один способ решения задачи без накопления чисел, через прямой подсчет их количества и сумм. Он отличен от того, что мы обсуждали выше.
круто))
тоже хочу попозже попробовать
будет теперь эталон с которым можно сравнить мои ошибки)))
Зато потренировался писать тест
from random import uniform
from G import enter_results, get_sum, get_average
from G_SK import enter_results_, get_sum_, get_average_
total = wrong = 0
for _ in range(1000):
for count in range(1, 201):
r_list = [uniform(1, 1001) for _ in range(10)]
total += 1
enter_results(*r_list)
enter_results_(*r_list)
# print(r_list)
# print(get_sum_())
# print(get_sum())
# print()
# print(get_average_())
# print(get_average())
if get_sum_() != get_sum():
wrong += 1
print(f’Тест номер: {total}, данные: {r_list},\n\n ожидали: \n\n{get_sum_()}, \nполучили: \n\n{get_sum_()}’) # noqa # nopep8
if get_average_() != get_average():
wrong += 1
print(f’Тест номер: {total}, данные: {r_list},\n\n ожидали: \n\n{get_average_()}, \n\nполучили: \n\n{get_average()}’) # noqa # nopep8
print(f’Всего сделано тестов: {total}, ошибок: {wrong}({wrong/total*100:.2f}%)’) # noqa # nopep8
Очень странно, что в разделе функции высших порядков не предусмотренно такое решение… Естественно чекер его не пропустит, поскольку ввод отличается. Но на мой взгляд суть данного раздела именно в этом.
def enter_results(*args):
first = []
second = []
for i in range(0, len(args), 2):
first.append(float(args[i]))
second.append(float(args[i + 1]))
def get_sum(first, second):
return (round(sum(first), 2),
round(sum(second), 2))
def get_average(first, second):
sum_first, sum_second = get_sum(first, second)
return (round(sum_first / len(first), 2),
round(sum_second / len(second), 2))
return get_sum(first, second), get_average(first, second)
get_sum, get_average = enter_results(1, 2, 3, 4, 5, 6)
print(get_sum, get_average)
</pre>