четверг, 6 ноября 2014 г.

внезапное открытие касательно list(), set(), tuple()

Бывает, что я использую одну и ту же конструкцию в python, и лишь спустя некоторое время открываю более красивый способ достичь того же самого. В данном случае речь идет о разбиении строки на символы. Раньше я использовал list comprehension вида
[c for c in mystring]

Оказывается, есть и более простой вариант:
list(mystring)

Соответственные варианты для кортежа и множества:
tuple(mystring), set(mystring)

среда, 29 октября 2014 г.

Verification of your TeamViewer version failed [in english]

A person recently asked me if I could translate my post on solving a teamviewer problem to English. There's not really much to translate, but here you go anyways.

Sometimes, using Teamviewer on Windows XP, you can run into this error. The point is, teamviewer's binary is signed with digital signature. To check this signature for validity, your OS needs two components:
1) functional cryptographic infrastructure (so OS can compute signature)
2) installed root certificates

If you have any issues with point 1), following console commands (source) will probably fix them:

regsvr32 Softpub.dll /s
regsvr32 Wintrust.dll /s
regsvr32 Initpki.dll /s
regsvr32 Mssip32.dll /s


Point 2) is achieved by (no prize for guessing) installing root certificates available here.
In my case, fulfilling these two points solved the problem.

пятница, 12 сентября 2014 г.

определяем "палиндромичность" строки в python 2.7

Рассмотрим основные варианты определения, является ли строка палиндромом, т.е. горизонтально симметричной относительно середины строкой.

Первый вариант, с использованием слайсов
def is_pali(s):
    return s==s[::-1]

Выражение s[::-1] возвращает новую строку, состоящую из символов данной строки, взятых в обратном порядке.

Второй вариант, с использованием функции (на самом деле, класса) reversed.
def is_pali(s):
    return s==''.join(reversed(s))

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

Третий вариант, также с использованием reversed.
def is_pali(s):
    return all(map(lambda x:x[0]==x[1],zip(s,reversed(s))))

Zip возвращает список кортежей длины 2, где первым элементом (индекс 0) является N-ный символ исходной строки, вторым (с индексом 1) - N-ный символ обращенной строки. В случае равенства между собой элементов каждого из кортежей строка является палиндромом.

И последний вариант, с использованием рекурсии. Сравниваем первый и последний символы строки. Если они различны, строка не является палиндромом. Если они одинаковы, строка может быть палиндромом, чтобы убедиться в этом, рекурсивно обрабатываем строку, полученную из текущей отбрасыванием первого и последнего символов. Базовый случай рекурсии: пустая строка и строка длиной в один символ являются палиндромами, возвращаем истинное значение.
def is_pali(s):
    if len(s)<=1:
        return True
    if s[0]==s[-1]:
        return is_pali(s[1:-1])
    else:
        return False

Перепишем, используя short-circuit evaluation (ленивое вычисление логических выражений c and и or).
Если длина строки меньше единицы, сразу возвращаем True. Здесь подойдет or:
def is_pali(s):
    return len(s)<=1 or ...

Далее, если первый и последний символы одинаковы, возвращаем значение, которое отдаст рекурсивный вызов, иначе, возвращаем ложное значение. Здесь напрашивается and:
def is_pali(s):
    return len(s)<=1 or s[0]==s[-1] and is_pali(s[1:-1])

Вышеописанные функции, как и многие другие однострочные функции, можно здать в виде lambda-выражения.

понедельник, 18 августа 2014 г.

BurdoBordo как генерализация FizzBuzz

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

def BurdoBordo(x,BURDO="BURDO",burdo=3,BORDO="BORDO",bordo=5):
    if x%burdo==0 and x%bordo==0:
        return BURDO+BORDO
    elif x%burdo==0:
        return BURDO
    elif x%bordo==0:
        return BORDO
    else:
        return str(x)
FizzBuzz=lambda x: BurdoBordo(x,BURDO="Fizz",burdo=3,BORDO="Buzz",bordo=5)
for x in xrange(1,101):
    print FizzBuzz(x)


