Решение задачи Расчет отпускных с Яндекс Контест

Без пояснения   Просмотров: 3057


Вас попросили разработать класс, с помощью которого вычисляется размер (в рублях) оплачиваемого отпуска сотрудника за определенный период.

Нужно написать класс Vacations, со следующим функционалом:

1) метод update_salary(date, salary) - обновить зарплату, начиная с некоторой даты date. Считается, что зарплата сотрудника равна salary до тех пор, пока не существует даты date_new > date, для которой был вызван метод update_salary. Зарплата указана за один рабочий день!

Пример:

my_vacations = Vacations()
my_vacations.update_salary('01-01-2021', 100)
my_vacations.update_salary('01-06-2021', 500)
my_vacations.update_salary('01-01-2020', 5000)
Тогда зарплата сотрудника в период с 01-01-2020 по 31-12-2020 (включительно) была равна 5000, в период с 01-01-2021 по 31-05-2021 была равна 100, в период с 01-06-2021 по настоящее время зарплата сотрудника равна 500. Допускается обновление информации с более ранними датами как в примере. Также нормально, что размер заработной платы может стать меньше (кризис). Считается, что дата выхода сотрудника на работу - это минимальная дата для которой есть информация о выплатах.

2) вызов экземпляра класса должен принимать на вход две даты: дата начала отпуска и дата окончания отпуска (включительно) и возвращать размер отпускной выплаты. Отпускная выплата - это средняя зарплата в день за расчетный период (как он определяется см. ниже), умноженная на количество дней в отпуске. Считается, что сотрудник все еще работает в компании в момент, когда запрашивается информация об отпускных выплатах.

Пример:

my_vacations = Vacations()
my_vacations.update_salary('01-01-2021', 10000)
vacation_salary = my_vacations('01-01-2021', '01-02-2021')
Количество отпускных дней не ограничено. В расчет берутся данные за последние 365 дней, не включая первый день отпуска (то есть если дата начала отпуска 01-01-2021, то нужно брать данные с 01-01-2020 по 31-12-2020), при этом если сотрудник работает меньше года, берется весь период его работы. Если дата выхода сотрудника на работу больше или равна дате начала отпуска (то есть ВСЕ даты, переданные вызовам метода .update_salary к моменту вызова экземпляра класса, больше или равны дате начала отпуска), среднюю зарплату в день за расчетный период считайте равной 0 (в примере выше vacation_salary равна 0).

Теперь, мы поняли, что средняя зарплата в день за расчетный период = (общее количество заработанных денег за расчётный период) / (количество дней (считаем их все рабочими) в расчетном периоде).

Общее количество заработанных денег за расчетный период - это сумма денег, которую заработал сотрудник за последние min(365, все отработанные дни), СЧИТАЯ, ЧТО КАЖДЫЙ ДЕНЬ БЫЛ РАБОЧИМ и за него была выплачена дневная зарплата.

Код

import sys
import datetime


class Vacations:
    def __init__(self):
        self.period = {}

    def update_salary(self, date, salary):
        self.period[date] = salary

    @staticmethod
    def get_days(a, b):
        if a == b:
            return 0
        a = a.split('-')
        b = b.split('-')
        aa = datetime.date(int(a[2]), int(a[1]), int(a[0]))
        bb = datetime.date(int(b[2]), int(b[1]), int(b[0]))
        cc = aa - bb
        dd = str(cc)
        return abs(int(dd.split()[0]))  # only days

    @staticmethod
    def compare_date(a, b):
        a = a.split('-')
        b = b.split('-')
        if int(a[2]) > int(b[2]):
            return 1
        elif int(a[2]) < int(b[2]):
            return 0
        elif int(a[1]) > int(b[1]):
            return 1
        elif int(a[1]) < int(b[1]):
            return 0
        elif int(a[0]) > int(b[0]):
            return 1
        elif int(a[0]) < int(b[0]):
            return 0
        else:
            return 1

    def __call__(self, *args):
        s = 0
        d = {}
        l = []
        for i in sorted(self.period):
            d[i] = self.period[i]
            l.append(i)
        for i in range(len(l)):
            for j in range(len(l)):
                if self.compare_date(l[i], l[j]) == 0:
                    l[i], l[j] = l[j], l[i]

        l.append('12-12-9999')
        # print(l)
        if l[0] == args[0]:
            return 0
        # print("list = ", l)
        idx = 0
        for i in range(len(l) - 1):
            b1 = self.compare_date(args[0], l[i])
            b2 = self.compare_date(args[0], l[i + 1]) == 0
            if b1 and b2:
                idx = i
                break
        # print("idx = ", idx)
        days = self.get_days(args[0], l[idx])
        s += days
        salary = days * int(d[l[idx]])
        idx -= 1
        # print("days = ", days)
        # print("salary = ", salary)
        while s < 366 and idx >= 0:
            days = self.get_days(l[idx + 1], l[idx])
            s += days
            salary += days * int(d[l[idx]])
            idx -= 1
        if s > 365:
            idx += 1
            salary -= (s - 365) * int(d[l[idx]])
            s = 365

        vac_days = abs((self.get_days(args[0], args[1]))) + 1
        return salary / s * vac_days


exec(sys.stdin.read())

         

Администратор Photo Автор: Администратор



Комментарии

Чтобы написать комментарии вам нужно войти в систему или зарегистрироваться

  1. Avatar
    Frank Benson
    2025-11-10 01:12:14

    Мориарти – это не просто маркетплейс, это портал в мир интриг, загадок и гениального зла. Вы попадаете в атмосферу, где каждое слово, каждая деталь продумана до мелочей, словно гениальный шахматный ход в партии, которую ведет сам профессор Мориарти.

    Сайт встречает вас мрачной элегантностью. Темные тона, стилизованные под викторианскую эпоху шрифты и динамичные элементы создают ощущение присутствия в тайном логове гения преступного мира. Навигация интуитивно понятна, но при этом каждый раздел таит в себе скрытые отсылки и намеки.Он затягивает в мир, где грань между гением и безумием размыта, а каждое решение может повлиять на исход игры. Готовы ли вы вступить в эту опасную игру?

    ВИЗИТКИ: "удалить пробелы"

    mega1 . to mgmarket6 . at mega2o2nde2gzktxse2fesqpyfeoma72qmvk3fkecip2l3uv3tbn5mad . onion

    Под управлением Мориарти, были созданы:
    - ///Mori-Coim.
    - ///Mori-Game.
    - ///Mori- casino.
    - ///Mega-приложение.
    - ///Youtube канал.
    - ///Бот медицинской помощи в telegram.
    - ///Бот юридической помощи в talegram.
    И это лишь начало!!!

    На youtube Вы можете увидеть такие видео как:
    - Я сделал своих подписчиков миллионерами. Заработал $60 МЛН за час!
    - Послание от МОРИАРТИ. $MORI COIN!
    - МОРИАРТИ: 60 Минут ГЕНИАЛЬНОГО общения обо ВСЕМ.
    - БОГ ЕСТЬ? Правда о Религии и Происхождении Человека!
    - Я создал лекарство от рака!
    - Учу Вас дышать: успех, власть, сила. Измени свою жизнь навсегда. Мориарти!
    - Как живёт МОРИАРТИ. Как стать умным - Метод спецслужб!
    - Я выполню любое ТВОЕ ЖЕЛАНИЕ!
    - Почта Мориарти - принимаем письма!


    И все это – под молчаливым наблюдением Профессора, играющего в свою дьявольскую шахматную партию.....
    ///M - это словно целая Вселенная, со своей жизненной экосистемой....



Заявка на расчет