<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>ZetBlog&#187; общие вопросы</title>
	<atom:link href="http://zetblog.ru/category/programming/general/feed/" rel="self" type="application/rss+xml" />
	<link>http://zetblog.ru</link>
	<description>Зеты говорят. Блог о программировании, администрировании и безопасности.</description>
	<lastBuildDate>Sat, 29 Oct 2011 18:59:40 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Python: Маленькая хитрость. if-else vs and-or.</title>
		<link>http://zetblog.ru/programming/201003/python-if-else-vs-and-or/</link>
		<comments>http://zetblog.ru/programming/201003/python-if-else-vs-and-or/#comments</comments>
		<pubDate>Wed, 17 Mar 2010 19:30:57 +0000</pubDate>
		<dc:creator>lizz</dc:creator>
				<category><![CDATA[общие вопросы]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[hints]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://zetblog.ru/?p=980</guid>
		<description><![CDATA[На этот раз будет мини-заметка, уж слишком мне понравился трюк, о котором пойдёт речь дальше :). Наверное любому программисту приходится часто писать конструкции такого вида: if a == b: c = d else: c = e Как-то разбирая исходники какого-то проекта наткнулся на весьма компактную замену. Вот для сравнения два аналогичных блока кода с использованием [...]]]></description>
			<content:encoded><![CDATA[<p>На этот раз будет мини-заметка, уж слишком мне понравился трюк, о котором пойдёт речь дальше :). </p>
<p>Наверное любому программисту приходится часто писать конструкции такого вида:</p>
<pre class=".brush: python">if a == b:
    c = d
else:
    c = e</pre>
<p>Как-то разбирая исходники какого-то проекта наткнулся на весьма компактную замену. Вот для сравнения два аналогичных блока кода с использованием логических операций python&#8217;а и с использованием конструкции if-else:</p>
<pre class=".brush: python"># if-else:
if random.random() > 0.5:
    a = 1
else:
    a = 0

# and-or style:
a = random.random() > 0.5 and 1 or 0</pre>
<p>На мой взгляд выглядит гораздо лучше и компактнее (да-да, if-else можно записать в 2 строчки вместо 4, но мне так не нравится ^__^) . Другое дело, что некоторым это может показаться противоречиво с некоторыми пунктами дзена python&#8217;а (import this), но это спорно :). В общем использую там, где считаю нужным.</p>
<p>Кстати, если кого-то интересует производительность, то она примерно одинакова, далее выложу тесты и объяснение логики для тех, кому интересно.<br />
<span id="more-980"></span></p>
<pre class=".brush: python">>>> import timeit
>>> t1 = timeit.Timer('if random.random()>0.5:a=1\nelse:a =0', 'from __main__ import a\nimport random')
>>> t2 = timeit.Timer('a=random.random()>0.5 and 1 or 0', 'from __main__ import a\nimport random')
>>> t1.repeat()
[0.21074632467116317, 0.2097615509806019, 0.20978293771349854]
>>> t2.repeat()
[0.21944338095772764, 0.21785226684687586, 0.21940797240040411]
</pre>
<p>Тесты привёл, теперь объяснение.</p>
<p>Дело в том, что логические операции <strong>and</strong> и <strong>or</strong> в python&#8217;е возвращают один из операндов. Операция and возвращает первый операнд, если он приводится к логическому типу False, иначе &#8212; второй. Операция or наоборот, возвращает 1й операнд, если он приводится к типу True, иначе &#8212; второй. Всё это связано с &#171;ленивостью&#187; (lazy) операций, вычисляется столько аргументов, сколько надо для того, чтобы однозначно определить результат (например, 1 or x всегда даёт True, поэтому x не вычисляется).</p>
]]></content:encoded>
			<wfw:commentRss>http://zetblog.ru/programming/201003/python-if-else-vs-and-or/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Python: Проблема с подвисанием GUI на TkInter.</title>
		<link>http://zetblog.ru/programming/200910/python-tkinter-antifreeze/</link>
		<comments>http://zetblog.ru/programming/200910/python-tkinter-antifreeze/#comments</comments>
		<pubDate>Wed, 21 Oct 2009 18:57:03 +0000</pubDate>
		<dc:creator>lizz</dc:creator>
				<category><![CDATA[общие вопросы]]></category>
		<category><![CDATA[прикладное]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[GUI]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[TkInter]]></category>

		<guid isPermaLink="false">http://zetblog.ru/?p=731</guid>
		<description><![CDATA[Встала задача написания небольшой графической оболочки для программы с минимальным интерфейсом (одна кнопка и одно поле вывода). Много нам не надо, поэтому решил обойтись идущей вместе с python&#8217;ом в поставке библиотекой TkInter. И тут столкнулся с небольшой проблемой &#8212; при нажатии кнопки запускаются довольно долгие и объёмные вычисления, из-за которых виснет весь интерфейс программы. Решений [...]]]></description>
			<content:encoded><![CDATA[<p>Встала задача написания небольшой графической оболочки для программы с минимальным интерфейсом (одна кнопка и одно поле вывода). Много нам не надо, поэтому решил обойтись идущей вместе с python&#8217;ом в поставке библиотекой TkInter. И тут столкнулся с небольшой проблемой &#8212; при нажатии кнопки запускаются довольно долгие и объёмные вычисления, из-за которых виснет весь интерфейс программы.<br />
<span id="more-731"></span></p>
<p>Решений у этого вопроса несколько.<br />
1 &#8212; Запускать эти вычисления в отдельном потоке, что меня вполне устроило:</p>
<pre>
<div class="codesnip-container" >
<div class="python codesnip" style="font-family:monospace;"><span class="co1"># -*- coding: utf-8 -*-</span>
<span class="kw1">from</span> <span class="kw3">Tkinter</span> <span class="kw1">import</span> <span class="sy0">*</span>
<span class="kw1">import</span> <span class="kw3">threading</span>, <span class="kw3">time</span>

<span class="kw1">class</span> AppGUI:
&nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">tk</span> = Tk<span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; frame = Frame<span class="br0">&#40;</span><span class="kw2">self</span>.<span class="me1">tk</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; frame.<span class="me1">pack</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; Button<span class="br0">&#40;</span>frame, text=<span class="st0">&quot;Compute&quot;</span>, command=<span class="kw2">self</span>.<span class="me1">computeWithGUIAntifreeze</span><span class="br0">&#41;</span>.<span class="me1">pack</span><span class="br0">&#40;</span><span class="br0">&#41;</span>

&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">def</span> run<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">tk</span>.<span class="me1">mainloop</span><span class="br0">&#40;</span><span class="br0">&#41;</span>

&nbsp; &nbsp; <span class="kw1">def</span> computeWithGUIAntifreeze<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;&quot; Метод-прокладка для запуска в новом потоке вычислений &quot;&quot;&quot;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">threading</span>.<span class="me1">Thread</span><span class="br0">&#40;</span>target=<span class="kw2">self</span>.<span class="me1">compute</span><span class="br0">&#41;</span>.<span class="me1">start</span><span class="br0">&#40;</span><span class="br0">&#41;</span>

&nbsp; &nbsp; <span class="kw1">def</span> compute<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;&quot;&quot; Тут как раз и происходят длительные вычисления &quot;&quot;&quot;</span><span class="st0">&quot;
&nbsp; &nbsp; &nbsp; &nbsp; time.sleep(15)

gui = AppGUI()
gui.run()</span></div>
</div>
</pre>
<p>2 &#8212; Использовать время от времени методы:</p>
<ul>
<li><strong>Tk.update()</strong>;</li>
<li><strong>Tk.update_idletasks()</strong> &#8212; только обновляет окна, но не вызывает обработку событий, сгенерированных пользователем, в отличие от Tk.update();</li>
</ul>
<p>Использовать эти методы стоит с осторожностью, дабы не возникло неприятных ситуаций (подробнее в документации). Таково предостережение официальной документации.</p>
<p>Ссылки к посту:<br />
<a href="http://www.tcl.tk/man/tcl8.5/TclCmd/update.htm">http://www.tcl.tk/man/tcl8.5/TclCmd/update.htm</a> &#8212; официальная документация по Tcl/Tk.</p>
]]></content:encoded>
			<wfw:commentRss>http://zetblog.ru/programming/200910/python-tkinter-antifreeze/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Python: Аналог интерактивного режима у себя в программе.</title>
		<link>http://zetblog.ru/programming/200903/%d0%b0%d0%bd%d0%b0%d0%bb%d0%be%d0%b3-%d0%b8%d0%bd%d1%82%d0%b5%d1%80%d0%b0%d0%ba%d1%82%d0%b8%d0%b2%d0%bd%d0%be%d0%b3%d0%be-%d1%80%d0%b5%d0%b6%d0%b8%d0%bc%d0%b0/</link>
		<comments>http://zetblog.ru/programming/200903/%d0%b0%d0%bd%d0%b0%d0%bb%d0%be%d0%b3-%d0%b8%d0%bd%d1%82%d0%b5%d1%80%d0%b0%d0%ba%d1%82%d0%b8%d0%b2%d0%bd%d0%be%d0%b3%d0%be-%d1%80%d0%b5%d0%b6%d0%b8%d0%bc%d0%b0/#comments</comments>
		<pubDate>Fri, 13 Mar 2009 17:01:19 +0000</pubDate>
		<dc:creator>lizz</dc:creator>
				<category><![CDATA[общие вопросы]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://zetblog.ru/?p=616</guid>
		<description><![CDATA[Как-то лень было писать для задачки интерфейс, а в универе требовали, и тут в мою голову пришла мысль, что не плохо было бы иметь что-то вроде аналога интерактивного режима интерпретатора python&#8217;а (лицезреть который Вы можете выполнив команду python или нажав в виндовской IDLE F5). Решение оказалось в одну строчку :). Есть в python&#8217;е (да и [...]]]></description>
			<content:encoded><![CDATA[<p>Как-то лень было писать для задачки интерфейс, а в универе требовали, и тут в мою голову пришла мысль, что не плохо было бы иметь что-то вроде аналога интерактивного режима интерпретатора python&#8217;а (лицезреть который Вы можете выполнив команду python или нажав в виндовской IDLE F5).<br />
<span id="more-616"></span></p>
<p>Решение оказалось в одну строчку :). Есть в python&#8217;е (да и не только в нём) такая функция с неприличным именем, как <strong>eval</strong>. Она пытается преобразовать полученное в качестве параметра выражение в некий результат. Например:</p>
<div class="codesnip-container" >&gt;&gt;&gt; eval(&#171;2 + 2&#8243;)<br />
4<br />
&gt;&gt;&gt; a = 4<br />
&gt;&gt;&gt; eval(&#171;a ** a&#187;)<br />
256</div>
<p>Как вы уже наверное догадались, при наличии такой функции задача сводится к тривиальной. В моей задачке был объект db, методы которого и надо было вызывать для демонстрации функций программы. Вот два варианта их вызова:</p>
<div class="codesnip-container" >
<div class="python codesnip" style="font-family:monospace;"><span class="kw1">while</span> <span class="kw2">True</span>:<br />
<span class="kw2">input</span><span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</div>
<p>При исполнении программы вводим &#171;db.method1(params)&#187;. Функция <strong>input([prompt])</strong> эквивалентна вызову <strong>eval(raw_input([prompt]))</strong>. Чтобы не писать каждый раз &#171;db.&#187;, можно упростить ввод пользователя:</p>
<div class="codesnip-container" >
<div class="python codesnip" style="font-family:monospace;"><span class="kw1">while</span> <span class="kw2">True</span>:<br />
<span class="kw2">eval</span><span class="br0">&#40;</span><span class="st0">&quot;db.&quot;</span> + <span class="kw2">raw_input</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span></div>
</div>
<p>Теперь достаточно писать просто &#171;method1(params)&#187;.</p>
<p>Так же у функции eval есть ещё 2 необязательных параметра <strong>eval(expression[, globals[, locals]])</strong>, через них можно передавать устанавливать значения глобальных и локальных переменных. Официальная документация находится <a href="http://docs.python.org/library/functions.html#eval">тут</a>.</p>
<p>На этом закончим. Конечно, данный вариант не подойдёт для конечного пользователя, т.к. любой пользовательский ввод следует проверять на корректность, но для демонстрации программы в универе вполне сойдёт.</p>
]]></content:encoded>
			<wfw:commentRss>http://zetblog.ru/programming/200903/%d0%b0%d0%bd%d0%b0%d0%bb%d0%be%d0%b3-%d0%b8%d0%bd%d1%82%d0%b5%d1%80%d0%b0%d0%ba%d1%82%d0%b8%d0%b2%d0%bd%d0%be%d0%b3%d0%be-%d1%80%d0%b5%d0%b6%d0%b8%d0%bc%d0%b0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Python: Импорт структур C++ с помощью SWIG.</title>
		<link>http://zetblog.ru/programming/200901/python-%d0%b8%d0%bc%d0%bf%d0%be%d1%80%d1%82-%d1%81%d1%82%d1%80%d1%83%d0%ba%d1%82%d1%83%d1%80-c-%d1%81-%d0%bf%d0%be%d0%bc%d0%be%d1%89%d1%8c%d1%8e-swig/</link>
		<comments>http://zetblog.ru/programming/200901/python-%d0%b8%d0%bc%d0%bf%d0%be%d1%80%d1%82-%d1%81%d1%82%d1%80%d1%83%d0%ba%d1%82%d1%83%d1%80-c-%d1%81-%d0%bf%d0%be%d0%bc%d0%be%d1%89%d1%8c%d1%8e-swig/#comments</comments>
		<pubDate>Thu, 22 Jan 2009 17:35:07 +0000</pubDate>
		<dc:creator>lizz</dc:creator>
				<category><![CDATA[общие вопросы]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[C/C++]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[SWIG]]></category>

		<guid isPermaLink="false">http://zetblog.ru/?p=458</guid>
		<description><![CDATA[Начнём с того, что такое SWIG. Итак, это мега-штука, которая предоставляет интерфейс скриптовым языкам (PHP, Python, Tcl, etc) к коду на C/C++. На официальном сайте есть несколько туториалов, которые вкратце показывают как можно применить SWIG для того или инного языка и python в их числе. Вроде при попытке повторить действия никаких ошибок не происходит, однако [...]]]></description>
			<content:encoded><![CDATA[<p>Начнём с того, что такое SWIG. Итак, это мега-штука, которая предоставляет интерфейс скриптовым языкам (PHP, Python, Tcl, etc) к коду на C/C++. На официальном сайте есть несколько туториалов, которые вкратце показывают как можно применить SWIG для того или инного языка и python в их числе. Вроде при попытке повторить действия никаких ошибок не происходит, однако почему-то никак не получалось получить доступ к описанной в C++ структуре и объявленой там же переменной.</p>
<p>Итак, данный пост содержит немного подправленые инструкции из туториала с официального сайта SWIG для python.<br />
<span id="more-458"></span></p>
<p>Файл example.cxx:</p>
<pre>
<div class="codesnip-container" >
<div class="cpp codesnip" style="font-family:monospace;"><span class="coMULTI">/* File : example.cxx */</span>
<span class="kw4">int</span> add<span class="br0">&#40;</span><span class="kw4">int</span> a, <span class="kw4">int</span> b<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="kw1">return</span> a <span class="sy2">+</span> b<span class="sy4">;</span>
<span class="br0">&#125;</span></div>
</div>
</pre>
<p>Файл example.i (файл swig&#8217;а, по которому строится интерфейс):</p>
<pre>
<div class="codesnip-container" >/* example.i */
%module example
%{
/* Put header files here or function declarations like below */
#define SWIG_FILE_WITH_INIT
int add(int a, int b);
struct V {
    double x,y,z;
};
int t = 5;
%}

int t = 5;
struct V {
    double x,y,z;
};
int add(int a, int b) {
    return a + b;
}</div>
</pre>
<p>Корявенько, но тем не менее, почему то другие комбинации не работали. Теперь посмотрим как это всё прикрутить к самом python&#8217;у:</p>
<div class="codesnip-container" >swig -c++ -python example.i &#038;&#038; \<br />
g++ -fPIC -c example.cxx &#038;&#038; \<br />
g++ -fPIC -c example_wrap.cxx -I/usr/local/include/python2.5 &#038;&#038; \<br />
g++ -shared example.o example_wrap.o -o _example.so</div>
<p>После выполнения всех действием проверяем что получили:</p>
<pre>
<div class="codesnip-container" >
<div class="python codesnip" style="font-family:monospace;"><span class="sy0">&gt;&gt;&gt;</span> <span class="kw1">import</span> example
<span class="sy0">&gt;&gt;&gt;</span> <span class="kw2">dir</span><span class="br0">&#40;</span>example<span class="br0">&#41;</span>
<span class="br0">&#91;</span><span class="st0">'V'</span>, <span class="st0">'V_swigregister'</span>, <span class="st0">'__builtins__'</span>, <span class="st0">'__doc__'</span>, <span class="st0">'__file__'</span>, <span class="st0">'__name__'</span>, <span class="st0">'_example'</span>, <span class="st0">'_newclass'</span>, <span class="st0">'_object'</span>, <span class="st0">'_swig_getattr'</span>, <span class="st0">'_swig_property'</span>, <span class="st0">'_swig_repr'</span>, <span class="st0">'_swig_setattr'</span>, <span class="st0">'_swig_setattr_nondynamic'</span>, <span class="st0">'add'</span>, <span class="st0">'cvar'</span><span class="br0">&#93;</span>
<span class="sy0">&gt;&gt;&gt;</span> example.<span class="me1">cvar</span>.<span class="me1">t</span>
5
<span class="sy0">&gt;&gt;&gt;</span> a = example.<span class="me1">V</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="sy0">&gt;&gt;&gt;</span> a.<span class="me1">x</span> = 10.123
<span class="sy0">&gt;&gt;&gt;</span> a.<span class="me1">x</span>
10.122999999999999
<span class="sy0">&gt;&gt;&gt;</span> a.<span class="me1">x</span> = 10.12
<span class="sy0">&gt;&gt;&gt;</span> a.<span class="me1">x</span>
10.119999999999999
<span class="sy0">&gt;&gt;&gt;</span> a.<span class="me1">x</span> = 10.1
<span class="sy0">&gt;&gt;&gt;</span> a.<span class="me1">x</span>
10.1
<span class="sy0">&gt;&gt;&gt;</span> a.<span class="me1">y</span>
0.0
<span class="sy0">&gt;&gt;&gt;</span> a
<span class="sy0">&lt;</span>example.<span class="me1">V</span><span class="sy0">;</span> proxy of <span class="sy0">&lt;</span>Swig Object of <span class="kw2">type</span> <span class="st0">'V *'</span> at 0x28427c60<span class="sy0">&gt;</span> <span class="sy0">&gt;</span>
<span class="sy0">&gt;&gt;&gt;</span> example.<span class="me1">add</span><span class="br0">&#40;</span><span class="nu0">1</span>, <span class="nu0">6</span><span class="br0">&#41;</span>
<span class="nu0">7</span>
<span class="sy0">&gt;&gt;&gt;</span> example.<span class="me1">add</span><span class="br0">&#40;</span><span class="nu0">1</span>, <span class="nu0">6.5</span><span class="br0">&#41;</span>
Traceback <span class="br0">&#40;</span>most recent call last<span class="br0">&#41;</span>:
&nbsp; File <span class="st0">&quot;&lt;stdin&gt;&quot;</span>, line 1, <span class="kw1">in</span> <span class="sy0">&lt;</span>module<span class="sy0">&gt;</span>
<span class="kw2">TypeError</span>: <span class="kw1">in</span> method <span class="st0">'add'</span>, argument 2 of <span class="kw2">type</span> <span class="st0">'int'</span>
<span class="sy0">&gt;&gt;&gt;</span></div>
</div>
</pre>
<p>Видно, что не всё гладко с типом double, но, тем не менее, оно работает и этого было достаточно для меня в своё время ;).</p>
<p>Ссылки к статье:<br />
<a href="http://www.swig.org">http://www.swig.org</a> &#8212; официальный сайт SWIG.<br />
<a href="http://ru.wikipedia.org/wiki/SWIG">http://ru.wikipedia.org/wiki/SWIG</a> &#8212; статья на википедии о SWIG.</p>
]]></content:encoded>
			<wfw:commentRss>http://zetblog.ru/programming/200901/python-%d0%b8%d0%bc%d0%bf%d0%be%d1%80%d1%82-%d1%81%d1%82%d1%80%d1%83%d0%ba%d1%82%d1%83%d1%80-c-%d1%81-%d0%bf%d0%be%d0%bc%d0%be%d1%89%d1%8c%d1%8e-swig/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