Следующий вариант, в котором более активно используются особенности python.

def BurdoBordo(x,BURDO="BURDO",burdo=3,BORDO="BORDO",bordo=5):
    return ((BURDO,)+('',)*burdo)[x%burdo]+((BORDO,)+('',)*bordo)[x%bordo] or str(x)

FizzBuzz=lambda x: BurdoBordo(x,BURDO="Fizz",burdo=3,BORDO="Buzz",bordo=5)
for x in xrange(1,101):
    print FizzBuzz(x)

И, наконец, последний вариант, с индексами и short-circuit evaluation.

def BurdoBordo(x,BURDO="BURDO",burdo=3,BORDO="BORDO",bordo=5):
    return (BURDO+BORDO)[x%burdo and len(BURDO):x%bordo and len(BURDO) or len(BURDO+BORDO)] or str(x)

FizzBuzz=lambda x: BurdoBordo(x,BURDO="Fizz",burdo=3,BORDO="Buzz",bordo=5)
for x in xrange(1,101):
    print FizzBuzz(x)

воскресенье, 6 июля 2014 г.

о необходимости использовать уместные термины

Я уже писал, что термины load sharing и load balancing зачастую используются не вполне корректно. Не так давно наблюдал, к чему это приводит. У человека, исключительно из-за использования термина 'балансировка', сформировалось неправильное представление о том, что он получит. Когда схема была реализована, расхождение между ожидаемым и реальностью породило закономерные вопросы. Всего этого можно было бы легко избежать, если бы автор статьи, которой вышеупомянутый человек руководствовался при настройке, ответственно подходил к выбору терминов.

понедельник, 5 мая 2014 г.

'Среда передачи не прошла проверку' на ethernet-интерфейсе

Недавно позвонил товарищ, пригласил поучаствовать в траблшутинге сетевых проблем windows xp по телефону. Я, конечно, легко обойдусь без подобных развлечений, но ведь никто, кроме нас. Симптом - "нет интернета", порт на маршрутизаторе не загорается. После обычных махинаций (смена кабеля и прочая), обратил внимание на вывод ipconfig (продекламированный мне по телефону), а именно: в статусе ethernet-интерфейса было указано 'Среда передачи не прошла проверку подлинности'. Ключевые слова 'среда передачи' и 'проверка' натолкнули меня, не так давно сдавшего-таки 642-813 SWITCH,  на мысль, что в деле замешан 802.1x. Так и вышло. Единственное, что заставило потратить дополнительных 10 минут - 802.1x отключался не вместе с IPv4/v6, службой принтеров, LLDP и прочая, а на отдельной вкладке.

Из этого непримечательного, в общем-то, случая я сделал выводы:
1) Надо бы углубить знания настройки сети в ОС Windows. Думаю, команда netsh при правильном подходе помогла бы сократить время диагностики проблемы.
2) Баребоны (это был баребон, маленький такой компьютер) могут идти в комплекте с довольно специфическими колокольчиками и свистелками (вроде включенного 802.1x на 'медном' интерфейсе. А еще там была программа от Juniper для постройки тоннеля неизвестно куда) 
3) Системный подход часто помогает решить проблему даже при отсутствии релевантного опыта (ни разу не настраивал 802.1x в Windows, например)

воскресенье, 15 декабря 2013 г.

клиенты-серверы

Читая книгу Робачевского-Немнюгина-Стесик про юниксы, поймал себя на мысли. Раньше, когда речь заходила о клиент-серверной архитектуре, я сразу представлял один мощный компьютер или их ферму (сервер/ы) и множество других компьютеров попроще, клиентов. Причем связь всегда подразумевалась через сетевые интерфейсы (чтоугодно-over-IP). В этой книге же представлена историческая перспектива  средств взаимодействия процессов, и соответственно сервер определяется как процесс, предоставляющий некие сервисы (вычисляющий, предоставляющий данные по запросу извне). Такое определение или, скорее, описание, кажется мне более общим и корректным.