Главная страница  Карта сайта  Печать  Написать письмо  Twitter  RSS
Войти
Персональный сайт
Стеллецкого Владимира
Обновлено: 29.06.2020 г.

Python

Некоторое время назад я решил изучить какой-нибудь ещё язык программирования, без конкретных задач, а пока для себя - глядишь потом пригодится когда-нибудь. После анализа текущего выбора языков программирования я остановил свой выбор на Python или Ruby. После ещё некоторых колебаний склонился всё же к Python. Может быть когда-нибудь и до Ruby руки дойдут.

Так как пока только учусь, то и решаемые задачи простые, и возможно, с ошибками. Если их обнаружите, или сможете предложить более "правильное" решение, или же предложите задачку для решения - пишите, буду очень признателен.

Ссылки (18.12.2019) #

«  ‹  1  2  следующая ›  последняя »

Python 3.9 (29.06.2020) #

В преддверие выхода новой версии языка программирования Python наткнулся на две статьи с анонсами будущих нововведений:

PS Это первая версия, которая выйдет после того, как создатель языка Python Гвидо Ван Россум покинул пост "великодушного пожизненного диктатора" (BDFL) проекта.

Интересная задачка (22.03.2020) #

Наткнулся на интересную задачку по программированию:

Бригада скорой помощи выехала по вызову в один из отделенных районов. К сожалению, когда диспетчер получил вызов, он успел записать только адрес дома и номер квартиры K1, а затем связь прервалась. Однако он вспомнил, что по этому же адресу дома некоторое время назад скорая помощь выезжала в квартиру K2, которая расположена в подъезда P2 на этаже N2. Известно, что в доме M этажей и количество квартир на каждой лестничной площадке одинаково. Напишите программу, которая вычисляет номер подъезда P1 и номер этажа N1 квартиры K1.

Входные данные:
Во входном файле записаны пять положительных целых чисел K1, M, K2, P2, N2. Все числа не превосходят 1000.

Выходные данные:
Выведите два числа P1 и N1. Если входные данные не позволяют однозначно определить P1 или N1, вместо соответствующего числа напечатайте 0 (ноль). Если входные данные противоречивы, напечатайте два числа –1 (минус один).

Примеры:

Ввод
89
20
41
1
11
Вывод
2 3

Ввод
11
1
1
1
1
Вывод
0 1

Своё решение планирую опубликовать в ближайшее время.

Новые фичи Python 3.8 и самое время перейти с Python 2 (25.01.2020) #

Наткнулся на статью с таким заголовком и решил ссылку на неё себе сохранить, тем более, что до сих пор использую Python 2.

Конечно, это не все нововведения третьей версии, так что Вас ждет ещё не мало открытий.

Табель сотрудников (28.10.2019) #

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

В итоге остановился на web-страничке (HTML с CSS и JS) и скрипте на Python, который её формирует на основании информации из базы данных.

Табель сотрудников

На этой несложной задачке с удовольствием освежил в памяти знания по всем четырём технологиям.

Также хотел бы отметить два удобных параметра запуска Python:

  • -i - после работы программы/скрипта войти в диалоговый режим. Это бывает удобно при отладке и поиске ошибок в скриптах (или при отказах).
  • -3 - выводит замечания к коду (вполне, возможно, работоспособному), который не сможет быть запущен в Python 3.x. Актуально, если приложение написано на второй версии, но Вы задумываетесь о переходе на третью версию.

Комментарии

Мой комментарий (29.06.2020)
Почти через год использования данного "решения" сделал ещё одну небольшую доработку - улучшил отображение этой странички на мобильных устройствах (постарался максимально сократить ширину таблицы).
Теперь, в случае открытия табеля с устройства с небольшим разрешением экрана, в таблице автоматически скрываются: год в дате, а также инициалы сотрудников (это позволило выиграть чуть более четверти от начальной ширины таблицы и, соответственно, улучшить отображение на маленьких экранах).
Сделать это было не так сложно, так как изначально вёрстка страницы была несложная и приближенная к стандартам. С технической точки зрения на этапе формирования страницы выделил потенциально скрываемый текст (назначением отдельного класса), а потом добавил адаптивный стиль:
@media screen and (max-width: 1150px) {
    .io {
        display: none;
    }
    .year {
        display: none;
    }
}

