<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Иван Дианов</title>
    <description></description>
    <link>http://dianov.org/</link>
    <atom:link href="http://dianov.org/feed.xml" rel="self" type="application/rss+xml" />
    <pubDate>Wed, 12 Jun 2024 11:58:08 +0000</pubDate>
    <lastBuildDate>Wed, 12 Jun 2024 11:58:08 +0000</lastBuildDate>
    <generator>Jekyll v3.9.5</generator>
    
      <item>
        <title>Самообновляющиеся  нейростикеры</title>
        <description>&lt;p&gt;&lt;a href=&quot;https://t.me/addstickers/neuroji_by_neuroji_bot&quot;&gt;Ссылка на телеграмовский стикерпак&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Когда я увидел, что сделали в &lt;a href=&quot;https://process.studio/works/aimoji-ai-generated-emoji/&quot;&gt;process.studio&lt;/a&gt;, я сразу понял, что невозможно из этого не сделать стикерпак для телеграма. Вопрос лишь в том, кто успеет первым. А тут ещё в студии Лебедева вышел самообновляющийся генеративный стикерпак &lt;a href=&quot;https://www.artlebedev.ru/stickers/stickerator/&quot;&gt;Стикератор&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Стикеры получились не очень детализированные, пиксельные, но душевные.&lt;/p&gt;

&lt;p&gt;Злые:
&lt;img src=&quot;/media/neuroji-evilous.png&quot; alt=&quot;Злые&quot; class=&quot;transparent&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Приунывшие:
&lt;img src=&quot;/media/neuroji-sad.png&quot; alt=&quot;Приунывшие&quot; class=&quot;transparent&quot; /&gt;&lt;/p&gt;

&lt;p&gt;В шоке:
&lt;img src=&quot;/media/neuroji-shocked.png&quot; alt=&quot;В шоке&quot; class=&quot;transparent&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Счастливые, насколько это возможно:
&lt;img src=&quot;/media/neuroji-happy.png&quot; alt=&quot;Счастливые, насколько это возможно&quot; class=&quot;transparent&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Опыта с нейросетями у меня никакого не было, поэтому мне помогал Саша Мохов, за что ему большое спасибо. Он помог выбрать инструмент и помогал советом в тупиковых ситуациях.&lt;/p&gt;

&lt;p&gt;Картинки для обучения сети скачал с &lt;a href=&quot;https://emojipedia.org/people/&quot;&gt;Эмоджипедии&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;lxml.html&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;lxml.cssselect&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CSSSelector&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;css&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;requests&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;urllib.request&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;urlretrieve&lt;/span&gt;


&lt;span class=&quot;n&quot;&gt;response&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;requests&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'https://emojipedia.org/people/'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;tree&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lxml&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;html&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fromstring&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;links&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;css&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'.emoji-list&amp;gt;li&amp;gt;a'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tree&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;l&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;links&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;l&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'href'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'serious-face-with-symbols-covering-mouth/'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# stops downloading on specific emoji
&lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;requests&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'https://emojipedia.org/people/'&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;tree2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lxml&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;html&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fromstring&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;imgs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;css&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'.vendor-image&amp;gt;img'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tree2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;imgs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;img_url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'src'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;img_url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'/'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'.'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'_'&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'.'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'       - '&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;img_url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;urlretrieve&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;img_url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'/Users/z/Downloads/Neuroji_images/'&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Сеть обучил &lt;a href=&quot;https://colab.research.google.com/drive/12B4BpvVH_Wo20xLWpDW5jADhYHDEuEIY#scrollTo=VBa6Ggebt5BR&quot;&gt;на бесплатном Google colab&lt;/a&gt;. Это офигенный сервис, можно запускать тяжёлые вычисления на серверах гугла и не греть свой ноутбук. Да и быстрее выходит. Результат обучения сохранил как два файла: структура нейросети и веса её связей.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;model_17500.h5
model_17500.json
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Модель делается долго, но её нужно сделать всего один раз, после этого для получения смайликов нужно совсем немножко ресурсов.&lt;/p&gt;

&lt;p&gt;Смайлики генерятся другим питоновским скриптом. Он при запуске загружает модель нейросети, потом по таймеру создаёт стикеры и заливает их в пак с помощью либы python-telegram-bot:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;matplotlib&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inline&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;telegram&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;telegram.ext&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Updater&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CommandHandler&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;PIL&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ImageDraw&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;random&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;randrange&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;io&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;BytesIO&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;matplotlib.pyplot&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;plt&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;numpy&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;keras.layers&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Dense&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Flatten&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Reshape&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;keras.layers.advanced_activations&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LeakyReLU&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;keras.models&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Sequential&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;keras.optimizers&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Adam&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;keras.models&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model_from_json&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;time&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;sample_images&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;global&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bot&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;global&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Hello, World!&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;n&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;normal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;z_dim&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;gen_imgs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;predict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'Generated {} images'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;gen_imgs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.5&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gen_imgs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.5&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;clear&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;im_ar&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gen_imgs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:])&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;256.&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;pil_im&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fromarray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;im_ar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;astype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'uint8'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'RGBA'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;pil_im&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pil_im&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;resize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;512&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;512&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NEAREST&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;bio&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;BytesIO&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;bio&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'image.png'&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;pil_im&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bio&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'PNG'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;bio&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seek&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;bot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_sticker_to_set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user_id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;115178271&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                               &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'neuroji_by_neuroji_bot'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                               &lt;span class=&quot;n&quot;&gt;png_sticker&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bio&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                               &lt;span class=&quot;n&quot;&gt;emojis&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'😶'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;bot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;send_message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chat_id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'@zbottesting'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'{} neurojis added!'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;clear&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;global&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bot&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;stickers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_sticker_set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'neuroji_by_neuroji_bot'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stickers&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stickers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;bot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;delete_sticker_from_set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;z_dim&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# Size of the noise vector, used as input to the Generator
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;number&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;80&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# load json and create model
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;json_file&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'model_17500.json'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'r'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;model_json&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;json_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;json_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model_from_json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model_json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;load_weights&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;model_17500.h5&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Loaded model from disk&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;bot&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;telegram&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Bot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'851927713:Aa0hGqlACKcGD-deGbTX5BPYdfv3biNywRE'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;#FIXME paste your token here
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;updater&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Updater&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bot&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;use_context&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;updater&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;job_queue&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;updater&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dispatcher&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_handler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CommandHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'clear'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;clear&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;recurring_job&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;sample_images&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# catch *all* exceptions
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exc_info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;bot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;send_message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chat_id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'@zbottesting'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'{}'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sleep&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;recurring_job&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    
&lt;span class=&quot;n&quot;&gt;recurring_job&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Рядом должны лежать файлы обученной модели:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;model_17500.h5
model_17500.json
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Этот код крутится на самом дешёвом сервере DigitalOcean. Причём я смешно запускаю: не просто питоновский файл, а целый jupyter notebook, на котором уже питоновский скрипт работает. Не уверен, что кроме меня так кто-то делает, но мне удобно, я к юпитеру привык.&lt;/p&gt;

