<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;A0AFQnk6cCp7ImA9WhRbEkk.&quot;"><id>tag:blogger.com,1999:blog-2025136836330523605</id><updated>2012-02-03T08:15:13.718+02:00</updated><category term="logging" /><category term="processing" /><category term="control" /><category term="protocol" /><category term="development" /><category term="free" /><category term="production" /><category term="command prompt" /><category term="stylesheet" /><category term="hash" /><category term="conversion" /><category term="info" /><category term="api" /><category term="service" /><category term="threading" /><category term="win32" /><category term="cource" /><category term="practice" /><category term="aliases" /><category term="sha224" /><category term="rss" /><category term="web.py" /><category term="video" /><category term="nosql" /><category term="clientlogin" /><category term="training" /><category term="opera" /><category term="protection" /><category term="sha512" /><category term="facebook" /><category term="scheme" /><category term="key-value" /><category term="tornado" /><category term="authentication" /><category term="friendfeed" /><category term="core" /><category term="intro" /><category term="example" /><category term="guid" /><category term="fetch" /><category term="conveyor" /><category term="sha384" /><category term="lambda" /><category term="camp" /><category term="artificial" /><category term="online" /><category term="rest" /><category term="introspection" /><category term="interview" /><category term="text" /><category term="flickr" /><category term="design" /><category term="network" /><category term="ubuntu" /><category term="datetime" /><category term="tree" /><category term="json" /><category term="google" /><category term="sha1" /><category term="feeds" /><category term="technology" /><category term="cluster" /><category term="decorator" /><category term="secure" /><category term="ticket" /><category term="template" /><category term="application" /><category term="sync" /><category term="it" /><category term="Steve Jobs" /><category term="portable" /><category term="flow" /><category term="description" /><category term="packet" /><category term="course" /><category term="compare" /><category term="stanford" /><category term="code" /><category term="async" /><category term="learning" /><category term="pyflowctrl" /><category term="comments" /><category term="unique" /><category term="kvlite" /><category term="walker" /><category term="lifehack" /><category term="processor" /><category term="reduce" /><category term="sqlite" /><category term="indexing" /><category term="post" /><category term="thread" /><category term="gae" /><category term="queue" /><category term="jquery" /><category term="identity" /><category term="datatype" /><category term="task" /><category term="kamaelia" /><category term="server" /><category term="md5" /><category term="install" /><category term="html5" /><category term="web" /><category term="system tray" /><category term="profiler" /><category term="mapreduce" /><category term="hadoop" /><category term="library" /><category term="presentation" /><category term="firefox" /><category term="test" /><category term="pool" /><category term="hint" /><category term="css" /><category term="stdin" /><category term="intelligence" /><category term="performance" /><category term="review" /><category term="get" /><category term="miltuthread" /><category term="cpu" /><category term="generator" /><category term="sha256" /><category term="notes" /><category term="overview" /><category term="xml" /><category term="business" /><category term="advice" /><category term="mysql" /><category term="logic" /><category term="seminar" /><category term="datastore" /><category term="css3" /><category term="machine" /><category term="cloud" /><category term="school" /><category term="testlab" /><category term="game" /><category term="data center" /><category term="filter" /><category term="chrome os" /><category term="people" /><category term="html" /><category term="reference" /><category term="stdout" /><category term="atom" /><category term="data munging" /><category term="widget" /><category term="request" /><category term="computing" /><category term="disqus" /><category term="url" /><category term="media" /><category term="extract" /><category term="javascript" /><category term="apple" /><category term="fast" /><category term="architechure" /><category term="map" /><category term="skype" /><category term="benchmark" /><category term="social" /><category term="directory" /><category term="youtube" /><category term="conference" /><category term="http" /><category term="curl" /><category term="start-up" /><category term="concurrent" /><category term="console" /><category term="find" /><category term="approach" /><category term="dynamo" /><category term="developers" /><category term="analysis" /><category term="python" /><category term="amazon" /><category term="internet" /><category term="parallel" /><category term="windows" /><category term="open" /><category term="ukraine" /><category term="stderr" /><category term="timestamp" /><category term="file" /><category term="authorization" /><category term="database" /><category term="linux" /><category term="debug" /><category term="key" /><category term="feed" /><category term="research" /><category term="cygwin" /><category term="process" /><category term="programming" /><category term="yandex" /><category term="font" /><category term="mongodb" /><category term="book" /><category term="blog" /><category term="time" /><category term="kiev" /><category term="blogger" /><category term="dictionary" /><category term="structure" /><category term="search" /><category term="mozilla" /><category term="data" /><category term="metadata" /><category term="reader" /><category term="distribution" /><title>Development for fun</title><subtitle type="html">Разработка как хобби</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://devel.ownport.net/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://devel.ownport.net/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/2025136836330523605/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>d.rey</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>116</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/develforfun" /><feedburner:info uri="develforfun" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;A0AFQnk5fip7ImA9WhRbEkk.&quot;"><id>tag:blogger.com,1999:blog-2025136836330523605.post-3554267479909194344</id><published>2012-02-03T07:16:00.001+02:00</published><updated>2012-02-03T08:15:13.726+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-02-03T08:15:13.726+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="structure" /><category scheme="http://www.blogger.com/atom/ns#" term="description" /><category scheme="http://www.blogger.com/atom/ns#" term="pyflowctrl" /><category scheme="http://www.blogger.com/atom/ns#" term="packet" /><category scheme="http://www.blogger.com/atom/ns#" term="json" /><category scheme="http://www.blogger.com/atom/ns#" term="scheme" /><title>Описание сложных типов данных для потоков</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-iNa2Or0pcDU/TytsqaaNhaI/AAAAAAAAAdk/10uj1zskr6Y/s1600/atoms.jpg" imageanchor="1" style="clear:left; float:left;margin-right:1em; margin-bottom:1em"&gt;&lt;img border="0" height="90" width="120" src="http://4.bp.blogspot.com/-iNa2Or0pcDU/TytsqaaNhaI/AAAAAAAAAdk/10uj1zskr6Y/s320/atoms.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;Потоки играют важную роль в обмене информации между процессами. Единицей переноса информации в потоках являются &lt;a href="http://devel.ownport.net/2012/01/pyflowctrl.html"&gt;пакеты&lt;/a&gt;. Описание структур пакетов позволяется без анализа кода процесса связывать процессы между собой. Простые структуры данных (без вложений) содержащиеся в пакетах можно описать достаточно просто. Для каждого параметра определить имя, тип и описание. Для случаев, когда данные переданные в потоках имеют сложную,  иерархическую структуру для их описания требуется определенный синтаксис.&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
Древовидные структуры данных в python удобно представлять в виде словарей (dictionary). Можно провести параллель структуры словаря python с JSON форматом. В обоих случаях для хранения данных используются схожие подходы. Для описания данных хранимых в JSON формате используется &lt;a href="http://tools.ietf.org/html/draft-zyp-json-schema-03"&gt;JSON Scheme&lt;/a&gt;. Принципы заложенные в этой спецификации можно использовать и для описания данных, хранимых в python словарях, а соответственно использовать для описания структуры данных пакетов &lt;a href="http://code.google.com/p/pyflowctrl/"&gt;pyflowctrl&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Кроме возможности корректной связи между собой процессов, описание должно иметь форму доступную для анализа не только человеком, но и программой. Это позволит выполнять валидацию данных передаваемых между процессами.&lt;br /&gt;
&lt;br /&gt;
Базовая спецификация JSON Schema определяет 8 типов данных JSON объекта: Object, Array, String, Number, Integer, Boolean, Null, Any. Два из них вложенные типы - Object и Array, 5 атомарных и один тип Any, который может содержать любые значения, включая Null. Для описания используются строки: “object”, “array”, “string”, “number”, “integerer”,”boolean”,”null”,”any”. Например:&lt;pre&gt;"module": {
    "type": "string",
    "title": "Module name",
     "required": "true",
    }&lt;/pre&gt;где атрибут type - описывает тип, title - краткое описание свойства объекта. Дополнительно к title можно указать атрибут description для более детального документирования свойтсва объекта. Атрибуты title и description - опциональны. По умолчанию принято, что все свойства в схеме опциональные. Если какое-то свойство должно быть  обязательно определено, оно должно быть описано с помощью атрибута required.&lt;br /&gt;
