четверг, 30 июня 2011 г.

От PHP к Python за 15 минут

Как-то у нас с менеджерами зашел разговор о том, сложно ли изучить язык программирования, если просит об этом заказчик. В частности был разговор о языке Python. Попытаюсь развеять миф о сложности освоения Python.

Python - это не .Net и не Java, где приходится осваивать довольно сложную библиотеку базовых классов. Здесь нет сложности в настройки IDE. Как-то работая в проекте на Java мне необходимо было потратить два дня только на настройку Netbeans.

Python идет в одном ряду с PHP и Perl. Чем-то похож на VB.NET. Кроме того он еще проще в освоении, чем PHP. Чтобы начать программировать в языках такого уровня необходимо только скачать бинарники и тупо начать, даже если вы ничего не знаете. Знания будут добываться по мере решения проблем.

Давайте рассмотрим, чем же отличаются PHP и Python. Я не буду описывать все тонкости, отмечу лишь самые главные моменты, которые помогут преодолеть барьер сложности.

  1. В python как и в php тип переменных назначается динамически, НО динамически не преобразуется. Т.е. вы не можете как в PHP использовать число там, где должна быть строка.
  2. Забудьте про фигурные скобочки для выделения блоков кода. Главное это отступы. Все структурирование осуществляется с помощью отступов. Вместо открывающей фигурной скобочки используется двоеточие. Конец блока определяется с помощью отступов. Чтобы разбить строку на несколько, используется обратный слэш в конце (аналог подчеркивания в VB.NET).
  3. Вместо слово function нужно писать def
  4. Все сущности включая функции являются объектами
  5. Определение ассоциативного массива (называется dictionary - словарь в python) похоже на JSON: a = {"server":"mpilgrim", "database":"master"}
  6. Определение списка тоже вам напомнит JSON: li = ["a", "b", "mpilgrim", "z", "example"]
  7. В язык встроены довольно мощные средства по манипуляции со списками:
    1. Получение последнего элемента: li[-1]
    2. Выделение подсписка: li[1:3]. Можно даже так: li[3:] или так: li[:]
    3. Можно складывать и размножать списки ( list * 3 = list + list + list).
    4. Применение выражения ко всем элементам списка с помощью конструкции [elem*2 for elem in li]. Так мы получим новый список, где каждый элемент старого списка умножен на два. Список в такой операции может быть списком кортежей, тогда после for указывается не одна, а несколько переменных. Более подробно см. http://ru.diveintopython.org/odbchelper_map.html и http://ru.diveintopython.org/apihelper_filter.html
  8. Есть упрощенный вариант списков - кортежи (tuple), которые объявляются с помощью круглых скобок вместо квадратных. Их можно назвать константными списками, которыми нельзя так легко манипулировать. Кортежы более быстро работают и могут быть ключами для словарей.
  9. В python есть возможность использовать кортеж слева от знака присваивания. Вот как можно быстро присвоить значения константам от 0 до 6: (MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY) = range(7)
  10. Еще одна фича python - это подстановка значений в строку по шаблону: "%s is not a good password for %s" % (pwd, uid). Данное выражение вернет отформатированную строку аналогично функции sprintf.
  11. Вместо explode и implode используйте методы строки split и join
  12. Подгрузка внешнего файла осуществляется с помощью import module_name. После этого вы можете обращаться к функциям модуля с помощью module_name.func_name. Если вы не хотите постоянно указывать префикс "module_name.", то можете использовать конструкцию from module_name import *, либо from module_name import a, b, c. Здесь a,b,c - элементы, которые мы хотим импортировать в модуль.
  13. В функции можно устанавливать значения по умолчанию: def help(object, spacing=10, collapse=1)
  14. Как и в VB.NET при вызове функции можно указывать названия параметров, которым назначаются значения: help(spacing=15, object=odbchelper)
  15. В python есть lambda-функции. Ее можно определить как объект-функция без названия. Например: lambda x: x*2. Это функция, которая возвращает аргумент умноженный на два. Тут же можно вызвать функцию: (lambda x: x*2)(3)