&lt;p&gt;Запускаю код так. Сперва подключаюсь к серверу по SSH:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;ssh -L 8080:localhost:8080 root@64.225.28.54
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Запускаю на удалённом сервере Jupyter notebook. Чтобы он продолжал работать после закрытия терминала, надо запускать его хитро:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;nohup jupyter nonohup jupyter notebook --allow-root --port 8080 &amp;amp;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;После чего ноутбук волшебным образом отрывается на &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;localhost:8080&lt;/code&gt;, можно запускать в нём код на выполнение, закрывать вкладку браузера и терминал, и заниматься другими делами.&lt;/p&gt;

&lt;h2&gt;&lt;br /&gt;&lt;/h2&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://t.me/addstickers/neuroji_by_neuroji_bot&quot;&gt;Ссылка на телеграмовский стикерпак&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Клёво было бы сделать естественный отбор, чтобы самые популярные выживали. Но, кажется, АПИ телеграма не отдаёт статистику об отдельных стикерах.&lt;/p&gt;

&lt;p&gt;UPD: Время от времени вылезали ошибки и приходилось перезапускать скрипт в юпитере. Поэтому переделал по-нормальному: теперь слегка переделанный скрипт запускается по крону. Для этого открыл редактор &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;crontab -e&lt;/code&gt; и добавил строчку&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*/5 * * * * /usr/bin/python3 /root/cron-neuroji.py&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Выбрать нужный интервал запуска можно на &lt;a href=&quot;https://crontab.guru/&quot;&gt;crontab.guru&lt;/a&gt;&lt;/p&gt;

</description>
        <pubDate>Sun, 01 Mar 2020 00:00:00 +0000</pubDate>
        <link>http://dianov.org/neuroji/</link>
        <guid isPermaLink="true">http://dianov.org/neuroji/</guid>
        
        
      </item>
    
      <item>
        <title>Как сделать из своего имени  поплавок</title>
        <description>&lt;video width=&quot;1441&quot; style=&quot;max-width: 100%;&quot; loop=&quot;&quot; autoplay=&quot;&quot;&gt;&lt;source src=&quot;/media/floattery.mp4&quot; type=&quot;video/mp4&quot; /&gt;&lt;/video&gt;

&lt;p&gt;&lt;a href=&quot;https://intuition.team/park&quot;&gt;В Парке Интуиции&lt;/a&gt; мы с ребятами сделали маленький клёвый проект. Не спрашивайте, зачем он этому миру. Давайте считать, что это не сервис, а искусство.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://floats.dianov.org/&quot;&gt;floats.dianov.org&lt;/a&gt;&lt;/p&gt;

&lt;p class=&quot;quote&quot;&gt;Флотерея берёт любое имя и — шмяк! Делает из него поплавок. Наконец-то вы сможете больше узнать о себе и своих друзьях&lt;/p&gt;

&lt;p&gt;Женя Арутюнов предложил написать про его устройство:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Сколько там переменных, как они связаны, как влияют на форму. Что такое грамматика, какая она. Как из текста получается набор переменных.
Как устроены все интеграции, как был устроен процесс совместной разработки.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;вкратце&quot;&gt;Вкратце&lt;/h2&gt;

&lt;p&gt;Поплавки собираются из заранее нарисованных секций. Не как попало, а в соответствии с правилами, описанными порождающей грамматикой. Она определяет разные варианты поплавков: какие в них типы секций, и в каком порядке они идут.&lt;/p&gt;

&lt;p&gt;Последовательность получается рандомной, но эта рандомность зависит от содержимого текстового поля. Одинаковые значения будут рисовать одинаковые поплавки.&lt;/p&gt;

&lt;h2 id=&quot;входной-свг-файл&quot;&gt;Входной СВГ файл&lt;/h2&gt;

&lt;p&gt;Поплавок собирается из секций, которые скрипт берёт из такого СВГ файла:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/floattery-figma.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p class=&quot;caption&quot;&gt;Все секции сдвинуты в верхний левый угол&lt;/p&gt;

&lt;p&gt;Каждая секция лежит в своей группе.&lt;/p&gt;

&lt;p&gt;Имена групп в формате &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;p-16-32-100&lt;/code&gt;. Первая цифра означает высоту. Вторая — диаметр верхнего стыка. Третья — нижнего. &lt;!--Спойлер: высота игнорируется грамматикой, нужна только для рисования поплавка.--&gt;&lt;/p&gt;

&lt;h2 id=&quot;порождающая-грамматика&quot;&gt;Порождающая грамматика&lt;/h2&gt;

&lt;p&gt;Это такая штука, которая может по заданным &lt;em&gt;правилам&lt;/em&gt; создавать составлять последовательности слов. Вообще, грамматики нужны для генерации текстов, например, описаний монстров и титулов в играх. Но её можно использовать и не по прямому назначению. Например, &lt;a href=&quot;https://www.leonrische.me/pages/generative_art_with_cfgs.html&quot;&gt;ими генерят фракталы&lt;/a&gt; и &lt;a href=&quot;https://twitter.com/tinyadv&quot;&gt;космические корабли в СВГ&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Почему бы не использовать её для рисования поплавков? Каждая секция — как бы слово. И эти «слова» надо расставить в таком порядке, чтобы вышло грамматически правильное предложение — поплавок.&lt;/p&gt;