&lt;br /&gt;
Для описания структур, таких как массивы существует атрибут items, определяющий типы элементов в массиве.&lt;pre&gt;"based_on": {
    "type": "array",
        "title": "list of bassed-on classes",
        "items": {
            "type": "string",
            "title": "Based-on class",
        }
},&lt;/pre&gt;Для описания объектов используется атрибуты object и properties&lt;pre&gt;{
    "type": "object",
    "title": "Class of module",
    "properties:": {
        "name": {
            "type": "string",
            "title": "name of class",
            "required": "true",
        },
        "path": {
            "type": "string",
            "title": "path for class importing",
            "required": "true",
        },
}&lt;/pre&gt;Примеры, приведенные выше взяты из последней версии процесса &lt;a href="http://code.google.com/p/pyflowctrl/source/browse/pyflowctrl/core4/processes/pymetainfo2.py"&gt;PyMetaInfo&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Ссылки:&lt;/b&gt;&lt;br /&gt;
JSON Scheme &lt;a href="http://tools.ietf.org/html/draft-zyp-json-schema-03"&gt;http://tools.ietf.org/html/draft-zyp-json-schema-03&lt;/a&gt;&lt;br /&gt;
JSON validator &lt;a href="http://code.google.com/p/jsonvalidator/"&gt;http://code.google.com/p/jsonvalidator/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Логотип: &lt;a href="http://www.freedigitalphotos.net/images/view_photog.php?photogid=659"&gt;Salvatore Vuono / FreeDigitalPhotos.net&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2025136836330523605-3554267479909194344?l=devel.ownport.net' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/develforfun/~4/aKQh--plzyM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://devel.ownport.net/feeds/3554267479909194344/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="http://devel.ownport.net/2012/02/blog-post.html#comment-form" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2025136836330523605/posts/default/3554267479909194344?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2025136836330523605/posts/default/3554267479909194344?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/develforfun/~3/aKQh--plzyM/blog-post.html" title="Описание сложных типов данных для потоков" /><author><name>d.rey</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-iNa2Or0pcDU/TytsqaaNhaI/AAAAAAAAAdk/10uj1zskr6Y/s72-c/atoms.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://devel.ownport.net/2012/02/blog-post.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUMEQHYycCp7ImA9WhRUGEw.&quot;"><id>tag:blogger.com,1999:blog-2025136836330523605.post-429184493348428618</id><published>2012-01-29T07:03:00.000+02:00</published><updated>2012-01-29T07:03:21.898+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-29T07:03:21.898+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="free" /><category scheme="http://www.blogger.com/atom/ns#" term="mongodb" /><category scheme="http://www.blogger.com/atom/ns#" term="book" /><title>Небольшая книга о MongoDB</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-MooC3V8Jqds/TyTRPeLN4PI/AAAAAAAAAdY/hBOqdIYOfic/s1600/the_little_mongodb_book.png" imageanchor="1" style="clear: left; display: inline !important; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-MooC3V8Jqds/TyTRPeLN4PI/AAAAAAAAAdY/hBOqdIYOfic/s1600/the_little_mongodb_book.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;i&gt;It's not my fault the chapters are short, MongoDB is just easy to learn.&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
Эта книга была написана всего за 4-5 часов. Немного более 30 страниц. Описана только базовая функциональность MongoDB. Примеры приводятся для командной строки. Первое конфигурирование. Что такое NoSQL базы данных и их реализация в MongoDB. Как управлять данными: insert, find, update. Моделирование данных: no joins, массивы и встроенные документы, коллекции. Когда использовать MongoDB.&amp;nbsp;MapReduce. Производительность и инструменты&lt;br /&gt;
&lt;br /&gt;
Книга The Little MongoDB Book бесплатна и доступна на &lt;a href="http://openmymind.net/2011/3/28/The-Little-MongoDB-Book/"&gt;сайте автора&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2025136836330523605-429184493348428618?l=devel.ownport.net' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/develforfun/~4/0lsLr0rZImg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://devel.ownport.net/feeds/429184493348428618/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="http://devel.ownport.net/2012/01/mongodb.html#comment-form" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2025136836330523605/posts/default/429184493348428618?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2025136836330523605/posts/default/429184493348428618?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/develforfun/~3/0lsLr0rZImg/mongodb.html" title="Небольшая книга о MongoDB" /><author><name>d.rey</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-MooC3V8Jqds/TyTRPeLN4PI/AAAAAAAAAdY/hBOqdIYOfic/s72-c/the_little_mongodb_book.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://devel.ownport.net/2012/01/mongodb.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkMGQXg6fip7ImA9WhRUFUs.&quot;"><id>tag:blogger.com,1999:blog-2025136836330523605.post-4404463027430968598</id><published>2012-01-26T08:47:00.000+02:00</published><updated>2012-01-26T08:47:00.616+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-26T08:47:00.616+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="data" /><category scheme="http://www.blogger.com/atom/ns#" term="production" /><category scheme="http://www.blogger.com/atom/ns#" term="pyflowctrl" /><category scheme="http://www.blogger.com/atom/ns#" term="conveyor" /><category scheme="http://www.blogger.com/atom/ns#" term="processing" /><title>Другой взгляд на pyflowctrl</title><content type="html">Бывает так, что для того чтобы лучше понять как работает система, нужно привести примеры подобия с другими системами. Вчера, случайно наткнувшись на сайт компании &lt;a href="http://www.eagletechnologies.com/"&gt;Eagle Technologies&lt;/a&gt;, специализирующейся на системах автоматизации производств, понял, что работу &lt;a href="http://code.google.com/p/pyflowctrl/"&gt;pyflowctrl&lt;/a&gt; можно сравнить с &lt;a href="http://ru.wikipedia.org/wiki/%D0%9F%D0%BE%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%BE%D0%B4%D1%81%D1%82%D0%B2%D0%BE"&gt;поточным производством&lt;/a&gt;. Где в качестве как сырья, так и конечного изделия выступают данные. &lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-gA30HmlfEO8/TyD123GT9MI/AAAAAAAAAdM/r60fxALyUl0/s1600/eagle-technologies-conveyor.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-gA30HmlfEO8/TyD123GT9MI/AAAAAAAAAdM/r60fxALyUl0/s1600/eagle-technologies-conveyor.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
На вход системы поступают “сырые” данные (Packet), требующие обработки. Проходя каждый процесс (Process) обработки, согласно определенной логики (ProcessFlow) над данными выполняются ряд манипуляций по обработке. Связь между процессами осуществляется с помощью потоков (Stream). Именно они служат конвейером, средством транспортировки данных (Packet)  между процессами (Process). Точно также машина проходя по сборочному цеху преобразуется из простых металлоконструкций в законченное изделие.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2025136836330523605-4404463027430968598?l=devel.ownport.net' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/develforfun/~4/r-W0qCEo_Cg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://devel.ownport.net/feeds/4404463027430968598/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="http://devel.ownport.net/2012/01/pyflowctrl_26.html#comment-form" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2025136836330523605/posts/default/4404463027430968598?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2025136836330523605/posts/default/4404463027430968598?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/develforfun/~3/r-W0qCEo_Cg/pyflowctrl_26.html" title="Другой взгляд на pyflowctrl" /><author><name>d.rey</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-gA30HmlfEO8/TyD123GT9MI/AAAAAAAAAdM/r60fxALyUl0/s72-c/eagle-technologies-conveyor.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://devel.ownport.net/2012/01/pyflowctrl_26.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0cDR3w5eyp7ImA9WhRUFEo.&quot;"><id>tag:blogger.com,1999:blog-2025136836330523605.post-9104823231701983726</id><published>2012-01-25T07:57:00.002+02:00</published><updated>2012-01-25T07:57:56.223+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-25T07:57:56.223+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="process" /><category scheme="http://www.blogger.com/atom/ns#" term="description" /><category scheme="http://www.blogger.com/atom/ns#" term="pyflowctrl" /><category scheme="http://www.blogger.com/atom/ns#" term="metadata" /><title>Описание процесса pyflowctrl</title><content type="html">Реализация процесса (класс Process) в pyflowctrl не позволяет определить с помощью &lt;a href="http://code.google.com/p/pyflowctrl/source/browse/pyflowctrl/core4/processes/pymetainfo1.py"&gt;pymetainfo&lt;/a&gt; достаточную информацию о процессе, без дополнительного его описания. Получаемые метаданные избыточны и содержат специфичную для python внутреннюю реализацию. Пример вывода можно посмотреть в посте “&lt;a href="http://devel.ownport.net/2012/01/c-python.html"&gt;Исследования python-кода&lt;/a&gt;”. &lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
После анализа процессов предыдущих релизов pyflowctrl был сформирован черновой список, необходимой информации о процессе:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;название процесса&lt;/li&gt;
&lt;li&gt;краткое описание процесса&lt;/li&gt;
&lt;li&gt;автор (-ы) кода процесса&lt;/li&gt;
&lt;li&gt;ссылки, где код процесса можно скачать&lt;/li&gt;
&lt;li&gt;зависимости с другими python модулями, библиотеками&lt;/li&gt;
&lt;li&gt;список потоков (входных, выходных, отладки)&lt;/li&gt;
&lt;li&gt;список функций с описанием&lt;/li&gt;
&lt;/ul&gt;Если определять перечисленные выше свойства в конструкторе процесса, получение информации о них, будет возможно только после создании экземпляра класса Process. В связи с тем, что метаданные о процессе часто являются статичными переменными, их можно вынести как атрибут процесса&lt;pre&gt;class Process(object):
    ''' Process '''
    
    __PROCESS__ = {
                    'name': 'Process',
                    'description': 'Basic process',
                    'author': '',
                    'url': '',
                    'depends on': '',
                    'io': {},
                }&lt;/pre&gt;Атрибут __PROCESS__ содержит словарь метаданных процесса, на основании которого базовый конструктор процесса выполняет создание экземпляра процесса. Наиболее важным является ключ “io”, определяющий словарь параметров потоков ввода/вывода. Пример __PROCESS__ на базе &lt;a href="http://code.google.com/p/pyflowctrl/source/browse/pyflowctrl/core4/processes/pymetainfo2.py"&gt;pymetainfo2.py&lt;/a&gt;:&lt;pre&gt;__PROCESS__ = {
                    'name': 'PyMetaInfo',
                    'description': 'Extact metadata information about module/class. Customized for pyflowctrl.',
                    'author': 'Andrey Usov &amp;lt;http://devel.ownport.net&amp;gt;',
                    'url': 'http://pyflowctrl.googlecode.com/hg/pyflowctrl/core4/processes/pymetainfo2.py',
                    'io': {'input': {}, 'output': {}, },
                }&lt;/pre&gt;Сейчас, если запустить pymetainfo2.py и указать в качестве аргумента его собственный код, вывод будет иметь следующий вид:&lt;pre&gt;$python examples/pymetainfo2.py pyflowctrl.core4.processes.pymetainfo2.PyMetaInfo

{'__namespaces': {},
 'meta': {'based_on': (&amp;lt;class 'pyflowctrl.core4.Process'&amp;gt;,),
          'classes': [('__class__', &amp;lt;type 'type'&amp;gt;, &amp;lt;type 'object'&amp;gt;)],
          'data': [('__PROCESS__',
                    {'author': 'Andrey Usov &amp;lt;http://devel.ownport.net&amp;gt;',
                     'description': 'Extact metadata information about module/class. Customized for pyflowctrl.',
                     'io': {'input': {}, 'output': {}},
                     'name': 'PyMetaInfo',
                     'url': 'http://pyflowctrl.googlecode.com/hg/pyflowctrl/core4/processes/pymetainfo1.py'})],
          'description': 'Extact metadata information about module/class ',
          'funcs': [('__init__', None),
                    ('get_classes', 'return list of classes '),
                    ('get_data', 'return data for object. filtered'),
                    ('get_elements',
                     "get list of object's elements by type"),
                    ('get_funcs', 'return list of functions, filtered'),
                    ('get_metadata', "get dictionary of object's metadata "),
                    ('get_modpkgs', "return list of module's packages "),
                    ('main', None),
                    ('remove_empty_meta', 'remove empty data '),
                    ('run_once',
                     'wrapper for main loop \n\nif packet is specified run_once return the result of processing\nif packet is not specified run_once return the status of process')],
          'name': 'PyMetaInfo',
          'type': &amp;lt;type 'type'&amp;gt;},
 'module': 'pyflowctrl.core4.processes.pymetainfo2.PyMetaInfo'}&lt;/pre&gt;Следует отметить, что с переходом на новый способ определения потоков ввода/вывода, возвращен, определенный в core3, подход доступа к потокам ввода/вывода.  &lt;br /&gt;
&lt;br /&gt;
получение пакета из входного потока &lt;i&gt;packet = process1.io['input'].get()&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
запись пакета в поток вывода &lt;i&gt;process1.io['output'].put(packet)&lt;/i&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2025136836330523605-9104823231701983726?l=devel.ownport.net' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/develforfun/~4/xNwyKoRbqqI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://devel.ownport.net/feeds/9104823231701983726/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="http://devel.ownport.net/2012/01/pyflowctrl_25.html#comment-form" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2025136836330523605/posts/default/9104823231701983726?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2025136836330523605/posts/default/9104823231701983726?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/develforfun/~3/xNwyKoRbqqI/pyflowctrl_25.html" title="Описание процесса pyflowctrl" /><author><name>d.rey</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://devel.ownport.net/2012/01/pyflowctrl_25.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ak8FRnYzeCp7ImA9WhRVGEs.&quot;"><id>tag:blogger.com,1999:blog-2025136836330523605.post-2982962409464220453</id><published>2012-01-12T08:20:00.001+02:00</published><updated>2012-01-18T08:40:17.880+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-18T08:40:17.880+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="pyflowctrl" /><category scheme="http://www.blogger.com/atom/ns#" term="python" /><category scheme="http://www.blogger.com/atom/ns#" term="code" /><category scheme="http://www.blogger.com/atom/ns#" term="introspection" /><title>Иcследование python кода</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-7rMaD5c1Yps/Tw57Ih_sIsI/AAAAAAAAAc4/AQs8sygMPlE/s1600/magnifying_glass.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="90" src="http://3.bp.blogspot.com/-7rMaD5c1Yps/Tw57Ih_sIsI/AAAAAAAAAc4/AQs8sygMPlE/s320/magnifying_glass.png" width="120" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;a href="http://ru.wikipedia.org/wiki/%D0%98%D0%BD%D1%82%D1%80%D0%BE%D1%81%D0%BF%D0%B5%D0%BA%D1%86%D0%B8%D1%8F_(%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5)"&gt;Интроспекция&lt;/a&gt;(англ. type introspection) в программировании — возможность в некоторых объектно-ориентированных языках определить тип и структуру объекта во время выполнения программы. &lt;a href="http://ru.wikipedia.org/"&gt;Wikipedia&lt;/a&gt;. Для python эта возможность интегрирована в сам язык. Хороший пример интроспекции в python - встроенная система помощи. Для любого кода на python достаточно набрать в командной строке: &lt;br /&gt;
&lt;pre&gt;$ pydoc "module/class/function name"&lt;/pre&gt;
как результат будет получено описание по модулю, классу или функции (см. примечание к посту ниже). &lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
Наибольший интерес представляет возможность анализа программы другой программой. В рамках проекта &lt;a href="http://code.google.com/p/pyflowctrl/"&gt;pyflowctrl&lt;/a&gt; это может быть очень полезной функциональностью, когда менеджер процессов ProcessFlow получает информации о процессах и осуществляет соединение на основании характеристик входных/выходных потоков. &lt;br /&gt;
&lt;br /&gt;
Процесс &lt;a href="http://pyflowctrl.googlecode.com/hg/pyflowctrl/core4/processes/pymetainfo1.py"&gt;PyMetaInfo&lt;/a&gt; позволяет провести анализ кода переданного имени модуля и вернуть метаданные в виде словаря. Пример использования процесса приведен в коде &lt;a href="http://code.google.com/p/pyflowctrl/source/browse/pyflowctrl/core4/examples/pymetainfo1.py"&gt;examples/pymetainfo1.py&lt;/a&gt;. На вход процесса передается пакет, содержащий имя модуля packet.module:&lt;br /&gt;
&lt;pre&gt;$ python examples/pymetainfo1.py pyflowctrl
{'__namespaces': {},
 'meta': {'data': [('__author__', 'Andrey Usov &lt;http: devel.ownport.net=""&gt;')],
          'description': 'Python Flow Control Library ',
          'module_packages': ['core4 (package)',
                              'examples (package)',
                              'libs (package)',
                              'processes (package)',
                              'streams (package)'],
          'name': 'pyflowctrl',
          'submodules': [('core4',
                          &lt;module '="" 'pyflowctrl.core4'="" __init__.pyc'="" core4="" data="" devel="" from="" media="" pyflowctrl=""&gt;)],
          'type': &lt;type 'module'=""&gt;},
 'module': 'pyflowctrl'}&lt;/type&gt;&lt;/module&gt;&lt;/http:&gt;&lt;/pre&gt;
На выходе получаем пакет с метаданными о библиотете. Пример вывода информации о процессе:  &lt;br /&gt;
&lt;pre&gt;$ python examples/pymetainfo1.py pyflowctrl.core4.processes.pymetainfo1.PyMetaInfo
{'__namespaces': {},
 'meta': {'based_on': (&lt;class 'pyflowctrl.core4.process'=""&gt;,),
          'classes': [('__class__', &lt;type 'type'=""&gt;, &lt;type 'object'=""&gt;)],
          'data': [('__dict__',
                    dict_proxy({'__module__': 'pyflowctrl.core4.processes.pymetainfo1', 'get_elements': &lt;function 0x2a21b18="" at="" get_elements=""&gt;, 'get_classes': &lt;function 0x2a21b90="" at="" get_classes=""&gt;, 'get_modpkgs': &lt;function 0x2a21c08="" at="" get_modpkgs=""&gt;, 'get_metadata': &lt;function 0x2a21c80="" at="" get_metadata=""&gt;, 'main': &lt;function 0x2a21cf8="" at="" main=""&gt;, '__doc__': ' Extact metadata information about module/class ', '__init__': &lt;function 0x29ba938="" __init__="" at=""&gt;})),
                   ('__weakref__',
                    &lt;attribute '__weakref__'="" 'process'="" objects="" of=""&gt;)],
          'description': 'Extact metadata information about module/class ',
          'funcs': [('__delattr__',
                     &lt;slot '__delattr__'="" 'object'="" objects="" of="" wrapper=""&gt;),
      
                    . . .

                    ('get_classes', &lt;unbound method="" pymetainfo.get_classes=""&gt;),
                    ('get_elements',
                     &lt;unbound method="" pymetainfo.get_elements=""&gt;),
                    ('get_metadata',
                     &lt;unbound method="" pymetainfo.get_metadata=""&gt;),
                    ('get_modpkgs', &lt;unbound method="" pymetainfo.get_modpkgs=""&gt;),
                    ('main', &lt;unbound method="" pymetainfo.main=""&gt;),
                    ('run_once', &lt;unbound method="" pymetainfo.run_once=""&gt;)],
          'name': 'PyMetaInfo',
          'type': &lt;type 'type'=""&gt;},
 'module': 'pyflowctrl.core4.processes.pymetainfo1.PyMetaInfo'}&lt;/type&gt;&lt;/unbound&gt;&lt;/unbound&gt;&lt;/unbound&gt;&lt;/unbound&gt;&lt;/unbound&gt;&lt;/unbound&gt;&lt;/slot&gt;&lt;/attribute&gt;&lt;/function&gt;&lt;/function&gt;&lt;/function&gt;&lt;/function&gt;&lt;/function&gt;&lt;/function&gt;&lt;/type&gt;&lt;/type&gt;&lt;/class&gt;&lt;/pre&gt;
Информация в выводе достаточно избыточна для работы pyflowctrl, отсутствует информация о потоках. Так как потоки создаются в __init__(), провести анализ содержимого объекта без его создания не получится. Необходимо пересмотреть принципы создания процессов для того, что бы существовала возможность получения информации о потоках без создания самого процесса.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Примечание&lt;/b&gt;: документация в python формируется автоматически на основании анализа кода объекта. При вызове pydoc выполняет импорт кода и проводит анализ его структуры, извлекает документацию.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2025136836330523605-2982962409464220453?l=devel.ownport.net' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/develforfun/~4/xtDg7eQvb7I" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://devel.ownport.net/feeds/2982962409464220453/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="http://devel.ownport.net/2012/01/c-python.html#comment-form" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2025136836330523605/posts/default/2982962409464220453?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2025136836330523605/posts/default/2982962409464220453?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/develforfun/~3/xtDg7eQvb7I/c-python.html" title="Иcследование python кода" /><author><name>d.rey</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-7rMaD5c1Yps/Tw57Ih_sIsI/AAAAAAAAAc4/AQs8sygMPlE/s72-c/magnifying_glass.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://devel.ownport.net/2012/01/c-python.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A08MSXk4eCp7ImA9WhRVEE0.&quot;"><id>tag:blogger.com,1999:blog-2025136836330523605.post-3590401168243368912</id><published>2012-01-08T07:03:00.000+02:00</published><updated>2012-01-08T10:04:48.730+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-08T10:04:48.730+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="core" /><category scheme="http://www.blogger.com/atom/ns#" term="pyflowctrl" /><category scheme="http://www.blogger.com/atom/ns#" term="python" /><title>Новое ядро (сore4) для pyflowctrl</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-0QlSKhlazYs/Td0QmxZusbI/AAAAAAAAAVE/POLgNtONbkQ/s1600/waterfall_process_flow.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-0QlSKhlazYs/Td0QmxZusbI/AAAAAAAAAVE/POLgNtONbkQ/s1600/waterfall_process_flow.png" /&gt;&lt;/a&gt;&lt;/div&gt;Причины перехода на новое ядро в основном были описаны в предыдущем посте “&lt;a href="http://devel.ownport.net/2012/01/pyflowctrl.html"&gt;Информационные пакеты в pyflowctrl&lt;/a&gt;”. Предыдущее ядро работу с пакетами не поддерживало, а плавно перейти на их поддержку не получалось. Кроме этого переход на новое ядро был обусловлен еще и давним желанием вывести работу над pyflowctrl в отдельный проект. Сейчас проект размещен на &lt;a href="http://code.google.com/p/pyflowctrl/"&gt;code.google.com&lt;/a&gt;. &lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
В будущем на нем будут публиковаться изменения начиная с ветки core4. С переходом на новую версию изменена структура директорий проекта:&lt;br /&gt;
&lt;br /&gt;
- core4.py перенесен в директорию core4 и__init__.py &lt;br /&gt;
- в директорию core4 добавлены под-директории processes/ для хранения кода процессов, streams/ для потоков, tests/ для тестов, examples/ для примеров работы с библиотекой, libs/ для хранения сторонних библиотек.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Изменения в логике работы core4 от core3 (core4 базируется на core3&lt;/b&gt;):&lt;br /&gt;
&lt;br /&gt;
В классе Process изменены атрибуты доступа к входным/выходным потокам. Сейчас доступ к ним осуществляется с помощью атрибутов input/output, которые нужно явно описать для нового процесса &lt;pre&gt;class TestProcess(Process):
    def __init__(self):
        super(TestProcess, self).__init__()
        self.input = Stream()
        self.output = Stream()&lt;/pre&gt;Пример определения основной функции процесса&lt;pre&gt;def main(self):
    while True:
        try:
            packet = self.input.get()
        except EmptyStream:
            yield WAITING
            continue
        # основной код для работы с данными пакета 
        self.output.put(packet)
        yield PROCESSING&lt;/pre&gt;В классе Stream убрана поддержка описания типизации потоков. В core3 давать описание потоков было не обязательно и зачастую потоки в процессах так и оставались без описаний, так как типизация данных приводила к сложностям соединения процессов. В будущем механизм описания данных в потоках будет доработан. В текущем релизе - это открытый вопрос.&lt;br /&gt;
&lt;br /&gt;
Основной единицей переноса данных между процессами является информационный пакет, класс Packet, см. “&lt;a href="http://devel.ownport.net/2012/01/pyflowctrl.html"&gt;Информационные пакеты в pyflowctrl&lt;/a&gt;”&lt;br /&gt;
&lt;br /&gt;
При создании пакета можно передавать “корневые ” переменные, которые он будет содержать &lt;pre&gt;&gt;&gt;&gt; p = Packet(counter=10, name=’test_process’)
&gt;&gt;&gt; p.counter, p.name
10 test_process&lt;/pre&gt;В классе ProcessFlow упрощен механизм создания сети взаимодействия процессов - словарь с описанием:&lt;pre&gt;network = {
    'processes': {
        'process1': TestProcess(),
        'process2': TestProcess(),
        'printer': Printer(),
    },
    'links': {
        # соединение между process1 и process2
        ('process1.output', 'process2.input', p1p2_handler), 
        # соединение между process2 и printer
        ('process2.output', 'printer.input', p2prn_handler),
    }
}&lt;/pre&gt;network[‘processes’] описывает процессы, участвующие в работе. Доступ к процессам осуществляется по их именам. &lt;br /&gt;
&lt;br /&gt;
network[‘links’] описывает взаимодействие между процессами. Каждое соединение - это список из трех аргументов: источник данных, получатель данных, обработчик данных. Источник и получатель данных  - это символьное описание, состоящее из имени процесса и имени потока. Обработчик данных позволяем изменить структуру пакета на этапе передачи его от процесса-источника до процесса-получателя. Это дает возможность адаптировать структуру пакета под нужды следующего процесса. Обработчик данных - это функция на вход которой поступает пакет и на выходе она должна возвращать его же, пример:&lt;pre&gt;def p1p2_handler(packet):
    # process1 -&gt; process2
    packet.set_namespace('test-env1')
    packet['test-env1'].name = packet.name
    packet['test-env1'].url = packet.url
    del packet.name
    del packet.url
    return packet&lt;/pre&gt;Если данные в обработке не нуждаются, то вместо обработчика данных передается None. &lt;pre&gt;'links': {
        ('process1.output', 'process2.input', None),
}&lt;/pre&gt;Обработчики данных можно использовать также как функции-отладчики для вывода данных обменивающихся между процессами.&lt;pre&gt;'links': {
        ('process1.output', 'process2.input', p1p2debug),
}&lt;/pre&gt;Загрузка сети network в ProcessFlow выполняется с помощью метода upload(network)&lt;pre&gt;flow = ProcessFlow()
flow.upload(network)
for i in xrange(10):
    flow.pmap['process1'].input.put(Packet(counter=i))
flow.run()&lt;/pre&gt;Метод run() выполняет запуск сети в работу&lt;br /&gt;
&lt;br /&gt;
Пример работы с core4 расположен в &lt;a href="http://pyflowctrl.googlecode.com/hg/core4/examples/example1.py"&gt;директории examples репозитория&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2025136836330523605-3590401168243368912?l=devel.ownport.net' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/develforfun/~4/QpKZUXPxo1o" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://devel.ownport.net/feeds/3590401168243368912/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="http://devel.ownport.net/2012/01/ore4-pyflowctrl.html#comment-form" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2025136836330523605/posts/default/3590401168243368912?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2025136836330523605/posts/default/3590401168243368912?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/develforfun/~3/QpKZUXPxo1o/ore4-pyflowctrl.html" title="Новое ядро (сore4) для pyflowctrl" /><author><name>d.rey</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-0QlSKhlazYs/Td0QmxZusbI/AAAAAAAAAVE/POLgNtONbkQ/s72-c/waterfall_process_flow.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://devel.ownport.net/2012/01/ore4-pyflowctrl.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUQAR346cSp7ImA9WhRWGUw.&quot;"><id>tag:blogger.com,1999:blog-2025136836330523605.post-3333478330547940426</id><published>2012-01-07T07:15:00.000+02:00</published><updated>2012-01-07T07:15:46.019+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-07T07:15:46.019+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="process" /><category scheme="http://www.blogger.com/atom/ns#" term="control" /><category scheme="http://www.blogger.com/atom/ns#" term="pyflowctrl" /><category scheme="http://www.blogger.com/atom/ns#" term="python" /><category scheme="http://www.blogger.com/atom/ns#" term="packet" /><title>Информационные пакеты в pyflowctrl</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-0QlSKhlazYs/Td0QmxZusbI/AAAAAAAAAVE/POLgNtONbkQ/s1600/waterfall_process_flow.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-0QlSKhlazYs/Td0QmxZusbI/AAAAAAAAAVE/POLgNtONbkQ/s1600/waterfall_process_flow.png" /&gt;&lt;/a&gt;&lt;/div&gt;
Основой любой вычислительной системы является обработка информации: получение одних данных из других с пользованием некоторых алгоритмов. Долгое время основной акцент при разработке pyflowctrl делался на работе самих процессов. Когда каждый процесс рассматривается как черный ящик, со временем возникают сложности в организации их совместной работы. Отсутствие механизма согласованного обмена данных не только между двумя процессами, но и между процессами системы в целом, приводит к необходимости постоянно адаптировать существующие процессы под меняющиеся задачи и как следствие гибкость системы теряется.&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
Приведу пример диаграммы взаимодействия процессов одного из предыдущих постов - “&lt;a href="http://devel.ownport.net/2011/06/html.html"&gt;Извлекаем ссылки из HTML страницы&lt;/a&gt;”&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-r8z6wRAmZMM/Tgf1G6NPxmI/AAAAAAAAAX4/1PFCJbrlmkc/s1600/UrlExtract.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-r8z6wRAmZMM/Tgf1G6NPxmI/AAAAAAAAAX4/1PFCJbrlmkc/s1600/UrlExtract.png" /&gt;&lt;/a&gt;&lt;/div&gt;
Ранее на диаграммах отображались только сами процессы, обмен данных между процессами уходил на второй план. В примере выше, цепочка процессов могла работать только в такой конфигурации. Каждый процесс выдавал свой набор выходных данных и следующий за ним процесс мог работать только с этими данными. Если бы понадобилось использовать существующие процессы для других случаев, перед передачей данных в процесс их необходимо было специально обрабатывать, подстраивать под исходные параметры входного потока процесса. Конечно же, если исходить из того, что каждый процесс - это черный ящик, то от этого не уйти. Чаще всего процессы выполняют узконаправленную работу и работают с определенными типами входных и выходных данных.&lt;br /&gt;
&lt;br /&gt;
Больше сложностей создает отсутствие прозрачного пропуска через процесс данных, необходимые не в текущем процессе, но в последующих. Например: на вход системы подается документ, проходя через различные процессы документ изменяет свою структуру. Каждый процесс выполняет над документом только определенные манипуляции, тогда как в конце обработки, необходимо вывести все обработанные данные документа. При существующем подходе pyflowctrl.core3 приходится адаптировать существующие процессы под каждую конкретную задачу. Для того, чтобы избежать подобной необходимости в pyflowctrl.core4 вводится новое понятие - информационный пакет.&lt;br /&gt;
&lt;br /&gt;
Информационный пакет является контейнером, переносчиком данных между процессами. Структура пакета не статична, она может меняться, подстраиваться под конкретные нужды как каждого процесса, так системы обработки данных в целом. &lt;br /&gt;
&lt;pre&gt;from pyflowctrl.core4 import Packet

p = Packet()
# “корневая” область
p.id = 1
p.url = 'http://example.com'
p.content = '&amp;lt;html&amp;gt;&amp;lt;body&amp;gt;test 1&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;'
p.tags = ['html','body']&lt;/pre&gt;
Процесс, получив пакет работает с его “корневыми” данными: принимает, обрабатывает, изменяют значения в существующих полях или создает новые. Важным моментом при таком подходе является необходимость избежания коллизии имен полей, используемых другими процессами и текущим процессом. Для решения этого вопроса в пакете можно создавать различные пространства имен (namespaces). Перед передачей пакета в процесс, данные, не относящиеся к текущему процессу переносятся из “корневой” области видимости в отдельное пространство имен. &lt;br /&gt;
&lt;pre&gt;# область имен “test-namespace”
p.set_namespace(“test-namespace”)
p[“test-namespace”].id = 10
p[“test-namespace”].url = 'http://example2.com'
p[“test-namespace”].content = '&amp;lt;html&amp;gt;&amp;lt;body&amp;gt;test 2&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;'
p[“test-namespace”].tags = ['html','body']&lt;/pre&gt;
Размещая данные в различных пространствах имен можно прозрачно передавать данные, необходимые для следующего процесса.&lt;br /&gt;
&lt;br /&gt;
Пространства имен в пакете можно создавать с помощью метода &lt;i&gt;set_namespace(name)&lt;/i&gt;, удалять &lt;i&gt;del_namespace(name)&lt;/i&gt;, выводить список &lt;i&gt;namespaces()&lt;/i&gt;. &lt;br /&gt;
&lt;br /&gt;
В связи с тем, что пространства имен могут быть доступны внутри процесса существует риск нарушении структуры пакета самим процессом в случае ошибки или его некорректной работы. Процесс должен работать только с корневыми переменными, а управление данными в пространствах имен выполняется на уровне управления потоками процессов. Число пространств имен внутри пакета не ограничивается.&lt;br /&gt;
&lt;br /&gt;
Часто возникают ситуации, когда процесс при получении одного пакета, должен вернуть несколько. В этом случае, для сохранения данных из пространств имен  входного пакета, процесс должен скопировать &lt;i&gt;copy()&lt;/i&gt; исходный пакет и изменить в нем “корневые” поля.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2025136836330523605-3333478330547940426?l=devel.ownport.net' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/develforfun/~4/GqphAn3YKvw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://devel.ownport.net/feeds/3333478330547940426/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="http://devel.ownport.net/2012/01/pyflowctrl.html#comment-form" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2025136836330523605/posts/default/3333478330547940426?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2025136836330523605/posts/default/3333478330547940426?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/develforfun/~3/GqphAn3YKvw/pyflowctrl.html" title="Информационные пакеты в pyflowctrl" /><author><name>d.rey</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-0QlSKhlazYs/Td0QmxZusbI/AAAAAAAAAVE/POLgNtONbkQ/s72-c/waterfall_process_flow.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://devel.ownport.net/2012/01/pyflowctrl.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkQHRn4_cCp7ImA9WhRXE0g.&quot;"><id>tag:blogger.com,1999:blog-2025136836330523605.post-9129425462683115556</id><published>2011-12-20T07:18:00.001+02:00</published><updated>2011-12-20T07:18:57.048+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-20T07:18:57.048+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="machine" /><category scheme="http://www.blogger.com/atom/ns#" term="stanford" /><category scheme="http://www.blogger.com/atom/ns#" term="online" /><category scheme="http://www.blogger.com/atom/ns#" term="free" /><category scheme="http://www.blogger.com/atom/ns#" term="course" /><category scheme="http://www.blogger.com/atom/ns#" term="learning" /><title>Курс "Машинное обучение", впечатления</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/--plt9AbvrJo/Togs-7fb1hI/AAAAAAAAAbE/vtjk9PqI9jM/s1600/machine_learning.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/--plt9AbvrJo/Togs-7fb1hI/AAAAAAAAAbE/vtjk9PqI9jM/s1600/machine_learning.png" /&gt;&lt;/a&gt;&lt;/div&gt;На прошлой неделе закончился курс &lt;a href="http://www.ml-class.org/"&gt;“Машинное обучение”&lt;/a&gt;. О нем я уже писал &lt;a href="http://devel.ownport.net/2011/10/blog-post.html"&gt;несколько месяцев назад&lt;/a&gt;, но напомню, это бесплатный online курс подготовленный профессором стенфордского университета &lt;a href="http://ai.stanford.edu/~ang/"&gt;Эндрю Энджи/Andrew Ng&lt;/a&gt; и его командой. Кратко темы курса:&lt;br /&gt;
&lt;br /&gt;
- Supervised learning: linear regression, logistic regression, neural networks, SVMs&lt;br /&gt;
- Unsupervised learning: K-means, PCA, Anomaly detection&lt;br /&gt;
- Special applications/special tools:&amp;nbsp;Recommended&amp;nbsp;systems, large scale machine&amp;nbsp;leanings&lt;br /&gt;
- Advice on building a machine learning system: bias/variance, regularization; deciding what to work in next: evaluation of learning algorithms, learning curves, error analysis, ceiling analysis.&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
Курс состоял их трех секций: лекции, теоретические вопросы, практические упражнения. Лекции можно было слушать/смотреть либо на сайте либо можно было скачать видеоматериалы и изучать их в не зависимости есть у вас доступ в Интернет или нет. В ходе лекции кроме объяснений теоретической части, приводилось много примеров. Это помогало лучше понять принципы и идеи использования различных подходов машинного обучения. Теоретическая часть хорошо сочеталась с вопросами к каждой теме. Буквально с первых занятий ушел некий “страх” ответить неправильно на вопросы или недобрать необходимых 5 баллов. Вопросы/ответы построены именно на то, чтобы в конечном счете лучше понять курс. Тесты можно было проходить по несколько раз.  Для всех ответов правильных и неправильных давались краткие пояснения, почему это правильно или почему нет. Часто я проходил тесты по несколько раз именно для того, чтобы проверить правильно я понял материал или нет.&lt;br /&gt;
&lt;br /&gt;
Для тех, кто записался на курс по расширенной программе, необходимо было выполнить еще и практические занятия. На основе &lt;a href="http://www.gnu.org/software/octave/"&gt;Octave&lt;/a&gt; моделировались различные ситуации применения алгоритмов машинного обучения на практике - кластеризация, предсказания, распознавание рукописного текста и изображений, рекомендательные системы и много другое. Результаты упражнений необходимо регистрировать через специальную систему оценки результатов либо прямо из Octave либо через web форму. &lt;br /&gt;
&lt;br /&gt;
Совет: перед началом курса стоит пройти или повторить &lt;a href="http://www.khanacademy.org/#linear-algebra"&gt;курс линейной алгебры&lt;/a&gt;. В основном практические занятия построены на работе с матрицами, умение с ними работать позволит сократить время на выполнение упражнений.&lt;br /&gt;
&lt;br /&gt;
Курс очень понравился, даже есть некое чувство сожаления, что курс закончился. Но впереди новый год, и в следующем году университет Стендфорда подготовил ряд новых курсов:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.launchpad-class.org/"&gt;Lean Launchpad&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.venture-class.org/"&gt;Technology Entrepreneurship&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.anatomy-class.org/"&gt;Anatomy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.greenbuilding-class.org/"&gt;Making Green Buildings&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.infotheory-class.org/"&gt;Information Teory&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.modelthinker-class.org/"&gt;Model Thinking&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.cs101-class.org/"&gt;Computer Science CS101&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://jan2012.ml-class.org/"&gt;Machine learning&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.saas-class.org/"&gt;Software as a service&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.hci-class.org/"&gt;Human-Computer Interaction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.nlp-class.org/"&gt;Natural Language Processing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.game-theory-class.org/"&gt;Game Theory&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.pgm-class.org/"&gt;Probabilistic Graphical Models&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.crypto-class.org/"&gt;Cryptography&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.algo-class.org/"&gt;Design and Analysis of Algorithms I&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.security-class.org/"&gt;Computer Security&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2025136836330523605-9129425462683115556?l=devel.ownport.net' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/develforfun/~4/h2ReH8CbTq8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://devel.ownport.net/feeds/9129425462683115556/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="http://devel.ownport.net/2011/12/blog-post.html#comment-form" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2025136836330523605/posts/default/9129425462683115556?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2025136836330523605/posts/default/9129425462683115556?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/develforfun/~3/h2ReH8CbTq8/blog-post.html" title="Курс &quot;Машинное обучение&quot;, впечатления" /><author><name>d.rey</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/--plt9AbvrJo/Togs-7fb1hI/AAAAAAAAAbE/vtjk9PqI9jM/s72-c/machine_learning.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://devel.ownport.net/2011/12/blog-post.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0MMR3o9eCp7ImA9WhRTEEU.&quot;"><id>tag:blogger.com,1999:blog-2025136836330523605.post-3211542606101634450</id><published>2011-10-31T19:15:00.001+02:00</published><updated>2011-10-31T19:18:06.460+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-31T19:18:06.460+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="nosql" /><category scheme="http://www.blogger.com/atom/ns#" term="mongodb" /><category scheme="http://www.blogger.com/atom/ns#" term="database" /><category scheme="http://www.blogger.com/atom/ns#" term="book" /><title>Книги по MongoDB</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-Ji1-VCg9B4w/Tq7WfRbvj8I/AAAAAAAAAbU/VKTEVZfmB1g/s1600/mongodb-the_definitive_guide.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-Ji1-VCg9B4w/Tq7WfRbvj8I/AAAAAAAAAbU/VKTEVZfmB1g/s1600/mongodb-the_definitive_guide.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;b&gt;MongoDB: The Definitive Guide&lt;/b&gt;&lt;br /&gt;
Kristina Chodorow &amp;amp; Mike Dirolf&lt;br /&gt;
&lt;br /&gt;
Книга раскрывает как MongoDB может помочь в управлении данными при разработке веб-приложений. Раскрываются как базовые принципы так и сложные примеры использования документо-ориентированных баз данных. Объясняется почему MongoDB является масштабируемой, высокопроизводительной и надежной базой данных. Авторитетное введение, написанное двумя инженерами компании &lt;a href="http://www.10gen.com/"&gt;10gen&lt;/a&gt; , представляет собой руководство как для разработчиков так и для системных администраторов.&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-LHeWOsHJebg/Tq7WlqmWnVI/AAAAAAAAAbg/2Ah4-SjRsm4/s1600/mongodb-in-action.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-LHeWOsHJebg/Tq7WlqmWnVI/AAAAAAAAAbg/2Ah4-SjRsm4/s1600/mongodb-in-action.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;b&gt;MongoDB in Action&lt;/b&gt;&lt;br /&gt;
Kyle Banker&lt;br /&gt;
&lt;br /&gt;
MongoDB in Action - это полное руководство по MongoDB для разработчиков приложений. Книга начинается с объяснения, что делает MongoDB уникальным решением и описывает идеальные случаи применения. Обучение построено на основе примеров применения MongoDB для электронной коммерции, социальных сетей, аналитических и других приложений.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-iqbW6H1V_ig/Tq7W3Sp7jvI/AAAAAAAAAbs/wmWZ_OoD1xU/s1600/scaling_mongodb.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-iqbW6H1V_ig/Tq7W3Sp7jvI/AAAAAAAAAbs/wmWZ_OoD1xU/s1600/scaling_mongodb.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;b&gt;Scaling MongoDB&lt;/b&gt;&lt;br /&gt;
Kristina Chodorow&lt;br /&gt;
&lt;br /&gt;
Создание MongoDB кластера, который будет расти для удовлетворения требований вашего приложения. В этой небольшой книге даются рекомендации по установке и использовании кластеров для хранения больших объемов данных, а также даются советы по организации эффективного доступа к данным. В процессе изучения будут получены знания, как приложение должно работать с системами распределенных баз данных.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-iZ6tbY1JfSk/Tq7W85eceDI/AAAAAAAAAb4/m1s6m_qhvE0/s1600/50-tips-and-tricks-for-mongodb-developers.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-iZ6tbY1JfSk/Tq7W85eceDI/AAAAAAAAAb4/m1s6m_qhvE0/s1600/50-tips-and-tricks-for-mongodb-developers.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;b&gt;50 Tips and Tricks for MongoDB Developers&lt;/b&gt;&lt;br /&gt;
Kristina Chodorow&lt;br /&gt;
&lt;br /&gt;
Начать работать с MongoDB просто, но как только вы начнете создавать приложения  с ней, возникают ряд сложных вопросов. Каковы компромиссы между нормализоваными и де-нормализованными данными? Как повысить отказоустойчивость системы? В книге предлагается ряд советов и рекомендаций, которые помогут решить проблемы от дизайна приложений до вопросов безопасного хранения данных, мониторинга системы.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-xJjJIS_-QMI/Tq7XCuwRTyI/AAAAAAAAAcE/ILTKH8hnIqw/s1600/definitive-guide-mongodb-nosql-database-for-cloud-desktop.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-xJjJIS_-QMI/Tq7XCuwRTyI/AAAAAAAAAcE/ILTKH8hnIqw/s1600/definitive-guide-mongodb-nosql-database-for-cloud-desktop.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;b&gt;The Definitive Guide to MongoDB: The NoSQL Database for Cloud and Desktop Computing&lt;/b&gt;&lt;br /&gt;
Peter Membry, Eelco Plugge, &amp;amp; Tim Hawkins&lt;br /&gt;
&lt;br /&gt;
MongoDB, кросс-платформенная NoSQL база данных, является одной из самых быстро развивающихся новых баз данных. MongoDB предоставляет богатую документо-ориентированную структуру для хранения данных с поддержкой динамических запросов. Это книга о NoSQL базах данных, для которых не нужно знать SQL для того, чтобы понимать как работают базы данных.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-tDyHI6PSIo0/Tq7XIJoRQHI/AAAAAAAAAcQ/XEniNYc3MNU/s1600/mongodb-and-python.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-tDyHI6PSIo0/Tq7XIJoRQHI/AAAAAAAAAcQ/XEniNYc3MNU/s1600/mongodb-and-python.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;b&gt;MongoDB and Python: Patterns and processes for the popular document-oriented database&lt;/b&gt;&lt;br /&gt;
Niall O'Higgins&lt;br /&gt;
&lt;br /&gt;
Используя практические советы данной книги вы научитесь использовать MongoDB в ваших python-приложениях, приводятся полные коды примеров для таких задач как выполнение быстрых гео-запросов для приложений определения местоположения, эффективная индексация пользовательских данных для социальных сетей и многие другие сценарии.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-uGQmHdFGB58/Tq7XOOU_P6I/AAAAAAAAAcc/Cs9t4XmnVqU/s1600/mongodb-for-web-development.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-uGQmHdFGB58/Tq7XOOU_P6I/AAAAAAAAAcc/Cs9t4XmnVqU/s1600/mongodb-for-web-development.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;b&gt;MongoDB for Web Development&lt;/b&gt;&lt;br /&gt;
Mitch Pirtle&lt;br /&gt;
&lt;br /&gt;
Митчел Пиртл хорошо известен как автор книги The Definitive Guide to Joomla. Он обладает богатым опытом работы с высоко-нагруженными веб сайтами, он так же был вовлечен в многие стартапы, некоторые из которых достигли заметных успехов. Митчел выступал на конференциях по всему миру с темами от технологий с открытым исходным кодом для предприятий до конвергенции систем управления контентом с социальными медиа и экстремальным методами масштабирования для веб-разработок.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2025136836330523605-3211542606101634450?l=devel.ownport.net' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/develforfun/~4/7sVaVE-rwKc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://devel.ownport.net/feeds/3211542606101634450/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="http://devel.ownport.net/2011/10/mongodb.html#comment-form" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2025136836330523605/posts/default/3211542606101634450?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2025136836330523605/posts/default/3211542606101634450?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/develforfun/~3/7sVaVE-rwKc/mongodb.html" title="Книги по MongoDB" /><author><name>d.rey</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-Ji1-VCg9B4w/Tq7WfRbvj8I/AAAAAAAAAbU/VKTEVZfmB1g/s72-c/mongodb-the_definitive_guide.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://devel.ownport.net/2011/10/mongodb.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D08HRXk7eip7ImA9WhdUFUg.&quot;"><id>tag:blogger.com,1999:blog-2025136836330523605.post-9079237914590544455</id><published>2011-10-02T12:45:00.000+03:00</published><updated>2011-10-02T14:43:54.702+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-02T14:43:54.702+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="machine" /><category scheme="http://www.blogger.com/atom/ns#" term="online" /><category scheme="http://www.blogger.com/atom/ns#" term="free" /><category scheme="http://www.blogger.com/atom/ns#" term="course" /><category scheme="http://www.blogger.com/atom/ns#" term="learning" /><title>Курс "Машинное обучение"</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/--plt9AbvrJo/Togs-7fb1hI/AAAAAAAAAbE/vtjk9PqI9jM/s1600/machine_learning.png" imageanchor="1" style="clear:left; float:left;margin-right:1em; margin-bottom:1em"&gt;&lt;img border="0" height="199" width="150" src="http://1.bp.blogspot.com/--plt9AbvrJo/Togs-7fb1hI/AAAAAAAAAbE/vtjk9PqI9jM/s320/machine_learning.png" /&gt;&lt;/a&gt;&lt;/div&gt;Бесплатный курс "Машинное обучение", доступный в онлайн можно пройти по адресу &lt;a href="http://openclassroom.stanford.edu/MainFolder/CoursePage.php?course=MachineLearning"&gt;http://openclassroom.stanford.edu/&lt;/a&gt;. В курсе расскрываются несколько наиболее широко используемых методов машинного обучения, которые можно реализовать самостоятельно и попробовать их на практике. Также будут показаны практические приемы и методы, позволяющие обучающим алгоритмам работать эффективнее. Акцент делается больше на понимание самих принципов машинного обучения, чем на предоставление математических выкладок. Знание программирования, основ линейной алгебры, теории вероятности приветствуется. &lt;br /&gt;
&lt;br /&gt;
Курс читает &lt;a href="http://www.cs.stanford.edu/people/ang/"&gt;Андрю Энджи (Andrew Ng)&lt;/a&gt;, профессор Стенфордского университета. &lt;br /&gt;
&lt;br /&gt;
P.S. Сейчас отрыта бесплатная регистрации на этот же курс (с расширенными возможностями) на сайте &lt;a href="http://www.ml-class.org/"&gt;http://www.ml-class.org/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2025136836330523605-9079237914590544455?l=devel.ownport.net' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/develforfun/~4/A3OykxJ5UMc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://devel.ownport.net/feeds/9079237914590544455/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="http://devel.ownport.net/2011/10/blog-post.html#comment-form" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2025136836330523605/posts/default/9079237914590544455?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2025136836330523605/posts/default/9079237914590544455?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/develforfun/~3/A3OykxJ5UMc/blog-post.html" title="Курс &quot;Машинное обучение&quot;" /><author><name>d.rey</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/--plt9AbvrJo/Togs-7fb1hI/AAAAAAAAAbE/vtjk9PqI9jM/s72-c/machine_learning.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://devel.ownport.net/2011/10/blog-post.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkYBRns4eSp7ImA9WhdUEUU.&quot;"><id>tag:blogger.com,1999:blog-2025136836330523605.post-3746594063388125788</id><published>2011-09-28T06:22:00.001+03:00</published><updated>2011-09-28T06:22:37.531+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-28T06:22:37.531+03:00</app:edited><title>Книга "Flow-Based Programming: A New Approach to Application Development"</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-hS6StBksjrE/ToKIatuKjII/AAAAAAAAAa4/4l_0qgZHVUY/s1600/FBP.2nd-edition-book.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-hS6StBksjrE/ToKIatuKjII/AAAAAAAAAa4/4l_0qgZHVUY/s1600/FBP.2nd-edition-book.png" /&gt;&lt;/a&gt;&lt;/div&gt;Работая на проектом &lt;a href="http://devel.ownport.net/2011/05/pyflowctrl-c-python.html"&gt;pyflowctrl&lt;/a&gt; всегда хотелось найти книгу, которая могла бы стать своего рода источником знаний для проекта. Книгой, раскрывающей многие аспекты работы, принципы, подходы программирования на уровне процессов и взаимодействия между ними. Похоже такая книга найдена - Flow-Based Programming: A New Approach to Application Development. Автор книги Паул Морримон долгое время работал в IBM, занимался разработкой компиляторов, баз данных, обработки текстовых данных, разработки приложений преимущественно в банковской сфере. В 1978 году была опубликована статья Пола "Data Stream Linkage Mechanism" раскрывающая принципы программирования потоков данных. &lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.amazon.com/exec/obidos/ISBN%3D0442017715"&gt;Первое&lt;/a&gt; и &lt;a href="http://www.amazon.com/Flow-Based-Programming-2nd-Application-Development/dp/1451542321/"&gt;второе&lt;/a&gt; издание книги доступно в бумажном виде на Amazon, а также на &lt;a href="https://www.createspace.com/3439170"&gt;CreateSpace&lt;/a&gt;. В электронном виде первое издание книги доступно на сайте &lt;a href="http://www.jpaulmorrison.com/fbp/"&gt;Flow-Based Programming&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2025136836330523605-3746594063388125788?l=devel.ownport.net' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/develforfun/~4/B1G_5fSxeZ8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://devel.ownport.net/feeds/3746594063388125788/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="http://devel.ownport.net/2011/09/flow-based-programming-new-approach-to.html#comment-form" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2025136836330523605/posts/default/3746594063388125788?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2025136836330523605/posts/default/3746594063388125788?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/develforfun/~3/B1G_5fSxeZ8/flow-based-programming-new-approach-to.html" title="Книга &quot;Flow-Based Programming: A New Approach to Application Development&quot;" /><author><name>d.rey</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-hS6StBksjrE/ToKIatuKjII/AAAAAAAAAa4/4l_0qgZHVUY/s72-c/FBP.2nd-edition-book.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://devel.ownport.net/2011/09/flow-based-programming-new-approach-to.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0YEQX0zeip7ImA9WhdUEEQ.&quot;"><id>tag:blogger.com,1999:blog-2025136836330523605.post-4609025662855606243</id><published>2011-09-27T06:44:00.002+03:00</published><updated>2011-09-27T06:45:00.382+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-27T06:45:00.382+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="conference" /><category scheme="http://www.blogger.com/atom/ns#" term="ukraine" /><category scheme="http://www.blogger.com/atom/ns#" term="python" /><category scheme="http://www.blogger.com/atom/ns#" term="kiev" /><title>PyCon Ukraine 2011</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-zI_RTUOGXLM/ToFGZlkqY3I/AAAAAAAAAa0/Vl4ZJ4vpSMA/s1600/pycon-logo.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-zI_RTUOGXLM/ToFGZlkqY3I/AAAAAAAAAa0/Vl4ZJ4vpSMA/s1600/pycon-logo.png" /&gt;&lt;/a&gt;&lt;/div&gt;22-23 октября в Киеве пройдет вторая ежегодная конференция PyCon. В этом году планируется провести двухдневную конференцию в два потока — включая доклады, мастер-классы, панельные дискуссии и lighting talks. Кроме того, будет проведена «recruiting session» — у желающих будет возможность больше узнать о украинских компаниях, которые разрабатывают на питоне, об их проектах и побеседовать с их представителями.&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
Среди докладчиков ожидаются:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Игорь Почечуев, Василий Дижак, Тарас Мурашко, Игорь Давыденко, Андрей Светлов, Павел Коломиец, Александр Соловьев, Роман Ворушин (Киев, Украина)&lt;/li&gt;
&lt;li&gt;Александр Бойко (Харьков, Украина)&lt;/li&gt;
&lt;li&gt;Александр Лябах (Днепропетровск, Украина)&lt;/li&gt;
&lt;li&gt;Михаил Кашкин (Одесса, Украина)&lt;/li&gt;
&lt;li&gt;Александр Литовченко (Донецк, Украина)&lt;/li&gt;
&lt;li&gt;Юрия Юревич (Омск, Россия)&lt;/li&gt;
&lt;li&gt;Армин Ронахер (Armin Ronacher, Австрия)&lt;/li&gt;
&lt;li&gt;Ендрю Годвин (Andrew Godwin, Великобритания)&lt;/li&gt;
&lt;li&gt;Мартин Шустрик (Martin Sustrik, Словакия)&lt;/li&gt;
&lt;li&gt;Анжей Млечко (Andrzej Mleczko, Италия)&lt;/li&gt;
&lt;li&gt;Маттео Босколо (Matteo Boscolo, Италия)&lt;/li&gt;
&lt;li&gt;Ожидаются подтверждения участия от Тарека Заде (Tarek Ziade) и Luke Kenneth Casson Leighton.&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
Более подробная информация о докладах, их содержании будут опубликованы на &lt;a href="http://ua.pycon.org/"&gt;официальном сайте&lt;/a&gt; после обработки материалов. &lt;br /&gt;
&lt;br /&gt;
Зарегестрироваться можно на сайте &lt;a href="http://ua.pycon.org/"&gt;http://ua.pycon.org&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2025136836330523605-4609025662855606243?l=devel.ownport.net' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/develforfun/~4/WrhkjYE7Pv0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://devel.ownport.net/feeds/4609025662855606243/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="http://devel.ownport.net/2011/09/pycon-ukraine-2011.html#comment-form" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2025136836330523605/posts/default/4609025662855606243?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2025136836330523605/posts/default/4609025662855606243?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/develforfun/~3/WrhkjYE7Pv0/pycon-ukraine-2011.html" title="PyCon Ukraine 2011" /><author><name>d.rey</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-zI_RTUOGXLM/ToFGZlkqY3I/AAAAAAAAAa0/Vl4ZJ4vpSMA/s72-c/pycon-logo.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://devel.ownport.net/2011/09/pycon-ukraine-2011.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0ECSX89eCp7ImA9WhdUEEs.&quot;"><id>tag:blogger.com,1999:blog-2025136836330523605.post-4080381803424430828</id><published>2011-09-26T05:32:00.001+03:00</published><updated>2011-09-26T22:34:28.160+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-26T22:34:28.160+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="notes" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="flow" /><title>Заметки про управление потоками данных, часть вторая</title><content type="html">Продолжим тему начатую в предыдущем посте “&lt;a href="http://devel.ownport.net/2011/09/wikipedia-flow-based-programming.html"&gt;Заметки, Управление потоками данных&lt;/a&gt;”. Как и для предыдущего поста, информация представленная ниже - это  лишь мое понимание вопроса, поэтому если найдете неточности или ошибку, буду признателен за исправление.&lt;br /&gt;
&lt;br /&gt;
Диаграмма представленная ниже демонстрирует основные принципы взаимодействия и может быть преобразована в список соединений, которые могут быть в дальнейшем выполнены на соответствующем фреймворке (программном или аппаратном).&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-h--eIpWUAzI/Tn_jjXiJRBI/AAAAAAAAAaw/fllIaqHHR8I/s1600/fbp-patterns.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-h--eIpWUAzI/Tn_jjXiJRBI/AAAAAAAAAaw/fllIaqHHR8I/s1600/fbp-patterns.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
Процессы А,B и C - это компоненты исполняющие код. O1, O2 и два IN порта используется для соединения (M и N) соответствующих процессов. Процессы В и С могут выполнять один и тот же код, поэтому каждый процесс должен содержать свою независимую область памяти, управляющие блоки. Процессы могут иметь один и тот же код и использовать одни и те же номера портов в рамках самого процесса, т.к. имена портов используются только для соединения компонентов на уровне сети.&lt;br /&gt;
&lt;br /&gt;
Соединения M и N часто являются буферами с ограниченным размеров памяти, только определенное количество информационных пакетов может быть сохранено в определенный момент времени.&lt;br /&gt;
&lt;br /&gt;
Концепция портов позволяет использовать компоненты-процессы более одного раза в сети, формируя гибкую архитектуру основанную на процессах и соединениях между ними. &lt;br /&gt;
&lt;br /&gt;
Информационные пакеты используются для обмена данными между процессами и имеют определенное время жизни, после истечения которого пакеты удаляются и занятая ими память освобождается. Процессы сами должны следить за освобождение памяти от пакетов. Пакеты перемещаются по выделенным для них соединениям, образуя потоки данных, имеющих асинхронную природу.&lt;br /&gt;
&lt;br /&gt;
Информационные пакеты обычно представляют собой структурированные блоки данных. Хотя некоторые пакеты могут и не содержать данных, а использоваться в качестве сигналов. Могут применяться пакеты, используемые для группировки пакетов. Это позволяет формировать внутри потока данных подпотоки. Информационные пакеты могут быть сгруппированы в виде сложных структур данных - деревьев пакетов, передаваемых через сеть как один объект.&lt;br /&gt;
&lt;br /&gt;
Система соединений и процессов может иметь сложную структуру практически любого размера. При разработке процессов, процессы отвечающие за отладку и мониторинг могут быть легко добавлены между парами процессов. Процессы могут объединятся в виде подсети. Для отладки реальные процессы могут быть заменены процессами симуляции. В связи с этим данный подход программирования потоков данных можно легко использовать для построения прототипов приложений. &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Ссылки:&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://en.wikipedia.org/wiki/Flow-based_programming"&gt;http://en.wikipedia.org/wiki/Flow-based_programming&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www.jpaulmorrison.com/fbp/morrison_2005.htm"&gt;Patterns in Flow-Based Programming&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://flowbased.org/"&gt;Flow-based programming and system design&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2025136836330523605-4080381803424430828?l=devel.ownport.net' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/develforfun/~4/o-DDtqC1W2o" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://devel.ownport.net/feeds/4080381803424430828/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="http://devel.ownport.net/2011/09/blog-post.html#comment-form" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2025136836330523605/posts/default/4080381803424430828?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2025136836330523605/posts/default/4080381803424430828?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/develforfun/~3/o-DDtqC1W2o/blog-post.html" title="Заметки про управление потоками данных, часть вторая" /><author><name>d.rey</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-h--eIpWUAzI/Tn_jjXiJRBI/AAAAAAAAAaw/fllIaqHHR8I/s72-c/fbp-patterns.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://devel.ownport.net/2011/09/blog-post.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A08FRnsyfSp7ImA9WhdVF0k.&quot;"><id>tag:blogger.com,1999:blog-2025136836330523605.post-5088394584337746472</id><published>2011-09-23T06:30:00.001+03:00</published><updated>2011-09-23T06:50:17.595+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-23T06:50:17.595+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="development" /><category scheme="http://www.blogger.com/atom/ns#" term="pyflowctrl" /><category scheme="http://www.blogger.com/atom/ns#" term="python" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="flow" /><title>Заметки "Управление потоками данных"</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-0QlSKhlazYs/Td0QmxZusbI/AAAAAAAAAVE/POLgNtONbkQ/s1600/waterfall_process_flow.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-0QlSKhlazYs/Td0QmxZusbI/AAAAAAAAAVE/POLgNtONbkQ/s1600/waterfall_process_flow.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;i&gt;Заметки представленные ниже все лишь мой свободный перевод, а правильнее сказать мое понимание концепций первой части &lt;a href="http://en.wikipedia.org/wiki/Flow-based_programming"&gt;статьи на Wikipedia “Flow-based programming”&lt;/a&gt;. Перевод далек от оригинала, текст был специально изменен. Задача была не сколько перевести, сколько понять принципы.&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Введение&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Программирование основанное на управлении потоков представляется собой парадигму, которая определяет приложения как сеть из “черных ящиков”-процессов, которые обмениваются данными (сообщениями) через предопределенные соединения. По отношению к процессам, соединения являются внешними и не зависят от внутренней реализации процессов. Основная идея заключается в многократном использовании процессов и соединений между ними без изменения внутренней логики процесса. &lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
Поточное программирование - это частная форма программирования потоков данных с применением конечных буферов, информационных пакетов, ограниченных временем жизни, именованными портами и соединениями.&lt;br /&gt;
&lt;br /&gt;
Подход поточного программирования рассматривает приложение не как единый, последовательный процесс, начинающийся в определенный момент времени, выполняющий некоторое действие и завершающийся, но как сеть асинхронныхпроцессов обменивающихся между собой потоками структурированных блоков данных - “информационными пакетами”. При построении сети акцент делается на данные процессов и преобразование их для получения желаемых результатов.  Сеть определяется списком соединений между процессами и управляется программным блоком - планировщиком, контролирующем обмен сообщениями между пакетами. С точки зрения сети, процессы являются “черными” ящиками. &lt;br /&gt;
&lt;br /&gt;
Процессы обмениваются данными на основании предопределенного количества соединений. Именованные порты процессов используются при определении соединений. Имя порту назначается при формировании сети. Порты могут быть простыми, предназначенные для передачи однотипных значений или сложными, предназначенные для обмена структур данных: массивов, словарей. Блоки данных упаковывается в информационные пакеты. Информационный пакет может быть адресован как самому процессу так и быть транзитным, предназначенным другому процессу. Функции сортировки, объединения, агрегации данных, … могут быть представлены в виде “черных” ящиков - комбинации портов с асинхронными процессами.  &lt;br /&gt;
&lt;br /&gt;
Более чем один процесс может выполнять один и тот де код.&lt;br /&gt;
&lt;br /&gt;
Асинхронная природа процессов позволяет обрабатывать данные и возвращать результат до тех пор, пока поступают данные на вход процесса. Это позволяет эффективно использовать  ресурсы процессора(-ов).&lt;br /&gt;
&lt;br /&gt;
Определение взаимодействия процессов или построение сети обычно выполняется на основе диаграмм, которые в дальнейшем могут быть преобразованы в код приложения. Подход визуального программирования позволяет строить более сложные сети с иерархической структурой, объединяя подсети c помощью соединений, аналогичных соединениям для процессов. Фактически без программирования можно реализовывать сложные алгоритмы обработки данных.&lt;br /&gt;
&lt;br /&gt;
Презентация фреймворка &lt;a href="http://pyfproject.org/"&gt;PyF&lt;/a&gt; в основе которого лежит поточное программирование (к сожалению качество видео оставляет желать лучшего)&lt;br /&gt;
&lt;br /&gt;
&lt;iframe allowfullscreen="" frameborder="0" height="400" src="http://www.youtube.com/embed/w_zl52L6CU4" width="600"&gt;&lt;/iframe&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Ссылки&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://www.jpaulmorrison.com/fbp/"&gt;Flow-based programming, 2nd edition ebook&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://en.wikipedia.org/wiki/Flow-based_programming"&gt;http://en.wikipedia.org/wiki/Flow-based_programming&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://en.wikipedia.org/wiki/Dataflow_programming"&gt;http://en.wikipedia.org/wiki/Dataflow_programming&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://wiki.python.org/moin/FlowBasedProgramming"&gt;http://wiki.python.org/moin/FlowBasedProgramming&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://en.wikipedia.org/wiki/Distributed_data_flow"&gt;http://en.wikipedia.org/wiki/Distributed_data_flow&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2025136836330523605-5088394584337746472?l=devel.ownport.net' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/develforfun/~4/WXhZFOiYeRg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://devel.ownport.net/feeds/5088394584337746472/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="http://devel.ownport.net/2011/09/wikipedia-flow-based-programming.html#comment-form" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2025136836330523605/posts/default/5088394584337746472?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2025136836330523605/posts/default/5088394584337746472?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/develforfun/~3/WXhZFOiYeRg/wikipedia-flow-based-programming.html" title="Заметки &quot;Управление потоками данных&quot;" /><author><name>d.rey</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-0QlSKhlazYs/Td0QmxZusbI/AAAAAAAAAVE/POLgNtONbkQ/s72-c/waterfall_process_flow.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://devel.ownport.net/2011/09/wikipedia-flow-based-programming.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkABQ3k4fip7ImA9WhdWGEU.&quot;"><id>tag:blogger.com,1999:blog-2025136836330523605.post-3043604492634743967</id><published>2011-09-13T06:31:00.000+03:00</published><updated>2011-09-13T06:32:32.736+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-13T06:32:32.736+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="video" /><category scheme="http://www.blogger.com/atom/ns#" term="online" /><category scheme="http://www.blogger.com/atom/ns#" term="training" /><category scheme="http://www.blogger.com/atom/ns#" term="learning" /><category scheme="http://www.blogger.com/atom/ns#" term="practice" /><title>Khan Academy</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-etHOkLDICU4/Tm7N6pUiPoI/AAAAAAAAAaE/BU9wUrDEqso/s1600/khanacademy_header.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="75" src="http://1.bp.blogspot.com/-etHOkLDICU4/Tm7N6pUiPoI/AAAAAAAAAaE/BU9wUrDEqso/s320/khanacademy_header.png" width="302" /&gt;&lt;/a&gt;&lt;/div&gt;
В разработке рано или поздно возникает необходимость реализации некоего алгоритма в основе которого могут лежать понимание теории множеств, векторов, графов, манипулирования данных в матрицах или просчет вероятностных характеристик. Хорошо, если принципы работы алгоритма описаны на родном языке. Хуже, когда на другом - могут возникнуть сложности языкового барьера. Для решения этого вопроса можно воспользоваться &lt;a href="http://www.khanacademy.org/"&gt;Khan Academy&lt;/a&gt;. 
&lt;br/&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br/&gt;
В бесплатном доступе более 2400 видео материалов от арифметики до физики, финансов, истории, 150 практических упражнений. Многие вопросы, если не все, объясняются достаточно просто и понятно. Проходя ряд курсов осознаешь, как не хватало тебе подобных объяснений в школе, институте. Иногда ловишь себя на мысли, что ты наконец понял для каких задач это можно использовать.
&lt;p&gt;
&lt;iframe allowfullscreen="" frameborder="0" height="345" src="http://www.youtube.com/embed/gM95HHI4gLk" width="560"&gt;&lt;/iframe&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2025136836330523605-3043604492634743967?l=devel.ownport.net' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/develforfun/~4/5rNX6OTn-uY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://devel.ownport.net/feeds/3043604492634743967/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="http://devel.ownport.net/2011/09/khan-academy.html#comment-form" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2025136836330523605/posts/default/3043604492634743967?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2025136836330523605/posts/default/3043604492634743967?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/develforfun/~3/5rNX6OTn-uY/khan-academy.html" title="Khan Academy" /><author><name>d.rey</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-etHOkLDICU4/Tm7N6pUiPoI/AAAAAAAAAaE/BU9wUrDEqso/s72-c/khanacademy_header.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://devel.ownport.net/2011/09/khan-academy.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkEFRX46cCp7ImA9WhdXFU4.&quot;"><id>tag:blogger.com,1999:blog-2025136836330523605.post-882455107320511135</id><published>2011-08-27T20:36:00.003+03:00</published><updated>2011-08-28T14:23:34.018+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-28T14:23:34.018+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="map" /><category scheme="http://www.blogger.com/atom/ns#" term="text" /><category scheme="http://www.blogger.com/atom/ns#" term="reduce" /><category scheme="http://www.blogger.com/atom/ns#" term="processing" /><category scheme="http://www.blogger.com/atom/ns#" term="book" /><title>Книга "Data-Intensive Text Processing with MapReduce"</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-DjEUKtbF9Bk/TlkmlhLmpXI/AAAAAAAAAZ4/LJuvQQ1MJh4/s1600/text-processing-mapreduce.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://4.bp.blogspot.com/-DjEUKtbF9Bk/TlkmlhLmpXI/AAAAAAAAAZ4/LJuvQQ1MJh4/s200/text-processing-mapreduce.jpg" width="161" /&gt;&lt;/a&gt;&lt;/div&gt;Совершенно случайно наткнулся на &lt;a href="http://www.umiacs.umd.edu/~jimmylin/"&gt;сайт Джими Лин&lt;/a&gt;, соавтора книги Data-Intensive Text Processing with MapReduce. &lt;a href="http://en.wikipedia.org/wiki/MapReduce"&gt;MapReduce&lt;/a&gt;&amp;nbsp;является моделью программирования для распределенной обработки больших массивов данных на кластерах, основанных на обычных компьютерах. Модель представляет легкие для понимания абстракции для разработки масштабируемых алгоритмов, в то время как фреймворк обрабатывает детали на системном уровне от синхронизации до отказоустойчивости. В книге рассматриваются MapReduce алгоритмы на примере обработки текстовых данных, извлечения информации, машинного обучения.&lt;br /&gt;
&lt;br /&gt;
Книга в электронном виде доступна &lt;a href="http://www.umiacs.umd.edu/~jimmylin/MapReduce-book-final.pdf"&gt;на сайте автора&lt;/a&gt; или ее можно заказать в бумажном переплете на сайте Amazon.com&amp;nbsp;&lt;a href="http://www.amazon.com/Data-Intensive-Processing-MapReduce-Synthesis-Technologies/dp/1608453421?ie=UTF8&amp;amp;tag=develoforfun-20&amp;amp;link_code=btl&amp;amp;camp=213689&amp;amp;creative=392969" target="_blank"&gt;Data-Intensive Text Processing with MapReduce (Synthesis Lectures on Human Language Technologies)&lt;/a&gt;&lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=develoforfun-20&amp;amp;l=btl&amp;amp;camp=213689&amp;amp;creative=392969&amp;amp;o=1&amp;amp;a=1608453421" style="border: none !important; margin: 0px !important; padding: 0px !important;" width="1" /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2025136836330523605-882455107320511135?l=devel.ownport.net' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/develforfun/~4/mR-Q19a5HVc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://devel.ownport.net/feeds/882455107320511135/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="http://devel.ownport.net/2011/08/data-intensive-text-processing-with.html#comment-form" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2025136836330523605/posts/default/882455107320511135?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2025136836330523605/posts/default/882455107320511135?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/develforfun/~3/mR-Q19a5HVc/data-intensive-text-processing-with.html" title="Книга &quot;Data-Intensive Text Processing with MapReduce&quot;" /><author><name>d.rey</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-DjEUKtbF9Bk/TlkmlhLmpXI/AAAAAAAAAZ4/LJuvQQ1MJh4/s72-c/text-processing-mapreduce.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://devel.ownport.net/2011/08/data-intensive-text-processing-with.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUYESHY7fyp7ImA9WhdQGUg.&quot;"><id>tag:blogger.com,1999:blog-2025136836330523605.post-643114257983009653</id><published>2011-08-21T21:21:00.002+03:00</published><updated>2011-08-21T21:58:29.807+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-21T21:58:29.807+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="pyflowctrl" /><category scheme="http://www.blogger.com/atom/ns#" term="xml" /><category scheme="http://www.blogger.com/atom/ns#" term="python" /><category scheme="http://www.blogger.com/atom/ns#" term="dictionary" /><title>Преобразование xml в словарь</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-zx-7XlzKW9s/TlFMcaRwLcI/AAAAAAAAAZg/QRNKJHmTWt4/s1600/text-xml.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-zx-7XlzKW9s/TlFMcaRwLcI/AAAAAAAAAZg/QRNKJHmTWt4/s1600/text-xml.png" /&gt;&lt;/a&gt;&lt;/div&gt;Несколько дней назад мне потребовалось обработать несколько тысяч небольших (от нескольких килобайт до 3 Мб) xml файлов, содержащих различные статистические данные.  В чистом виде работать с xml файлами не очень удобно. Гораздо проще, когда сложные структуры такие как данные в xml файлах представлены в виде словаря. Процесс &lt;a href="http://code.google.com/p/sources-ownport/source/browse/pyflowctrl/processes/xml2dict1.py"&gt;xml2dict&lt;/a&gt; предназначен как раз для таких задач.&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
На вход процесса input подаются данные в виде списка из имени xml файла и его содержимого. На выходе получаем список состоящий из имени файла и словаря, данные которого соответствуют входному xml файлу. Парсинг исходных данных выполняется с помощью входящей в стандартный пакет python библиотеки &lt;a href="http://docs.python.org/library/xml.etree.elementtree.html"&gt;cElementTree&lt;/a&gt;. В связи с тем, что для обработки используется DOM подход, данные XML файла загружаются в память целиком. Нужно быть аккуратным при работе с большими объемами данных.&lt;br /&gt;
&lt;br /&gt;
Пример исходных данных (xml_data): &lt;br /&gt;
&lt;pre&gt;&amp;lt;?xml version="1.0"?&amp;gt;
&amp;lt;MeasurementData&amp;gt;
  &amp;lt;Setup  startTime="2011-06-24T02:45:00.000-04:00:00" interval="15"&amp;gt;
    &amp;lt;Result&amp;gt;
      &amp;lt;Object&amp;gt;
        	&amp;lt;DN&amp;gt;&amp;lt;![CDATA[platform1]]&amp;gt;&amp;lt;/DN&amp;gt;
      &amp;lt;/Object&amp;gt;
      &amp;lt;Target measurementType="CPULoad"&amp;gt;
        &amp;lt;cpuAverageLoad&amp;gt;65&amp;lt;/cpuAverageLoad&amp;gt;
        &amp;lt;cpuPeakLoad&amp;gt;87&amp;lt;/cpuPeakLoad&amp;gt;
        &amp;lt;memFree&amp;gt;344985&amp;lt;/memFree&amp;gt;
        &amp;lt;memUsed&amp;gt;1456239&amp;lt;/memUsed&amp;gt;
        &amp;lt;sysAvailability&amp;gt;54&amp;lt;/sysAvailability&amp;gt;
        &amp;lt;sysUptime&amp;gt;569&amp;lt;/sysUptime&amp;gt;
      &amp;lt;/Target&amp;gt;
    &amp;lt;/Result&amp;gt;
  &amp;lt;/Setup&amp;gt;
&amp;lt;/MeasurementData&amp;gt;&lt;/pre&gt;Пример использования процесса xml2dict &lt;br /&gt;
&lt;pre&gt;import pprint
from processes.xml2dict1 import xml2dict
x2d = xml2dict()
pprint.pprint(x2d.run_once(data=(None, xml_data)))&lt;/pre&gt;На выходе процесса получаем следующий словарь &lt;br /&gt;
&lt;pre&gt;(None,
 {'MeasurementData': {'Setup': {'@interval': '15',
                                '@startTime': '2011-06-24T02:45:00.000-04:00:00',
                                'Result': {'Object': {'DN': {'$': 'platform1'}},
                                           'Target': {'@measurementType': 'CPULoad',
                                                      'cpuAverageLoad': {'$': '65'},
                                                      'cpuPeakLoad': {'$': '87'},
                                                      'memFree': {'$': '344985'},
                                                      'memUsed': {'$': '1456239'},
                                                      'sysAvailability': {'$': '54'},
                                                      'sysUptime': {'$': '569'}}}}}})&lt;/pre&gt;В некоторых xml файлах используются пространства имен (namespace). По умолчанию в процессе xml2dict они удаляются. Для случаев, когда пространства имен необходимы, отключить их удаление можно с помощью параметра remove_xmlns: &lt;br /&gt;
&lt;pre&gt;x2d = xml2dict(remove_xmlns=False)&lt;/pre&gt;&lt;br /&gt;
Процесс &lt;a href="http://code.google.com/p/sources-ownport/source/browse/pyflowctrl/processes/xml2dict1.py"&gt;xml2dict&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
P.S. Небольшой юбилей - 100й пост&lt;br /&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2025136836330523605-643114257983009653?l=devel.ownport.net' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/develforfun/~4/J53f-MBFBkg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://devel.ownport.net/feeds/643114257983009653/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="http://devel.ownport.net/2011/08/xml.html#comment-form" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2025136836330523605/posts/default/643114257983009653?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2025136836330523605/posts/default/643114257983009653?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/develforfun/~3/J53f-MBFBkg/xml.html" title="Преобразование xml в словарь" /><author><name>d.rey</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-zx-7XlzKW9s/TlFMcaRwLcI/AAAAAAAAAZg/QRNKJHmTWt4/s72-c/text-xml.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://devel.ownport.net/2011/08/xml.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0cEQnozcSp7ImA9WhdQE0o.&quot;"><id>tag:blogger.com,1999:blog-2025136836330523605.post-6897922244656961308</id><published>2011-08-15T06:30:00.000+03:00</published><updated>2011-08-15T06:30:03.489+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-15T06:30:03.489+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="core" /><category scheme="http://www.blogger.com/atom/ns#" term="pyflowctrl" /><category scheme="http://www.blogger.com/atom/ns#" term="python" /><category scheme="http://www.blogger.com/atom/ns#" term="processing" /><title>Новое ядро (core3) для pyflowctrl</title><content type="html">Время показало, что версия ядра core2.py имеет недостатки, ограничивающие выполнение ряда операций над данными. Разберем текущую схему реализации:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-QRViSOmpRnU/TkiQtacq_rI/AAAAAAAAAZE/ddm5pFYWtyk/s1600/core2-sheme.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-QRViSOmpRnU/TkiQtacq_rI/AAAAAAAAAZE/ddm5pFYWtyk/s1600/core2-sheme.png" /&gt;&lt;/a&gt;&lt;/div&gt;Если у процесса есть входной поток, процесс ожидает поступление из него данных. Отсутствие данных на входе приводит к формированию исключения EmptyStream, и следом за ним исключения StopIteration. Согласно специфики реализации ProcessFlow на базе &lt;a href="http://code.google.com/p/sources-ownport/source/browse/pyflowctrl/core2.py"&gt;core2&lt;/a&gt;, это событие приведет к останову процесса и некорректной работе для случаев, когда предыдущие в цепочке процессы могут не возвращать данные.&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
Например:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-jYq0jspqF7c/TkiRbbDaWZI/AAAAAAAAAZM/ds-lJDYDgIE/s1600/core2-example.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-jYq0jspqF7c/TkiRbbDaWZI/AAAAAAAAAZM/ds-lJDYDgIE/s1600/core2-example.png" /&gt;&lt;/a&gt;&lt;/div&gt;В этом случае, как только на процесс Output  не поступят данные, процесс завершит свою работу. Это приведет к ситуации, когда Generator и Filter еще будут работать, а вывод результата будет уже невозможен из-за останова процесса Output.&lt;br /&gt;
&lt;br /&gt;
Необходим новый подход в управлении потоков как данных, так и процессов. Исходная схема для нового ядра core3:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-LJMmb30ou5c/TkiRhJNK_6I/AAAAAAAAAZU/XxS02NOT29A/s1600/core3-sheme.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-LJMmb30ou5c/TkiRhJNK_6I/AAAAAAAAAZU/XxS02NOT29A/s1600/core3-sheme.png" /&gt;&lt;/a&gt;&lt;/div&gt;Новый подход позволяет выполнять контроль работы процессов на основании внутреннего статуса процессов. &lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-0yuj-cq_1zY/TkiRmKtUa4I/AAAAAAAAAZc/gI3pijkDS6w/s1600/core3-process-status.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-0yuj-cq_1zY/TkiRmKtUa4I/AAAAAAAAAZc/gI3pijkDS6w/s1600/core3-process-status.png" /&gt;&lt;/a&gt;&lt;/div&gt;При создании процесс имеет статус NOT_STARTED. После первой итерации, если данных во входном потоке нет, он переходит в статус WAITING. При получении данных и и их обработке, статус процесса меняется на PROCESSING. Когда все процессы переходят в состояние WAITING, работа ProcessFlow завершается.&lt;br /&gt;
&lt;br /&gt;
Пример метода main() для процесса на базе нового ядра core3: &lt;br /&gt;
&lt;pre&gt;def main(self):
    while True:
        try:
            data = self.io['input'].get()
        except EmptyStream:
            yield WAITING
            continue
        
        self.io['output'].put(handle_data(data))
        yield PROCESSING&lt;/pre&gt;Часть процессов уже переведена на работу с &lt;a href="http://code.google.com/p/sources-ownport/source/browse/pyflowctrl/core3.py"&gt;core3&lt;/a&gt;:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://code.google.com/p/sources-ownport/source/browse/pyflowctrl/processes/filereader2.py"&gt;FileReader&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://code.google.com/p/sources-ownport/source/browse/pyflowctrl/processes/htmlspecials2.py"&gt;HTMLSpecials&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://code.google.com/p/sources-ownport/source/browse/pyflowctrl/processes/textprocessing2.py"&gt;TextProcessing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://code.google.com/p/sources-ownport/source/browse/pyflowctrl/processes/treewalker2.py"&gt;TreeWalker&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;Остальные будут переводиться по мере необходимости.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2025136836330523605-6897922244656961308?l=devel.ownport.net' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/develforfun/~4/4qZM_aXdpgk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://devel.ownport.net/feeds/6897922244656961308/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="http://devel.ownport.net/2011/08/core3-pyflowctrl.html#comment-form" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2025136836330523605/posts/default/6897922244656961308?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2025136836330523605/posts/default/6897922244656961308?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/develforfun/~3/4qZM_aXdpgk/core3-pyflowctrl.html" title="Новое ядро (core3) для pyflowctrl" /><author><name>d.rey</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-QRViSOmpRnU/TkiQtacq_rI/AAAAAAAAAZE/ddm5pFYWtyk/s72-c/core2-sheme.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://devel.ownport.net/2011/08/core3-pyflowctrl.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEMHQnsyeyp7ImA9WhdRFU4.&quot;"><id>tag:blogger.com,1999:blog-2025136836330523605.post-3835692747089508794</id><published>2011-08-05T11:17:00.001+03:00</published><updated>2011-08-05T11:20:33.593+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-05T11:20:33.593+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="training" /><category scheme="http://www.blogger.com/atom/ns#" term="intelligence" /><category scheme="http://www.blogger.com/atom/ns#" term="artificial" /><category scheme="http://www.blogger.com/atom/ns#" term="cource" /><title>Introduction to Artificial Intelligence</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://www.ai-class.com/" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="152" src="http://1.bp.blogspot.com/-gTXFjJnlmhU/TjulAdICgJI/AAAAAAAAAY8/v3ZhqF5p9I4/s320/artificial_intelligence_header.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;A free, online version of "Introduction to Artificial Intelligence", taught by Sebastian Thrun and Peter Norvig. A syllabus and more information about the Stanford course is &lt;a href="http://robot.cc/cs221"&gt;available here&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
The class runs from Sept 26 through Dec 16, 2011. While this class is being offered online, it is also taught at Stanford University, where it continues to be a popular intro-level class on AI. For the online version, the instructors aim to offer identical materials, assignments, and exams, and to use the same grading criteria. Both instructors will be available for online discussions.&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
A high speed internet connection is recommended as most of the course content will be video based. Access to a copy of &lt;a href="http://aima.cs.berkeley.edu/"&gt;Artificial Intelligence: A Modern Approach&lt;/a&gt; is also suggested.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Course Description&lt;/b&gt;&lt;br /&gt;
This course is 10 weeks long. The in-class version starts Tue, Sept 27. The online version begins Mon, Oct 2, 2011. The course consists of&lt;br /&gt;
Approximately 20 lectures. Each lecture includes quizzes that we ask you to do, but which are not counted towards the final grade of this class. Instead, you can see the right answer to each quizz right after submitting your answers.&lt;br /&gt;
&lt;br /&gt;
Approximately 8 homework assignments. Those are just like our quizzes, and if you do well in the quizzes, you should do well in the assignments. However, we won't show you the correct answer only with a few days delay, to discourage cheating.&lt;br /&gt;
One midterm and one final exam. These are like extended quizzes, covering all subject areas of the course discussed so far. The exams will also check your general knowledge about topics covered in the reading materials (the book).&lt;br /&gt;
&lt;br /&gt;
The central objective is to teach basic methods in AI, and to convey enthusiasm for the field. AI has emerged as one of the most impactful disciplines in science and technology. Google, for example, is massively run on AI. Students passing this course should be proficient basic methods of AI, and have a broad overview of the field.q&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.ai-class.com/"&gt;Course registration &lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2025136836330523605-3835692747089508794?l=devel.ownport.net' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/develforfun/~4/r4IZcKXQaX4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://devel.ownport.net/feeds/3835692747089508794/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="http://devel.ownport.net/2011/08/introduction-to-artificial-intelligence.html#comment-form" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2025136836330523605/posts/default/3835692747089508794?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2025136836330523605/posts/default/3835692747089508794?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/develforfun/~3/r4IZcKXQaX4/introduction-to-artificial-intelligence.html" title="Introduction to Artificial Intelligence" /><author><name>d.rey</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-gTXFjJnlmhU/TjulAdICgJI/AAAAAAAAAY8/v3ZhqF5p9I4/s72-c/artificial_intelligence_header.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://devel.ownport.net/2011/08/introduction-to-artificial-intelligence.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUEEQn8ycSp7ImA9WhdRFUw.&quot;"><id>tag:blogger.com,1999:blog-2025136836330523605.post-8105902319127004561</id><published>2011-08-05T07:09:00.001+03:00</published><updated>2011-08-05T07:13:23.199+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-05T07:13:23.199+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="text" /><category scheme="http://www.blogger.com/atom/ns#" term="pyflowctrl" /><category scheme="http://www.blogger.com/atom/ns#" term="python" /><category scheme="http://www.blogger.com/atom/ns#" term="processing" /><title>Обработка текста, часть третья</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-fbT-P40hvn8/TgRK2-NhCpI/AAAAAAAAAXY/k98QYK-lOCc/s1600/text-plain.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-fbT-P40hvn8/TgRK2-NhCpI/AAAAAAAAAXY/k98QYK-lOCc/s1600/text-plain.png" /&gt;&lt;/a&gt;&lt;/div&gt;Используя подходы из предыдущего &lt;a href="http://devel.ownport.net/2011/08/blog-post.html"&gt;поста по обработке данных&lt;/a&gt;, редко когда бывает достаточным выполнить выборку значений из текста с помощью регулярных выражений. Зачастую данные требуют дополнительной пост-обработки. Для этих целей можно воспользоваться процессом &lt;a href="http://code.google.com/p/sources-ownport/source/browse/pyflowctrl/processes/textprocessing1.py"&gt;DictProcessing&lt;/a&gt;, позволяющим для каждого поля выполнить свои функции преобразования данных.&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
Рассмотрим использование процесса на примере: с выхода процесса &lt;a href="http://code.google.com/p/sources-ownport/source/browse/pyflowctrl/processes/textprocessing1.py"&gt;Text2Dict&lt;/a&gt; был получен словарь с параметрами:&lt;pre&gt;block = ('msg#1',
    { 
        'datetime': '11/08/02 12:54:03',
        'ip address': 'C0A80101',
        'details': 'No access to IP address',
        'info': '...',
    }
)&lt;/pre&gt;Предположим, что для дальнейшей работы с этими данными необходимо преобразовать: datetime  представить в виде объекта datetime, IP адрес из hex перевести в более привычный вид и сохранить в новом поле ‘ip address (dec)’, поле details нужно оставить без изменений, а поле info удалить. &lt;pre&gt;from pprint import pprint
from datetime import datetime
from processes.textprocessing1 import DictProcessing

def ip_hex2dec(h):
    ''' convert hex ip address to decimal '''
    return '%d.%d.%d.%d' % (int(h[0:2],16), int(h[2:4],16),
                            int(h[4:6],16), int(h[6:8],16))

dict_rules = (
    ('datetime','datetime', lambda d: datetime.strptime(d,'%y/%m/%d %H:%M:%S')),
    ('ip address', 'ip address (dec)', ip_hex2dec),
    ('info', None, None),
)

dp = DictProcessing(rules=dict_rules)
pprint(dp.run_once(block))&lt;/pre&gt;В качестве параметра для обработки словаря block в процесс DictProcessing передается список правил по преобразованию полей. Каждое правило состоит из трех полей: исходное имя поля, результирующее имя поля, функция преобразования. Разберем каждое правило более подробно &lt;pre&gt;('datetime','datetime', lambda d: datetime.strptime(d,'%y/%m/%d %H:%M:%S')),&lt;/pre&gt;из словаря берется значение с ключом datetime, преобразуется в объект datetime c помощью lambda функции и сохраняется в словаре под тем же самым именем. &lt;pre&gt;('ip address', 'ip address (dec)', ip_hex2dec),&lt;/pre&gt;значение IP адреса из поля ‘ip address’ с помощью функции ip_hex2dec()  преобразуется к виду X.X.X.X и сохраняется в новом поле ‘ip address (dec)’. Поле ‘ip address’ не удаляется.&lt;pre&gt;('info', None, None),&lt;/pre&gt;для удаления info достаточно указать, что результирующее имя поля и функция преобразования определены как None.&lt;br /&gt;
&lt;br /&gt;
Если поле не указывается в правилах преобразования, оно остается без изменений.&lt;br /&gt;
&lt;br /&gt;
Если необходимо выполнить множественные преобразования над значениями словаря, правила преобразования должны быть указаны в списке в той последовательности, в которой действия над данными должны быть выполнены. Например: &lt;pre&gt;('text', 'text', remove_spaces),  # удаление лишних пробелов
('text', 'text', conv2uppercase),  # все символы в тексте будут 
                                   # представлены заглавными буквами&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2025136836330523605-8105902319127004561?l=devel.ownport.net' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/develforfun/~4/cw_Uo5_-1G8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://devel.ownport.net/feeds/8105902319127004561/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="http://devel.ownport.net/2011/08/blog-post_05.html#comment-form" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2025136836330523605/posts/default/8105902319127004561?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2025136836330523605/posts/default/8105902319127004561?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/develforfun/~3/cw_Uo5_-1G8/blog-post_05.html" title="Обработка текста, часть третья" /><author><name>d.rey</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-fbT-P40hvn8/TgRK2-NhCpI/AAAAAAAAAXY/k98QYK-lOCc/s72-c/text-plain.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://devel.ownport.net/2011/08/blog-post_05.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUUNRH4_fyp7ImA9WhdRE0k.&quot;"><id>tag:blogger.com,1999:blog-2025136836330523605.post-7621248243279780991</id><published>2011-08-03T06:45:00.001+03:00</published><updated>2011-08-03T06:48:15.047+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-03T06:48:15.047+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="text" /><category scheme="http://www.blogger.com/atom/ns#" term="pyflowctrl" /><category scheme="http://www.blogger.com/atom/ns#" term="python" /><category scheme="http://www.blogger.com/atom/ns#" term="processing" /><title>Обработка текста, часть вторая</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-fbT-P40hvn8/TgRK2-NhCpI/AAAAAAAAAXY/k98QYK-lOCc/s1600/text-plain.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-fbT-P40hvn8/TgRK2-NhCpI/AAAAAAAAAXY/k98QYK-lOCc/s1600/text-plain.png" /&gt;&lt;/a&gt;&lt;/div&gt;В первой части “&lt;a href="http://devel.ownport.net/2011/07/blog-post_31.html"&gt;Обработка текста&lt;/a&gt;” были рассмотрены вопросы разбивки структурированного текста на блоки с использованием разделителей и случаи, когда блоки текста можно выделить с помощью регулярных выражений. Полученные в результате наборы текстовых блоков и имеющие общую структуру представления можно представить в виде словаря используя процесс &lt;a href="http://code.google.com/p/sources-ownport/source/browse/pyflowctrl/processes/textprocessing1.py"&gt;Text2Dict&lt;/a&gt;&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
В качестве примера используем текстовый блок (block) содержащий следующую информацию: &lt;br /&gt;
&lt;pre&gt;POST /xmlrpc.php HTTP/1.1
User-Agent: wp-iphone/1.0
Content-Type: text/xml
Content-Length: 2963
Accept: */*
Accept-Language: en-us
Accept-Encoding: gzip, deflate
Connection: keep-alive
Host: example.com&lt;/pre&gt;Для удобства дальнейшей обработки преобразуем этот блок в словарь параметров с помощью &lt;a href="http://code.google.com/p/sources-ownport/source/browse/pyflowctrl/processes/textprocessing1.py"&gt;Text2Dict&lt;/a&gt; &lt;br /&gt;
&lt;pre&gt;from pprint import pprint
from processes.textprocessing1 import Text2Dict

dict_selectors = {
    'method':           r'(?m)^(\w+) .+? HTTP/\d\.\d$',
    'url':              r'(?m)^\w+ (.+?) HTTP/\d\.\d$',
    'http':             r'(?m)^\w+ .+? (HTTP/\d\.\d)$',
    'user-agent':       r'(?m)^User-Agent: (.+?)$',
    'content-type':     r'(?m)^Content-Type: (.+?)$',
    'content-length':   r'(?m)^Content-Length: (\d+)$',
    'accept':           r'(?m)^Accept: (.+?)$',
    'accept-language':  r'(?m)^Accept-Language: (.+?)$',
    'accept-encoding':  r'(?m)^Accept-Encoding: (.+?)$',
    'connection':       r'(?m)^Connection: (.+?)$',
    'host':             r'(?m)^Host: (.+?)$',
}

t2d = Text2Dict(selectors=dict_selectors)
pprint(t2d.run_once(('block#1',block)))&lt;/pre&gt;В качестве параметра для процесса Text2Dict передается словарь dict_selectors на основании которого производится выборка. Ключи словаря - это имена переменных, значение словаря - регулярное выражение на основании которого делается выборка текста. Выборка выполняется с помощью метода re.findall, поэтому, если в тексте содержится несколько блоков удовлетворяющих регулярному выражению, Text2Dict вернет список значений.&lt;br /&gt;
&lt;br /&gt;
Метод run_once() с указанными параметрами (‘block#1’, block) позволяет передать на вход процесса исходные данные, выполнить одну итерацию и вернуть результат. Без указанных параметров код выглядел бы следующим образом: &lt;pre&gt;t2d.io[‘input’].put((‘block#1’, block))
t2d.run_once()
pprint(t2d.io[‘output’].get())&lt;/pre&gt;В результате выполнения скрипта, получаем словарь параметров текстового блока &lt;pre&gt;('block#1',
    {'accept': '*/*',
    'accept-encoding': 'gzip, deflate',
    'accept-language': 'en-us',
    'connection': 'keep-alive',
    'content-length': '2963',
    'content-type': 'text/xml',
    'host': 'example.com',
    'http': 'HTTP/1.1',
    'method': 'POST',
    'url': '/xmlrpc.php',
    'user-agent': 'wp-iphone/1.0'})&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2025136836330523605-7621248243279780991?l=devel.ownport.net' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/develforfun/~4/HYTTJcEgRA0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://devel.ownport.net/feeds/7621248243279780991/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="http://devel.ownport.net/2011/08/blog-post.html#comment-form" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2025136836330523605/posts/default/7621248243279780991?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2025136836330523605/posts/default/7621248243279780991?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/develforfun/~3/HYTTJcEgRA0/blog-post.html" title="Обработка текста, часть вторая" /><author><name>d.rey</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-fbT-P40hvn8/TgRK2-NhCpI/AAAAAAAAAXY/k98QYK-lOCc/s72-c/text-plain.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://devel.ownport.net/2011/08/blog-post.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DU4CRXc7eip7ImA9WhdREEU.&quot;"><id>tag:blogger.com,1999:blog-2025136836330523605.post-2885097946379048877</id><published>2011-07-31T07:52:00.000+03:00</published><updated>2011-07-31T07:52:44.902+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-07-31T07:52:44.902+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="text" /><category scheme="http://www.blogger.com/atom/ns#" term="pyflowctrl" /><category scheme="http://www.blogger.com/atom/ns#" term="python" /><category scheme="http://www.blogger.com/atom/ns#" term="processing" /><title>Обработка текста, часть первая</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-fbT-P40hvn8/TgRK2-NhCpI/AAAAAAAAAXY/k98QYK-lOCc/s1600/text-plain.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-fbT-P40hvn8/TgRK2-NhCpI/AAAAAAAAAXY/k98QYK-lOCc/s1600/text-plain.png" /&gt;&lt;/a&gt;&lt;/div&gt;В продолжении темы работы с текстовыми файлами стоит рассмотреть несколько подходов обработки структурированных текстовых данных. Наиболее известные форматы представления данных: HTML, XML, JSON, - форматы, использующие специальную разметку. Для многих из них существуют специальные библиотеки для парсинга и обработки. Существую также форматы, в которых данные не содержат разметки, а представлены в виде некоторой текстовой структуры. К таким данным относятся лог-файлы, вывод аварийных сообщений, дампы системы, статистические отчеты в текстовом формате, результаты мониторинга и многое другое.&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
