Thursday, October 28, 2010

Урок 6, возвращение мавра. Функции.

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

В домашнем задание мы написали функцию которая получает 2 числа и печатает их сумму.
def my_sum(num1, num2):
    sum = num1 + num2
    print sum

Теперь мы хотим не распечатать сумму, а вернуть ее, как ответ на запрос.

Вспомним базовые встроенные системные функции которыми мы уже воспользовались:

size = raw_input("Ukazhite razmer kvadrata")

raw_input - функция которая получает переменную - строку - "Ukazhite razmer kvadrata", показывает ее на экране, принимает от пользователя данные и передает в наше пользования. Мы же ее записываем в переменную size.

num = int(size)

int - функция которая получает переменную типа текст, превращает ее в число, и возвращает в наше пользование. Мы же ее записываем в переменную num.

Итого, для того чтобы получить данные из функции, нам надо:

1. Не просто выполнить функцию, а присвоить ее (точнее ее результат) переменной.

2. В теле функции, сообщить что нам надо не просто распечатать результат, а вернуть его. Для этого мы используем новое ключевое слово - return.

Теперь наша функция суммы, выглядит так:
def my_sum(num1, num2):
    sum = num1 + num2
    return (num1 + num2)
А вызов и использование функции в теле кода будет выглядеть так:
sum = my_sum(5,3)
print sum

Вопросы радиослушателей:

Дорогой Джипа,

Я пишу самую великую программу в мире. У меня пока 854 строчки кода и ни одна не повторяется! Правда мне не нужны функции?

Целую, Нубас Подгорелов.

Ответ:

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

Вопрос:

Дорогой Джипа,

Что считается большой функцией? Как понять что я создал монстра? Есть ли какие-то принятые в народе индикаторы?

Целую, Нубас Пригорелов.

Ответ:

Я придерживаюсь довольно простого правила - функция должна целиком помещаться на экране. На нее удобно смотреть. Это плюс минус 40 строк кода. Разумеется не стоит вешаться если у вас в функции 60 строк, но как приблизительная индикация, это вполне хорошее правило.

Домашнее задание:

1. Напишите программу которая получает от пользователя оценки по 3 экзаменам и печатает среднюю оценку. Используйте функцию для подсчета и возврата средней оценки.

2. Напишите программу которая получает от пользователя 2 числа (num1, num2) и печатает число num1 в степени num2. Используйте функцию для подсчета и возврата числа.

3. Перепишите функцию из п.2 не используя символ возвода в степень.
Подсказка (для того чтобы показать нажмите ctrl+a): используйте цикл.

Thursday, October 21, 2010

Урок 5, про мавра в Вегасе. Функции.

Теперь, когда мы научились рисовать и квадратик, и треугольник, и стрелочку, вернемся к основе нашего рисунка. В основе лежит вот этот код:
i=size
while i>0:
    print "#",
    i=i-1
print
Который печатает "#" столько раз сколько в переменной size.

Часть кода которая повторяется, принято выделять, давать имя (соответствующее функциональности этой части кода) и в дальнейшем, вместо повторения, обращаться к ней по имени. Такие выделения называются функции.

Функция является отдельной частью программы. Это крайне важно понять. Все что происходит у нас в программе, все переменные которые мы определили, все что мы сделали до сих пор, функция об этом не знает ничего. Когда мы вызываем функцию из нашей программы, происходит передача контроля, функция проходит по своему списку команд, и при окончании, вернет управление программе.

Поведение функции можно описать двумя цитатами:
1. Все что происходит в Вегасе, остается в Вегасе.
2. Мавр сделал свое дело, мавр может гулять смело.

В нашем случае, у нас есть код который печатает строку символов.
Но сколько раз функция должна печатать символ?
Функция как мы сказали, существует отдельно от области выполнения программы.
Если в главной программе мы получили от пользователя переменную size, функция о нем ничего не знает. Ей надо об этом рассказать.

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

Синтакс функции в пайтоне выглядит следующим образом:
def имя_функции(список_переменных):
    команда1
    команда2
    ...

Имя функции как обычно латиницей, список переменных передается через запятую: переменная1, переменная2, переменная3.

В нашем примере, у нас есть функция которая печатает символы в строке.
Так ее и назовем - print_symbol_line.
Мы передаем ей одну переменную - сколько раз печатать символ, переменная size.

Итого, в главной программе, вызов функции и передача переменной, будет выглядеть вот так:
print_symbol_line(size)

А определение функции вот так:
def print_symbol_line(size):
    i=size
    while i>0:
        print "#",
        i=i-1
    print

