Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 88 additions & 0 deletions lesson_05/task_1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
"""
1. Пользователь вводит данные о количестве предприятий, их наименования и прибыль
за 4 квартала (т.е. 4 отдельных числа) для каждого предприятия.
Программа должна определить среднюю прибыль (за год для всех предприятий)
и вывести наименования предприятий, чья прибыль выше среднего и отдельно
вывести наименования предприятий, чья прибыль ниже среднего.

Подсказка:
Для решения задачи обязательно примените какую-нибудь коллекцию из модуля collections
Для лучшее освоения материала можете даже сделать несколько решений этого задания,
применив несколько коллекций из модуля collections

Пример:
Введите количество предприятий для расчета прибыли: 2
Введите название предприятия: Рога
через пробел введите прибыль данного предприятия
за каждый квартал(Всего 4 квартала): 235 345634 55 235

Введите название предприятия: Копыта
через пробел введите прибыль данного предприятия
за каждый квартал(Всего 4 квартала): 345 34 543 34

Средняя годовая прибыль всех предприятий: 173557.5
Предприятия, с прибылью выше среднего значения: Рога

Предприятия, с прибылью ниже среднего значения: Копыта
"""

from collections import namedtuple, defaultdict


def get_firms_data(number):
"""Формирует словарь с шаблоном namedtuple по умолчанию
и заполняет его данными по предприятиям за 4 квартала"""
FIRM_PROFIT = namedtuple('Profits', 'I II III IV sum_profit')
firms_dict = defaultdict(FIRM_PROFIT)
try:
for _ in range(number):
firm_name = input('\nВведите название предприятия: ')
firm_profit = [float(elem)for elem in input(
'Через пробел введите прибыль данного предприятия поквартально: ').split()]
sum_profit = sum(firm_profit)
firms_dict[firm_name] = FIRM_PROFIT(*firm_profit, sum_profit)
except ValueError:
print('\nНеобходимо ввести числа в качестве значений прибыли!')
return get_firms_data(number)
except TypeError:
print('\nНеобходимо ввести прибыль за четыре квартала!')
return get_firms_data(number)
return firms_dict


def average_profit(firms_dct):
"""Считает среднюю прибыль по всем предприятиям"""
profit = sum(value.sum_profit for value in firms_dct.values())
return profit / len(firms_dct)


def below_profit(firms_dct, profit):
"""Возвращает генератор, содержащий наименования предприятий,
прибыль которых ниже средней"""
result = (key for key in firms_dct if firms_dct[key].sum_profit < profit)
return result


def over_profit(firms_dct, profit):
"""Возвращает генератор, содержащий наименования предприятий,
прибыль которых выше средней"""
result = (key for key in firms_dct if firms_dct[key].sum_profit > profit)
return result


def firms_count():
"""Возвращает количество предприятий"""
try:
count = int(input('\nВведите количество фирм: '))
except ValueError:
print('\nНеобходимо ввести целое число!')
return firms_count()
return count


firms_num = firms_count()
firms_data = get_firms_data(firms_num)
av_profit = average_profit(firms_data)
print(f'\nСредняя годовая прибыль всех предприятий: {av_profit}')
print('\nПредприятия с прыбылью выше средней:', *over_profit(firms_data, av_profit), sep='\n')
print('\nПредприятия с прыбылью ниже средней:', *below_profit(firms_data, av_profit), sep='\n')
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

выполнено

66 changes: 66 additions & 0 deletions lesson_05/task_2_OOP.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
"""
2. Написать программу сложения и умножения двух шестнадцатеричных чисел.
При этом каждое число представляется как массив, элементы которого это цифры числа.
Например, пользователь ввёл A2 и C4F. Сохранить их как [‘A’, ‘2’] и [‘C’, ‘4’, ‘F’] соответственно.
Сумма чисел из примера: [‘C’, ‘F’, ‘1’], произведение - [‘7’, ‘C’, ‘9’, ‘F’, ‘E’].

Подсказка:
Для решения задачи обязательно примените какую-нибудь коллекцию из модуля collections
Для лучшее освоения материала можете даже сделать несколько решений этого задания,
применив несколько коллекций из модуля collections
Также попробуйте решить задачу вообще без collections и применить только ваши знания по ООП
(в частности по перегрузке методов)
"""