Зачастую данные представленные в виде некоторой структуры повторяются для описания различных событий внутри одного текстового файла. В данном случае для извлечения структур данных можно воспользоваться двумя процессами TextSplit и TextSelector из небольшой библиотеки &lt;a href="http://code.google.com/p/sources-ownport/source/browse/pyflowctrl/processes/textprocessing1.py"&gt;textprocessing&lt;/a&gt;  для &lt;a href="http://code.google.com/p/sources-ownport/source/browse/pyflowctrl"&gt;pyflowctrl&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;TextSplit&lt;/b&gt; &lt;br /&gt;
&lt;br /&gt;
позволяет данные поступающие во входной поток разделять на основании некоторого разделителя. В качестве разделителя может выступать как один символ, так и несколько. Регулярные выражения не поддерживаются. Например, в текстовом файле сообщения разделены двойным &lt;a href="http://en.wikipedia.org/wiki/Newline"&gt;EOL (end of line)&lt;/a&gt; ‘\n\n’ &lt;pre&gt;from processes.filereader1 import FileReader
from processes.textprocessing1 import TextSplitter 
from processes.stdoutprinter1 import Printer

flow = ProcessFlow()
id_reader = flow.new(FileReader())
id_tsplit = flow.new(TextSplitter(separator='\n\n'))
id_print = flow.new(Printer())