&lt;p&gt;Для работы с грамматикой я выбрал библиотеку &lt;a href=&quot;https://rednoise.org/rita/reference/index.php&quot;&gt;RiTa&lt;/a&gt;. Она понимает формат YAML.&lt;/p&gt;

&lt;p&gt;Ниже покажу пример грамматики и расскажу, как она собирает поплавки из секций.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;lt;start&amp;gt;:
- &amp;lt;type1&amp;gt;
- &amp;lt;type2&amp;gt;
- &amp;lt;type3&amp;gt;
- &amp;lt;type4&amp;gt;

&amp;lt;type1&amp;gt;:
- &amp;lt;0_8&amp;gt; &amp;lt;8_8&amp;gt; &amp;lt;8_8&amp;gt; &amp;lt;8_32&amp;gt; &amp;lt;water&amp;gt; &amp;lt;32_32&amp;gt; &amp;lt;32_8&amp;gt; &amp;lt;8_0&amp;gt;

&amp;lt;type2&amp;gt;:
- &amp;lt;0_8&amp;gt; &amp;lt;8_8&amp;gt; &amp;lt;8_8&amp;gt; &amp;lt;8_64&amp;gt; &amp;lt;water&amp;gt; &amp;lt;64_64&amp;gt; &amp;lt;64_8&amp;gt; &amp;lt;8_0&amp;gt;

&amp;lt;type3&amp;gt;:
- &amp;lt;0_8&amp;gt; &amp;lt;8_8&amp;gt; &amp;lt;8_8&amp;gt; &amp;lt;8_128&amp;gt; &amp;lt;water&amp;gt; &amp;lt;128_128&amp;gt; &amp;lt;128_8&amp;gt; &amp;lt;8_0&amp;gt;

&amp;lt;type4&amp;gt;:
- &amp;lt;dragonfly&amp;gt; &amp;lt;0_32&amp;gt; &amp;lt;water&amp;gt; &amp;lt;32_128&amp;gt; &amp;lt;128_8&amp;gt; &amp;lt;8_0&amp;gt;

&amp;lt;water&amp;gt;:
- &amp;lt;0_0&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p class=&quot;caption&quot;&gt;Сокращённый, но по-прежнему рабочий пример поплавковой грамматики&lt;/p&gt;

&lt;p&gt;В треугольных скобках &lt;em&gt;токены&lt;/em&gt; — это такие штуки, которые могут превращаться в другие штуки. В примере ниже есть шесть секций, и в каждой из них говорится, чем тот или иной токен может стать. Если вариантов превращения несколько, они записываются один под другим.&lt;/p&gt;

&lt;p&gt;В начале генерации есть единственный токен &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;start&amp;gt;&lt;/code&gt;, потом он в соответствии с правилами грамматики превращается в другие токены. Например, первое правило означает, что &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;start&amp;gt;&lt;/code&gt; может с равной вероятностью стать &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;type1&amp;gt;&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;type2&amp;gt;&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;type3&amp;gt;&lt;/code&gt; или в &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;type4&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Допустим, мы получили из него токен &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;type1&amp;gt;&lt;/code&gt;. Посмотрим, во что может превратиться он:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;lt;type1&amp;gt;:
- &amp;lt;0_8&amp;gt; &amp;lt;8_8&amp;gt; &amp;lt;8_8&amp;gt; &amp;lt;8_32&amp;gt; &amp;lt;water&amp;gt; &amp;lt;32_32&amp;gt; &amp;lt;32_8&amp;gt; &amp;lt;8_0&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Тут только один вариант. Зато какой длинный! Из токена неминуемо получается целая цепочка других токенов. Причём &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;water&amp;gt;&lt;/code&gt; в свою очередь неминуемо превратится в &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;0_0&amp;gt;&lt;/code&gt;. Потому что такое правило в грамматике тоже есть. И тогда последовательность токенов станет такой:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;lt;0_8&amp;gt; &amp;lt;8_8&amp;gt; &amp;lt;8_8&amp;gt; &amp;lt;8_32&amp;gt; &amp;lt;0_0&amp;gt; &amp;lt;32_32&amp;gt; &amp;lt;32_8&amp;gt; &amp;lt;8_0&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Кажется, полученная последовательность токенов ни во что уже превратиться не может. Ведь в грамматике нет правил для превращения, скажем, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;0_8&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Но превращения ещё не закончены. Фокус в том, что некоторые правила грамматики создаются скриптом в зависимости от того, какие секции поплавков нашлись во входном СВГ файле.&lt;/p&gt;

&lt;p&gt;Происходит этот так. Мы берём из входного СВГ все секции и запоминаем их в массиве. У каждого сегмента в массиве есть свой &lt;em&gt;индекс&lt;/em&gt;, по которому его можно этот сегмент узнать и нарисовать на экране.&lt;/p&gt;

&lt;p&gt;Для каждого сегмента мы добавляем в грамматику правило. Например, в массиве есть сегмент &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;p-8-8-100&lt;/code&gt; с индексом &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2&lt;/code&gt;. Вспомним, что в названии секции первая цифра означает высоту, а последние две — верхний и нижний диаметры секций поплавка. &lt;!--Например у `&lt;8_32&gt;` верхний край тонюсенький, а нижний — пошире. А нулевой диаметр в `&lt;8_0&gt;` означает, что это самый нижний кусок и ниже уже ничего стоять не может.--&gt;&lt;/p&gt;

&lt;p&gt;При его обработке в грамматику добавится правило:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;lt;8_8&amp;gt;
- 2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p class=&quot;caption&quot;&gt;То есть, секция поплавка с верхним радиусом 8 и нижним радиусом 8 может превратиться в секцию номер 2 из массива секций&lt;/p&gt;

&lt;p&gt;Допустим, обработав все секции поплавков из входного СВГ, мы добавили такие правила:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;lt;0_8&amp;gt;
- 0
- 1