# реализация через ООП, принцип расчётов тот же, что и в функциональной реализации,
# но переопределены методы сложения и умножения и не используется defaultdict


class HexNumber:

alphabet = '0123456789ABCDEF'

def __init__(self, number: str):
self.number = list(number)

def __str__(self):
return str(self.number)

def from_hex(self):
"""Переводит шестнадцатеричное число в виде списка в десятичное число"""
num = dict()
number = self.number[::-1]
for idx in range(len(number)):
if idx not in num:
num[idx] = []
num[idx].append(number[idx])
result = [int(elem, 16) * 16 ** key
for key in num
for elem in num[key]]
return sum(result)

def to_hex(self, number, result=''):
"""Переводит десятичное число в объект класса"""
if number == 0:
return HexNumber(result)
result = self.alphabet[number % 16] + result
return self.to_hex(number // 16, result)

def __add__(self, other):
"""Складывает два объекта класса и возвращает объект класса"""
result = self.from_hex() + other.from_hex()
return self.to_hex(result)

def __mul__(self, other):
"""Перемножает два объекта класса и возвращает объект класса"""
result = self.from_hex() * other.from_hex()
return self.to_hex(result)


if __name__ == '__main__':

number_1 = HexNumber(input('Введите первое число: '))
number_2 = HexNumber(input('Введите второе число: '))
print(f'Числа теперь выглядят так: {number_1} и {number_2}')
print(f'Сумма чисел: {number_1 + number_2}')
print(f'Произведение чисел: {number_1 * number_2}')
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

выполнено

66 changes: 66 additions & 0 deletions lesson_05/task_2_collections.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
"""
2. Написать программу сложения и умножения двух шестнадцатеричных чисел.
При этом каждое число представляется как массив, элементы которого это цифры числа.
Например, пользователь ввёл A2 и C4F. Сохранить их как [‘A’, ‘2’] и [‘C’, ‘4’, ‘F’] соответственно.
Сумма чисел из примера: [‘C’, ‘F’, ‘1’], произведение - [‘7’, ‘C’, ‘9’, ‘F’, ‘E’].

Подсказка:
Для решения задачи обязательно примените какую-нибудь коллекцию из модуля collections
Для лучшее освоения материала можете даже сделать несколько решений этого задания,
применив несколько коллекций из модуля collections
Также попробуйте решить задачу вообще без collections и применить только ваши знания по ООП
(в частности по перегрузке методов)
"""

from collections import defaultdict

# Использовала defaultdict со списком по умолчанию для сохранения позиций элементов
# Переводила числа в десятичные поэлементно, затем складывала или умножала и
# переводила результат обратно в нужный формат с помощью рекурсивной функции


def from_string(number):
"""Переводит число в строковом формате в список"""
return list(number)


def from_hex(number):
"""Переводит шестнадцатеричное число в виде списка в десятичное число"""
num = defaultdict(list)
number = number[::-1]
for idx in range(len(number)):
num[idx].append(number[idx])
result = [int(elem, 16) * 16**key
for key in num
for elem in num[key]]
return sum(result)


def to_hex(number, result=''):
"""Переводит десятичное число в шестнадцатеричное число в виде списка"""
alphabet = '0123456789ABCDEF'
if number == 0:
return list(result)
result = alphabet[number % 16] + result
return to_hex(number // 16, result)


def add_numbers(num_1, num_2):
"""Складывает два шестнадцатеричных числа и возвращает результат в виде списка"""
result = from_hex(num_1) + from_hex(num_2)
return to_hex(result)


def mul_numbers(num_1, num_2):
"""Умножает два шестнадцатеричных числа и возвращает результат в виде списка"""
result = from_hex(num_1) * from_hex(num_2)
return to_hex(result)


if __name__ == '__main__':

number_1 = from_string(input('Введите первое число: '))
number_2 = from_string(input('Введите второе число: '))
print(f'Числа теперь выглядят так: {number_1} и {number_2}')
print(f'Сумма чисел: {add_numbers(number_1, number_2)}')
print(f'Произведение чисел: {mul_numbers(number_1, number_2)}')
152 changes: 152 additions & 0 deletions lesson_05/task_3.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
"""
Задача 3.
В соответствии с документацией Python,
deque – это обобщение стеков и очередей.
Вот основное правило: если вам нужно что-то быстро дописать или вытащить, используйте deque.
Если вам нужен быстрый случайный доступ, используйте list.

Задача: создайте простой список (list) и очередь (deque).
Выполните различные операции с каждым из объектов.
Сделайте замеры и оцените, насколько информация в документации
соответствует дейстивтельности.
"""

from collections import deque
from timer import timer
from random import randint


NUMBER = 5000


@timer(NUMBER)
def fill_obj(obj, num):
for _ in range(num):
obj.append(randint(1, 100))


@timer(NUMBER)
def left_app_deque(deq):
deq.appendleft(randint(1, 100))


@timer(NUMBER)
def left_insert(lst):
lst.insert(0, randint(1, 100))


@timer(NUMBER)
def random_insert(obj):
pos = randint(0, len(obj) - 1)
obj.insert(pos, randint(1, 100))


@timer(NUMBER)
def element_get(obj):
idx = randint(0, len(obj) - 1)
elem = obj[idx]
return elem


@timer(NUMBER)
def pop_right(obj):
elem = obj.pop()
return elem


@timer(NUMBER)
def pop_left_deq(deq):
elem = deq.popleft()
return elem


@timer(NUMBER)
def pop_left_list(lst):
elem = lst.pop(0)
return elem


@timer(NUMBER)
def random_pop(obj):
idx = randint(0, len(obj) - 1)
elem = obj.pop(idx)
return elem


test_list = list()
test_deque = deque()

print('\nЗаполнение list и deque:')
print('list:', end=' ')
fill_obj(test_list, 100)
print('deque:', end=' ')
fill_obj(test_deque, 100)

# list: 0.2732127999999997
# deque: 0.2661854000000027
# Замеры показывают, что очередь заполняется незначительно быстрее, чем список

print('\nДобавление элемента в начало:')
print('list:', end=' ')
left_insert(test_list)
print('deque:', end=' ')
left_app_deque(test_deque)

# list: 1.3033582000000026
# deque: 0.00318570000000018
# Элементы в начало списка добавляются в гораздо медленнее,
# чем в начало очереди - что соответствует документации.

print('\nДобавление элемента в произвольную позицию:')
print('list:', end=' ')
random_insert(test_list)
print('deque:', end=' ')
random_insert(test_deque)

# list: 0.6128666999999923
# deque: 0.6984531000000018

# Добавление элемента в произвольную позицию в список происходит несколько быстрее,
# чем в очередь, впрочем незначительно.

print('\nПолучение значения элемента по индексу:')
print('list:', end=' ')
element_get(test_list)
print('deque:', end=' ')
element_get(test_deque)

# list: 0.003778700000016233
# deque: 0.09563959999998817

# А вот обращение к элементу по индексу в списке происходит значительно быстрее, чем в очереди, что соответствует
# документации.

print('\nЗабрать элемент справа:')
print('list:', end=' ')
pop_right(test_list)
print('deque:', end=' ')
pop_right(test_deque)

# list: 0.000668099999998617
# deque: 0.0006687999999948069

# Получение элемента справа в списке происходит почти за то же время (чуть быстрее), что и в очереди -
# разница настолько мала, что ею можно пренебречь.

print('\nЗабрать элемент слева:')
print('list:', end=' ')
pop_left_list(test_list)
print('deque:', end=' ')
pop_left_deq(test_deque)

# list: 0.4595461000000016
# deque: 0.00066099999999647

# А вот получение элемента из начала списка происходит невероятно долго по сравнению с той же операцией в очереди.
# Метод pop в очереди не позволяет извлекать элементы из произвольной позиции,
# что только подтверждает назначение класса.

# По результатам замеров видно, что информация в документации соответствует действительности:
# очередь незначительно хуже справляется с добавлением и извлечением элементов с конца,
# и гораздо быстрее выполняет операции извлечения и вставки элементов в начало, а вот при работе с обращением
# по индексу и вставкой или извлечением элементов из произвольной позиции имеет смысл обратиться к списку.
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

выполнено

Loading