# FileReader -&amp;gt; TextSplitter 
flow.link({'sid': id_reader, 'son': 'output', 'tid': id_tsplit, 'tin': 'input'})
# TextSplitter -&amp;gt; Printer
flow.link({'sid': id_tsplit, 'son': 'output', 'tid': id_print, 'tin': 'input'})

flow.pmap[id_reader].io['input'].put('/media/data/traces/wireshark/camel.log')
flow.run()&lt;/pre&gt;&lt;b&gt;TextSelector&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
позволяет извлекать из текста данные, на основании регулярных выражений. Может быть удобен в случаях, когда из текстовых данных нужно выбрать определенный блок данных. Можно выполнить разделение однотипных данных, поставив каждому выбранному блоку в соответствие свой поток.  Например, есть HTML страница содержащая информацию о погоде. Вместо парсинга всего документа можно выделить только данные, относящиеся к погоде и заключенные в ‘&amp;lt;div class="weather-info"&amp;gt;’ и '&amp;lt;/div&amp;gt;' &lt;pre&gt;from processes.filereader1 import FileReader
from processes.textprocessing1 import TextSelector
from processes.stdoutprinter1 import Printer

weather_info_selectors = {
    'weather-info': r'&amp;lt;div class="weather-info"&amp;gt;(.+?)&amp;lt;/div&amp;gt;',
}