Пенсионная реформа (06.02.2019) #

Была у меня одна простенькая задачка - определять по дате рождения пенсионер человек или нет.

До недавнего времени отлично работало следующее решение: из текущей даты вычитаем 60 и 55 лет и получаем минимальную дату рождения мужчины и женщины, для которых наступил пенсионный возраст. После этого сравниваем эту дату с датой рождения конкретного человека и определяем пенсионер он или нет. Ниже приведён код данного решения (только обсуждаемая часть):

import datetime

now_date = datetime.date.today() # Текущая дата (без времени)
cur_year = now_date.year # Год текущий
men_retirement_date = now_date.replace(year = cur_year - 60)
women_retirement_date = now_date.replace(year = cur_year - 55)

...

for people in list:
    if isMale:
        isPensioner = brs_date < men_retirement_date
    else:
        isPensioner = brs_date < women_retirement_date    

Решение было всем хорошее, кроме одного момента - при вычитании годов (для определения даты выхода на пенсию) не учитывалось, что в високосные годы в феврале на 1 день больше, поэтому при запуске 29 февраля программка вылетела с ошибкой преобразования даты.

Теперь же, после принятия новой пенсионной реформы, появился переходный период и пришлось писать отдельную функцию для того же функционала:

import datetime

def isPensioner(isMale, dtBirth):
    """Вычисляет является человек пенсионером или нет.

    Параметры:
      isMale - пол: для мужчин - True, для женщин - False
      dtBirth - дата рождения"""

    is_pensioner = False # пенсионер?
    retirement_age = 55
    addhalfyear = False

    retirement_date = dtBirth
    birth_year = dtBirth.year
    birth_month = dtBirth.month
    birth_day = dtBirth.day

    if isMale:
        if birth_year <= 1958:
            retirement_age = 60
        elif birth_year == 1959:
            retirement_age = 60
            addhalfyear = True
        elif birth_year == 1960:
            retirement_age = 61
            addhalfyear = True
        elif birth_year == 1961:
            retirement_age = 63
        elif birth_year == 1962:
            retirement_age = 64
        else:
            retirement_age = 65
    else: # Female
        if birth_year <= 1963:
            retirement_age = 55
        elif birth_year == 1964:
            retirement_age = 55
            addhalfyear = True
        elif birth_year == 1965:
            retirement_age = 56
            addhalfyear = True
        elif birth_year == 1966:
            retirement_age = 58
        elif birth_year == 1967:
            retirement_age = 59
        else:
            retirement_age = 60

    # прибавим к дате рождения пенсионный возраст
    if birth_day > 28:
        retirement_date = retirement_date.replace(day = 28)
    retirement_date = retirement_date.replace(year = birth_year + retirement_age)
    if addhalfyear:
        if birth_month > 6:
            retirement_date = retirement_date.replace(year = birth_year + retirement_age + 1)
            retirement_date = retirement_date.replace(month = birth_month + 6 - 12)
        else:
            retirement_date = retirement_date.replace(month = birth_month + 6)
    if birth_day > 28:
        nday = 28
        while nday < birth_day:
            nday += 1
            try:
                retirement_date = retirement_date.replace(day = nday)
            except ValueError:
                pass

    is_pensioner = now_date > retirement_date
    return is_pensioner

for people in list:
    if isMale:
        isPensioner = isPensioner(True, brs_date)
    else:
        isPensioner = isPensioner(False, brs_date)    

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

PS Для прибавления 6 месяцев к указанной дате на StackOverflow предложили использовать отдельную библиотеку dateutil, но мне показалось, что в данном случае это было бы избыточно, да и лишнюю зависимость "тащить" не хотелось. Ниже предложенное там решение:

