<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2enclosuresfull.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-640162977889194353</atom:id><lastBuildDate>Sat, 14 Nov 2009 20:26:36 +0000</lastBuildDate><title>sash_ko's blog</title><description>каждый из нас беспонтовый пирожок (с) Летов</description><link>http://sashkoblog.blogspot.com/</link><managingEditor>noreply@blogger.com (sash_ko)</managingEditor><generator>Blogger</generator><openSearch:totalResults>149</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/Sash_ko" type="application/rss+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item><guid isPermaLink="false">tag:blogger.com,1999:blog-640162977889194353.post-3142188042299834552</guid><pubDate>Wed, 23 Sep 2009 18:18:00 +0000</pubDate><atom:updated>2009-09-23T22:00:23.141+03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">linux</category><title>666 и туалетное чтиво</title><description>Недавно решил сменить репертуар туалетного чтива с Маяковского на что-нибудь более практичное. И вот получил первый положительный результат. Читая давно пылившуюся в шкафу книгу "Операционная система Unix", открыл для себя тайный смысл магической команды:&lt;br /&gt;&lt;textarea name="code" class="html"&gt;&lt;br /&gt;chmod 666 *&lt;br /&gt;&lt;/textarea&gt;В юниксе права доступа (чтение - r, запись - w, выполнение - e) могут устанавливаться владельцу (u), группе (g) и остальным (o). Например, для того, что бы установить всем классам доступа право на чтение и запись нужно выполнить следующее:&lt;br /&gt;&lt;textarea name="code" class="html"&gt;&lt;br /&gt;chmod u=rw, g=rw, o=rw *&lt;br /&gt;&lt;/textarea&gt; Если в последовательности rwe заменить каждый элемент на 1 в случае наличия и 0 в случае отсутсвия права, а затем полученное число перевести в десятичную систему счисления (rwe =&gt; 111 =&gt; 7), параметры предыдущей команды можно будет записать более компактно - &lt;span style="font-weight:bold;"&gt;666&lt;/span&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/640162977889194353-3142188042299834552?l=sashkoblog.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Sash_ko/~4/udHcoRWDhfM" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/Sash_ko/~3/udHcoRWDhfM/666.html</link><author>noreply@blogger.com (sash_ko)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">4</thr:total><feedburner:origLink>http://sashkoblog.blogspot.com/2009/09/666.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-640162977889194353.post-9009096983419257095</guid><pubDate>Fri, 24 Apr 2009 06:40:00 +0000</pubDate><atom:updated>2009-04-24T09:44:07.666+03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Events</category><title>Kyiv Mapping Party</title><description>&lt;a href=http://mapping.in.ua/&gt;Kyiv Mapping Party 2009&lt;/a&gt; состоится завтра. Приглашаются все любители GPS'ов ;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/640162977889194353-9009096983419257095?l=sashkoblog.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Sash_ko/~4/so6924Ozfvc" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/Sash_ko/~3/so6924Ozfvc/kyiv-mapping-party.html</link><author>noreply@blogger.com (sash_ko)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://sashkoblog.blogspot.com/2009/04/kyiv-mapping-party.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-640162977889194353.post-3642999281491397673</guid><pubDate>Sat, 28 Feb 2009 11:19:00 +0000</pubDate><atom:updated>2009-02-28T14:05:29.479+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">задачки</category><title>Найти стороны прямоугольника (еще одно решение)</title><description>В комментариях &lt;a href=http://sashkoblog.blogspot.com/2009/02/blog-post_26.html&gt;задачи на нахождение сторон прямоугольника&lt;/a&gt; было предложено несколько вариантов решений, вот еще одно - графическое.&lt;br /&gt;&lt;span id="fullpost"&gt;&lt;br /&gt;На прямоугольник можно наложить сетку с ячейками 1х1. Получится такая картинка:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_lU8mYvjtzEQ/Sakeh2ujn-I/AAAAAAAAAhM/-EMryqOqQ0c/s1600-h/task.JPG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 171px; height: 130px;" src="http://2.bp.blogspot.com/_lU8mYvjtzEQ/Sakeh2ujn-I/AAAAAAAAAhM/-EMryqOqQ0c/s400/task.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5307807202808143842" /&gt;&lt;/a&gt;&lt;br /&gt;Периметр - это длина красной линии, состоящей из сторон серых ячеек. Если заметить, что угловые ячейки "предоставляют" красной линии по 2 стороны, а остальные - только по одной, становится очевидно, что периметр будет на 4 единицы больше, чем количество серых ячеек.&lt;br /&gt;&lt;br /&gt;Площадь - сумма площадей ячеек, для нашего случая (1*1=1) она численно равна количеству ячеек - серых и белых.&lt;br /&gt;&lt;br /&gt;Если периметр равен площади, значит он численно равен количеству ячеек и на 4 меньше, чем количество серых ячеек, а значит белых ячеек должно быть 4. Это возможно только в 2-х случаях - прямоугольник 6х3 и 4х4:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_lU8mYvjtzEQ/SakkOdvwJLI/AAAAAAAAAhc/AykBQGl-lxs/s1600-h/task2.JPG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 252px; height: 131px;" src="http://1.bp.blogspot.com/_lU8mYvjtzEQ/SakkOdvwJLI/AAAAAAAAAhc/AykBQGl-lxs/s400/task2.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5307813466754524338" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_lU8mYvjtzEQ/SakkOK3HZbI/AAAAAAAAAhU/VsTgmv6n2DM/s1600-h/task1.JPG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 175px; height: 174px;" src="http://3.bp.blogspot.com/_lU8mYvjtzEQ/SakkOK3HZbI/AAAAAAAAAhU/VsTgmv6n2DM/s400/task1.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5307813461685134770" /&gt;&lt;/a&gt;&lt;br /&gt;Для так такого решения не нужно вспоминать как решаются системы неравенств или что такое &lt;a href=http://ru.wikipedia.org/wiki/%D0%94%D0%B8%D0%BE%D1%84%D0%B0%D0%BD%D1%82%D0%BE%D0%B2%D0%BE_%D1%83%D1%80%D0%B0%D0%B2%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5&gt;диофантовы уравнения&lt;/a&gt;. Последние я мало того, что забыл, дак еще и не знал.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/640162977889194353-3642999281491397673?l=sashkoblog.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Sash_ko/~4/uDG-ju1XtGk" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/Sash_ko/~3/uDG-ju1XtGk/blog-post_28.html</link><author>noreply@blogger.com (sash_ko)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_lU8mYvjtzEQ/Sakeh2ujn-I/AAAAAAAAAhM/-EMryqOqQ0c/s72-c/task.JPG" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://sashkoblog.blogspot.com/2009/02/blog-post_28.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-640162977889194353.post-6057976509878754998</guid><pubDate>Thu, 26 Feb 2009 09:22:00 +0000</pubDate><atom:updated>2009-02-26T11:29:10.465+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">задачки</category><title>Найти стороны прямоугольника</title><description>Найти длины сторон прямоугольника (целые числа), у которого периметр равен площади.&lt;br /&gt;&lt;br /&gt;PS: Задачка для 6-го класса ;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/640162977889194353-6057976509878754998?l=sashkoblog.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Sash_ko/~4/e8fKqVL05bw" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/Sash_ko/~3/e8fKqVL05bw/blog-post_26.html</link><author>noreply@blogger.com (sash_ko)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">12</thr:total><feedburner:origLink>http://sashkoblog.blogspot.com/2009/02/blog-post_26.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-640162977889194353.post-2257454954830052325</guid><pubDate>Wed, 25 Feb 2009 10:48:00 +0000</pubDate><atom:updated>2009-02-25T13:01:02.006+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">linux</category><title>Hello Ubuntu</title><description>Поставил себе на ноут вторую ось - Ubuntu 8.10. Для меня это первый linux, который сразу заработал, без проблем с видео, звуком и т.д. Неработающий wi-fi не считается - &lt;a href="http://blog.hyperandy.com/2008/11/01/atheros-ar242x-ubuntu-810-ibex/"&gt;все решилось&lt;/a&gt; за считанные минуты. Сложнее было найти как у висты отобрать кусок диска - менеджер дисков не позволял за один раз ужать до нужного мне размера.&lt;br /&gt;&lt;br /&gt;Наконец-то у меня появился &lt;a href=http://sashkoblog.blogspot.com/search/label/vim&gt;vim&lt;/a&gt; :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/640162977889194353-2257454954830052325?l=sashkoblog.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Sash_ko/~4/JYeb8PwpwOw" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/Sash_ko/~3/JYeb8PwpwOw/hello-ubuntu.html</link><author>noreply@blogger.com (sash_ko)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">12</thr:total><feedburner:origLink>http://sashkoblog.blogspot.com/2009/02/hello-ubuntu.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-640162977889194353.post-592746811356978136</guid><pubDate>Fri, 13 Feb 2009 07:24:00 +0000</pubDate><atom:updated>2009-02-13T09:50:54.410+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">erlang</category><title>Просто об Erlang'e</title><description>Несколько ссылок, где можно доступно почитать об Erlang'e на русском. &lt;br /&gt;&lt;br /&gt;&lt;a href=http://rsdn.ru/article/erlang/GettingStartedWithErlang.xml&gt;Начала работы с Erlang&lt;/a&gt; - перевод на русский эрланговского туториала. Не думаю, что можно написать об этом языке еще проще.&lt;br /&gt;&lt;br /&gt;&lt;a href=http://rsdn.ru/article/erlang/Erlang_Error_Handling.xml&gt;Обработка ошибок в Erlang&lt;/a&gt; - тоже на &lt;a href=&gt;rsdn'e&lt;/a&gt;, тоже перевод.&lt;br /&gt;&lt;br /&gt;&lt;a href=http://erlang.dmitriid.com/&gt;Erlang по-русски&lt;/a&gt; - проект, занимающийся переводом документации на русский. Плюс дополнительный бонус - постоянно обновляющиеся новости о событиях в мире Эрланга.&lt;br /&gt;&lt;br /&gt;&lt;a href=http://habrahabr.ru/blogs/erlang/51517/&gt;Erlang в Рисоваське, часть 1&lt;/a&gt;, &lt;a href=http://habrahabr.ru/blogs/erlang/51796/&gt;Erlang в Рисоваське, часть 2&lt;/a&gt; - разработчик &lt;a href=http://risovaska.ru/&gt;Рисоваськи&lt;/a&gt; раскрывает секреты :) Начало цикла статей об Эрланге и его применении в реальном проекте.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;Дополнительно:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href=http://se-radio.net/podcast/2008-03/episode-89-joe-armstrong-erlang&gt;Joe Armstrong on Erlang&lt;/a&gt; - подкаст на английском с &lt;a href=http://armstrongonsoftware.blogspot.com/&gt;Joe Armstrong'ом&lt;/a&gt;, создателем Erlang.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/640162977889194353-592746811356978136?l=sashkoblog.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Sash_ko/~4/WODbCuJwcWo" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/Sash_ko/~3/WODbCuJwcWo/erlange.html</link><author>noreply@blogger.com (sash_ko)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://sashkoblog.blogspot.com/2009/02/erlange.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-640162977889194353.post-2034787077322757900</guid><pubDate>Tue, 03 Feb 2009 23:34:00 +0000</pubDate><atom:updated>2009-02-04T01:34:04.542+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">задачки</category><title>Задачка про вирусы и бактерии</title><description>В колонии из Х бактерий, которая каждую секунду увеличивается вдвое, заводится вирус. Каждую секунду он съедает одну бактерию и "рождает" еще один вирус. Обречена ли колония бактерий на полное уничтожение?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/640162977889194353-2034787077322757900?l=sashkoblog.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Sash_ko/~4/NlL3soEFKkg" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/Sash_ko/~3/NlL3soEFKkg/blog-post_04.html</link><author>noreply@blogger.com (sash_ko)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://sashkoblog.blogspot.com/2009/02/blog-post_04.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-640162977889194353.post-2456182658657116353</guid><pubDate>Tue, 03 Feb 2009 14:12:00 +0000</pubDate><atom:updated>2009-02-03T16:19:52.879+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">задачки</category><title>Мешки с деньгами (задача)</title><description>&lt;span style="font-style:italic;"&gt;Еще одна задача про фальшивое бабло...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Есть 5 мешков с деньгами. Мешки небольшие - в каждом всего по 10 монет. В четырех мешках монеты фальшивые. Фальшивая монета, весом 10 грамм, на один грамм легче настоящей. Как при помощи весов за одно взвешивание определить настоящие монеты?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/640162977889194353-2456182658657116353?l=sashkoblog.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Sash_ko/~4/Cjbv4dL8zjI" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/Sash_ko/~3/Cjbv4dL8zjI/blog-post.html</link><author>noreply@blogger.com (sash_ko)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">9</thr:total><feedburner:origLink>http://sashkoblog.blogspot.com/2009/02/blog-post.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-640162977889194353.post-8738320896513132058</guid><pubDate>Mon, 26 Jan 2009 09:03:00 +0000</pubDate><atom:updated>2009-02-09T22:02:06.495+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">python</category><title>На свои же грабли...</title><description>Недавно писал про &lt;a href=http://sashkoblog.blogspot.com/2008/08/with-python.html&gt;with&lt;/a&gt; в Python'e и сам же наступил на связанные с ним грабли: некоторые исключения при таинственных обстоятельствах исчезали. Кроме with'а, подозреваемых не было, но следствие показало, что сам по себе оператор в этом не виноват. Причина была в менеджере контекста, функция __exit__ которого всегда возвращала True и тем самым подавлял все возможные исключения.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/640162977889194353-8738320896513132058?l=sashkoblog.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Sash_ko/~4/cn94akzE7jQ" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/Sash_ko/~3/cn94akzE7jQ/blog-post_26.html</link><author>noreply@blogger.com (sash_ko)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://sashkoblog.blogspot.com/2009/01/blog-post_26.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-640162977889194353.post-6506835888760061401</guid><pubDate>Thu, 22 Jan 2009 20:29:00 +0000</pubDate><atom:updated>2009-01-22T22:34:55.951+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">python</category><title>Пример оптимизации кода на Python</title><description>Интересный пример оптимизации кода на Python можно посмотреть &lt;a href=http://effbot.org/zone/wide-finder.htm&gt;здесь&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/640162977889194353-6506835888760061401?l=sashkoblog.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Sash_ko/~4/MvK_6PI0vb0" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/Sash_ko/~3/MvK_6PI0vb0/python.html</link><author>noreply@blogger.com (sash_ko)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://sashkoblog.blogspot.com/2009/01/python.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-640162977889194353.post-2754417016773659726</guid><pubDate>Thu, 15 Jan 2009 08:17:00 +0000</pubDate><atom:updated>2009-01-15T10:22:54.630+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">python</category><title>The History of Python</title><description>&lt;a href=http://neopythonic.blogspot.com/&gt;Гвидо ван Россум&lt;/a&gt;, тот который автор Питона, начал вести блог об истории Питона, который так и называется &lt;a href=http://python-history.blogspot.com/&gt;The History of Python&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/640162977889194353-2754417016773659726?l=sashkoblog.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Sash_ko/~4/h2ueHRquVS0" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/Sash_ko/~3/h2ueHRquVS0/history-of-python.html</link><author>noreply@blogger.com (sash_ko)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://sashkoblog.blogspot.com/2009/01/history-of-python.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-640162977889194353.post-7319340827538473658</guid><pubDate>Wed, 14 Jan 2009 16:00:00 +0000</pubDate><atom:updated>2009-01-14T18:53:27.401+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">python</category><category domain="http://www.blogger.com/atom/ns#">Qt</category><title>Трабла setHidden у QTreeWidgetItem</title><description>&lt;span style="font-weight:bold;"&gt;Суть проблемы &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Есть дерево (QTreeWidget) элементов (QTreeWidgetItem). По событию некоторые элементы нужно скрыть, а скрытые отобразить, для чего используется функция setHidden у QTreeWidgetItem. После фильтрации это все сортируется:&lt;span id="fullpost"&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;def add_subitems(self, root_item):        &lt;br /&gt;    '''Добавить элементы к корневому элементу'''&lt;br /&gt;&lt;br /&gt;    def add(text, hide=False):&lt;br /&gt;        sub_item = QtGui.QTreeWidgetItem(root_item)&lt;br /&gt;        sub_item.setText(0, text)        &lt;br /&gt;        sub_item.setHidden(hide)&lt;br /&gt;&lt;br /&gt;    map(lambda val: add(*val), ( ('one',), &lt;br /&gt;                                 ('two', True), &lt;br /&gt;                                 ('three',) ))&lt;br /&gt;&lt;br /&gt;def update_subitems(self, root_item):&lt;br /&gt;    '''Обновить под-элементы - скрыть или отобразить'''&lt;br /&gt;    &lt;br /&gt;    for index in range(root_item.childCount()):&lt;br /&gt;        item = self.root_item.child(index)&lt;br /&gt;        # для упрощения скрываются видимые элементы,&lt;br /&gt;        # а скрытые отображаются&lt;br /&gt;        item.setHidden(not item.isHidden())&lt;br /&gt;&lt;br /&gt;    self.treeWidget.sortItems(0, QtCore.Qt.AscendingOrder)&lt;/pre&gt;&lt;br /&gt;Если update_subitems вызывается когда окно скрыто (свернуто в трей), часть вызовов setHidden отрабатывается не правильно и при восстановлении окна из трея пользователь видит не то, что должен видеть. Если убрать сортировку или не скрывать окно - все работает как надо.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Решение&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Единственное решение, которое я нашел - отлавливать момент, когда окно отображается (QShowEvent) и обновлять дерево еще раз:&lt;br /&gt;&lt;pre class="prettyprint"&gt;def event(self, ev):&lt;br /&gt;    if ev.type()==QtCore.QEvent.Show:&lt;br /&gt;        #....&lt;br /&gt;        self.update_subitems(root_item) &lt;/pre&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/640162977889194353-7319340827538473658?l=sashkoblog.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Sash_ko/~4/sv-sCL4Ud5o" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/Sash_ko/~3/sv-sCL4Ud5o/sethidden-qtreewidgetitem.html</link><author>noreply@blogger.com (sash_ko)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://sashkoblog.blogspot.com/2009/01/sethidden-qtreewidgetitem.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-640162977889194353.post-4512037662474259130</guid><pubDate>Tue, 06 Jan 2009 09:36:00 +0000</pubDate><atom:updated>2009-01-06T12:12:36.514+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Программизм</category><title>Меньше кодить, больше думать</title><description>&lt;span style="font-style:italic;"&gt;Джордж Сантаяне: Фанатизм состоит в удвоении Вашего усилия, когда Вы забыли свою цель&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Первый пост в этом году будет обещанием самому себе - &lt;span style="font-weight:bold;"&gt;не писать ни строки кода пока не будет до конца ясно зачем это надо&lt;/span&gt;. Под этим я имею ввиду, что каждая задача должна разбиваться на подзадачи (строки кода) только когда понятна сама задача (зачем это надо). Делать наоборот - на ходу придумывать подзадачи и подгонять их под конкретную задачу - пустая трата времени и источник ошибок.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/640162977889194353-4512037662474259130?l=sashkoblog.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Sash_ko/~4/iUE3E6n5O9o" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/Sash_ko/~3/iUE3E6n5O9o/blog-post.html</link><author>noreply@blogger.com (sash_ko)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">3</thr:total><feedburner:origLink>http://sashkoblog.blogspot.com/2009/01/blog-post.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-640162977889194353.post-8537336197249195388</guid><pubDate>Sun, 21 Dec 2008 08:39:00 +0000</pubDate><atom:updated>2008-12-21T11:03:51.780+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Qt</category><title>Qt Creator</title><description>Qt Software (так называется Trolltech после покупки компанией Nokia) выпустили бету новой кросс-платформенной IDE для работы с Qt - Qt Creator. На данном этапе среда поддерживает только компилятор gcc и дебагер gdb. Можно так же использовать Microsoft Visual Studio компилятор, но тогда не получится дебажить.&lt;br /&gt;&lt;span id="fullpost"&gt;&lt;br /&gt;Qt Creator - это не попытка заменить Eclipse и Visual Studio: &lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-style:italic;"&gt;Qt Creator is not an Eclipse replacement, but instead a lightweight IDE designed specifically for cross-platform Qt development.&lt;br /&gt;&lt;br /&gt;Qt Creator is not a Visual Studio replacement, but instead a lightweight IDE designed specifically for cross-platform Qt development.&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;Финальный релиз намечается на начало 2009 года. Подробнее можно почитать &lt;a href=http://trolltech.com/developer/qt-creator/qt-creator&gt;здесь&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Выглядит это так:&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/U7yje3D1UM4&amp;hl=en&amp;fs=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/U7yje3D1UM4&amp;hl=en&amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;Самореклама: &lt;a href=http://sashko-life.blogspot.com/&gt;мой второй блог&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/640162977889194353-8537336197249195388?l=sashkoblog.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Sash_ko/~4/jjLybQDlNQQ" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/Sash_ko/~3/jjLybQDlNQQ/qt-creator.html</link><author>noreply@blogger.com (sash_ko)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://sashkoblog.blogspot.com/2008/12/qt-creator.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-640162977889194353.post-1255786273048772234</guid><pubDate>Sat, 20 Dec 2008 13:51:00 +0000</pubDate><atom:updated>2008-12-20T16:34:50.226+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Программизм</category><title>1+1=4</title><description>Недавно попробовали на работе использовать парное программирование. Я к этому относился довольно скептически, поэтому все получалось спонтанно и дало неожиданные результаты. Вместо того, что бы каждый решал свою задачу, два человека делают одно и тоже да еще за одним компьютером. Но полученное решение получилось намного лучше, чем каждый предлагал в отдельности (все началось со спора, когда каждый отстаивал свое). И большинство ошибок было выявлено сразу - пока один пишет, у другого есть возможность проверять. Так что дополнительные затраты, связанные с привлечением другого человека, окупаются значительно меньшим количеством ошибок и меньшей вероятностью рефакторинга. Самое главное в этом процессе - не отстаивать только свою точку зрения, так как это заведомо проигрышный вариант. Если приструнить свои амбиции (лично для меня, это довольно не легко), можно получить &lt;a href=http://ru.wikipedia.org/wiki/%D0%A1%D0%B8%D0%BD%D0%B5%D1%80%D0%B3%D0%B8%D1%8F&gt;синергетический&lt;/a&gt; результат. Не зря говорят, что одна голова хорошо, а две - лучше. Этот принцип прекрасно работает в программировании.&lt;br /&gt;&lt;span id="fullpost"&gt;&lt;br /&gt;Заинтересовавшись этим вопросом, почитал главу &lt;a href=http://www.ozon.ru/context/detail/id/3159814/&gt;Совершенного кода&lt;/a&gt;, посвященную совместной разработке. Оказывается парное программирование и другие подобные методы (обзор кода), действительно дают большие преимущества, позволяют выявлять огромный процент ошибок, даже больший чем тестирование. В книге указанны конкретные цифры, но это очень специфично для каждого конкретного проекта.&lt;br /&gt;&lt;br /&gt;Из этого можно сделать несколько выводов. Во-первых, командная работа, это не только когда несколько человек работают над различными подзадачами общей задачи. Командная работа - это еще коммуникация которая, если она хорошо налажена, позволяет достигать синергии. А методы совместной разработки способствуют этому. Во-вторых, стоит время от времени экспериментировать.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;Самореклама: &lt;a href=http://sashko-life.blogspot.com/&gt;мой второй блог&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/640162977889194353-1255786273048772234?l=sashkoblog.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Sash_ko/~4/OnxHqdwx_V8" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/Sash_ko/~3/OnxHqdwx_V8/114.html</link><author>noreply@blogger.com (sash_ko)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">6</thr:total><feedburner:origLink>http://sashkoblog.blogspot.com/2008/12/114.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-640162977889194353.post-8128817592092535824</guid><pubDate>Thu, 18 Dec 2008 22:58:00 +0000</pubDate><atom:updated>2008-12-19T01:24:42.668+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Программизм</category><title>Бесконечные проекты</title><description>&lt;span style="font-style:italic;"&gt;Навеяло постом &lt;a href=http://ua-coder.blogspot.com/2008/12/blog-post_11.html&gt;про собеседования&lt;/a&gt;.&lt;/span&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/640162977889194353-8128817592092535824?l=sashkoblog.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Sash_ko/~4/JECctAmn0Hk" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/Sash_ko/~3/JECctAmn0Hk/blog-post_19.html</link><author>noreply@blogger.com (sash_ko)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">3</thr:total><feedburner:origLink>http://sashkoblog.blogspot.com/2008/12/blog-post_19.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-640162977889194353.post-934580111235999711</guid><pubDate>Tue, 02 Dec 2008 06:02:00 +0000</pubDate><atom:updated>2008-12-03T15:42:36.328+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">задачки</category><title>Рассуждения вместо уравнения</title><description>В &lt;a href=http://www.ozon.ru/context/detail/id/1688988/&gt;"Математической смекалке"&lt;/a&gt; довольно красиво показано как решение задачи плавно вытекает из условия при помощи простых рассуждений и элементарных вычислений:&lt;br /&gt;&lt;blockquote&gt;Если некоторое двузначное число прочесть справа налево, то полученное "обращенное" число будет в 4.5 раза больше данного. Что это за число?&lt;br /&gt;&lt;br /&gt;В условии задачи данных немного, но, искусно их используя, можно решить эту задачу одними "рассуждениями" примерно так:&lt;br /&gt;1. Искомое число больше 10, так как оно двузначное.&lt;br /&gt;2. Но оно меньше 23, так как 23*4.5 - число трехзначное.&lt;br /&gt;3. Искомое число четное, так как при умножении его на 4.5 получается целое число.&lt;br /&gt;4. Обращенное число по условию в 9 раз больше половины данного числа, значит, обращенное число кратно 9.&lt;br /&gt;5. Так как обращенное число кратно 9, то сумма его цифр делится на 9, а данное число состоит из тех же цифр, что и обращенное, значит, и оно кратно 9.&lt;br /&gt;...&lt;/blockquote&gt;Дальше уже не сложно продолжить рассуждения и найти искомое число.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/640162977889194353-934580111235999711?l=sashkoblog.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Sash_ko/~4/rO5GNZzhYtM" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/Sash_ko/~3/rO5GNZzhYtM/blog-post_02.html</link><author>noreply@blogger.com (sash_ko)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">8</thr:total><feedburner:origLink>http://sashkoblog.blogspot.com/2008/12/blog-post_02.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-640162977889194353.post-5159832011584353820</guid><pubDate>Mon, 01 Dec 2008 20:21:00 +0000</pubDate><atom:updated>2008-12-01T22:27:33.519+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">life</category><title>Утренний артхаус</title><description>Сегодня в 5 утра ехал на такси на вокзал. Всю дорогу таксист рассказывал как он  прикручивал индексацию на ассемблере для базы данных, хранящейся на 8-ми дюймовой дискете...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/640162977889194353-5159832011584353820?l=sashkoblog.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Sash_ko/~4/DpFC4PjBLoQ" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/Sash_ko/~3/DpFC4PjBLoQ/blog-post.html</link><author>noreply@blogger.com (sash_ko)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://sashkoblog.blogspot.com/2008/12/blog-post.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-640162977889194353.post-7927315493065084278</guid><pubDate>Fri, 28 Nov 2008 08:31:00 +0000</pubDate><atom:updated>2008-11-28T10:44:48.522+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">life</category><title>Кризисный оффтоп: "увольнения"</title><description>То, что экономический кризис не коснулся меня лично, не значит, что его нет. Среди моих знакомых, работающих в банках и тому подобных организациях, уже есть пострадавшие, которых "уволили". Я не зря взял это слово в кавычки - странно называть увольнением, когда человека &lt;span style="font-weight:bold;"&gt;вынуждают&lt;/span&gt; писать заявление по собственному желанию. Я сужу со своей колокольни и поэтому не понимаю, что значит &lt;span style="font-weight:bold;"&gt;вынуждают&lt;/span&gt;? Что мешает человеку, отработавшему на одном месте больше года, отказаться писать заявление по собственному желанию? Страх, что в трудовую напишут какую нибудь гадость? Но насколько я знаю, написать гадость не так то просто, КЗОТ хоть как-то от этого должен защищать. Возможно дело именно в незнании своих прав и &lt;span style="font-weight:bold;"&gt;вынуждение&lt;/span&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/640162977889194353-7927315493065084278?l=sashkoblog.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Sash_ko/~4/KVBp2Xptd4I" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/Sash_ko/~3/KVBp2Xptd4I/blog-post_28.html</link><author>noreply@blogger.com (sash_ko)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">13</thr:total><feedburner:origLink>http://sashkoblog.blogspot.com/2008/11/blog-post_28.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-640162977889194353.post-1921932211245120981</guid><pubDate>Thu, 27 Nov 2008 07:00:00 +0000</pubDate><atom:updated>2008-11-27T08:56:36.354+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Программизм</category><title>Тестирование "белого ящика"</title><description>В большинстве случаев, когда говорят о тестировании программистами своего кода, упоминаются юнит-тесты. Когда говорят о юнит-тестах, обычно говорят об инструментах, организации и нужно ли вообще это делать. Но обычно никто не говорит о том, как именно нужно писать тесты. Просто запуск функции с некоторыми параметрами и получение ожидаемого результата еще не означает, что функция полностью работоспособна и завтра удастся повторить это действие с другими параметрами. Непонятно от чего отталкиваться, когда пишешь тест.&lt;br /&gt;&lt;span id="fullpost"&gt;&lt;br /&gt;Пусть есть функция, которая получает длину сторон треугольника и возвращает его тип: равносторонний, не равносторонний или равнобедренный. В остальных случаях возвращается ошибка. Попробуем ее протестировать.&lt;br /&gt;&lt;pre class="prettyprint"&gt;// типы треугольников&lt;br /&gt;enum type_t {t_scalene=1, t_isosceles=2,&lt;br /&gt;             t_equilateral=3, t_error=4};&lt;br /&gt;&lt;br /&gt;type_t triangle_type(int sideA, int sideB, int sideC)&lt;br /&gt;{&lt;br /&gt;   // проверка валидности треугольника -&lt;br /&gt;   // сумма длин двух любых сторон не должна превышать&lt;br /&gt;   // длину третьей стороны&lt;br /&gt;   if((sideA&gt;0 &amp;&amp; sideB&gt;0 &amp;&amp; sideC&gt;0) &amp;&amp;           // 1&lt;br /&gt;      (sideA&lt;(sideB+sideC))&amp;&amp;&lt;br /&gt;      (sideB&lt;(sideA+sideC))&amp;&amp;&lt;br /&gt;      (sideC&lt;(sideA+sideB)))&lt;br /&gt;   {&lt;br /&gt;      int ab = (sideA==sideB)?1:0;                 // 2&lt;br /&gt;      int ac = (sideA==sideC)?1:0;                 // 3&lt;br /&gt;      int bc = (sideB==sideC)?1:0;                 // 4&lt;br /&gt;&lt;br /&gt;      int num = ab+ac+bc;&lt;br /&gt;&lt;br /&gt;      // if num==0 - scalene&lt;br /&gt;      // if num==1 - isosceles&lt;br /&gt;      // if num==3 - equilateral&lt;br /&gt;      type_t types [] = {t_scalene, t_isosceles,&lt;br /&gt;                         t_error, t_equilateral};&lt;br /&gt;      return types[num];                           // 5&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   return t_error;&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Функция состоит из трех частей - входящие данные, действия, выполняемые над ними и результат. Единственное, чем мы можем управлять в полной мере - это входящие данные, а результат служит индикатором. Тогда остается выбрать несколько подходящих наборов данных и следить за индикатором. Самое сложное - это понять, какой &lt;span style="font-weight:bold;"&gt;минимум параметров&lt;/span&gt; нужно передать, что бы найти &lt;span style="font-weight:bold;"&gt;максимум ошибок&lt;/span&gt; в коде (тестирование - это выявление ошибок, а не доказательство того, что функция работает).&lt;br /&gt;&lt;br /&gt;Почему одного запуска функции и получение нужного результата недостаточно? Программы очень редко выполняются строчка за строчкой - этому препятствуют всевозможные логические операторы &lt;span style="font-weight:bold;"&gt;if, for, while, until, or, and, switch&lt;/span&gt;. Они разветвляют код, создавая сложные пути исполнения одной и той же программы при разных входящих данных. И по всем этим путям нужно пройти, один запуск с одними параметрами - это проверка одного пути из многих. Значит тестов нужно не меньше, чем перечисленных выше ключевых слов в коде. (В рассматриваемом случае под тестами я понимаю вызов функции с различными наборами параметров.)&lt;br /&gt;&lt;br /&gt;Первый if, в приведенной выше функции, проверяет четыре условия - длины сторон треугольника должны быть неотрицательными и длина каждой из сторон должна быть меньше суммы длин двух других. Все условия объединены операторами &amp;&amp;, поэтому достаточно невыполнения одного из них, что бы не выполнился код, следующий за if. Но неплохо бы знать, все ли условия вычисляются правильно. Поэтому нужно передать функции значения, которые будут true и значения, которые будут false для каждого из условий. Проверить это можно по возвращаемому значению t_error, в случае если любое из условий не выполняется. Хотя первое из условий является само по себе составным, но все проверки в нем довольно простые и объеденены оператором &amp;&amp;, поэтому допустим, что достаточно будет проверки, когда одна длина отрицательная и когда все длины положительные.&lt;br /&gt;&lt;br /&gt;В случае успешного прохождения if, выполняются проверки, помеченные как 2, 3, 4. Они не создают больших ответвлений, но вычисляют значения, которые влияют на выбор нужного элемента массива types в строке 5. Количество выполненных условий записывается в переменную num, которая может принимать только три значения 0, 1, 3 (2 не может быть, так как при выполнении двух автоматически выполняется третье). Значит для тестирования этой части кода достаточно 3-х наборов входящих параметров - все стороны неравны (num==0), все стороны равны (num==3), равны только 2 стороны (num==1).&lt;br /&gt;&lt;br /&gt;Больше ответвлений в программе не наблюдается, поэтому можно подводить итог. Для тестирования функции triangle_type, нужно передать ей 14 наборов входящих параметров (8 для условия 1, 6 для условий 2, 3, 4) и проверить возвращаемый результат. После этого можно быть уверенным, что в большинстве случаев поведение функции будет предсказуемым. Хотя нет... это только часть возможных проверок. Еще можно проверять передаваемые параметры, например, как будет вести себя функция при максимально и минимально допустимых значениях, но это уже отдельная тема. Я хотел рассказать только о тестировании, базирующемся на изучении кода. Это как раз то, что теоретически отличает тестирование программистами от тестирования тестировщиками - программисты тестируют не "черный ящик".&lt;br /&gt;&lt;br /&gt;PS: Не смотря, на то что получилось много текста, на практике это занимает не так уж много времени :)&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/640162977889194353-1921932211245120981?l=sashkoblog.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Sash_ko/~4/L-dRV795JdI" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/Sash_ko/~3/L-dRV795JdI/blog-post_23.html</link><author>noreply@blogger.com (sash_ko)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">4</thr:total><feedburner:origLink>http://sashkoblog.blogspot.com/2008/11/blog-post_23.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-640162977889194353.post-5694367855544423608</guid><pubDate>Sat, 22 Nov 2008 20:09:00 +0000</pubDate><atom:updated>2008-11-22T22:17:24.045+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">задачки</category><title>Задача про банку и дробь</title><description>В полевых условиях нужно получить свинцовую пластинку определенного объема. Из инструментов и материалов есть только охотничья дробь и политровая стеклянная банка с делениями, как мензурка. Есть так же все необходимое для плавления свинца, но это не поможет для решения задачи. А задача такая: как определить достаточный объем дроби? Дополнительное условие - при расчетах можно использовать только одно действие - вычитание.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/640162977889194353-5694367855544423608?l=sashkoblog.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Sash_ko/~4/7V9CSwyeeu0" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/Sash_ko/~3/7V9CSwyeeu0/blog-post_22.html</link><author>noreply@blogger.com (sash_ko)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">8</thr:total><feedburner:origLink>http://sashkoblog.blogspot.com/2008/11/blog-post_22.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-640162977889194353.post-6325664750066127156</guid><pubDate>Wed, 19 Nov 2008 14:08:00 +0000</pubDate><atom:updated>2008-11-19T16:26:20.057+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">C++</category><title>Удивительное рядом - shared_ptr и виртуальный деструктор</title><description>Интересную штуку про &lt;span style="font-weight:bold;"&gt;boost::shared_ptr&lt;/span&gt; прочитал здесь &lt;a href=http://dvinogradov.blogspot.com/2008/11/storing-dynamic-created-objects-in.html&gt;Storing dynamicly created objects in a container&lt;/a&gt;. Для &lt;span style="font-weight:bold;"&gt;shared_ptr&lt;/span&gt; не обязательно наличие виртуального деструктора у базового класса. Это не значит, что виртуальные деструкторы теперь не нужны, но может быть полезно, когда есть legacy-код без них и менять его нельзя.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/640162977889194353-6325664750066127156?l=sashkoblog.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Sash_ko/~4/53xgYaDlHUU" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/Sash_ko/~3/53xgYaDlHUU/sharedptr.html</link><author>noreply@blogger.com (sash_ko)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://sashkoblog.blogspot.com/2008/11/sharedptr.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-640162977889194353.post-9141940683484329128</guid><pubDate>Sun, 16 Nov 2008 18:25:00 +0000</pubDate><atom:updated>2008-11-16T22:34:06.396+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">задачки</category><title>Объединение двух отсортированных массивов</title><description>Как объединить два отсортированных массива (n1 и n2 элементов) в один отсортированный массив? Такой вопрос мне неоднократно попадался на собеседованиях и даже пару раз сталкивался с ним на практике. Вся сложность этого вопроса не в том как это сделать, а как это сделать максимально быстро. &lt;br /&gt;&lt;span id="fullpost"&gt;&lt;br /&gt;Быстрее всего это делается за n1+n2 итераций (линейное время). Пусть есть два отсортированных по возрастанию массива A1 и A2. Можно легко определить первый элемент результирующего массива - им будет либо первый элемент первого массива, либо первый элемент второго массива, в зависимости от того, что меньше. Допустим, наименьший - это A1[0]. На следующей итерации при помощи одного сравнения определяется второй элемент результирующего массива - опять сравниваются первые элементы исходных массивов, при условии, что для A1 первый элемент - это A1[1], так как A1[0] - уже выбыл из игры. И так продолжается пока не будет заполнен результирующий массив. На картинке это выглядит так:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_lU8mYvjtzEQ/SSB2Nq4v4ZI/AAAAAAAAAXs/Oql0jp6rHS0/s1600-h/merge.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 214px; height: 400px;" src="http://4.bp.blogspot.com/_lU8mYvjtzEQ/SSB2Nq4v4ZI/AAAAAAAAAXs/Oql0jp6rHS0/s400/merge.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5269341541246165394" /&gt;&lt;/a&gt;&lt;br /&gt;Как видно, ничего сложного в этом алгоритме нет. Самое интересное в нем - это возможность использования для сортировки. Любой массив размера n можно представить в виде n массивов, состоящих из одного элемента. Пары соседних элементов, представленных ввиде массивов можно объединять по описанному выше алгоритму. Получится примерно в 2 раза (примерно, потому что n может быть как четным так и нечетным числом) меньше отсортированных массива по 2 элемента, которые в свою очередь тоже можно объединить. И так пока не получится один отсортированный массив.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_lU8mYvjtzEQ/SSCC6fpQLSI/AAAAAAAAAX0/RY3wyDjHOsI/s1600-h/merges.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 252px; height: 168px;" src="http://4.bp.blogspot.com/_lU8mYvjtzEQ/SSCC6fpQLSI/AAAAAAAAAX0/RY3wyDjHOsI/s400/merges.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5269355505462029602" /&gt;&lt;/a&gt; А все это называется &lt;a href=http://ru.wikipedia.org/wiki/%D0%A1%D0%BE%D1%80%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%BB%D0%B8%D1%8F%D0%BD%D0%B8%D0%B5%D0%BC&gt;сортировка слиянием&lt;/a&gt;.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/640162977889194353-9141940683484329128?l=sashkoblog.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Sash_ko/~4/oQ5KQ33mipw" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/Sash_ko/~3/oQ5KQ33mipw/blog-post_16.html</link><author>noreply@blogger.com (sash_ko)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_lU8mYvjtzEQ/SSB2Nq4v4ZI/AAAAAAAAAXs/Oql0jp6rHS0/s72-c/merge.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://sashkoblog.blogspot.com/2008/11/blog-post_16.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-640162977889194353.post-8567230397031169817</guid><pubDate>Sat, 15 Nov 2008 18:51:00 +0000</pubDate><atom:updated>2008-11-15T23:24:10.164+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">C++</category><title>Concepts в C++0x</title><description>Наконец то удалось посмотреть видео о новых расширениях С++ &lt;a href=http://deepencpp.blogspot.com/2008/11/concepts-extending-c-templates-for.html&gt;Concepts: Extending C++ Templates For Generic Programming&lt;/a&gt;. Решил поделиться своими впечатлениями.&lt;br /&gt;&lt;span id="fullpost"&gt;&lt;br /&gt;Concepts - это расширение существующих шаблонов С++, позволяющие устанавливать требования к параметрам шаблона. Концепция позволяет ответить на несколько вопросов: &lt;br /&gt;&lt;ul&gt;&lt;li&gt;чем должен быть параметр? &lt;br /&gt;&lt;li&gt;что он должен уметь делать? &lt;br /&gt;&lt;li&gt;как установить соответствие между параметром и тем, чем он должен являться?&lt;/ul&gt;&lt;br /&gt;В ролике это называлось Concept definitions, Where clauses и Concept maps соответственно. Насколько я понимаю, то, что было озвучено и то, что будет в стандарте немного отличается, по крайне мере вместо &lt;span style="font-weight:bold;"&gt;where&lt;/span&gt; будет использоваться &lt;span style="font-weight:bold;"&gt;requires&lt;/span&gt;, поэтому пример будет выглядеть не как в видео:&lt;br /&gt;&lt;pre class="prettyprint"&gt;// Вычисление суммы элементов последовательности&lt;br /&gt;&lt;br /&gt;// Параметр шаблона должен быть Forward Iterator - &lt;br /&gt;// позволяет двигаться только в перед&lt;br /&gt;template&lt; ForwardIterator Iter &gt;&lt;br /&gt;  // два значения, на которые указывают итераторы,&lt;br /&gt;  // могут быть сложены при помощи оператора +&lt;br /&gt;  requires Addable&lt; Iter::value_type &gt;, &lt;br /&gt;  // объект, на который указывает итератор,&lt;br /&gt;  // должен иметь оператор присваивания  &lt;br /&gt;     &amp;&amp; Assignable&lt; Iter::value_type &gt;&lt;br /&gt;  Iter::value_type sum(Iter first, Iter last, &lt;br /&gt;                        Iter::value_type result)&lt;br /&gt;  {&lt;br /&gt;    for (; first != last; ++first)&lt;br /&gt;      result = result + *first;&lt;br /&gt;    return result;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;// у типа double* нет оператора сложения, присваивания,&lt;br /&gt;// получения следующего элемента последовательности,&lt;br /&gt;// но реализация алгоритма sum будет корректно работать&lt;br /&gt;// с этим типом, поэтому устанавливается соответствие&lt;br /&gt;// между ForwardIterator и double*&lt;br /&gt;concept_map ForwardIterator&lt;double*&gt; {&lt;br /&gt;  typedef double value_type;&lt;br /&gt;};&lt;/pre&gt;&lt;br /&gt;Надеюсь, теперь понятно, зачем вводятся concepts, если нет, то подробней можно почитать здесь: &lt;a href=http://www.generic-programming.org/languages/conceptcpp/tutorial/&gt;ConceptC++ Tutorial&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;На видео, дядька приводит другой пример, знакомый всем, кто использовал STL: простой алгоритм поиска, реализованный в соответствие с требованиями STL, отлично работает с вектором, но не хочет работать со списком. Хотя внешне все вписывается в общую структуру библиотеки: контейнеры - итераторы - алгоритмы. Для того, что бы понять, что не так с алгоритмом нужно копаться в его коде либо использовать concepts. Начиная с этого места у меня появилось чувство, что &lt;span style="font-weight:bold;"&gt;concepts - это костыль&lt;/span&gt;, который подсовывают С++. Проблема как была, так и осталась, но теперь можно уверенно хромать в перед. Лечится только следствие проблемы - теперь компилятор будет сам говорить, что хотя все вписывается в рамки, но работать все равно не будет. При этом, &lt;span style="font-weight:bold;"&gt;возможность писать неработающий код так и остается&lt;/span&gt; - для совместимости с предыдущими версиями. &lt;br /&gt;&lt;br /&gt;Кроме того, и без того, часто трудночитаемый код с шаблонами, станет во много раз менее читабельным. А разработчику придется больше потеть, определяя жесткие требования к написанным функциям.&lt;br /&gt;&lt;br /&gt;Это первое впечатление, основанное на двухчасовом знакомстве с этим нововведением. Надо будет еще обдумать прочитанное и просмотренное, а то прям бесполезная какая-то штука получается :) Поэтому интересно было бы услышать критику моего обзора и мысли по поводу concepts.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/640162977889194353-8567230397031169817?l=sashkoblog.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Sash_ko/~4/4zTytNk_uh8" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/Sash_ko/~3/4zTytNk_uh8/concepts-c0x.html</link><author>noreply@blogger.com (sash_ko)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://sashkoblog.blogspot.com/2008/11/concepts-c0x.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-640162977889194353.post-5422741370827913143</guid><pubDate>Thu, 13 Nov 2008 19:33:00 +0000</pubDate><atom:updated>2008-11-13T21:50:37.622+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">задачки</category><title>Задачка про прилив</title><description>&lt;span style="font-style:italic;"&gt;Нашел в шкафу старую книгу "Математическая смекалка". Замечательная книга! Теперь по вечерам сижу с удовольствием решаю задачки - неплохая гимнастика для мозгов и хорошая альтернатива вечернему созерцанию интернета. Вот одна из задач, которая мне понравилась (кстати, ничем не хуже &lt;a href=http://sashkoblog.blogspot.com/2008/10/microsoft.html&gt;майкрософтовских&lt;/a&gt; :)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Недалеко от берега стоит корабль со спущенной на воду веревочной лестницей вдоль борта. У лестницы 10 ступенек; расстояние между ступеньками 30 см. Самая нижняя ступенька касается поверхности воды. Океан сегодня очень покоен, но начинается прилив, который поднимает воду за каждый час на 15 см. Через сколько времени покроется водой третья ступенька веревочной лесенки?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/640162977889194353-5422741370827913143?l=sashkoblog.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Sash_ko/~4/qZRUNJP-wZk" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/Sash_ko/~3/qZRUNJP-wZk/blog-post.html</link><author>noreply@blogger.com (sash_ko)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">12</thr:total><feedburner:origLink>http://sashkoblog.blogspot.com/2008/11/blog-post.html</feedburner:origLink></item></channel></rss>