flow = ProcessFlow()
id_reader = flow.new(FileReader())
id_tselect = flow.new(TextSelector(selectors=weather_info_selectors))
id_print = flow.new(Printer())

# FileReader -&amp;gt; TextSelector
flow.link({'sid': id_reader, 'son': 'output', 'tid': id_tselect, 'tin': 'input'})
# TextSelector -&amp;gt; Printer
flow.link({'sid': id_tselect, 'son': 'weather-info', 'tid': id_print, 'tin': 'input'})

flow.pmap[id_reader].io['input'].put('/media/data/weather/weather-info.20110731.html')
flow.run()&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2025136836330523605-2885097946379048877?l=devel.ownport.net' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/develforfun/~4/aNPJzR-v4q0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://devel.ownport.net/feeds/2885097946379048877/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="http://devel.ownport.net/2011/07/blog-post_31.html#comment-form" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2025136836330523605/posts/default/2885097946379048877?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2025136836330523605/posts/default/2885097946379048877?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/develforfun/~3/aNPJzR-v4q0/blog-post_31.html" title="Обработка текста, часть первая" /><author><name>d.rey</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-fbT-P40hvn8/TgRK2-NhCpI/AAAAAAAAAXY/k98QYK-lOCc/s72-c/text-plain.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://devel.ownport.net/2011/07/blog-post_31.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkUAQ34-eyp7ImA9WhdSFkg.&quot;"><id>tag:blogger.com,1999:blog-2025136836330523605.post-1152052657128151175</id><published>2011-07-26T06:17:00.000+03:00</published><updated>2011-07-26T06:17:22.053+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-07-26T06:17:22.053+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="conversion" /><category scheme="http://www.blogger.com/atom/ns#" term="text" /><category scheme="http://www.blogger.com/atom/ns#" term="python" /><category scheme="http://www.blogger.com/atom/ns#" term="html" /><title>html2txt: очистка html документа от тегов</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-44APA9vDnxM/Tgf2dJ6tlEI/AAAAAAAAAYA/H8WBXcXxMjU/s1600/text-xhtml%252Bxml.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-44APA9vDnxM/Tgf2dJ6tlEI/AAAAAAAAAYA/H8WBXcXxMjU/s1600/text-xhtml%252Bxml.png" /&gt;&lt;/a&gt;&lt;/div&gt;Для случаев, когда необходимо очистить html документов от тегов и сформировать тестовый документ, можно использовать небольшую функцию html2txt. В качестве параметра передается содержимое html документа, на выходе получаем текст очищенный от тегов. &lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# html2txt
#
import re

