Created
September 21, 2015 08:56
-
-
Save macint0sh/5d1227deb66c0672db3a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/local/Cellar/python3/3.4.3/Frameworks/Python.framework/Versions/3.4/bin/python3.4 | |
| # -*- coding: utf-8 -*- | |
| __author__ = 'admin' | |
| api_url = "http://basicdata.ru/api/json/calend/" | |
| from functools import lru_cache | |
| import calendar | |
| import datetime | |
| import urllib.request | |
| import json | |
| def flatten(a): | |
| if isinstance(a, list): | |
| for b in a: | |
| for x in flatten(b): | |
| yield x | |
| else: | |
| yield a | |
| # Генерирует расписание на заданный год по умолчанию | |
| # Все дни с понедельника по пятницу отмечаются рабочими | |
| # Все субботы и воскресенья - выходными | |
| def generate_default_calendar(year): | |
| return group_by_month( | |
| map(lambda x: (x[0], x[1] < 6), | |
| map(lambda x: (x[0], x[1] + 1), | |
| filter(lambda x: x[0] > 0, | |
| flatten(calendar.Calendar.yeardays2calendar(calendar.Calendar(), year)) | |
| ) | |
| ) | |
| ) | |
| ) | |
| # Разделяет дни на группы по месяцам | |
| def group_by_month_inner(items): | |
| month = [] | |
| for day, flag in items: | |
| if month and month[-1][0] > day: | |
| # new month starting | |
| yield month | |
| month = [] | |
| month.append((day, flag)) | |
| if month: | |
| yield month | |
| def group_by_month(items): | |
| return list(group_by_month_inner(items)) | |
| # Загружает дни-исключения | |
| @lru_cache(maxsize=None) | |
| def load_exceptions(apiurl, year): | |
| return json.loads(urllib.request.urlopen(apiurl).read().decode('utf8'))["data"][str(year)] | |
| # Меняет значения структуры по умолчанию для дней-исключений | |
| def apply_exceptions(months, exc): | |
| i = 0 | |
| for m in months: | |
| newm = [] | |
| i += 1 | |
| for d in m: | |
| if str(i) in exc and str(d[0]) in exc[str(i)]: | |
| d = (d[0], exc[str(i)][str(d[0])]["isWorking"] != 2) | |
| newm.append(d) | |
| yield newm | |
| # Удаляет все выходные, конвертирует кортежи в простые дни месяца | |
| def filter_holidays(months): | |
| for m in months: | |
| yield list( | |
| map( | |
| lambda x: x[0], | |
| filter( | |
| lambda x: x[1], | |
| m | |
| ) | |
| ) | |
| ) | |
| # Получает все рабочие дни за определенные месяц/год в виде массива. Если указать месяц, вернет только его | |
| def get_workdays(year=None, month=None): | |
| if year is None and month is None: | |
| year = datetime.datetime.now().year | |
| month = datetime.datetime.now().month | |
| if month is None: | |
| return list(filter_holidays(apply_exceptions(generate_default_calendar(year), load_exceptions(api_url, year)))) | |
| else: | |
| return get_workdays(year)[month - 1] | |
| # Считает кол-в рабочих дней в году/месяце | |
| @lru_cache(maxsize=None) | |
| def count_workdays(year=None, month=None): | |
| if month is None and year is None: | |
| return len(get_workdays()) | |
| elif month is not None: | |
| return len(get_workdays(year, month)) | |
| else: | |
| return sum(list(map(lambda x: len(x), get_workdays(year))), 0) | |
| @lru_cache(maxsize=None) | |
| def _get_expected_hours(year, month, day): | |
| return len(list(filter(lambda x: x < day, get_workdays()))) * 8 | |
| # Возвращает сколько часов ты уже должен был отработать | |
| def get_expected_hours(): | |
| return _get_expected_hours(datetime.datetime.now().year, datetime.datetime.now().month, datetime.datetime.now().day) | |
| # Считает заработанные деньги исходя из зарплаты и кол-ва отработанны часов | |
| @lru_cache(maxsize=None) | |
| def earned(salary, hours): | |
| return hours / (count_workdays(datetime.datetime.now().year, datetime.datetime.now().month) * 8) * salary | |
| def print_earned_with_stats(hours, salary=None): | |
| if salary is None: | |
| salary = 50000 | |
| real = earned(salary, hours) | |
| expected = earned(salary, get_expected_hours()) | |
| print("Earned: ", real, " Expected: ", expected) | |
| if real > expected: | |
| print("Well done, you've already earned extra ", real - expected, " money -", hours - get_expected_hours(), | |
| " extra hours worked") | |
| elif real < expected: | |
| print("You should work extra ", get_expected_hours() - hours, " hours to catch schedule") | |
| else: | |
| print("Going on schedule!") | |
| if __name__ == '__main__': | |
| import sys | |
| _salary = None | |
| _hours = None | |
| if len(sys.argv) > 1: | |
| _hours = int(sys.argv[1]) | |
| if len(sys.argv) > 2: | |
| _salary = int(sys.argv[2]) | |
| if _hours is None: | |
| _hours = 8 | |
| print_earned_with_stats(_hours, _salary) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment