Архив метки: Python

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

Как работать с LDAP в Python

Недавно я написал о том, что такое LDAP и с чем его едят. Сегодня, в продолжение этой темы, расскажу, как работать с LDAP сервером из программы на языке программирования Python. Для создания примеров я использую Python 2.7 и MS Active Directory. В примерах все имена организаций, подразделений и пользователей являются вымышленными, а всякое совпадение с реальностью является совершенно случайным 🙂

Для работы с LDAP из Python нам понадобится пакет python-ldap. Пакет позволяят работать с различными LDAP-серверами, и с Active Directory, в частности.

>>> import ldap
>>> ad = ldap.initialize("ldap://192.168.0.16")
>>> ad.simple_bind_s("trofimov_a@SKY", "nooneknows")
(97, [], 1, [])

По LDAP URL ldap://192.168.0.16, который указывает на Active Directory сервер, получен объект LDAPObject и присвоен переменной ad. Далее используем метод simple_bind_s этого объекта для присоединения к серверу, передавая имя и пароль пользователя для аутентификации. (Символы _s в конце имени метода означают, что метод выполняется синхронно.)

Аутентификация пользователей — одна из функций LDAP сервера, реализуемая операцией bind. Другие функции: поиск, чтение и модификация данных в каталоге.

Найдем и выведем на экран атрибут name всех подразделений (objectClass=organizationalUnits) верхнего уровня (ldap.SCOPE_ONELEVEL) для организации «Синее Небо» (O=Синее Небо,DC=org,DC=ru):

>>> basedn = 'O=Синее Небо,DC=org,DC=ru'
>>> scope = ldap.SCOPE_ONELEVEL
>>> filterexp = 'objectClass=organizationalUnit'
>>> attrlist = ['name']
>>> results = ad.search_s(basedn, scope, filterexp, attrlist)
>>> for result in results:
... print result[0].decode('utf-8'), result[1]['name'][0].decode('utf-8')
...
OU=Коммерческий отдел,O=Синее Небо,DC=org,DC=ru Коммерческий отдел
OU=Общее руководство,O=Синее Небо,DC=org,DC=ru Общее руководство
OU=Отдел обеспечения,O=Синее Небо,DC=org,DC=ru Отдел обеспечения
OU=Производственный отдел,O=Синее Небо,DC=org,DC=ru Производственный отдел

Метод search_s возвращает результат поиска как список кортежей (DN записи, словарь с запрошенными атрибутами). А поскольку атрибут может иметь больше одного значения, то значения атрибутов представлены списком. В рассмотренном примере атрибут name имеет одно значение, то есть, список значений содержит единственный элемент result[1]['name'][0].

Значения, которые может принимать параметр scope (в соответствии со спецификацией LDAP):

  • ldap.SCOPE_BASE — запись base DN,
  • ldap.SCOPE_ONELEVEL — дочерние записи base DN,
  • ldap.SCOPE_SUBTREE — поддерево с вершиной base DN.

Найду запись о пользователе (objectClass=user), указав в списке атрибутов objectClass, — этот атрибут имеет несколько значений:

>>> basedn = 'O=Синее Небо,DC=org,DC=ru'
>>> scope = ldap.SCOPE_SUBTREE
>>> filterexp = "(&(cn=Трофимов Андрей*)(objectClass=user))"
>>> attrlist = ["sAMAccountName", "mail", "objectClass"]
>>> results = ad.search_s(basedn, scope, filterexp, attrlist)
>>> for result in results:
... print 'DN'.rjust(15) + ' = ' + result[0].decode('utf-8')
... print 'n'.join(x.rjust(15) + ' = ' + str(result[1][x]) for x in attrlist)
...
DN = CN=Трофимов Андрей,OU=Производственный отдел,O=Синее Небо,DC=org,DC=ru
sAMAccountName = ['trofimov_a']
mail = ['trofimov_a@sineenebo.org.ru']
objectClass = ['top', 'person', 'organizationalPerson', 'user']

Несколько значений атрибута objectClass отражают тот факт, что класс user явлется наследником классов organizationalPerson, person и top. Таким образом, запись класса user является одновременно записью каждого из классов-предков.

Атрибут sAMAccountName содержит имя пользователя, под которым пользователь регистрируется в корпоративном домене, атрибут mail — адрес электронной почты.

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

# -*- coding: utf-8 -*-

import ldap

LDAP_URL = "ldap://192.168.0.16"
USERNAME = "trofimov_a@SKY"
PASSWORD = "nooneknows"

ad = ldap.initialize(LDAP_URL)
ad.simple_bind_s(USERNAME, PASSWORD)

basedn = "O=Синее Небо,DC=org,DC=ru"
scope = ldap.SCOPE_SUBTREE
filterexp = "(&(objectClass=user)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(cn=*)(mail=*))"
attrlist = ["cn", "mail"]
results = ad.search_s(basedn, scope, filterexp, attrlist)

for result in results:
print result[1]["cn"][0].decode("utf-8").rjust(35), result[1]["mail"][0]

ad.unbind_s()

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

В отличие от операции поиска, операции LDAP для изменения данных всегда выполняются ровно для одной записи в каталоге, идентифицированной ее уникальным именем DN.

Добавим новую запись класса organizationalPerson в Производственный отдел:

>>> dn = "CN=Обломов Илья,OU=Производственный отдел,O=Синее Небо,DC=org,DC=ru"
>>> addlist = [
... ("cn", "Обломов Илья"),
... ("sn", "Обломов"),
... ("objectClass", ["organizationalPerson","person","top"]),
... ("telephoneNumber", "2121212")
... ]
>>> ad.add_s(dn, addlist)
(105, [])

Метод add_s объекта LDAPObject принимает в качестве параметров DN новой записи и список кортежей (атрибут, значение). Запись успешно добавлена. Для чтения записи создам функцию:

>>> def show_entry(dn):
... try:
... results = ad.search_s(dn, ldap.SCOPE_BASE)
... print "DN".rjust(20), "=", results[0][0].decode("utf-8")
... for attr in ["cn", "sn", "givenName", "telephoneNumber"]:
... print attr.rjust(20), "=", (results[0][1][attr][0].decode("utf-8") if results[0][1].get(attr) else '')
... except:
... print ("Не найден DN %s" % dn).decode("utf-8")
...
>>> show_entry(dn)
DN = CN=Обломов Илья,OU=Производственный отдел,O=Синее Небо,DC=org,DC=ru
cn = Обломов Илья
sn = Обломов
givenName =
telephoneNumber = 2121212

Для изменения существующей записи нужно подготовить список модификаций:

>>> modlist = [
... (ldap.MOD_ADD, "givenName", "Илья"),
... (ldap.MOD_REPLACE, "sn", "Обломоff"),
... (ldap.MOD_DELETE, "telephoneNumber", None)
... ]

Первый элемент каждого кортежа в списке определяет тип модификации, одно из:

  • ldap.MOD_ADD — добавить атрибут
  • ldap.MOD_REPLACE — заменить атрибут
  • ldap.MOD_DELETE — удалить атрибут (или одно из его значений)

Изменяю запись и смотрю результат:

>>> ad.modify_s(dn, modlist)
(103, [])
>>> show_entry(dn)
DN = CN=Обломов Илья,OU=Производственный отдел,O=Синее Небо,DC=org,DC=ru
cn = Обломов Илья
sn = Обломоff
givenName = Илья
telephoneNumber =

Метод rename_s объекта LDAPObject позволяет изменить RDN записи:

>>> ad.rename_s(dn, "cn=Обломов Илья Ильич")
(109, [], 10, [])

>>> show_entry(dn)
Не найден DN CN=Обломов Илья Ильич,OU=Производственный отдел,O=Синее Небо,DC=org,DC=ru

>>> dn = "CN=Обломов Илья Ильич,OU=Производственный отдел,O=Синее Небо,DC=org,DC=ru"
>>> show_entry(dn)
DN = CN=Обломов Илья Ильич,OU=Производственный отдел,O=Синее Небо,DC=org,DC=ru
cn = Обломов Илья Ильич
sn = Обломоff
givenName = Илья
telephoneNumber =

Наконец, удаляю экспериментальную запись:

>>> ad.delete_s(dn)
(107, [], 12, [])
>>> show_entry(dn)
Не найден DN CN=Обломов Илья Ильич,OU=Производственный отдел,O=Синее Небо,DC=org,DC=ru

Закрываю соединение с Active Directory:

>>> ad.unbind_s()

Все примеры выше используют синхронные операции с LDAP. Объект LDAPObject предоставляет также асинхронные методы search, add, modify, rename, delete. Эти методы возвращают целочисленный идентификатор операции, который затем нужно передать методу result для получения результата операции, или методу abandon — для отмены операции.

Были рассмотрены базовые возможности, предоставлемые пакетом python-ldap, для чтения и изменения данных в LDAP каталоге.

Автор: Andrei Trofimov
Дата публикации: 2013-11-10T18:05:00.000+11:00

Определение текущей дирректории в Python

import os

#получим полный путь до текущего файла
path = os.path.abspath(os.path.dirname(__file__))

#получим путь на уровень выше
path = os.path.split(path)[0]

#и ещё на уровень, нам же на 2 уровня подняться надо
path = os.path.split(path)[0]

print path

#в path и будет путь.
#можно покороче

print os.path.split(os.path.split(os.path.abspath(os.path.dirname(__file__)))[0])[0]

Автор: D1VER
Дата публикации: 2013-10-17T06:47:00.003-07:00

Python, функция return нескольких значений

Несколько возвращаемых значений

Функции Python могут возвращать больше одного значения. Предположим, есть функция вида:

frac{dy}{dt} = v_0 - gt.

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

def yfunc(t, v0):
g = 9.81
y = v0*t - 0.5*g*t**2
dydt = v0 - g*t
return y, dydt

Когда далее будет вызывана yfunc, необходимо в левой части операции присваивания указать две переменные, в которые будут записаны два значения:

position, velocity = yfunc(0.6, 3)

Автор: D1VER
Дата публикации: 2013-09-17T00:04:00.001-07:00