&amp;lt;8_8&amp;gt;
- 2
- 3

&amp;lt;8_32&amp;gt;
- 4

&amp;lt;0_0&amp;gt;
- 5

&amp;lt;32_32&amp;gt;
- 6

&amp;lt;32_8&amp;gt;
- 7

&amp;lt;8_0&amp;gt;
- 8
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Тогда наша строка&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;lt;0_8&amp;gt; &amp;lt;8_8&amp;gt; &amp;lt;8_8&amp;gt; &amp;lt;8_32&amp;gt; &amp;lt;0_0&amp;gt; &amp;lt;32_32&amp;gt; &amp;lt;32_8&amp;gt; &amp;lt;8_0&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;может превратиться в&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  1     3     2     4      9      6       7     8
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Поскольку некоторые токены, например &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;0_8&amp;gt;&lt;/code&gt;, имеют несколько вариантов превращения, итоговая последовательность может выйти немного другой.&lt;/p&gt;

&lt;p&gt;Поздравляю! Мы получили последовательность индексов секций. Теперь остаётся вытащить секции с такими индексами из массива и нарисовать их одну под другой. И поплавок готов!&lt;/p&gt;

&lt;!--Ещё часть грамматики генерируется скриптом автоматически.
Грамматика выбирает один из вариантов с одинаковой вероятностью.--&gt;

&lt;h2 id=&quot;делаем-из-имени-поплавок&quot;&gt;Делаем из имени поплавок&lt;/h2&gt;

&lt;p&gt;Когда в грамматике есть несколько вариантов превращений, один из них выбирается рандомно. Это обеспечивает многообразие возможных форм. Однако, чтобы одинаковые значения в текстовом поле создавали одинаковые поплавки, нам надо сделать эту рандомность зависимой от значения текстового поля. Библиотека RiTa может сделать рандомность предсказуемой:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;RiTa.randomSeed(pseudoRandom);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p class=&quot;caption&quot;&gt;Одинаковые значения pseudoRandom будут создавать одинаковые поплавки&lt;/p&gt;