Вспомним последний пример на прошлом уроке, который печатал квадрат, и выглядел вот так:
size = raw_input("Ukazhite razmer kvadrata")
size = int(size)
j=size
while j>0:
    i=size
    while i>0:
        print "#",
        i=i-1
    print
    j=j-1

И теперь перепишем его используя функцию, получим:
def print_symbol_line(size):
    i=size
    while i>0:
        print "#",
        i=i-1
    print

size = raw_input("Ukazhite razmer kvadrata")
size = int(size)
j=size
while j>0:
    print_symbol_line(size)
    j=j-1

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

Домашнее задание:

1. Напишите функцию которая получает число и печатает его квадрат.
2. Напишите функцию которая получает 2 числа, и печатает их сумму.
3. Добавьте в функцию print_symbol_line еще одну переменную, которая будет говорить какой символ печатать (вместо #, хочу *).

Tuesday, October 12, 2010

Урок 4, про исскуство. Ввод и вывод данных.

Хватит наверно с математикой, перейдем к искуству.
Изобразим квадрат Малевича. Вот такой:
####
####
####
####
Похож, правда?
Кроме того, пусть размер квадрата будет не постоянный, а задаваться пользователем.

Разбиваем задачу на несколько простых блоков:
1. Получить от пользователя число - размер стороны квадрата, и записать его в переменную (назовем ее size).
2. Напечатать одну строку - вывести квадратик # столько раз, сколько записано в size.
3. Повторить эту строку столько раз, сколько записано в size.

Для получения данных от пользователя знакомимся с новой командой:

raw_input("Preved medved, kak dela?")

Пользователь получит окошка для ввода с заголовком "Preved medved, kak dela?" и строчкой для ввода данных. Эти данные, полученные от пользователя мы можем записать в переменную вот так:

otvet = raw_input("Preved medved, kak dela?")

Отлично. Нас правда интересует размер квадрата, а не дела медведя, и в нашем случае строчка будет выглядеть вот так:

size = raw_input("Ukazhite razmer kvadrata")

Есть только одна проблема. Рассмотрим два примера:
1. size=3
В переменную size записали число - 3.

2. size="3"
В переменную size записали текст - "3".

В первом примере, наша переменная число, во втором текст.
Если наша следующая команда:
size = size -1
То в первом примере, переменная size теперь содержит число 2, а во втором пайтон недоуменно смотрит на нас и удивляется, ведь отнять от текста число мы уже пробовали в уроке 0, и это у нас не получилось.

Команда raw_input всегда возвращает данные как текст.
Для преобразования текста в число, знакомимся с новыми командами:
Целые числа - int
Дробные числа - float

Пример:
text = "345"
num = int(text)
num = num - 5
print num

Важно отметить, попытка преобразовать текст "3.45" в целое число с командой int выдаст ошибку. Нам придется сделать 2 преобразования, текста в дробное число, и из дробного числа в целое:

text = "12.34"
num = float(text)
num = int(num)
num = num - 5
print num

Теперь когда мы научились преобразовать текст в числа, вернемся к Малевичу.
Мы остановились на:

size = raw_input("Ukazhite razmer kvadrata")

добавляем:

size = int(size)

получаем:

size = raw_input("Ukazhite razmer kvadrata")
size = int(size)

Отлично. Дальше мы уже умеем. Нарисуем одну строчку квадратиков:
size = raw_input("Ukazhite razmer kvadrata")
size = int(size)

i=size
while i>0:
    print "#"
    i=i-1
Запускаем. Так. Ну и какого хрена на экране столбик. С криками "глупый компьютер почему ты не делаешь то что я хочу, ведь я твой властелин" мы колошматим клавиатуру, выпиваем стакан воды и начинаем думать.
Ну да, конечно, ведь команда print после каждого вывода переходит на новую строку. Во избежания этого добавим в конце команды print знак "," который сообщает что мы еще не закончили писать на этой строке, а в конце пустой print для того чтобы перейти на новую строку, и получим:
size = raw_input("Ukazhite razmer kvadrata")
size = int(size)

i=size
while i>0:
    print "#",
    i=i-1
print
Работает. Так, теперь берем весь этот кусок печатания строки, начиная с i=size, и заканчивая print, и вставляем его в цикл, который повторит вывод одной строки много раз и получим:
size = raw_input("Ukazhite razmer kvadrata")
size = int(size)
j=size
while j>0:
    i=size
    while i>0:
        print "#",
        i=i-1
    print
    j=j-1

Великая победа альянса. (ц)

Домашнее задание:

1. Напишите программу которая рисует вот такой треугольник:

*
**
***
****
*****

2. А теперь стрелочку:

*
**
***
****
*****
****
***
**
*

Monday, October 11, 2010

Урок 3, про мужа программиста. Условия и циклы.

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

Лопата, да, но иллюстрирует принцип условия в жизни - если што-то делай то-то.

Рассмотрим пример. Напечатать все четные числа от 1 до 20.

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

Во первых, напечатаем все числа от 1 до 20, это мы умеем:
i=0
while i < 20:
    i=i+1
    print i
Теперь, добавим условие - печатать только четные числа. Что такое четное число? То которое делится на 2 без остатка. Как проверить деление на 2 без остатка? Вспоминаем первый урок и знак %. Итак, нам надо условие - если i % 2 равен 0. В переводе с русского на пайтон, получим:
if i % 2 == 0:
Важно отметить, для обозначения равенства, используется символ "==". Символ "=" используется для присваивания. Соединяем:
i=0
while i < 20:
    if i % 2 == 0:
        print i
    i=i+1
Обратите внимание на вложенность - цикл > условие > печать. Теперь нас просят повторить, но на этот раз распечатать только нечетные. Что такое нечетные? Это те которые не четные. (Логично, да ). Итого все что нам надо изменить, это символ равно (==) на не равно (!=).
i=0
while i < 20:
    if i % 2 != 0:
        print i
    i=i+1
Часто нам нужна возможность не только совершить какое-то действие если условие выполнилось, но и в обратном случае. Распечатаем для чисел от 1 до 10, четные они или нет:
i=0
while i < 10:
    if i % 2 == 0:
        print i, "chetnoe"
    else:
        print i, "nechetnoe"
    i=i+1

Ну и последнее, если мы хотим более сложные условия, из нескольких проверок, мы их связываем логическими союзами: "and", "or".
Союз "and" требует чтобы выполнялись оба условия, а союз "or" любое из них.

Числа больше 20 и меньше 30 -
if (i > 20) and (i < 30):

Числа которые делятся без остатка или на 2 или на 3 -
if (i % 2 == 0) or (i % 3 == 0):

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

Домашнее задание:

Напишите программу которая печатает числа от 1 до 100.
Вместо чисел которые делятся на 3, выводите слово Fizz.
Вместо чисел которые делятся на 5, выводите слово Buzz.
Если число делится и на 3 и на 5, выводите FizzBuzz.
Пример:
1, 2, Fizz, 4, Buzz, Fizz, 7, 8, Fizz, Buzz, 11, Fizz, 13, 14, FizzBuzz, 16 ...

Friday, October 8, 2010

Урок 2, в котором мы познаем радость циклов.

Целью этого урока будет помочь Барту Симпсону:



Бедняга стоит у доски и пишет 10 раз одно и то же предложение. А что бы сделали мы, великие покорители пайтона, если бы нас попросили написать 10 раз одно и то же? Мы бы научились писать циклы.

Цикл это программная структура у которой есть:
1. Ключевое слово
2. Условие
3. Список команд
Когда пайтон увидит ключевое слово обозначающее что впереди цикл, он посмотрит на условие и пока условие соблюдается, раз за разом будет повторять весь список команд.

Расмотрим пример Барта:
Условие - 10 раз
Команда - написать "I will not illegally download this movie".

Для того чтобы выполнить некое условие 10 раз нам нужна переменная, которая будет выполнять роль счетчика. В начале будет равна 0, каждый раз когда мы будем писать на доске она будет увеличиваться на 1, а в условие мы поставим проверку что эта переменная меньше 10. Итого:
i=0
while i<10:
    i=i+1
    print "I will not illegally download this movie"
Тут читатель должен возмутиться, мы же только на прошлом уроке говорили что у переменных должно быть значимое имя, а тут какой-то i, и он будет прав. Однако i является общепринятым именем в мире программирования для переменной которая простой счетчик (сокращение от англ. iterator).

Важно отметить, создание отступа для вложенных команд (3 и 4 строки) обычно считается хорошим тоном в программировании, но в случае пайтона является суровой необходимостью. У пайтона нет символов начала/конца цикла, и он догадывается какие из команд "принадлежат" циклу на основании их отступа от команды цикла. Если бы Барт попросил нас разбить запись на две строки - "I will not" и "illegally download this movie", а так-же в конце добавить его подпись, новая программа выглядела бы так:
i=0
while i<10:
    i=i+1
    print "I will not"
    print "illegally download this movie"
print "by Bart Simpson"

Домашнее задание:

Напишите все числа фибоначчи меньше 100.

Thursday, October 7, 2010

Урок 1, в котором мы пишем нашу первую программу.

На прошлом уроке мы узнали:
  •  A ** B - поднять A в степень B
  • A % B - остаток от деления A на B
  • При делении, если одно (или оба) из чисел записано с дробной частью, результат будет с дробной частью
  • Знак + позволяет складывать цифры или соединять слова
  • Магическое слово print позволяет нам выводить на экран цифры и буквы, а используя символ "," чередовать и выводить на экран любое их количество.

До сих пор мы работали в командной строке пайтона, давали ему одну команду, которую он выполнял и просил следующую. Пришло время создать нашу первую программу, в которой будет целых 2 команды! Запускаем pyscripter, и обращаем внимание на 2 окошка, верхнее, с ярлычком нового файла (module1) и нижнее под именем Python Interpreter. В верхнем мы будем писать наш код, запускать, и получать результат в нижнем окне. Запуск производится по нажатию ctrl+f9. Можно конечно и нажать мышкой на зеленую иконку play, но мы учимся быть продуктивными.

Попробуем написать и запустить:

x=2
print x+3

Нижнее окошко подумало подумало и выдало:
>>>
5
>>>

Отлично!
Умные читатели уже подмигивают нам и доверчиво сообщают "да знаем, знаем, икс это переменная", и они безусловно правы. Но что такое переменная?

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

У переменных в пайтоне нет фиксированного типа данных. Мы не должны определять заранее, что вот "x" у нас будет числом целым, или дробью, и так вовеки веков. Пайтон просто радуется что мы хотим что-то куда-то записать.
Попробуем запустить:

x=5
print x
x="moo"
print x

Переменная "х", сначала было числом, потом стала текстом.
Несколько слов о том какие имена можно и нужно давать переменным.

Пайтон требует чтобы первый символ переменной была буква, а дальше разрешает любые латинские буквы (a-z, A-Z) цифры (0-9) и подчеркивание (_).

Крайне важно заметить что переменная VasyaPupkin и vasyapupkin это две разных переменных, и не ошибаться.

Несмотря на то что переменная odinodin1111trolololo считается приемлемой с точки зрения пайтона, она таковой не является. Имя переменной должно описывать что именно мы планируем держать в этой переменной, и за использование одной переменной для разных ролей можно получить тумаков. Кроме того не стоит сокращать переменные в какие-то одним вам понятные аббревиатуры, например video_frames_counter отличное и понятное имя, vfc понятно только вам, да и то в ближайший час.

Домашнее задание:

Вы приехали на выходные в деревню к дяде Паше. У него небольшая ферма - 5 коров, 12 куриц и 32 свинки. Дядя Паша смотрит на ваш гламурный лаптоп, и вы решаете сразить бедного фермера новейшими нанотехнологиями. Напишите программу которая выдаст на экран сколько у дяди Паши коров, куриц и свинок по очереди, а потом общее количество животноводности на ферме.

    Wednesday, October 6, 2010

    Урок номер ноль, подготовительный.

    Итак, вы решили научиться программировать. На пайтоне. Не на питоне, как говорят глупые люди полагающие что python это такая змея, а умные, которые прочитали пару слов об этом языке от его создателя, и знающие что это от любви к Монти Пайтону.

    "I chose Python as a working title for the project, being in a slightly irreverent mood (and a big fan of Monty Python's Flying Circus)."

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

    1. Скачать и установить пайтон -
    http://www.python.org/ftp/python/2.7/python-2.7.msi

    2. Скачать и установить удобный редактор/компилятор для пайтона, например -
    http://code.google.com/p/pyscripter/downloads/detail?name=PyScripter-v2.1.1-Setup.exe

    Теперь, попробуем запустить пайтон из командной строки.
    Start > Programs > Python > Python (command line)

    На экране появилось пару слов о том какая версия пайтона у нас бежит, много непонятных букв, а в конце ">>>". Этот значек означает что пайтон ожидает нашего приказа. В качестве первого домашнего задания, проверим знания пайтона в элементарной математике, вводим (построчно):
    2+2
    3-5
    12*15
    5**2
    20/3
    20.0/3
    22%10

    а так-же немного поболтаем, вводим:
    print "Python"
    print "Monthy " + "Python"
    print "Monthy " - "Python"
    print "dvazhdi dva =" + 2*2
    print "dvazhdi dva =", 2*2

    Домашнее задание:
    1. Номер версии пайтона которая у вас бежит.
    2. Что делает значек **?
    3. Почему 20/3 и 20.0/3 дали разный результат?
    4. Что делает значек %?
    5. Результат каждой из построчных текстовых команд.
    6. Можете ли вы объяснить почему некоторые из них выдали ошибку?