def html2txt(html):
    """Convert the html to raw txt """
    content = html

    p = re.compile('(&amp;lt;p.*?&amp;gt;)|(&amp;lt;tr.*?&amp;gt;)', re.I)
    t = re.compile('&amp;lt;td.*?&amp;gt;', re.I)
    comm = re.compile('&amp;lt;!--.*?--&amp;gt;', re.M)
    tags = re.compile('&amp;lt;.*?&amp;gt;', re.M)
    abbrv = re.compile('&amp;amp;[#\w\d]+;')    
    
    # replace abbreviation by space
    content = abbrv.sub(' ', content) 
    # remove returns time this compare to split filter join
    content = content.replace('\n', '') 
    # replace p and tr by \n
    content = p.sub('\n', content)
    # replace td by \t
    content = t.sub('\t', content) 
    # remove comments
    content = comm.sub('', content) 
    # remove all remaining tags
    content = tags.sub('', content) 
    # remove running spaces this remove the \n and \t
    content = re.sub('\ +', ' ', content) 
    return content&lt;/pre&gt;&lt;br /&gt;
&lt;b&gt;Ссылки&lt;/b&gt;&lt;br /&gt;
html2text, &lt;a href="http://www.aaronsw.com/2002/html2text/"&gt;http://www.aaronsw.com/2002/html2text/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2025136836330523605-1152052657128151175?l=devel.ownport.net' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/develforfun/~4/YI3c65K6tII" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://devel.ownport.net/feeds/1152052657128151175/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="http://devel.ownport.net/2011/07/html2txt-html.html#comment-form" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2025136836330523605/posts/default/1152052657128151175?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2025136836330523605/posts/default/1152052657128151175?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/develforfun/~3/YI3c65K6tII/html2txt-html.html" title="html2txt: очистка html документа от тегов" /><author><name>d.rey</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-44APA9vDnxM/Tgf2dJ6tlEI/AAAAAAAAAYA/H8WBXcXxMjU/s72-c/text-xhtml%252Bxml.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://devel.ownport.net/2011/07/html2txt-html.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEEMR3o6eyp7ImA9WhdSFE0.&quot;"><id>tag:blogger.com,1999:blog-2025136836330523605.post-8925392742270672080</id><published>2011-07-23T09:31:00.000+03:00</published><updated>2011-07-23T09:31:26.413+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-07-23T09:31:26.413+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="sha1" /><category scheme="http://www.blogger.com/atom/ns#" term="file" /><category scheme="http://www.blogger.com/atom/ns#" term="hash" /><category scheme="http://www.blogger.com/atom/ns#" term="pyflowctrl" /><category scheme="http://www.blogger.com/atom/ns#" term="sha512" /><category scheme="http://www.blogger.com/atom/ns#" term="python" /><category scheme="http://www.blogger.com/atom/ns#" term="md5" /><category scheme="http://www.blogger.com/atom/ns#" term="sha256" /><category scheme="http://www.blogger.com/atom/ns#" term="sha224" /><category scheme="http://www.blogger.com/atom/ns#" term="sha384" /><title>Расчет контрольных сумм файлов</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-NlXz1O055QE/TipqjahNNGI/AAAAAAAAAY0/GPKH9XkK2EU/s1600/crypto.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-NlXz1O055QE/TipqjahNNGI/AAAAAAAAAY0/GPKH9XkK2EU/s1600/crypto.png" /&gt;&lt;/a&gt;&lt;/div&gt;Контрольные суммы файлов используются для проверки целостности файлов, сравнения файлов на неэквивалентность. Расчет контрольных сумм выполняется на основе специальных хеш-функций, на вход которых передают исходные данные произвольной длины, на выходе получают битовую строку фиксированной длины - хеш-кодом, соответствующей исходным данным. В общем случае однозначного соответствия между исходными данными и хеш-кодом нет в силу того, что количество значений хеш-функций меньше, чем вариантов входного массива.&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
Существует множество исходных данных, которым соответствуют одинаковые хеш-коды. Такие ситуации называются коллизиями. В зависимости от поставленной задачи необходимо внимательно подходить к выбору функций. Процесс &lt;a href="http://code.google.com/p/sources-ownport/source/browse/pyflowctrl/processes/filehash1.py"&gt;FileHash&lt;/a&gt; позволяет делать расчет хеш-кодов для файлов используя хеш-функции, включенные в стандартную поставку python: md5, sha1, sha224, sha256, sha384, sha512.&lt;br /&gt;
&lt;br /&gt;
Пример использования процесса FileHash:&lt;br /&gt;
&lt;pre&gt;from core2 import EmptyStream, ProcessFlow
from processes.treewalker1 import TreeWalker
from processes.filehash1 import FileHash
from processes.stdoutprinter1 import Printer

flow = ProcessFlow()
id_walker = flow.new(TreeWalker())
id_hash = flow.new(FileHash(algorithm='md5'))
id_print = flow.new(Printer())

flow.link({'sid': id_walker, 'son': 'output', 'tid': id_hash, 'tin': 'input'})
flow.link({'sid': id_hash, 'son': 'output', 'tid': id_print, 'tin': 'input'})

flow.pmap[id_walker].io['input'].put('/media/photos/')
flow.run()&lt;/pre&gt;Приведенный выше пример очень похож на пример из предыдущего поста “&lt;a href="http://devel.ownport.net/2011/07/blog-post_22.html"&gt;Работа с текстовыми файлами небольшого объема&lt;/a&gt;”. С небольшим отличием - вместо FileReader используется процесс &lt;a href="http://code.google.com/p/sources-ownport/source/browse/pyflowctrl/processes/filehash1.py"&gt;FileHash&lt;/a&gt;. Выбор алгоритма хеш-функции осуществляется с помощью algorithm, который может принимать значения md5, sha1, sha224, sha256, sha384, sha512. Результатов выполнения данного скрипта будет вывод на консоль пар значений для файлов из исходной директории: путь к файлу и его контрольная сумма.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Полезные ссылки&lt;/b&gt;:&lt;br /&gt;
Cryptographic hash function, &lt;a href="http://en.wikipedia.org/wiki/Cryptographic_hash_function"&gt;http://en.wikipedia.org/wiki/Cryptographic_hash_function&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2025136836330523605-8925392742270672080?l=devel.ownport.net' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/develforfun/~4/ougqmuweF-c" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://devel.ownport.net/feeds/8925392742270672080/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="http://devel.ownport.net/2011/07/blog-post_23.html#comment-form" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2025136836330523605/posts/default/8925392742270672080?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2025136836330523605/posts/default/8925392742270672080?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/develforfun/~3/ougqmuweF-c/blog-post_23.html" title="Расчет контрольных сумм файлов" /><author><name>d.rey</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-NlXz1O055QE/TipqjahNNGI/AAAAAAAAAY0/GPKH9XkK2EU/s72-c/crypto.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://devel.ownport.net/2011/07/blog-post_23.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkcGQX06fCp7ImA9WhdSFE8.&quot;"><id>tag:blogger.com,1999:blog-2025136836330523605.post-4132717841559662825</id><published>2011-07-22T06:41:00.001+03:00</published><updated>2011-07-23T16:33:40.314+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-07-23T16:33:40.314+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="reader" /><category scheme="http://www.blogger.com/atom/ns#" term="file" /><category scheme="http://www.blogger.com/atom/ns#" term="pyflowctrl" /><category scheme="http://www.blogger.com/atom/ns#" term="python" /><title>Работа с текстовыми файлами небольшого объема</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-fbT-P40hvn8/TgRK2-NhCpI/AAAAAAAAAXY/k98QYK-lOCc/s1600/text-plain.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-fbT-P40hvn8/TgRK2-NhCpI/AAAAAAAAAXY/k98QYK-lOCc/s1600/text-plain.png" /&gt;&lt;/a&gt;&lt;/div&gt;В одном из предыдущих постов “&lt;a href="http://devel.ownport.net/2011/06/blog-post_24.html"&gt;Работа с текстовыми файлами&lt;/a&gt;” рассматривался подход открытия больших текстовых файлов. Для случаев, когда текстовых файлов много, а объем их относительно не велик (скажем, до 500кб), использовать процесс для чтения файлов из упомянутого выше поста не совсем удобно. Для этого лучше воспользоваться процессом &lt;a href="http://code.google.com/p/sources-ownport/source/browse/pyflowctrl/processes/filereader1.py"&gt;FileReader&lt;/a&gt;&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
В входной поток ‘input’ процесса, FileReader передается путь к файлу. Процесс проверяет существует ли данный файл. В случае успеха, в выходной поток ‘output’ передается список из двух значений: путь к файлу и содержимое самого файла. В случае, если файл не существует информация об этом заносится в поток ошибок ‘error’.&lt;br /&gt;
&lt;br /&gt;
Например необходимо вывести на экран содержимое всех файлов из директории /data/log/:&lt;br /&gt;
&lt;pre&gt;from core2 import EmptyStream, ProcessFlow
from processes.treewalker1 import TreeWalker
from processes.filereader1 import FileReader
from processes.stdoutprinter1 import Printer