&lt;p&gt;На вход &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;randomSeed()&lt;/code&gt; принимает число. А у нас в текстовом поле строка. Значит нам надо научиться из этой строки делать число. Нашёл для этого такую функцию на стековерфлоу, работает отлично:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;function hashCode(str) {
  return str.split('').reduce((prevHash, currVal) =&amp;gt;
    (((prevHash &amp;lt;&amp;lt; 5) - prevHash) + currVal.charCodeAt(0))|0, 0)
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p class=&quot;caption&quot;&gt;&lt;a href=&quot;https://stackoverflow.com/a/34842797&quot;&gt;stackoverflow.com/a/34842797&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Арбайтен!&lt;/p&gt;

&lt;h2 id=&quot;совместная-работа-над-грамматикой&quot;&gt;Совместная работа над грамматикой&lt;/h2&gt;

&lt;p&gt;Чтобы вместе весело работать над грамматикой и не лезть каждый раз в код, засунули правила в гуглотаблицу:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/floattery-table.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Слева я расставил все доступные в СВГ виды секций.&lt;/p&gt;

&lt;p&gt;Справа, начиная со столбца G — правила грамматики. Тут можно использовать только те виды секций, которые перечислены слева.&lt;/p&gt;

&lt;p&gt;Внизу — регулярное выражение для &lt;a href=&quot;https://en.wikipedia.org/wiki/Vim_(text_editor)&quot;&gt;любимого текстового редактора Вим&lt;/a&gt;. Вставляю в Вим данные из правой части таблицы, запускаю команду, вставленная таблица преобразуется в формат YAML, который можно вставить в код. Знаки табуляции меняются на пробелы, лишние пробелы удаляются, и т. д.&lt;/p&gt;

&lt;!--Чтобы быстрее переносить грамматику из таблицы в код, я написал регулярное выражение

```
%s:\(&lt;.\{-\}&gt;\)\s*\(.*\)\s*$:\1\:\r- \2: | %s:\d\+_\d\+:&lt;&amp;&gt;:g | %s:\s*$:: | %s:\s\+: :g
↑                                          ↑                    ↑           ↑         
1                                          2                    3           4
```

1. Разбивает каждое правило грамматики на две строки. В первой нетерминальный токен, во второй — во что он может превратиться.
2. Выбирает значения похожие на `16_16` и заворачивает их в треугольные скобки `&lt;16_16&gt;`.
3. Удаляет пробельные символы в концах строк.
4. Заменяет подряд идущие пробельные символы одним пробелом.

Каждый раз, когда Максим менял грамматику, я копировал ячейки из гуглдока в буфер обмена, вставлял в вим, выполнял эту комманду. И получал почти правильную грамматику, разве что стартовый символ ещё надо было разобрать на несколько строк-правил.--&gt;

&lt;h2 id=&quot;круги-на-воде-и-стрекоза&quot;&gt;Круги на воде и стрекоза&lt;/h2&gt;

&lt;p&gt;Они по сути — те же секции поплавков. Они лежат в том же входном СВГ файле, их положение в поплавке определяется грамматикой. Однако, они имеют хитрые размеры, чтобы грамматика не спутала их с какой-нибудь другой секцией. У воды размер верхнего и нижнего радиусов &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;0_0&amp;gt;&lt;/code&gt;, а у стрекозы &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;256_256&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Такой подход позволяет на уровне грамматики определять,&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;на каких секциях стрекоза может сидеть, а на каких — нет.&lt;/li&gt;
  &lt;li&gt;Насколько часто стрекоза будет появляться.&lt;/li&gt;
  &lt;li&gt;Между какими секциями поплавка будут расходиться круги по воде.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Удобно держать такие настройки в грамматике, это упрощает программу.&lt;/p&gt;

&lt;h2 id=&quot;итог&quot;&gt;Итог&lt;/h2&gt;

&lt;p&gt;Кратко отвечу на Женины вопросы:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Как из текста получается набор переменных. Сколько там переменных, как они связаны, как влияют на форму.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Переменная одна, она делается из строки и является её хешем. То есть даже у почти одинаковых строк хеши будут сильно отличаться.&lt;/p&gt;

&lt;p&gt;Эта переменная делает построение поплавка предсказуемым, определяя, какой из нескольких возможных способов превращения каждого токена будет выбран.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Что такое грамматика, какая она.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It’s breathtaking! They are all breathtaking!&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;как был устроен процесс совместной разработки.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Секции ребята рисовали в Фигме, дико удобно. Грамматику вместе редачили в таблице.&lt;/p&gt;
</description>
        <pubDate>Tue, 05 Nov 2019 00:00:00 +0000</pubDate>
        <link>http://dianov.org/floattery/</link>
        <guid isPermaLink="true">http://dianov.org/floattery/</guid>
        
        
      </item>
    
      <item>
        <title>Перевёрстка данных  о миграции</title>
        <description>&lt;p&gt;Росстат нарисовал такое:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/makeover-migration.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Округи можно вывести списком, не обязательно привязывать к карте. Стрелки всё окончательно запутывают: почему они делятся на сегменты? Важен ли их цвет? Куда уехало больше всего жителей ЦФО? Какой процент людей уезжает?&lt;/p&gt;

&lt;p&gt;Было бы круче показать таблицей. В строках — откуда, в столбцах — куда уезжают. В исходной визуализации такой инфы нет.&lt;/p&gt;

&lt;p&gt;Нажожу исходные данные &lt;a href=&quot;http://www.gks.ru/wps/wcm/connect/rosstat_main/rosstat/ru/statistics/population/demography/&quot;&gt;на сайте Росстата&lt;/a&gt;. Да они прекрасны, всё как я и хотел :–) Даже больше: тут инфа разбита на городские и сельские поселения. По каждому федеральному округу можно посмотреть, сколько человек переехало из сёл в города, а сколько из городов в сёла.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/makeover-migration-gks.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Попробую для начала визуализировать в Табло. Сейчас данные в виде разреженной таблицы, надо сделать её плотной. То есть такой, чтобы в каждой строке было указано: из какого ФО, из города или из села, сколько человек переехало, в какой ФО, в город или в село. Часть работы делаю вручную:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/makeover-data-cleanup.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Выделенными данными надо заполнить столбцы to_district и amount. Тогда в каждой строке будет по одному числовому значению, как нам и надо. Вручную делать это долго, к счастью, Табло умеет так:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/makeover-migration-pivot.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Ррраз — и данные в правильном формате:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/makeover-data-dense.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Здорово. Попробуем визуализировать:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/makeover-migration-tableau-0.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Теперь посмотрим миграцию между сёлами и городами:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/makeover-migration-tableau-2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;В диагональных ячейках, вероятно, показано, сколько человек переехало внутри своего ФО, оставаясь в городской или сельской местности. То есть, из города в другой город, или из села в другое село.&lt;/p&gt;

&lt;p&gt;Уберём переезды внутри своего ФО, чтобы внимательнее рассмотреть остальные:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/makeover-migration-tableau-3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Чтобы цветовая палитра была ближе к действительности, лучше сдвинуть так, чтобы нулевые значения были белыми. Тогда число в ячейке будет пропорционально количеству синей краски:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/makeover-migration-tableau-5.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;В данных Росстата есть информация за несколько лет, почему бы не показать динамику изменения миграции? Перевожу остаток данных Росстата в нужный формат при помощи Vim и Табло, рисую гарфики:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/makeover-migration-ts.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p class=&quot;caption&quot;&gt;Площадь графика показывает число переездов за все годы. Видим, что в 11 году все дружно начали переезжать&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/makeover-migration-ts_to_other.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p class=&quot;caption&quot;&gt;Если оставить только переезды в другие регионы, будет так&lt;/p&gt;

&lt;p&gt;Между делом показываю результат &lt;a href=&quot;http://revealthedata.com/&quot;&gt;Роме Бунину&lt;/a&gt;, он предлагает попробовать санки чарт. И показать всё-таки карту России. Пробую санки:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/makeover-migration-sankey.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p class=&quot;caption&quot;&gt;Справа порядок неправильный, не стал пока исправлять&lt;/p&gt;

&lt;p&gt;Слева — сколько уехало из округа, справа — сколько приехало. Клёво, что все потоки видны и что они похожи именно на потоки. Если с таблицей надо разбираться, тут сразу видно, что что-то куда-то перетекает. А если не повторять каждый регион по два раза? Пробую вариант с chord diagram, которую собираю &lt;a href=&quot;http://mkweb.bcgsc.ca/tableviewer/visualize/&quot;&gt;в онлайн-генераторе&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/makeover-migration-chord.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Даже если не обращать внимания на весь обвес, стало слишком сложно. В середине каша. А ещё в подобных диаграммах потоки в середине становятся тоньше. Такое решение улучшает читаемость, но искажает данные.&lt;/p&gt;

&lt;p&gt;Тупик. Запоздало иду искать аналогичные визуализации.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/makeover-migration-analogue-animated.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p class=&quot;caption&quot;&gt;&lt;a href=&quot;http://metrocosm.com/global-immigration-map/&quot;&gt;Визуализация Метрокосма&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/makeover-migraion-analogue_arrows.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p class=&quot;caption&quot;&gt;Красиво, но если показать миграции между всеми штатами, будет каша&lt;/p&gt;

&lt;p&gt;Плюс много санки и chord:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/makeover-migration-analogues-sankey_chord.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Делаю десяток набросков, в голову приходит странный вариант: а что, если сделать аналог &lt;a href=&quot;http://dianov.org/all/plitochnaya-karta-rossii/&quot;&gt;плиточной карты&lt;/a&gt; для округов? Прототипирую в табло:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/makeover-migration-tilemap-from.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;«Карта» состоит из восьми клеток-округов. Внутри каждого округа — такая же карта округов. Чтобы узнать, из какого округа чаще всего переезжают в ЦФО, надо выбрать в клетке ЦФО самый большой кружок. И посмотреть, какой округ он означает. Переезды внутри региона показываю серыми кружками.&lt;/p&gt;

&lt;p&gt;Экспортирую из Табло ПДФ и допиливаю в Скетче:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/makeover-migration-bubbles.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Показываю &lt;a href=&quot;http://andreieres.ru/&quot;&gt;Андрею Ересу&lt;/a&gt;. Оказывается, ничего не понятно, надо было раньше показать :–\&lt;/p&gt;

&lt;p&gt;Решаю вернуться к старой версии с таблицей. Пробую импортнуть ПДФ из Табло в Скетч, но всё очень тормозит. Поэтому визуализирую на d3, дорабатываю в Скетче:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/makeover-migration-d3-prettified.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/makeover-migration-im-eres.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Доработать не успеваю, решаю на этом закончить. Клёво было бы ещё показать численность населения округов и её прирост.&lt;/p&gt;
</description>
        <pubDate>Sun, 15 Jul 2018 00:00:00 +0000</pubDate>
        <link>http://dianov.org/all/perevyorstka-dannyh-o-migracii/</link>
        <guid isPermaLink="true">http://dianov.org/all/perevyorstka-dannyh-o-migracii/</guid>
        
        
      </item>
    
      <item>
        <title>Перевёрстка тарифов  246 маршрутки</title>
        <description>&lt;p&gt;Мы тут с Андреем Ересом пробуем &lt;a href=&quot;https://t.me/redesignit&quot;&gt;вести канал в телеграме&lt;/a&gt;. Перевёрстываем разные штуки, постим результат и процесс.&lt;/p&gt;

&lt;p&gt;На этой неделе улучшали красоту:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/makeover-shuttle-src.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Никогда не понимал таких бумажек. Сколько, например, стоит проехать от ПМК до Новенького? В каком порядке идут остановки? Попробовал сменить формат. Процесс:&lt;/p&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/4fh_qdasdWI&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;Результат:
&lt;img src=&quot;/media/makeover-shuttle-1.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Сразу видно, что от ПМК до Новенького цена не предусмотрена, надо торговаться с водителем. Но в любом случае, не дороже 33 ₽.&lt;/p&gt;

&lt;p&gt;Опубликовал в телеграме а потом понял, что полосочки можно ещё плотнее утрясти:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/makeover-shuttle-2@3x.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;У такого варианта большой косяк: чтобы убедиться в правильности цены, надо весь лист обежать глазами. Тут надо помнить, что лист висит на стене и пальцем по нему водить не всегда получится. Например, чтобы узнать стоимость проезда от Современника до Средней Ахтубы, надо глазами проделать вот такой путь:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/makeover-shuttle-2.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Чтобы решить эту проблему, нарисовал вариант с дугами:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/makeover-shuttle-4@3x-2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Пожалуй, так лучше. Глаз быстрее находит линию, соединяющую две нужные остановки.&lt;/p&gt;

&lt;p&gt;Пробую вариант с треугольной таблицей. Где не хватает цен — додумываю.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/makeover-shuttle-6@3x.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Но это, конечно, жесть: надо инструкцию рядом вешать, как цену определять. Чтобы сделать формат понятнее, придётся дублировать информацию. Раз уж у нас в итоге получилась скучная таблица, добавим немного визуализации:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/makeover-shuttle-7@3x.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Знаете, как сделать лучше? Присылайте свой вариант мне в телеграм: @ivan_dianov. Опубликуем и прокомментируем его &lt;a href=&quot;https://t.me/redesignit&quot;&gt;в канале «Перевёрстка»&lt;/a&gt;.&lt;/p&gt;
</description>
        <pubDate>Wed, 02 May 2018 00:00:00 +0000</pubDate>
        <link>http://dianov.org/all/perevyorstka-tarifov-246-marshrutki/</link>
        <guid isPermaLink="true">http://dianov.org/all/perevyorstka-tarifov-246-marshrutki/</guid>
        
        
      </item>
    
      <item>
        <title>Как я конспектирую  оффлайновые лекции</title>
        <description>&lt;p&gt;Алексей Белицкий спрашивает:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;как ты делал заметки на курсе? я скачал симплнот, но не вижу как загружать туда фотографии. Когда поеду на профсоюкс тоже хочу все законспектировать. У тебя получились очень хорошие подробные заметки&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Текст набираю в &lt;a href=&quot;https://daringfireball.net/projects/markdown/&quot;&gt;формате Markdown&lt;/a&gt; в редакторе &lt;a href=&quot;http://macvim-dev.github.io/macvim/&quot;&gt;Vim&lt;/a&gt;, но подойдёт любой другой с подсветкой синтаксиса. Можно сразу писать в &lt;a href=&quot;http://simplenote.com/&quot;&gt;Simplenote&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Фотографирую на телефон, в конспекте тут же отмечаю текущее время, вот так:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(15:52)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Эти отметки помогают потом найти нужную фотографию. Дату снимка не пишу, если она понятна из контекста. Вечером прохожусь по отметкам и заменяю их на фотографии.&lt;/p&gt;

&lt;p&gt;Фотографии для этого загружаю на Amazon S3 или в комментарии в Github Issues. Гитхаб даёт маркдаун-код для вставки в конспект, удобно:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/upload.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Думаю, есть способы и попроще. А как вы ведёте конспекты?&lt;/p&gt;
</description>
        <pubDate>Sun, 01 Apr 2018 00:00:00 +0000</pubDate>
        <link>http://dianov.org/all/kak-ya-vedu-konspekty/</link>
        <guid isPermaLink="true">http://dianov.org/all/kak-ya-vedu-konspekty/</guid>
        
        
      </item>
    
      <item>
        <title>Скриншоты в текст</title>
        <description>&lt;p&gt;Когда нужно распознать текст скриншота, открываю сервис http://www.free-ocr.com/. От сотни подобных он отличается возможностью вставить картинку из буфера обмена.&lt;/p&gt;

&lt;p&gt;Распознаёт с ошибками, но иногда их исправить быстрее, чем вбивать текст с нуля.&lt;/p&gt;
</description>
        <pubDate>Sat, 02 Dec 2017 00:00:00 +0000</pubDate>
        <link>http://dianov.org/all/skrinshoty-v-tekst/</link>
        <guid isPermaLink="true">http://dianov.org/all/skrinshoty-v-tekst/</guid>
        
        
      </item>
    
      <item>
        <title>Как запомнить нумерацию  месяцев</title>
        <description>&lt;p&gt;Придумал себе запоминалку: номера первых месяцев сезона делятся на 3:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;3 — март,&lt;/li&gt;
  &lt;li&gt;6 — июнь,&lt;/li&gt;
  &lt;li&gt;9 — сентябрь,&lt;/li&gt;
  &lt;li&gt;12 — декабрь.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Номера остальных месяцев после этого тоже легко запоминаются. Октябрь идёт за сентябрём, значит десятый, и так далее.&lt;/p&gt;
</description>
        <pubDate>Sat, 02 Dec 2017 00:00:00 +0000</pubDate>
        <link>http://dianov.org/all/zapomnil-numeraciyu-mesyacev/</link>
        <guid isPermaLink="true">http://dianov.org/all/zapomnil-numeraciyu-mesyacev/</guid>
        
        
      </item>
    
      <item>
        <title>Идеальное  согласование макета</title>
        <description>&lt;p&gt;Однажды я за четверть часа согласовал правки по макету сразу с восемью представителями заказчика — муниципальной организации.&lt;/p&gt;

&lt;p&gt;Сперва думал, что работу не закончу никогда: буду показывать новые версии, получать пакеты правок, и так в бесконечном цикле. Сложнее всего было договориться о расположении 15 информационных блоков: каждый участник обсуждения хотел расставить их по-своему.&lt;/p&gt;

&lt;p&gt;Помог такой приём: я распечатал макет, порезал его ножницами, отдал толпе и отошёл в сторонку. Они бурно спорили между собой, перекладывали листики, а потом вдруг пришли к консенсусу. Я уточнил, все ли согласны, и торжественно сфотографировал бумажки. Сделал по этой фотографии макет и его сразу приняли.&lt;/p&gt;

&lt;p&gt;До сих пор вспоминать приятно.&lt;/p&gt;
</description>
        <pubDate>Sat, 02 Dec 2017 00:00:00 +0000</pubDate>
        <link>http://dianov.org/all/keys-idealnoe-soglasovaniya-maketa/</link>
        <guid isPermaLink="true">http://dianov.org/all/keys-idealnoe-soglasovaniya-maketa/</guid>
        
        
      </item>
    
      <item>
        <title>Плиточная  карта России</title>
        <description>&lt;p&gt;Коллега прислал ссылку &lt;a href=&quot;http://telegra.ph/Konkurs-Raspili-Rossiyu-Na-kvadraty-11-13&quot;&gt;на конкурс со странным названием.&lt;/a&gt; Нужно придумать, как разделить Россию на квадратики, чтобы делать клёвые плиточные визуализации. У Америки такая есть:&lt;/p&gt;

&lt;p class=&quot;large&quot;&gt;&lt;img src=&quot;/media/tilemap-usa.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Все штаты-квадратики одного размера, поэтому их данные легко сравнить между собой&lt;/p&gt;

&lt;p&gt;Для России такую карту сделать сложнее, потому что её субъекты сильно отличаются размерами:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/tilemap-feel-difference.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p class=&quot;caption&quot;&gt;Чтобы прочувствовать проблему, сравните Ингушетию с Сахой&lt;/p&gt;

&lt;p&gt;Кажется, квадратами нарисовать Россию невозможно. Решаю «приблизиться к оленю» и пробую шестиугольную сетку. Рисую графики похожие на настоящие. Придумываю, как сократить названия регионов. Выходит так:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/tilemap-hex-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Я ничего не потеряю, если сделаю тайлы квадратными. График тогда можно увеличить а рамку удалить:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/tilemap-rect-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Оу, теперь можно сдвинуть колонки на полвысоты и получить нормальную квадратную карту. Это круто: ячейки выстраиваются в горизонтальные линии и данные проще сравнивать.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/tilemap-rect-2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Показываю &lt;a href=&quot;http://revealthedata.com/&quot;&gt;Роме Бунину,&lt;/a&gt; ведущему курса о визуализации данных. Кстати, &lt;a href=&quot;https://datalaboratory.ru/course/&quot;&gt;курс стартует 8 декабря&lt;/a&gt; в Москве, приходите. Можно удалённо.&lt;/p&gt;

&lt;p&gt;Рома недоволен:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/tilemap-rbunin1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Чтобы сделать карту ближе к России, пробую равномерно надуть восток:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/tilemap-rect-twosizes.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Чтобы хоть как-то уплотнить карту, убираю горизонтальные отступы:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/tilemap-rect-twosizes2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Вышла расчёска :–( Никто не догадается, почему одни регионы рядом а другие далеко. Может разрешить карте быть дырявой? Нет, станет ещё непонятнее.&lt;/p&gt;

&lt;p&gt;Пробую гигантские субъекты нарисовать гигантскими:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/tilemap-rect-oligomer1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Мало надул, не похоже на Россию. Дуем дальше:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/tilemap-rect-oligomer2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Форма похожая, но теперь понятно: нельзя к каким-то двум регионам привлекать столько внимания. Поэтому распиливаю страну по Уралу и показываю европейскую часть крупно. Так в некоторых проектах делает &lt;a href=&quot;https://datalaboratory.ru/&quot;&gt;Лаборатория Данных:&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/tilemap-division.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Получается так:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/tilemap-rect-cut1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;С Сибирью беда. Ямало-Ненецкий и Ханты-Мансийский округа отвалились от Ненецкого. Свердловская область почему-то на севере. Надо ближе половинки сдвинуть, а то непонятно, что это одна страна.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/tilemap-division-v1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Нравится, что строки востока и запада не совпадают, это усиливает ощущение разреза. Показываю Роме, он одобряет:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/tilemap-rbunin-ok.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;На радостях рисую римейк &lt;a href=&quot;https://upload.wikimedia.org/wikipedia/commons/6/6b/Flag-maps_of_the_subjects_of_Russia.png&quot;&gt;карты с флагами&lt;/a&gt;.&lt;/p&gt;

&lt;p class=&quot;large&quot;&gt;&lt;img src=&quot;/media/tilemap-flags.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p class=&quot;caption&quot;&gt;У Сахалина флаг крутой&lt;/p&gt;

&lt;p&gt;В её форме не угадывается Россия, однако, рассматривать интересно. С названиями было бы круче, но уже лень.&lt;/p&gt;

&lt;p&gt;Чтобы оценить, точность плиточной карты, раскрашиваю её колонки в разные цвета, так же крашу исходную карту:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/tilemap-test-vertical.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Жесть. На Кавказе всё перемешалось: Кабардино-Балкария прилипла к Краснодару, хотя надо было прилипить Карачаево-Черкесию. Ингушетия граничит с Астраханью и Дагестаном, а с Чечнёй — нет. На северо-западе тоже плохо. Надо всё выравнивать заново.&lt;/p&gt;

&lt;p&gt;Выравниваю, выравниваю, выравниваю. Не выравнивается. Стоит исправить один косяк, вылезают два других.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;
А-а-а-а-а-а! Россия кривая!
&lt;strong&gt;(╯°□°）╯︵ ┻━┻&lt;/strong&gt;
&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;Запоздало придумываю принципы:&lt;/p&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;/ul&gt;

&lt;p&gt;Ещё надо по-другому сократить названия субъектов. Никто не догадается, что «Мрл» — республика Марий Эл. Назваю регионы их первыми буквами, короткие названия пишу полностью. Тут тоже не без сюрпризов. Как сократить Краснодар и Красноярск? «Крас» и «Крас»? Решаю иногда делать исключения.&lt;/p&gt;

&lt;p&gt;В английской верии с сокращениями регионов будет дико проще, есть официальные.&lt;/p&gt;

&lt;p&gt;Снова всё двигаю. Выходит лучше:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/tilemap-test-vertical2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Рисую горизонтальные полоски:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/tilemap-test-horizontal2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Стало чуть менее криво. Проверяю, не развалились ли округа:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/tilemap-test-districts.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Северо-Западный федеральный округ порвался, ну и пускай.&lt;/p&gt;

&lt;p&gt;Придумал более наглядный способ оценки качества карты. У каждого квадратика от 0 до 4 соседей. Обозначу эти соседские отношения линиями на исходной карте и получу сетку четырёхугольников. Чем ровнее сетка, тем лучше карта.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/tilemap-test-graph1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Сразу видно, что западный Урал задрался наверх.&lt;/p&gt;

&lt;p&gt;Другая проблема: восточная часть по форме не похожа на Россию. Исправляю:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/tilemap-test-districts2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/tilemap-test-graph2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Запад стал лучше. Квадратик Оренбурга ушёл вниз, Ненецкий округ — наверх, проверочная сетка выровнялась.&lt;/p&gt;

&lt;p&gt;На востоке сетка ухудшилась. Алтай и Алтайский край уехали от Кемерово, а Бурятия присоседилась к Еврейскому АО. Но я на это согласен, потому что форма страны стала узнаваемой. Алтай вывалился вниз, как на настоящей карте, и стал дополнительным ориентиром.&lt;/p&gt;

&lt;p&gt;Хуже всего то, что Омск между Свердловской областью, Тюменью и Курганом. Хотя на самом деле он восточнее этой тройки. Пробую поменять его местами с Курганом.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/tilemap-test-districts3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/tilemap-test-graph3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Проверочная сетка разъехалась в районе Омска в тартарары, но зато федеральные округа «расцепились», находить нужные субъекты стало проще.&lt;/p&gt;

&lt;p&gt;Если квадратики карты на визуализации залиты полностью, можно сдвинуть половинки карты поближе:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/media/tilemap-test-districts-joined.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Если нет заливки, то лучше оставить линию на месте Урала:&lt;/p&gt;

&lt;p class=&quot;large&quot;&gt;&lt;img src=&quot;/media/tilemap-rect-twosizes3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Готово :–)&lt;/p&gt;

&lt;p&gt;Следующий этап — что-нибудь визуализировать. Например, &lt;a href=&quot;http://stat.gibdd.ru/&quot;&gt;число аварий на дорогах.&lt;/a&gt;&lt;/p&gt;
</description>
        <pubDate>Wed, 29 Nov 2017 00:00:00 +0000</pubDate>
        <link>http://dianov.org/all/plitochnaya-karta-rossii/</link>
        <guid isPermaLink="true">http://dianov.org/all/plitochnaya-karta-rossii/</guid>
        
        
      </item>
    
      <item>
        <title>Список списков  ресурсов для айтишников</title>
        <description>&lt;p&gt;Я недавно &lt;a href=&quot;http://dianov.org/all/spisok-spiskov-resursov-o-vizualizacii-dannyh/&quot;&gt;писал&lt;/a&gt; про пользу изучения списков.&lt;/p&gt;

&lt;p&gt;На Гитхабе лежит &lt;a href=&quot;https://github.com/sindresorhus/awesome&quot;&gt;очень крутой список списков&lt;/a&gt;. В основном всё про разработку и айти. Мне понравились такие:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/fasouto/awesome-dataviz&quot;&gt;про визуализацию данных&lt;/a&gt;: фреймворки, библиотеки, приложения&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/mojoaxel/awesome-regression-testing&quot;&gt;про визуальное тестирование&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/nicolesaidy/awesome-web-design#productivity&quot;&gt;про дизайн интерфейсов&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/kakoni/awesome-healthcare&quot;&gt;про здоровье&lt;/a&gt;: приложения, библиотеки, инструменты, ресурсы&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Wed, 22 Nov 2017 00:00:00 +0000</pubDate>
        <link>http://dianov.org/all/spisok-krutyh-spiskov-aytishnyh-resursov/</link>
        <guid isPermaLink="true">http://dianov.org/all/spisok-krutyh-spiskov-aytishnyh-resursov/</guid>
        
        
      </item>
    
  </channel>
</rss>
