Содержание
Основы командной строки UNIX
Большая часть работы с веб у нас будет происходить на сервере web-corpora.net, который работает под управлением ОС UNIX, и нам бы неплохо научиться этой ОС управлять.
Для начала нам потребуется:
Открываем PuTTY, вводим адрес web-corpora.net, остальное оставляем как есть, попадаем на сервер. Тут мы можем давать ему команды и видеть ответы.
Как ходить и смотреть
Посмотрим, какие есть файлы там, где мы сейчас:
ls
никаких? Тогда попросим показать и скрытые файлы тоже. (В командной строке UNIX команды отделяются от аргументов пробелами и разные аргументы тоже отделяются друг от друга пробелами).
ls -a
Вывод: в UNIX скрытые файлы это те файлы, имя которых начинается с точки.
Среди прочих скрытых файлов видим две папочки: . и ..
. обозначает саму эту же самую директорию
.. обозначает директорию уровнем выше
И вспомним, что ещё мы знаем про пути:
a/b обозначает внутри директории a нам нужно b (NB: в UNIX и вебе слэши прямые, и только в Windows обратные – это была коммерческая уловка Билла Гейтса на заре DOS)
/ обозначает корень (в отличие от Windows, в UNIX корень один, а не по одному на диск)
/a обозначает путь, отсчитываемый от корня
a – если путь не начинается со слэша, то это путь относительно нашего местонахождения
.. – подняться выше
../a – директория a рядом с той, где мы находимся
~ обозначает нашу домашнюю директорию (но только если с неё начинается путь); домашняя директория – это место, которое отведено вам для того, чтобы хранить там всё, что вы туда положите. Помните, что на сервере есть ещё полно пользователей.
Узнать, где мы находимся, можно командой pwd (print working directory)
pwd
Перейти в другое место можно командой cd (change working directory – на заре UNIX клавиатуры были очень жёсткие, и когда Денниса Ритчи спросили, что бы он изменил в UNIX, если бы сочинял его заново, он ответил: переименовал бы creat в c).
cd dirname pwd ls cd .. pwd ls cd /tmp pwd ls cd ../home pwd ls
/tmp – это специальная папка, являющаяся всеобщей свалкой всего временного. Она периодически очищается, и вы не имеете над этим власти. Не кладите туда ничего ценного. И убирайте там за собой, если вы что-нибудь вы туда положили (а то и вправду воняет).
Когда мы загуляли куда-то далеко, очень хочется телепортироваться домой. Для этого есть специальное сокращение:
cd
Без аргументов она переносит нас домой.
Как наводить порядок: создавать, удалять и переименовывать
Теперь будем учиться организовывать своё рабочее пространство: создавать, удалять, переименовыать.
mkdir dirname
Так и расшифровывается: make directory. (В смысле, создать)
rmdir dirname
Remove directory – пояснений не требует.
Теперь мы хотим создать файл с каким-нибудь наполнением. Текстовые редакторы в UNIX не очень удобные, так что их не трогаем. Зато очень легко сохранить в файл выдачу команды, например, ls:
ls > file_list
Оператор перенаправления > говорит, что на экран ничего не попадёт, зато вся выдача программы будет сохранена в файл с именем, которое мы дали. (В данном случае file_list).
Некоторые программы умеют замечать, что их таким образом подслушивают, и выдавать в файл другое содержимое, чем на экран. ls, например, в файл пишет список файлов по одному в столбик, чтобы с ними было удобно раборать программам, а на экран форматирует их покучнее и почитаемее.
Теперь мы умеем создавать файлики и их можно подвигать взад-вперёд:
mkdir stuff mv file_list stuff ls ls stuff
mv от слова move, имеет такие аргументы: mv что что что... куда
создадим ещё файликов:
cd stuff ls > stuff_file_list ls pwd
Теперь хочется сделать что-нибудь с кучей файликов. Для этого в качестве частей аргументов команд можно использовать такие выражения (они называются glob или wildcard):
* обозначает все файлы в этой папке
ну и вообще в любой части пути можно использовать * для обозначения любого количества символов, продолжающих путь
? обозначает один любой символ
[a-e] обозначает один символ от a до e
[abcd] обозначет один из перечисленных симоволов
NB: это совсем не регулряные выражения, это сильно более простые шаблоны, возможности их гораздо более ограничены, и смысл символов в них другой.
Чтобы поиграться с шаблонами нам полезно знать, что ls -d не показывает содержимое папки, а показывает только список папок, которые мы ему дали:
ls -d ls -d /??? ls -d * ls -d a* ls -d /[a-n]*
Как смотреть содержимое
Вернёмся к нашим файлам:
cd cd stuff
Мы хотим посмотреть их содержимое. В UNIX особо богаты средства работы с текстами. (Да и вообще, идеология UNIX предполагает, что всё в операционной системе должно быть текстом). Поэтому в нём безумное количество возможностей обрабатывать, преобразовывать и выводить текст на экран. Расскажу только две самые простые.
cat file_list
Утилита cat тупо выводит файл на экран. Она очень тупая. Она не ждёт, пока вы прочитаете страницу, а вываливает его целиком. Если файл очень большой, то выводиться на экран он будет очень долго.
Но для маленьких файлов удобно.
Если ей дать несколько аргументов, она склеит файлы вместе:
cat * > new_file
В честь этого она и названа: conCATenate.
А если мы хотим удобств, нормальной работы со сколь-угодно большими файлами, возможности поиска, нормальной работы со стрелочками и пр, возможности делать закладки и прыгать через них, возможности открывать несколько файлов и переключаться между ними, то для этого существует просмотрщик less:
less new_file
Два главных знания про less:
кнопка h от слова help показывает хелпы
кнопка q от слова quit выпускает вас наружу
Хелпы
И самая главная команда UNIX:
man ls
от слова manual (тот manual, который мануал или пользовательское руководство, а не другие manual). Она знает хелпы почти про что угодно и показывает их с помощью less.
Teaser
Ну и напоследок пример на тему того, что можно делать в UNIX за счёт его вопиюще-текстовой природы. UNIX не умеет делать такое дело, как считать, сколько файлов с каким расширением находится в данной папке, да ещё и игнорируя файлы в подпапках .svn где-либо. Однако, команду, которая это умеет делать, очень несложно сочинить, выглядеть она будет, например, так:
find | fgrep -v '.ssh' | sed -r 's/.*([.][^.]*$)/\1/' | sort | uniq -c | sort -n | tail
Здесь нет ничего сложного. Достаточно знания полутора десятка команд, парочки параметров для некоторых из них, регулярных выражений и ещё двух-трёх элементов синтаксиса командной строки UNIX, – и вы сможете писать так же. В итоге многие часто возникающие в жизни компьютерного лингвиста технические задачи массовой обработки данных можно решать неделями вручную, за пару часов, написав скрипт на питоне, или за пять-десять минут, составив вот такого рода конструкцию. (Я почти всегда из этих вариантов предпочитаю последний).
Эта тема в плане называется "Основы UNIX для обработки текстов".
Flask: адреса, шаблоны, переменные
Подготовка рабочего места.
Установите pip. Нужно скачать get-pip.py и запустить его.1
Откройте командную строку (Windows -> Run -> cmd)
Зайдите в директорию, где установлен питон (chdir C:\Python27\Scripts), и запустите pip install flask
Либо можете работать на нашем сервере: web-corpora.net
В прошлый раз мы написали такую программку, которая отвечает на все запросы "покажи мне страницу" словами "404 ошиблись адресом":
В качестве параметра port мы даём ей номер порта, которым мы будем пользоваться. Так как две программы не могут принимать соединения с одним и тем же номером порта (ведь номер порта и есть идентификатор программы), то нам нужно всем пользоваться разными номерами. Чтобы не ссориться, я записал в ведомость колонку "порт" и присвоил каждому его номер порта. Выучите его и пользуйтесь всегда им.
Если вы работаете дома: не парьтесь, берите любой больше, чем 1024! (Меньшие номера зарезервированы для системных нужд).
Запускаем в puTTY python имя_программы.
Заходим на http://web-corpora.net:порт (или на http://localhost:порт, если вы запускаете flask на своём компьютере) и радуемся.
app.route
Первое: мы хотим, чтобы когда мы открываем страницу, нам _что-нибудь_ выдавалось.
Нам нужно сделать функцию, которая будет обрабатывать запросы и сказать, чтобы именно она вызывалась, когда пользователь хочет посмотреть адрес "/". (Flask опускает занудное повторение части "http://web-corpora.net:порт" и даёт нам указывать только то, что идёт в адресе после неё).
Flask пользуется для этого новой для нас конструкцией из питона (таких осталось совсем немного) – это декоратор. Декоратор – это пометка, которую мы приделываем к функции, чтобы функция приобрела какой-то новый смысл. Мы можем определять свои такие пометки, но об этом я сейчас рассказывать не буду. Если хотите, соответствующая тема в плане называется "как из питона сделать язык, заточенный под нашу задачу (domain-specific language, DSL): декораторы"
Использовать декораторы просто: нужно написать @ и текст декоратора перед функцией. Декораторов может быть сколько угодно (тогда их нужно стопочкой писать, по одному на строке).
@app.route("/"), будучи прилепленным к определению функции index, собственно, и говорит, что когда пользователь открывает путь / (то есть адрес http://web-corpora.net:порт/), нужно вызвать функцию index и показать пользователю то, что она вернула.
Теперь нам нужно перезапустить питон. Для этого сначала останавливаем его (Ctrl-C), а затем пускаем заново (можно вызвать предыдущую команду стрелочкой вверх).
И зайдём на http://web-corpora.net:порт/ – и там должно быть приветствие.
Мы можем к одной функции прилепить много декораторов. Тогда она будет отзываться на много разных адресов:
Теперь приветствие висит и на http://web-corpora.net:порт/ , и на http://web-corpora.net:порт/hello , и на http://web-corpora.net:порт/a/b
Разумеется, мы можем описать сколько угодно таких функций и привесить их к сколько угодно разных адресов:
Аргументы
Гораздо интереснее, когда мы можем не перечислять разные адреса запроса, а взять кусочек запроса и положить в переменную. И мы это можем сделать. Для этого нужно кусочек запроса, который нам интересен, обозначить словом в угловых скобках (например <who>), а ещё сделать так, чтобы функция, которая этот запрос обрабатывает, принимала аргумент с таким именем:
Шаблоны
Но играться со строками не интересно.
Создадим папочку templates (слово templates играет для Flask существенную роль: это то место, где он ищет файлы страничек) рядом с нашим питонским файлом и положим туда какую-нибудь html-ку, например, такую:
Я положил её в файл templates/index.html (если смотреть относительно места, где лежит питонская программа).
Теперь нам надо в нашей программе проимпортировать ещё и функцию render_template, и в ответ на какой-нибудь запрос попросить её выдать нашу html-ку:
1 from flask import Flask, render_template
2
3 app = Flask(__name__)
4
5 @app.route("/")
6 @app.route("/hello")
7 def index():
8 return render_template("index.html")
9
10 @app.route("/bye/<who>")
11 def index(who):
12 return "Goodbye, {}!".format(who)
13
14 if __name__ == "__main__":
15 app.run(host='0.0.0.0', port=2020)
Суперзадача: энциклопедия натуральных чисел!
Феноменальная новость!
Студент Иванов выучил весь натуральный ряд! Демонстрация феномена продолжается в аудитории 1234.
Мы хотим сделать сайт, в котором на каждой странице показывается число и есть ссылочки на соседние два числа.
Для этого мы хотим сделать сайт, у которого по запросу /число рисуется страница с числом и ссылками на страницы /число-1 и /число+1 (имеется в виду не дословно -1 и +1, а следующее и предыдущее число в натуральном ряду).
Начнём это делать с html-ки, то есть с её шаблона. Тут, вроде, всё просто, только нужно воткнуть куда-то число и ссылочки в шаблон. Число мы получим из переменной из питона. В шаблон мы можем подставлять питонские переменные в виде: {{переменная}} или {{выражение}} (там работает чуть-чуть видоизменённое подмножество питона)
Осталось научиться передавать переменную в шаблон. Это очень просто: функция render_template принимает после названия шаблона сколько угодно каких-угодно именованных параметров, и они-то и становятся переменными для наших подстановок:
Нам нужно, чтобы по ссылке вида /<число> открывалась страница с number=число:
Обзор типичной архитектуры сайта
Дабы понимать, к чему мы стремимся.
Как устроена типичная поисковая система?
Во-первых, у неё есть морда – это просто обычный html, который раздаётся без каких-либо изменений.
Во-вторых, в этом html есть формочка для поиска (это мы научимся делать в следующий раз), при заполнении которой отправляется запрос на сервер с тем, чтобы показать результаты. В этом запросе, среди прочего, есть текст, вбитый в формочку.
Теперь мы понимаем, что этот текст попадёт вот в такую питонскую функцию вроде нашей index. Эта функция, наверное, отправит запрос в базу данных и дождётся оттуда ответа, а потом результат подставит в шаблон, как мы и сделали с числом.
Конечно, чтобы сделать большой красивый сложный сайт, в него нужно вложить кучу сил. Да и с технической стороны у нас ещё осталась пара белых пятен (например, как делать формочки, и обрабатывать данные из них). Но, кажется, сейчас приципиальное устройство таких сайтов не кажется полной магией. Сейчас кажется, что это потребует ужасно много работы, но мы скоро узнаем, как шаблоны flask (а точнее, пакета jinja2, которым пользуется flask) могут нам сэкономить очень много повторной работы.
Если вы вдруг решили освоить третий питон, то в python3.4 pip установлен из коробочки. (1)