Объектно-ориентированное программирование на python
  1. Объявление класса: "class FileInfo:"
  2. Объявление с наследованием: "class FileInfo(UserDict):"
  3. Аналог конструктора - метод __init__. Вызывается после создания объекта.
  4. Первый аргумент метода - всегда текущий экземпляр объекта. Общепринято называть self.
  5. Создание объекта: obj = FileInfo(x)
  6. Сеттеры и геттеры. Есть специальные названия методов __setitem__ и __getitem__. Если вы их объявили в классе, то можете использовать объект как словарь: f["name"]
  7. Если вы внутри класса объявите переменные, то это будут статические переменные и ими можно пользоваться без создания класса. Если вы хотите создать настоящие переменные-члены класса, то нужно их присвоить в методах с помощью self.var_name = value.
  8. Если вы хотите объявить приватный метод, то объявите его с помощью двух знаков подчеркивания в имени: __method. Не используйте два знака подчеркивания в конце. Это особенность системных методов. В действительности в python нет ничего приватного. Если вы захотите до чего-нибудь добраться, то вы сможете это сделать.
Материал составлен на основе книги В глубь языка Python

пятница, 10 июня 2011 г.

Типичные ошибки программиста в проектировании интерфейсов

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

Проблемы, связанные со структурами данных.


  • Использование имен переменных или технических терминов для текстовых меток. Такие имена мало значимы для пользователей. Например, подумайте, сколько человек знает, что такое полный дуплекс?
  • Злоупотребление текстовыми полями. Простое текстовое поле предоставляет слишком много вариантов пользователю. Если поле типа String это не значит, что необходимо всегда использовать TextBox.
  • Ограничения по хранению значения в коде переносятся в формы. Например, телефон должен всегда храниться в определенном формате. Но это не значит, что необходимо запрещать пользователю вводить телефон в другом общеупотребимом формате. Пусть программа автоматически преобразует текст в нужный формат.
  • Избыток сообщений об ошибках. Часто выводят сообщения об ошибках при малейших проблемах вне зависимости от сложности проблемы и понимания ее пользователем. Необходимо выводить сообщения об ошибках, которые пользователь сам может легко исправить.
  • Выдача специальных значений переменных. Часто используют спец. значения для переменных для обозначения отсутствия значения. Например "-1" для натуральных чисел. Необходимо выдавать понятный текст, а не спец. значение и позволять вводить это спец. значение с помощью кнопки, либо еще как-нибудь.
Проблемы простоты
  • Не включение в форму элементов ввода наиболее вероятных значений. С точки зрения кода значения, вводимые в форме равновероятны, хотя для пользователя это не так. Например при выборе шрифта наиболее вероятно, что пользователь выберет последний выбранный шрифт или шрифт, выбранный в прошлом.
  • Чрезмерное обобщение. Программисты шутят, что есть только три числа: 0, 1 и бесконечность. Для выполнения функции 2 и более раз пишется цикл. Такое обобщение часто приводит к избыточной сложности.
  • То, что требуется согласно коду не всегда знает пользователь. Например, в программе требуется код аэропорта, а пользователь знает только название города. Необходимо спрашивать пользователя то, что он знает.
Проблемы жизненного цикла
  • Слишком долгая обработка форм. Вы когда-нибудь видели большие формы, которые состоят полностью из пустых полей и вы не знаете, что заполнять? Обнулять все значения можно коде для структур данных, но не для пользователя. Можно заполнять значениями по умолчанию, либо разбивать форму на несколько форм.
  • Отображение сразу всех полей. Структуры данных в коде не должны полностью отображаться в интерфейсе. Необходимо учитывать зависимости между полями, определять важное от неважное, обязательные и опциональные поля, скрывать редко используемые поля. 
  • Заполни все или ничего. Еще одна проблема отображения структуры данных в интерфейс. Нельзя заставлять пользователя обязательно вводить все данные, которые есть в структуре. Пусть он введет только самое необходимое на текущем этапе, а остальное он заполнит потом.
Проблемы эффективности
  • Барьер приватности. Если структуры данных требуют какой-то персональной информации, которую сложно получить (иметь логин, найти забытый пароль), то пользователь может не захотеть давать личные данные, особенно если эти данные не требуются для выполнения задачи (по крайней мере начала). 
  • Частый ввод одних и тех же данных. Человек не компьютер, он не любит выполнять одну и ту же работу по нескольку раз. Реализуйте заполнение полей значениями по умолчанию.
  • Слишком много полей на экране. Сложные формы вызывают панику и неприязнь. Уменьшайте количество полей на формах!
  • Избыточные ограничения на ввод данных. Если пользователь верит, что он ввел верные данные, то скорее всего это так. Позвольте вводить информацию в разных форматах. На эту тему см. статью We cannot accept that behavior.
При проектировании UI заботьтесь о том, чтобы пользователи достигли своих целей, а не о том, как заполнить структуры данных или сделать красивым код. Плохо спроектированный интерфейс требует пользователей подгонять свои задачи под интерфейс, а хороший интерфейс позволяет решать задачи не задумываясь.