# 1. Реализовать скрипт, в котором должна быть предусмотрена функция расчета заработной платы сотрудника.
# В расчете необходимо использовать формулу: (выработка в часах * ставка в час) + премия.
# Для выполнения расчета для конкретных значений необходимо запускать скрипт с параметрами.

def pay_calc():
    """
    Функция не имеет входных аргументов, при запуске запрашивает отработанные часы, стоимость одного часа
    и размер премии.
    Возвращает  значение по формуле (выработка в часах * ставка в час) + премия.

    """

    x = float(input('Введите количество отработанных часов : '))
    y = float(input('Введите стоимость труда за 1 час : '))
    c = float(input('Введите  размер премии - '))
    pay = (x * y) + c
    return pay

print(f'Размер заработной платы составил: {pay_calc() } рублей.')


# 2. Представлен список чисел.
# Необходимо вывести элементы исходного списка, значения которых больше предыдущего элемента.
# Подсказка: элементы, удовлетворяющие условию, оформить в виде списка.
# Для формирования списка использовать генератор.
# Пример исходного списка: [300, 2, 12, 44, 1, 1, 4, 10, 7, 1, 78, 123, 55].
# Результат: [12, 44, 4, 10, 78, 123].

my_list = [300, 2, 12, 44, 1, 1, 4, 10, 7, 1, 78, 123, 55]


def gen_list(my_list):
    """

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

    """
    q = len(my_list)
    for it in range(1, q):
        if int(my_list[it]) > int(my_list[it - 1]):
            a = my_list[it]
            yield a



new_list = []
for it in gen_list(my_list): # Запускаем функцию с каждым элементом списка поочередно.
   new_list.append(it) # Добавляем возвращаемый элемент в новый список.

print(new_list) # Старый список, проста для наглядности.
print(my_list) # Новый список.

# 3. Для чисел в пределах от 20 до 240 найти числа, кратные 20 или 21.
# Необходимо решить задание в одну строку.
# Подсказка: использовать функцию range() и генератор.

new_list = [el for el in range(20,240) if el % 20 == 0 or el % 21 == 0] # Добавляем элемент в список если он без остатка
#                                                                         делится на 20 или 21.

print(new_list) # Печатаем новый список.

# 4. Представлен список чисел. Определить элементы списка, не имеющие повторений.
# Сформировать итоговый массив чисел, соответствующих требованию.
# Элементы вывести в порядке их следования в исходном списке.
# Для выполнения задания обязательно использовать генератор.
# Пример исходного списка: [2, 2, 2, 7, 23, 1, 44, 44, 3, 2, 10, 7, 4, 11].
# Результат: [23, 1, 3, 10, 4, 11]

my_list = [2, 2, 2, 7, 23, 1, 44, 44, 3, 2, 10, 7, 4, 11]
new_list = []


new_list = [el for el in my_list if (my_list.count(el)) == 1] # Добавляем элемент в список если
#                                     он встечается в списке один раз, проверяем это с помощью .count

print(new_list) # Выводим новый список.

# 5. Реализовать формирование списка, используя функцию range() и возможности генератора.
# В список должны войти четные числа от 100 до 1000 (включая границы).
# Необходимо получить результат вычисления произведения всех элементов списка.
# Подсказка: использовать функцию reduce().

from functools import reduce # Импоритруем reduce из functools


def my_func (pred_el, el):
    """
    Функция принимает два позиционных числовых значения и возвращает их произведение

    """
    return pred_el * el  # pred_el - предыдущий элемент *  el - текущий элемент


my_list = [el for el in range(100, 1002) if el % 2 == 0]  # Создаем список состоящий из четных чисел от 100 до 1000

result = (reduce(my_func, my_list)) # Произведение всех элементов списка

print(result)

# 6. Реализовать два небольших скрипта:
# а) итератор, генерирующий целые числа, начиная с указанного,
# б) итератор, повторяющий элементы некоторого списка, определенного заранее.
# Подсказка: использовать функцию count() и cycle() модуля itertools.
# Обратите внимание, что создаваемый цикл не должен быть бесконечным.
# Необходимо предусмотреть условие его завершения.
# Например, в первом задании выводим целые числа, начиная с 3, а при достижении числа 10 завершаем цикл.
# Во втором также необходимо предусмотреть условие, при котором повторение элементов списка будет прекращено.

from itertools import count, cycle # Импортируем функции.


# а) итератор, генерирующий целые числа, начиная с указанного,

def my_iterator(n):
    """
    Функция-итератор, генерирующий целые числа, начиная с указанного (входящего аргумента) и завершая 15.

    """
    for el in count(n):
        if el > 15:
            break
        else:
            yield el

from itertools import cycle

def my_generator (n):
    """
    Функция создающая итератор для формирования бесконечного цикла набора значения.
    Аргумент n, указывает сколько раз сработае итератор.

    """
    c = 0
    for el in cycle("АБВГДЕЖЗ"):
        if c >= n:
            break
        yield el
        c = c + 1

for it in my_generator(15):
    print(it)


# 7. Реализовать генератор с помощью функции с ключевым словом yield, создающим очередное значение.
# При вызове функции должен создаваться объект-генератор.
# Функция должна вызываться следующим образом: for el in fact(n).
# Функция отвечает за получение факториала числа.
# В в цикле необходимо выводить только первые n чисел, начиная с 1! и до n!.

def fact(n):
    """

    Функция отвечает за получение факториала числа.
    Принимает n.
    Возвращает первые n чисел, начиная с 1! и до n!

    """
    temp = 1
    for i in range(1, n + 1):
        temp = i * i
        yield temp


n = int(input("Факториал какого числа Вы хотели бы узнать? "))
for _ in fact(n):
    print(_ , end=' ')