flow = ProcessFlow()
id_tw = flow.new(TreeWalker())
id_fr = flow.new(FileReader())
id_print = flow.new(Printer())

flow.link({'sid': id_tw, 'son': 'output', 'tid': id_fr, 'tin': 'input'})
flow.link({'sid': id_fr, 'son': 'output', 'tid': id_print, 'tin': 'input'})

flow.pmap[id_tw].io['input'].put('/data/logs/')
flow.run()&lt;/pre&gt;Создается поток процессов flow = ProcessFlow(), добавляются три процесса: &lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://devel.ownport.net/2011/07/blog-post.html"&gt;TreeWalker&lt;/a&gt;, для получения списка файлов из директорий&lt;/li&gt;
&lt;li&gt;&lt;a href="http://code.google.com/p/sources-ownport/source/browse/pyflowctrl/processes/filereader1.py"&gt;FileReader&lt;/a&gt;, для чтения содержимого файлов&lt;/li&gt;
&lt;li&gt;&lt;a href="http://code.google.com/p/sources-ownport/source/browse/pyflowctrl/processes/stdoutprinter1.py"&gt;Printer&lt;/a&gt;, вывод содержимого файлов в стандартный вывод (stdout)&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
Входные и выходные потоки процессов объединяются между собой с помощью &lt;a href="http://devel.ownport.net/2011/05/pyflowctrl-c-python.html"&gt;flow.link()&lt;/a&gt;. На вход процесса TreeWalker передается исходная директория. flow.run() запускает на выполнение поток процессов.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2025136836330523605-4132717841559662825?l=devel.ownport.net' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/develforfun/~4/9uKaf2zi_kc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://devel.ownport.net/feeds/4132717841559662825/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="http://devel.ownport.net/2011/07/blog-post_22.html#comment-form" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2025136836330523605/posts/default/4132717841559662825?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2025136836330523605/posts/default/4132717841559662825?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/develforfun/~3/9uKaf2zi_kc/blog-post_22.html" title="Работа с текстовыми файлами небольшого объема" /><author><name>d.rey</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-fbT-P40hvn8/TgRK2-NhCpI/AAAAAAAAAXY/k98QYK-lOCc/s72-c/text-plain.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://devel.ownport.net/2011/07/blog-post_22.html</feedburner:origLink></entry></feed>