from datetime import date
from dateutil.relativedelta import relativedelta

six_months = date.today() + relativedelta(months=+6)

Напомню, что предварительно библиотеку надо установить: pip install python-dateutil

Python: коллекции (05.02.2017) #

Наткнулся на интересную для начинающих изучать Python серию статей посвященную коллекциям.

  • Часть 1: классификация, общие подходы и методы, конвертация
  • Часть 2: индексирование, срезы, сортировка
  • Часть 3: объединение коллекций, добавление и удаление элементов
  • Часть 4: Все о выражениях-генераторах, генераторах списков, множеств и словарей

Рекомендую к прочтению.

Произвольные коды (02.01.2016) #

На днях возникла необходимость получить 3,5 тысячи уникальных, но произвольных 12 значных цифровых кодов. Решений, очевидно, можно придумать массу, но скрипт на Python показался самым простым:

#-*- coding: utf-8 -*-
import random as r
codes = []
with file('oo.csv', 'w+') as f:
    while len(codes) < 3500:
        # cod = '11' + str(r.randint(int('1'*9), int('9'*9)))
        cod = '11' + ('0'*5 + str(r.randint(0, int('9'*5))))[-5:] 
        if cod not in codes:
            codes.append(cod)
            f.write(cod + '\n')

На всякий случай зарезервировал первые две позиции для "типа" - мало ли потом понадобится ещё что-то аналогичное, а также добавил (не в этом скрипте) в конец контрольный разряд (или число), который рассчитал по методу Луна (Lunh, см. Wikipedia).

UPD: Немного скорректировал скрипт: было решено сократить длину кода до 8 знаков, тогда для увеличения количества кодов решил произвольные составляющие искать с нуля, а не со всех единиц, как в первоначальном варианте, что потребовало выравнивания нулями слева. Первоначальный вариант тоже сохранил - закомментированная строка.

Тест на знание Python (23.05.2015) #

Коллега по работе прислал интересный тест на знание Python: https://alexbers.com/python_quiz/.
Тест в основном ориентирован на знание тонкостей и особенностей языка и классического интерпретатора.

Тест я, к сожалению, прошёл плохенько, так как мало практики и в нескольких местах поторопился и плохо подумал.
Интересующимся Python рекомендую попробовать пройти.

UPD: А вот коллега тест прошел очень хорошо - в 10 лучших! Говорит, что главное не торопиться и внимательно смотреть задание.

Python 2.7.x и 3.x (обзор различий) (08.08.2014) #

Коллега по работе прислал ссылку на интересное сравнение посвященное различиям второй и третьей версии Python.

Отдельно хотелось бы отметить два коварных момента, которые выявить будет довольно сложно, так как ошибки выполнения они не вызовут (просто программа будет работать не корректно):

Транспортный налог (18.10.2012) #

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

#-*- coding: utf-8 -*-
tnc = list()
tnc.append((0, 0, 0))
tnc.append((70, 7, 12))
tnc.append((100, 20, 25))
tnc.append((125, 30, 35))
tnc.append((150, 38, 45))
tnc.append((175, 45, 50))
tnc.append((200, 60, 65))
tnc.append((225, 75, 75))
tnc.append((250, 150, 150))
tnc.append((410, 150, 300))

while True:
    title = u'Введите количество лошадиных сил (или ENTER для выхода): '
    print title
    title_e = 'Enter the amount of horsepower (or ENTER to exit): '
    s = raw_input(title_e)
    if s == '':
        break
    x = int(s)
    for c in tnc:
            if x > c[0]:
                    c1 = c
            else:
                    break
    print u'Транспортный налог для %s "лошадей" был %s р., станет %s р. (+%s р.) \n' % (x, x*c1[1], x*c1[2], x*(c1[2] - c1[1]))

«  ‹  1  2  следующая ›  последняя »

  Вы 14445 посетитель этой странички
с 05 марта 2009 года
© http://svv-home.ru
О сайте