Архив рубрики: Python

Python преобразование числа [0-999] в текст

Например преобразовать 310 => three hundred ten


Мое решение:

FIRST_TEN = [«zero», «one», «two», «three», «four», «five», «six», «seven», «eight», «nine»]

SECOND_TEN = [«ten», «eleven», «twelve», «thirteen», «fourteen», «fifteen», «sixteen», «seventeen», «eighteen», «nineteen»]

OTHER_TENS = [«twenty», «thirty», «forty», «fifty», «sixty», «seventy», «eighty», «ninety»]

HUNDRED = «hundred»

number = 310

res_n = «»
lst = list(str(number))

if len(lst) == 1:
    res_n = FIRST_TEN[int(lst[0])]
    
if len(lst) == 2:
    if int(lst[0]) == 1:
        res_n = SECOND_TEN[int(lst[1])]
    elif int(lst[0]) > 1:
        if int(lst[1]) == 0:
            res_n = OTHER_TENS[int(lst[0]) — 2]
        elif int(lst[1]) > 0:
            res_n = OTHER_TENS[int(lst[0]) — 2] + ' ' + FIRST_TEN[int(lst[1])]   

if len(lst) == 3:
    if int(lst[1]) == 0:
        if int(lst[2]) == 0:
            res_n = FIRST_TEN[int(lst[0])] + ' ' + HUNDRED
        elif int(lst[2]) > 0:
            res_n = FIRST_TEN[int(lst[0])] + ' ' + HUNDRED + ' ' + FIRST_TEN[int(lst[2])]
    elif int(lst[1]) == 1:
        res_n = FIRST_TEN[int(lst[0])] + ' ' + HUNDRED + ' ' + SECOND_TEN[int(lst[2])]
    elif int(lst[1]) > 1:
        if int(lst[2]) == 0:
            res_n = FIRST_TEN[int(lst[0])] + ' ' + HUNDRED + ' ' + OTHER_TENS[int(lst[1]) — 2]
        elif int(lst[2]) > 0:
            res_n = FIRST_TEN[int(lst[0])] + ' ' + HUNDRED + ' ' + OTHER_TENS[int(lst[1]) — 2] + ' ' + FIRST_TEN[int(lst[2])]

print res_n

three hundred ten

Решение от гуру:

def convert(i):
if i < 20:
result = 'zero,one,two,three,four,five,six,seven,eight,nine,ten,eleven,twelve,thirteen,fourteen,fifteen,sixteen,seventeen,eighteen,nineteen'.split(',')[i]
elif i < 100:
result = ',,twenty,thirty,forty,fifty,sixty,seventy,eighty,ninety'.split(',')[i//10]
if i % 10:
result += ' ' + checkio(i % 10)
elif i < 1000:
result = checkio(i // 100) + ' hundred'
if i % 100:
result += ' ' + checkio(i % 100)
return result

Автор: Viktor

Python нахождение наиболее часто встречающегося символа в тексте

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

  • ищем только буквы
  • нет зависимости от регистра ('a' и 'A' считаются одинаковой буквой)
  • ищем букву которая встречается максимальное количество раз
  • если таких букв несколько, то результат выдаем первую встречающуюся по алфавиту
Решение мое:

>>> dict = {}
>>> text = «AavvvddAsfgh»
>>> letters = map(chr, range(ord('a'), ord('z')))

>>> for ch in text:
>>>     ch_lower = ch.lower()
>>>     if ch_lower in letters:
>>>         if dict.has_key(ch_lower):
>>>             dict[ch_lower] += 1            
>>>         else:
>>>             dict[ch_lower] = 1            

>>> out = [key for key, value in dict.items() if value == max(dict.values())]
>>> out.sort()
>>> print out[0]
a
Решение от гуру:
для Python 3.3

>>> import string
>>> def out_chr(text):
>>>     return max(string.ascii_lowercase, 

                   key=lambda ch: text.lower().count(ch))

для Python 2.7
>>> import re
>>> from collections import Counter

>>> def out_chr(text):
>>>     text = «».join(re.findall(«w», text.lower()))
>>>     return Counter(text).most_common()[0][0]


Автор: Viktor

Python проверка на сложность пароля

Например, установлены такие требования к паролю:

  • не меньше 8 символов
  • должна присутствовать хотя бы одна цифра [0-9]
  • должна присутствовать хотя бы одна заглавная буква [A-Z]
  • должна присутствовать хотя бы одна строчная буква [a-z]


Для последовательного перебора символов [a-z] при сравнении, можно использовать такую конструкцию:

>>> for c in range( ord('a'), ord('z')+1 ):
>>> print chr(c),


чтобы получить список [a-z]:
>>> map(chr, range(97, 123))
или
>>> map(chr, range(ord('a'), ord('z')))

Пример реализации. Функция возвращает False, если пароль не удовлетворяет требованиям, или True если ОК:

>>> def lst_seq(v1, v2):
>>>     return map(chr, range(ord(v1), ord(v2)))
>>> def check_psw(psw):
>>>     digit = False
>>>     upper = False
>>>     lower = False
>>>     if len(psw) >= 8:
>>>         for x in psw:
>>>             if x in 
lst_seq('0','9'): 
>>>                 digit = True
>>>             if x in 
lst_seq('A', 'Z'): 
>>>                 upper = True
>>>             if x in 
lst_seq('a', 'z'): 
>>>                 lower = True
>>>     return digit and upper and lower
Теперь варианты от гуру:
для Python 3.3

>>> def check_psw(psw):
>>>     return (len(psw) >= 8 and
>>>         any([ch.isupper() for ch in psw]) and
>>>         any([ch.isdigit() for ch in psw]) and
>>>         any([ch.islower() for ch in psw]))


Вариант с регекспами:

>>> import re
>>> def check_psw(psw):
>>>     return len(psw) >= 8 and

>>>            bool(re.match(«^.*[A-Z]+.*$», psw) and

>>>                 re.match(«^.*[a-z]+.*, psw) and
>>>                 re.match(«^.*[0-9]+.*, psw))

или
>>> import re
>>> def check_psw(psw):
>>>     return bool(re.match(«((?=.*d)(?=.*[a-z])(?=.*[A-Z]).{8})», psw))

или
>>> import re
>>> def check_psw(psw):    
>>>     if len(psw) < 8:
>>>         return False
>>>     for r in ('[a-z]', '[A-Z]', 'd'):
>>>         if re.search(r, psw) is None:
>>>             return False
>>>     return True

Вариант с set для Python 3.3:
>>> import string 
>>> upper  = set(string.ascii_uppercase)
>>> lower  = set(string.ascii_lowercase)
>>> digits = set(string.digits) 
>>> def check_psw(psw):    
>>>     letters = set(psw)
>>>     return bool(len(psw) >= 8 and upper & letters and lower & letters and digits & letters)

Автор: Viktor

Python set методы с наглядными рисунками

Не хватает графики для ясного понимания действий методов set. Хотелось бы как в SQL рисунки пересечений окружностей при работе с join. И вот попал на такой сайт . Выкладываю оттуда картинки.
Union |
>>> s1 = set([1, 2, 3])
>>> s2 = set([3, 4, 5])
>>> print s1.union(s2)

set([1, 2, 3, 4, 5])



Intersection & 
>>> s1 = set([1, 2, 3])
>>> s2 = set([3, 4, 5])
>>> print s1.intersection(s2)

set([3])

Difference 
>>> s1 = set([1, 2, 3])
>>> s2 = set([3, 4, 5])
>>> print s1.difference(s2)

set([1, 2])

Symmetric Difference ^
>>> s1 = set([1, 2, 3])
>>> s2 = set([3, 4, 5])
>>> print s1.symmetric_difference(s2)

set([1, 2, 4, 5])




Автор: Viktor

Использование lambda вместе со списком в Python

Очень наглядный пример использования lambda с методами списков в Python

>>> foo = [2, 18, 9, 22, 17, 24, 8, 12, 27]
>>> 
>>> print filter(lambda x: x % 3 == 0, foo)

[18, 9, 24, 12, 27]

>>> 
>>> print map(lambda x: x * 2 + 10, foo)

[14, 46, 28, 54, 44, 58, 26, 34, 64]

>>> 
>>> print reduce(lambda x, y: x + y, foo)

139

>>> digit = [1, 2, 3]
>>> 
>>> print [(lambda x: x * x)(x) for x in digit)]

[1, 4, 9]

или лучше

>>> print [x * x for x in digit]

Еще интересный пример (вырезать в строке лишние дефисы)

>>> line = 'I—like—python'
>>> print '-'.join(filter(lambda x: x != '', line.split('-')))

I-like-python
Объяснение:
>>> line.split('-')
['I', '', '', 'like', '', 'python']
>>> filter(lambda x: x != '', line.split('-')) 
['I', 'like', 'python']

Пример в котором нужно вывести список с НЕ уникальными значениями
Неудачное решение:
>>> lst = [10, 9, 10, 10, 9, 8]
>>> out_lst = []

>>> for i in range(len(lst)):
>>>     x = lst.pop(i)    
>>>     if x in lst:
>>>         out_lst.append(x)
>>>     lst.insert(i, x)
>>> print out_lst
[10, 9, 10, 10, 9]
Лучшее решение:
>>>  print (lambda d:[x for x in d if d.count(x)>1])(lst)
[10, 9, 10, 10, 9]

Автор: Viktor

Функциональный стиль в питоне

Пост чисто философский

Периодическое чтение кусков кода, написанных при обострении хаскеля головного мозга, выработало у меня четкую ассоциацию: функциональный стиль — это не читаемо.

Точнее стиль с множеством map/filter/zip. Вот немного облагороженный пример такого кода (автор считает, что с кодом все ок): Читать