<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[TMvK]]></title><description><![CDATA[Thoughts, stories and ideas. Mostly IT.]]></description><link>https://blog.zztt.eu/</link><image><url>https://blog.zztt.eu/favicon.png</url><title>TMvK</title><link>https://blog.zztt.eu/</link></image><generator>Ghost 1.24</generator><lastBuildDate>Sun, 03 May 2026 12:16:39 GMT</lastBuildDate><atom:link href="https://blog.zztt.eu/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Quickie: JS - input change]]></title><description><![CDATA[<div class="kg-card-markdown"><p>Many developers try to handle change of input value with <code>change</code> or <code>keyup</code>/<code>keydown</code> event listeners. Well, that's not enough.</p>
<p>You can change the value also by:</p>
<ul>
<li>dropping selected text,</li>
<li>copying it to clipboard and right clicking mouse -&gt; Paste.</li>
</ul>
<p>The correct way to handle it is with <code>input</code></p></div>]]></description><link>https://blog.zztt.eu/js-input-change/</link><guid isPermaLink="false">5a7326f2efb40800014dee25</guid><category><![CDATA[input]]></category><category><![CDATA[js]]></category><category><![CDATA[keyup]]></category><category><![CDATA[keydown]]></category><category><![CDATA[change]]></category><category><![CDATA[event-listener]]></category><category><![CDATA[quickie]]></category><dc:creator><![CDATA[TvK]]></dc:creator><pubDate>Tue, 19 Jun 2018 16:25:11 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>Many developers try to handle change of input value with <code>change</code> or <code>keyup</code>/<code>keydown</code> event listeners. Well, that's not enough.</p>
<p>You can change the value also by:</p>
<ul>
<li>dropping selected text,</li>
<li>copying it to clipboard and right clicking mouse -&gt; Paste.</li>
</ul>
<p>The correct way to handle it is with <code>input</code> event listnener. You can read about it on <a href="https://developer.mozilla.org/en-US/docs/Web/Events/input">MDN</a>. And you might find interesting this <a href="https://stackoverflow.com/questions/6458840/detecting-input-change-in-jquery">StackOverflow post</a>.</p>
<p>Tags:<br>
<a href="https://blog.zztt.eu/tag/input">#input</a> <a href="https://blog.zztt.eu/tag/js">#js</a> <a href="https://blog.zztt.eu/tag/keyup">#keyup</a> <a href="https://blog.zztt.eu/tag/keydown">#keydown</a> <a href="https://blog.zztt.eu/tag/change">#change</a> <a href="https://blog.zztt.eu/tag/event-listener">#event-listener</a> <a href="https://blog.zztt.eu/tag/quickie">#quickie</a></p>
</div>]]></content:encoded></item><item><title><![CDATA[HTML]]></title><description><![CDATA[<div class="kg-card-markdown"><p>I'd like to make a small series of correct markup / semantic HTML. I have many drafts of smaller parts and will publish them later. So here is a small introduction to them.</p>
<p>I found interest in correct HTML a few months ago. Partly because I saw some interesting websites from</p></div>]]></description><link>https://blog.zztt.eu/html/</link><guid isPermaLink="false">5ab5705b28e0f70001824de1</guid><category><![CDATA[semantics]]></category><category><![CDATA[markup]]></category><category><![CDATA[html]]></category><category><![CDATA[accessibility]]></category><dc:creator><![CDATA[TvK]]></dc:creator><pubDate>Sat, 24 Mar 2018 00:28:38 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1454165205744-3b78555e5572?ixlib=rb-0.3.5&amp;q=80&amp;fm=jpg&amp;crop=entropy&amp;cs=tinysrgb&amp;w=1080&amp;fit=max&amp;ixid=eyJhcHBfaWQiOjExNzczfQ&amp;s=2df61c1bdccccb7e5ebe83e987bf02f8" medium="image"/><content:encoded><![CDATA[<div class="kg-card-markdown"><img src="https://images.unsplash.com/photo-1454165205744-3b78555e5572?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=1080&fit=max&ixid=eyJhcHBfaWQiOjExNzczfQ&s=2df61c1bdccccb7e5ebe83e987bf02f8" alt="HTML"><p>I'd like to make a small series of correct markup / semantic HTML. I have many drafts of smaller parts and will publish them later. So here is a small introduction to them.</p>
<p>I found interest in correct HTML a few months ago. Partly because I saw some interesting websites from concrete web-specialized companies, that employ very many experts in web technologies. Okay. &quot;Interesting&quot; can have a negative meaning, in case you didn't know.<br>
Also it's interesting to see all the people that claim they are experts in HTML in their CVs.</p>
<h2 id="motivation">Motivation</h2>
<p>Some people would probably consider such approach to be useless <strike>Grammar</strike> Semantic Naziing. And thinking: &quot;It works, and it looks the same, so what do you want?&quot;.</p>
<p>With correct markup, you make your code better machine readable. You can find information, that bots' traffic takes up about 40-50% of all internet traffic. According to <a href="https://www.incapsula.com/blog/bot-traffic-report-2016.html">first search result</a> - commercial crawlers, search engine bots and feed fetchers form almost 22%.</p>
<p>You also help disabled people. And it's good to think also for future. If developers start using correct markup now, they'll probably continue even in future. And future is us - &quot;IT generation&quot; - being old, bad sighted, slow... So it's really a good idea to invest a little time to study about semantics and accessibility, it'll pay back. Unless by then we (web developers) are replaced by robots 😃</p>
<p>And last, but not least - if you know cycles, conditions and basic syntax of a programming language, it doesn't make a good programmer. Or programmer at all. Also you probably wouldn't rank yourself &quot;advanced&quot; in language you know at such level. And if you would, you're a fool.</p>
<p>Same goes with HTML and CSS. If you know few basic tags, and abuse <code>div</code>s for buttons, add headings to random places, use <code>&lt;b&gt;</code> and headings for styling; you don't really know HTML.</p>
<p>It's not always easy to decide which element to choose. Or there can be more correct solution. I'll cover that later in some posts.</p>
<p>There are really tons of things to know about it.</p>
<p>Tags:<br>
<a href="https://blog.zztt.eu/tag/semantics">#semantics</a> <a href="https://blog.zztt.eu/tag/markup">#markup</a> <a href="https://blog.zztt.eu/tag/html">#html</a> <a href="https://blog.zztt.eu/tag/accessibility">#accessibility</a></p>
</div>]]></content:encoded></item><item><title><![CDATA[Quickie: Rsync]]></title><description><![CDATA[<div class="kg-card-markdown"><p>Just a command to help you backup / archive your server.</p>
<pre><code class="language-bash">sudo rsync -avhe 'ssh -i /home/user/.ssh/id_rsa -p 2222' \
--numeric-ids \
--progress \
admin@your.server.tld:/path/to/your/data/ \
/path/to/local/data/backup/
</code></pre>
<p><code>-a</code> - archive, this is an alias to lots of other options<br>
<code>-v</code></p></div>]]></description><link>https://blog.zztt.eu/quickie-rsync/</link><guid isPermaLink="false">5a92f80928e0f70001824db7</guid><category><![CDATA[rsync]]></category><category><![CDATA[bash]]></category><category><![CDATA[quickie]]></category><category><![CDATA[backup]]></category><category><![CDATA[archive]]></category><dc:creator><![CDATA[TvK]]></dc:creator><pubDate>Sun, 25 Feb 2018 18:54:35 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>Just a command to help you backup / archive your server.</p>
<pre><code class="language-bash">sudo rsync -avhe 'ssh -i /home/user/.ssh/id_rsa -p 2222' \
--numeric-ids \
--progress \
admin@your.server.tld:/path/to/your/data/ \
/path/to/local/data/backup/
</code></pre>
<p><code>-a</code> - archive, this is an alias to lots of other options<br>
<code>-v</code> - verbose, so you see what's happenning<br>
<code>-h</code> - human readable numbers<br>
<code>-e</code> - remote shell<br>
<code>--progress</code> - self explanatory<br>
<code>--numeric-ids</code> - don't map UID/GID by user/group name<br>
For more options refer to manual.</p>
<p>In this example we connect with local user SSH key, to non-standard SSH port 2222.</p>
<p>Keep in mind, if you want to keep permissions and ownership, you need to run this command as root. Otherwise owner will be your local user.</p>
<p>Tags:<br>
<a href="https://blog.zztt.eu/tag/rsync">#rsync</a> <a href="https://blog.zztt.eu/tag/quickie">#quickie</a> <a href="https://blog.zztt.eu/tag/bash">#bash</a> <a href="https://blog.zztt.eu/tag/backup">#backup</a> <a href="https://blog.zztt.eu/tag/archive">#archive</a></p>
</div>]]></content:encoded></item><item><title><![CDATA[Quickie: JavaScript decimal multiplication]]></title><description><![CDATA[<div class="kg-card-markdown"><p>Another oddity of JavaScript I found. Multiplying decimal numbers can be tricky (or malicious?).</p>
<p>Order of numbers can matter in multiplication.</p>
<pre><code class="language-js">// order #1
135*1.15*10.5
// = 1630.125

// order #2
1.15 * 10.5 * 135
// = 1630.125

// order #3
10.5 * 1.15 * 135
// = 1630.125

// order #4</code></pre></div>]]></description><link>https://blog.zztt.eu/javascript-decimal-multiplication/</link><guid isPermaLink="false">5a7e4053e873fa000169959d</guid><category><![CDATA[toFixed]]></category><category><![CDATA[js]]></category><category><![CDATA[math]]></category><category><![CDATA[decimal]]></category><category><![CDATA[round]]></category><category><![CDATA[multiplication]]></category><dc:creator><![CDATA[TvK]]></dc:creator><pubDate>Sat, 10 Feb 2018 00:57:36 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>Another oddity of JavaScript I found. Multiplying decimal numbers can be tricky (or malicious?).</p>
<p>Order of numbers can matter in multiplication.</p>
<pre><code class="language-js">// order #1
135*1.15*10.5
// = 1630.125

// order #2
1.15 * 10.5 * 135
// = 1630.125

// order #3
10.5 * 1.15 * 135
// = 1630.125

// order #4
10.5 * 135 * 1.15
// = 1630.1249999999998
</code></pre>
<p>This can be bad, if you want to round to 2 decimals. For example in financial operations.</p>
<pre><code class="language-js">(10.5 * 135 * 1.15).toFixed(2)
// &quot;1630.12&quot;

(10.5 * 1.15 * 135).toFixed(2)
// &quot;1630.13&quot;
</code></pre>
<p>Boom! One cent difference.<br>
The solution can be adding a pretty small number to the product. For example 0.000001.</p>
<pre><code class="language-js">(10.5 * 135 * 1.15 + 1e-6).toFixed(2)
// &quot;1630.13&quot;

(10.5 * 1.15 * 135 + 1e-6).toFixed(2)
// &quot;1630.13&quot;
</code></pre>
<p>Tags:<br>
<a href="https://blog.zztt.eu/tag/js">#js</a> <a href="https://blog.zztt.eu/tag/decimal">#decimal</a> <a href="https://blog.zztt.eu/tag/math">#math</a> <a href="https://blog.zztt.eu/tag/multiplication">#multiplication</a> <a href="https://blog.zztt.eu/tag/toFixed">#toFixed</a> <a href="https://blog.zztt.eu/tag/round">#round</a></p>
</div>]]></content:encoded></item><item><title><![CDATA[Quickie: shortened "for" and "if"]]></title><description><![CDATA[<div class="kg-card-markdown"><h2 id="if">If</h2>
<p>Today after debugging minified JS code I discovered an interesting way to write <code>if</code>s:</p>
<pre><code class="language-js">var i = 0;
var s = 'foo';

if (s === 'bar') {
    i = 1;
}
</code></pre>
<p>can also be written:</p>
<pre><code class="language-js">var i = 0;
var s = 'foo';

(s === 'bar') &amp;&amp; (i = 1);
</code></pre>
<h3 id="for">For</h3>
<p>Shorthand for <code>for</code> cycle. Not that</p></div>]]></description><link>https://blog.zztt.eu/short-for-if/</link><guid isPermaLink="false">5a79e8a4e873fa000169958f</guid><category><![CDATA[quickie]]></category><category><![CDATA[for]]></category><category><![CDATA[if]]></category><category><![CDATA[short]]></category><dc:creator><![CDATA[TvK]]></dc:creator><pubDate>Tue, 06 Feb 2018 17:55:20 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><h2 id="if">If</h2>
<p>Today after debugging minified JS code I discovered an interesting way to write <code>if</code>s:</p>
<pre><code class="language-js">var i = 0;
var s = 'foo';

if (s === 'bar') {
    i = 1;
}
</code></pre>
<p>can also be written:</p>
<pre><code class="language-js">var i = 0;
var s = 'foo';

(s === 'bar') &amp;&amp; (i = 1);
</code></pre>
<h3 id="for">For</h3>
<p>Shorthand for <code>for</code> cycle. Not that you should use it like this.</p>
<pre><code class="language-js">for (var $i = 0, $j = 0; $i &lt; 3, $j &lt; 4; console.log($i * $j), $j+=2, $i++ );
</code></pre>
<p>Tags:<br>
<a href="https://blog.zztt.eu/tag/quickie">#quickie</a> <a href="https://blog.zztt.eu/tag/if">#if</a> <a href="https://blog.zztt.eu/tag/short">#short</a> <a href="https://blog.zztt.eu/tag/for">#for</a></p>
</div>]]></content:encoded></item><item><title><![CDATA[Leaving Swarm]]></title><description><![CDATA[<div class="kg-card-markdown"><p>My little story of why I switched to Docker Swarm. And few weeks later left it for &quot;standard Docker&quot;.</p>
<p>First I had one server, which ran Docker. I used <a href="https://hub.docker.com/r/jwilder/nginx-proxy/">nginx-proxy</a> image to automatically run images. That was quite easy, functioning, so I was happy.</p>
<p>Then, when I bought</p></div>]]></description><link>https://blog.zztt.eu/leaving-swarm/</link><guid isPermaLink="false">5a76f53fefb40800014dee3f</guid><category><![CDATA[swarm]]></category><category><![CDATA[docker]]></category><category><![CDATA[nginx]]></category><category><![CDATA[traefik]]></category><category><![CDATA[flow]]></category><category><![CDATA[docker-flow]]></category><dc:creator><![CDATA[TvK]]></dc:creator><pubDate>Sun, 04 Feb 2018 17:49:14 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1516434233442-0c69c369b66d?ixlib=rb-0.3.5&amp;q=80&amp;fm=jpg&amp;crop=entropy&amp;cs=tinysrgb&amp;w=1080&amp;fit=max&amp;ixid=eyJhcHBfaWQiOjExNzczfQ&amp;s=acc553d3545a4a2bcba2075b1bbdcee9" medium="image"/><content:encoded><![CDATA[<div class="kg-card-markdown"><img src="https://images.unsplash.com/photo-1516434233442-0c69c369b66d?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=1080&fit=max&ixid=eyJhcHBfaWQiOjExNzczfQ&s=acc553d3545a4a2bcba2075b1bbdcee9" alt="Leaving Swarm"><p>My little story of why I switched to Docker Swarm. And few weeks later left it for &quot;standard Docker&quot;.</p>
<p>First I had one server, which ran Docker. I used <a href="https://hub.docker.com/r/jwilder/nginx-proxy/">nginx-proxy</a> image to automatically run images. That was quite easy, functioning, so I was happy.</p>
<p>Then, when I bought second server, I wanted to have them connected. I needed communication to be encrypted, because they are not just virtual servers on the same physical machine. I wanted just one DNS record, and servers to decide which will server which request.</p>
<h2 id="nginx">Nginx</h2>
<p>Nginx-proxy was not swarm-ready, so I couldn't use this one easily. Firstly I thought of connecting them via 2 nginx instances. But I couldn't find an easy way to do this. I was reading about creating custom CA, or using LE certificates to secure communication between the node. Then I also needed to configure nginx.conf and other stuff.<br>
So I looked for something easier.</p>
<h2 id="traefik">Traefik</h2>
<p><a href="https://hub.docker.com/_/traefik/">Traefik</a> looked like a good alternative. It is pretty simple, has nice features, is Swarm-ready.<br>
I found problems with redirect to HTTPS. Also problem with proxy being unable to run if LE server is down was reported.<br>
So once again I had to search another solution.</p>
<h2 id="dockerflowproxy">Docker flow proxy</h2>
<p><a href="https://hub.docker.com/r/vfarcic/docker-flow-proxy/">Docker Flow Proxy</a> (DFP) is a really nice image. It uses HAProxy, is highly configurable, supports plugin system (e.g. you can plug in LE support image).</p>
<p>The problems I found might be related to Swarm or anything else, but I discovered them after using DFP, so I suspect this image.</p>
<ol>
<li>I often get dangling images.</li>
<li>Sometimes after server restart / docker restart some images won't run correctly. They show as running. If you <code>docker stack ps</code> them, you see no problems, but visiting the URL - you'll get disappointed.</li>
<li>Very often I cannot <code>docker exec</code> to running container.</li>
<li>The same applies to removing images or containers. The command will hang and that's it.</li>
<li>I was often unable to even successfully run <code>sudo service docker restart</code>. First had to <code>ps aux|grep docker</code> and kill concrete processes, to be able to restart docker service.</li>
</ol>
<h2 id="swarmadvantages">Swarm advantages</h2>
<p>I will not list all advantages of Swarm - they are multiple. For full list please refer to <a href="https://docs.docker.com/engine/swarm/">Docker docs</a>.</p>
<h3 id="swarmclusteractsasonemachine">Swarm / cluster acts as one machine</h3>
<p>When it comes to IP, it does. You can have one server with IP 1.2.3.4 and another one with IP 9.8.7.6.<br>
It's enough to run some proxy image on 1.2.3.4. If your DNS record points to 9.8.7.6, it will still work.<br>
Nice, that was one of my goals.</p>
<h3 id="scalability">Scalability</h3>
<p>You can super simply &quot;duplicate&quot; containers. For example if you run 1 PHP container and it gets overloaded, you just run one docker command to add new instances. Swarm will automatically load-balance the traffic.</p>
<h2 id="swarmproblems">Swarm problems</h2>
<h3 id="swarmnetworks">Swarm networks</h3>
<p>The problem with Swarm itself is, its networks (at least the configuration I needed) can't pass you the real IP address.<br>
I suspect this of being responsible for getting into spamlist. And you can imagine whole lot of situations when you real IP is necessary - be it analytics, request limiting, session fixation, ...</p>
<h3 id="swarmquorum">Swarm quorum</h3>
<p>Another problem can be Swarm manager quorum. I experienced the problem once. Probably forgot it since I read the documentation to Swarm.<br>
You need more than half of managers to be available to run manager commands. My situation (with 2 servers, both being managers) is the worst one :D<br>
If I had only one manager, I couldn't execute manager commands from the other node.</p>
<h3 id="customimages">Custom images</h3>
<p>If you have your own image and want to deploy it to Swarm, you have to use your own registry container, or build image on each node, or if you restrict container to only some nodes, you have to have this image available on them.</p>
<h3 id="datapersistency">Data persistency</h3>
<p>If you want to persist your data, it isn't all that easy. You can use <code>docker config</code>. However, if I'm not mistaken, this approach only supports 500kB of data. Even if you could use this for source codes, it's still not solution for database data or file uploads. You'd need to dump data with cron - e.g. every 15 minutes or so.</p>
<p>Binding to host is also possible, but you need to specify placement constraint (by which you lose one of the advantages of Swarm - redeploying containers on any working node).</p>
<p>You could even use SSHFS to persist data (the Docker Swarm plugin didn't work though).</p>
<h3 id="debbuging">Debbuging</h3>
<p>With Swarm it's pretty harder to debug where the problem is. If you run pure <code>docker-compose</code>, you'll normally spot the problem instantly or quickly. With Swarm it can take quite few minutes.</p>
<h2 id="conclusion">Conclusion</h2>
<p>So finally I'm moving back to non-swarm solution. I didn't need all the fancy features Swarm provides.<br>
It was interesting to learn about all this though, and maybe I'll use this knowledge in future.</p>
<p>Tags:<br>
<a href="https://blog.zztt.eu/tag/swarm">#swarm</a> <a href="https://blog.zztt.eu/tag/docker">#docker</a> <a href="https://blog.zztt.eu/tag/nginx">#nginx</a> <a href="https://blog.zztt.eu/tag/flow">#flow</a> <a href="https://blog.zztt.eu/tag/traefik">#traefik</a></p>
</div>]]></content:encoded></item><item><title><![CDATA[PHP - static vs self]]></title><description><![CDATA[<div class="kg-card-markdown"><p>PHP's difference between <code>static</code> and <code>self</code>.</p>
<pre><code class="language-php">
class Mom
{
    private const DEFAULT_AGE = 21;


    public static function getName(): string
    {
        return 'Alice';
    }
    
    public function tellAge(int $age = self::DEFAULT_AGE): string
    {
        return 'My age is: ' . $age;
    }
    
    public function tellAge2(int $age = self::DEFAULT_AGE): string
    {
        return 'My age is: ' . $age;</code></pre></div>]]></description><link>https://blog.zztt.eu/php-static-vs-self/</link><guid isPermaLink="false">5a5db332f871f6000124d69e</guid><category><![CDATA[php]]></category><category><![CDATA[self]]></category><category><![CDATA[static]]></category><dc:creator><![CDATA[TvK]]></dc:creator><pubDate>Fri, 02 Feb 2018 17:01:41 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>PHP's difference between <code>static</code> and <code>self</code>.</p>
<pre><code class="language-php">
class Mom
{
    private const DEFAULT_AGE = 21;


    public static function getName(): string
    {
        return 'Alice';
    }
    
    public function tellAge(int $age = self::DEFAULT_AGE): string
    {
        return 'My age is: ' . $age;
    }
    
    public function tellAge2(int $age = self::DEFAULT_AGE): string
    {
        return 'My age is: ' . $age;
    }
    
    public static function tellAge3(): string
    {
        return 'My default age is: ' . self::DEFAULT_AGE;
    }
    
    // this would explode with 'Fatal error: &quot;static::&quot; is not allowed in compile-time constants'
    //public function tellAge4(int $age = static::DEFAULT_AGE): string
    //{
    //    return 'My age is: ' . $age;
    //}
    
    public static function returnInstance(): self
    {
        return new self();
    }
    
    public static function returnInstance2(): self
    {
        return new static();
    }
}

class Child extends Mom
{
    private const DEFAULT_AGE = 1;

    public static function getName(): string
    {
        return 'Bob';
    }
    
    // tell age 1 is not overridden
    
    public function tellAge2(int $age = self::DEFAULT_AGE): string
    {
        return 'My age is: ' . $age;
    }
    
    public static function tellAge3(): string
    {
        return 'My default age is: ' . self::DEFAULT_AGE;
    }
}


$alice = new Mom();
$bob = new Child();

echo '---------------'. PHP_EOL;
echo Mom::getName() . PHP_EOL;
echo Child::getName() . PHP_EOL;

echo '---------------'. PHP_EOL;
echo $alice-&gt;tellAge() . PHP_EOL;
echo $bob-&gt;tellAge() . PHP_EOL;

echo '---------------'. PHP_EOL;
echo $alice-&gt;tellAge2() . PHP_EOL;
echo $bob-&gt;tellAge2() . PHP_EOL;

echo '---------------'. PHP_EOL;
echo Mom::tellAge3() . PHP_EOL;
echo Child::tellAge3() . PHP_EOL;

echo '---------------'. PHP_EOL;
echo get_class(Mom::returnInstance()) . PHP_EOL;
echo get_class(Child::returnInstance()) . PHP_EOL;

echo '---------------'. PHP_EOL;
echo get_class(Mom::returnInstance2()) . PHP_EOL;
echo get_class(Child::returnInstance2()) . PHP_EOL;
</code></pre>
<p>Output:</p>
<pre><code>---------------
Alice
Bob
---------------
My age is: 21
My age is: 21
---------------
My age is: 21
My age is: 1
---------------
My default age is: 21
My default age is: 1
---------------
Mom
Mom
---------------
Mom
Child
</code></pre>
<p>Tags:<br>
<a href="https://blog.zztt.eu/tag/php">#php</a> <a href="https://blog.zztt.eu/tag/static">#static</a> <a href="https://blog.zztt.eu/tag/self">#self</a></p>
</div>]]></content:encoded></item><item><title><![CDATA[Quickie: a = b || c]]></title><description><![CDATA[<div class="kg-card-markdown"><p>This little post can be handy specially for full-stack devs, who use JS and PHP. PHP being a requirement here.</p>
<p>Do you know what happens when you assign OR-logical expression to a variable? Specifically in PHP, as it acts differently from other languages.</p>
<p>Python:</p>
<pre><code class="language-python">result = &quot;hello&quot; || &quot;world&</code></pre></div>]]></description><link>https://blog.zztt.eu/quickie-assign-logical-expression/</link><guid isPermaLink="false">5a748f73efb40800014dee32</guid><category><![CDATA[php]]></category><category><![CDATA[python]]></category><category><![CDATA[js]]></category><category><![CDATA[quickie]]></category><dc:creator><![CDATA[TvK]]></dc:creator><pubDate>Fri, 02 Feb 2018 16:26:39 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>This little post can be handy specially for full-stack devs, who use JS and PHP. PHP being a requirement here.</p>
<p>Do you know what happens when you assign OR-logical expression to a variable? Specifically in PHP, as it acts differently from other languages.</p>
<p>Python:</p>
<pre><code class="language-python">result = &quot;hello&quot; || &quot;world&quot;
print(result)
</code></pre>
<p>JavaScript:</p>
<pre><code class="language-js">result = 'hello' || 'world';
console.log(result);
</code></pre>
<p>In python and javascript the result is <code>&quot;hello&quot;</code>.</p>
<p>PHP:</p>
<pre><code class="language-php">$result = 'hello' || 'world';
echo $result;
</code></pre>
<p>But in PHP you get <code>true</code>.<br>
Don't forget about this when you switch contexts or rewrite code to/from PHP.</p>
<p>Tags:<br>
<a href="https://blog.zztt.eu/tag/php">#php</a> <a href="https://blog.zztt.eu/tag/python">#python</a> <a href="https://blog.zztt.eu/tag/js">#js</a> <a href="https://blog.zztt.eu/tag/quickie">#quickie</a></p>
</div>]]></content:encoded></item><item><title><![CDATA[Correct markup - <meter> vs <progress>]]></title><description><![CDATA[<div class="kg-card-markdown"><p>What's the difference between <code>&lt;meter&gt;</code> and <code>&lt;progress&gt;</code> and when to use them?</p>
<h2 id="meter">Meter</h2>
<p>indicates value in given range. Do not use this for progress indication.<br>
You can set min, max, current value; low, optimum, and high.</p>
<p>Examples are:</p>
<ul>
<li>distance (e.g. from your city to other</li></ul></div>]]></description><link>https://blog.zztt.eu/correct-markup-meter-vs-progress/</link><guid isPermaLink="false">5a628e983dd8440001ec6d18</guid><category><![CDATA[meter]]></category><category><![CDATA[progress]]></category><category><![CDATA[html]]></category><category><![CDATA[semantics]]></category><dc:creator><![CDATA[TvK]]></dc:creator><pubDate>Thu, 01 Feb 2018 23:10:45 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>What's the difference between <code>&lt;meter&gt;</code> and <code>&lt;progress&gt;</code> and when to use them?</p>
<h2 id="meter">Meter</h2>
<p>indicates value in given range. Do not use this for progress indication.<br>
You can set min, max, current value; low, optimum, and high.</p>
<p>Examples are:</p>
<ul>
<li>distance (e.g. from your city to other cities),</li>
<li>height of person,</li>
<li>grades at school,</li>
<li>wind strength,</li>
<li>precipitation,</li>
<li>temperature,</li>
<li>similarity when comparing 2 things.</li>
</ul>
<h2 id="progress">Progress</h2>
<p>Indicates completion of a task or process.<br>
Minimum value is 0. Maximum should be given (1 assumed if <code>max</code> attribute isn't present).</p>
<p>Examples are:</p>
<ul>
<li>steps in cart,</li>
<li>file upload,</li>
<li>multi-step form completion,</li>
<li>milestone completion (e.g. on Github),</li>
<li>loading of application.</li>
</ul>
<h2 id="uncertainity">Uncertainity</h2>
<p>If you have a CV, which indicates the level of your skills - which would you choose?</p>
<p>Let's take language level (A1-C2) as an example.</p>
<p>Meter makes sense, because it indicates value from range. If your knowledge of a language is B1, we can express it as something between 33-50%.<br>
The nice thing about meter is also low / high / optimum parameters. So you can set B1 to &quot;optimum&quot; (considering Cx being &quot;high&quot;).</p>
<p>Progress might make sense, because you can still be improving yourself. Language levels can be nice 6 steps in progress.<br>
But user visiting your site will probably not see any progress during her/his visit :)<br>
I think progress is generally better if your visitor can see changes in the process. Well, except milestone completion.</p>
<p>I would personally go with meter.</p>
<h2 id="styling">Styling</h2>
<p>For styling please refer to some other resource. I find these two to be nice:</p>
<ul>
<li><a href="https://css-tricks.com/html5-meter-element/">https://css-tricks.com/html5-meter-element/</a></li>
<li><a href="https://css-tricks.com/html5-progress-element/">https://css-tricks.com/html5-progress-element/</a></li>
</ul>
<p>Tags:<br>
<a href="https://blog.zztt.eu/tag/html">#html</a> <a href="https://blog.zztt.eu/tag/semantics">#semantics</a> <a href="https://blog.zztt.eu/tag/meter">#meter</a> <a href="https://blog.zztt.eu/tag/progress">#progress</a></p>
</div>]]></content:encoded></item><item><title><![CDATA[Quickie: Docker - root]]></title><description><![CDATA[<div class="kg-card-markdown"><p>Have you ever gave up solving some server problem and gave temporal non-root access to anybody?<br>
Or shared your hosting with some other person, how is not supposed to run <code>sudo</code>?</p>
<p>If you run Docker, it could be potentially dangerous.</p>
<ol>
<li>Let's assume you were bothered by always having to type</li></ol></div>]]></description><link>https://blog.zztt.eu/docker-root/</link><guid isPermaLink="false">5a723d8eefb40800014dee1c</guid><category><![CDATA[docker]]></category><category><![CDATA[root]]></category><category><![CDATA[sudo]]></category><dc:creator><![CDATA[TvK]]></dc:creator><pubDate>Wed, 31 Jan 2018 22:28:31 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>Have you ever gave up solving some server problem and gave temporal non-root access to anybody?<br>
Or shared your hosting with some other person, how is not supposed to run <code>sudo</code>?</p>
<p>If you run Docker, it could be potentially dangerous.</p>
<ol>
<li>Let's assume you were bothered by always having to type <code>sudo</code> when working with Docker.<br>
So you added your user to docker group (<a href="https://askubuntu.com/questions/477551/how-can-i-use-docker-without-sudo#477554">https://askubuntu.com/questions/477551/how-can-i-use-docker-without-sudo#477554</a>).</li>
<li>You probably don't run only custom images, which use by default non-root user.</li>
<li>And you probably also didn't do <a href="https://docs.docker.com/engine/security/userns-remap/#enable-userns-remap-on-the-daemon">ns-mapping</a> of UIDs.</li>
</ol>
<p>So anybody with access to such your user can run something like:</p>
<pre><code>docker run -it -v /etc:/host/etc alpine:stretch sh
</code></pre>
<p>And voila, he now has root access to your <code>/etc</code> directory.</p>
<p>Tags:<br>
<a href="https://blog.zztt.eu/tag/docker">#docker</a> <a href="https://blog.zztt.eu/tag/root">#root</a> <a href="https://blog.zztt.eu/tag/sudo">#sudo</a></p>
</div>]]></content:encoded></item><item><title><![CDATA[Quickie: round()]]></title><description><![CDATA[<div class="kg-card-markdown"><p>Once again, different programming languages give different results. Now let's focus on rounding negative numbers.</p>
<p>Python + PHP</p>
<pre><code class="language-python">print(round(-1.5)) # -2
print(round(1.5))  # 2
</code></pre>
<pre><code class="language-php">echo round(-1.5) // -2
echo round(1.5)  // 2
</code></pre>
<p>JavaScript</p>
<pre><code class="language-js">console.debug(Math.round(-1.5)); // -1
console.debug(Math.round(1.</code></pre></div>]]></description><link>https://blog.zztt.eu/round/</link><guid isPermaLink="false">5a7238d9efb40800014dee12</guid><category><![CDATA[javascript]]></category><category><![CDATA[js]]></category><category><![CDATA[math]]></category><category><![CDATA[round]]></category><dc:creator><![CDATA[TvK]]></dc:creator><pubDate>Wed, 31 Jan 2018 21:56:26 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>Once again, different programming languages give different results. Now let's focus on rounding negative numbers.</p>
<p>Python + PHP</p>
<pre><code class="language-python">print(round(-1.5)) # -2
print(round(1.5))  # 2
</code></pre>
<pre><code class="language-php">echo round(-1.5) // -2
echo round(1.5)  // 2
</code></pre>
<p>JavaScript</p>
<pre><code class="language-js">console.debug(Math.round(-1.5)); // -1
console.debug(Math.round(1.5)); // 2
</code></pre>
<h2 id="rounding">Rounding</h2>
<p>There are way more rounding methods that we were taught at school.<br>
I will not explain them here, but rather share links with you:</p>
<ul>
<li><a href="http://mathforum.org/library/drmath/view/71202.html">http://mathforum.org/library/drmath/view/71202.html</a></li>
<li><a href="https://en.wikipedia.org/wiki/Rounding#Round_half_towards_zero">https://en.wikipedia.org/wiki/Rounding#Round_half_towards_zero</a><br>
Enjoy!</li>
</ul>
<p>This message was edited, firstly I declared JS negative number rounding incorrent. Then after feedback I read about rounding, so now I don't claim it's wrong. I will just say - be careful with different languages, and check them before you engage in any important math.</p>
<p><strong>Edit 2</strong>:<br>
In PHP you can specify which rounding method you want to use (well, I should RTFM next time). It's the 3rd parameter to <a href="https://secure.php.net/manual/en/function.round.php"><code>round</code> function</a>.</p>
<table>
<thead>
<tr>
<th>Constant</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>PHP_ROUND_HALF_UP</td>
<td>Round val up to precision decimal places away from zero, when it is half way there. Making 1.5 into 2 and -1.5 into -2.</td>
</tr>
<tr>
<td>PHP_ROUND_HALF_DOWN</td>
<td>Round val down to precision decimal places towards zero, when it is half way there. Making 1.5 into 1 and -1.5 into -1.</td>
</tr>
<tr>
<td>PHP_ROUND_HALF_EVEN</td>
<td>Round val to precision decimal places towards the nearest even value.</td>
</tr>
<tr>
<td>PHP_ROUND_HALF_ODD</td>
<td>Round val to precision decimal places towards the nearest odd value.</td>
</tr>
</tbody>
</table>
<p><a href="https://stackoverflow.com/questions/41586838/rounding-of-negative-numbers-in-javascript#41586903">StackOverflow suggests</a> to always convert to positive number, and then multiply with -1, if it was a negative number.</p>
<p>Tags:<br>
<a href="https://blog.zztt.eu/tag/js">#js</a> <a href="https://blog.zztt.eu/tag/javascript">#javascript</a> <a href="https://blog.zztt.eu/tag/math">#math</a> <a href="https://blog.zztt.eu/tag/round">#round</a> <a href="https://blog.zztt.eu/tag/quickie">#quickie</a></p>
</div>]]></content:encoded></item><item><title><![CDATA[2017 recap]]></title><description><![CDATA[<div class="kg-card-markdown"><h2 id="duolingo">Duolingo</h2>
<p>In January I signed up to Duolingo.<br>
Since about August I started a long streak. The last day of year I reached 142 day streak!<br>
I got to learn a lot of languages. I just wish I had more time.<br>
Also, what a pity Esperanto didn't become world-wide used</p></div>]]></description><link>https://blog.zztt.eu/2017-recap/</link><guid isPermaLink="false">5a380f15289e320001d99778</guid><dc:creator><![CDATA[TvK]]></dc:creator><pubDate>Sun, 31 Dec 2017 22:59:00 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1482932542078-12df7104cc78?ixlib=rb-0.3.5&amp;q=80&amp;fm=jpg&amp;crop=entropy&amp;cs=tinysrgb&amp;w=1080&amp;fit=max&amp;s=af3a07e2106a90ceb94acba79feb422e" medium="image"/><content:encoded><![CDATA[<div class="kg-card-markdown"><h2 id="duolingo">Duolingo</h2>
<img src="https://images.unsplash.com/photo-1482932542078-12df7104cc78?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=1080&fit=max&s=af3a07e2106a90ceb94acba79feb422e" alt="2017 recap"><p>In January I signed up to Duolingo.<br>
Since about August I started a long streak. The last day of year I reached 142 day streak!<br>
I got to learn a lot of languages. I just wish I had more time.<br>
Also, what a pity Esperanto didn't become world-wide used language...</p>
<h2 id="work">Work</h2>
<p>A lot of changes happened at my work. And it changed to worse.<br>
So after almost exactly 3 years it was time to say good-bye and change.<br>
So far, so good :)</p>
<p>There are only like 2 things that I <em>do</em> miss:</p>
<ul>
<li>our &quot;Friday parties&quot; (no longer active, as I can imagine),</li>
<li>few ex-colleagues (many of them left too, though).</li>
</ul>
<h2 id="servers">Servers</h2>
<p>In May I got my first server. Got so much self-hosted stuff. It was also important to talk to those nice people from work. Especially after I was going to leave.</p>
<p>It also pushed me to learn more about Docker. And later even try Docker Swarm.</p>
<p>Still haven't created and published any site of mine :(</p>
<h2 id="other">Other</h2>
<p>In March I joined amateur badminton league. Got from F-group to E-group. Peaking D.</p>
<p>Got to know that hedgehogs are extremely cute animals.</p>
<p>I joined Github. Not that I'm much active there, but helping with some issues - like Docker :)</p>
<p>In May I got into Mensa.</p>
<h2 id="lastlyasurprise">Lastly - a surprise</h2>
<p>Without any expensive research I discovered the existence of living organisms that weren't supposed to exist.</p>
<p>And got to know how firewalls can make life harder. Ugh.</p>
<p>JBFIM</p>
<h2 id="2018">2018</h2>
<p>I would be glad if the next year made at least half of my wishes true:</p>
<ul>
<li>improve my foreign languages skills,</li>
<li>improve myself in IT field,</li>
<li>after having most of my servers running, I'd like to start using my framework - so many ideas!,</li>
<li>to get the bug fixed.</li>
</ul>
<p>And not to forget:<br><br>
<span style="font-size:40px;">Happy New Year everyone! :)</span></p>
</div>]]></content:encoded></item><item><title><![CDATA[How long are you working?]]></title><description><![CDATA[<div class="kg-card-markdown"><p>When you want to get notified every half hour how long you are already working, you can use this simple script, run it in terminal.</p>
<p>Notice however, that it won't save your life nor make the time go faster, but at least it will distract you with little pop-ups :)</p>
<p>Here's</p></div>]]></description><link>https://blog.zztt.eu/how-long-are-you-working/</link><guid isPermaLink="false">5a38b6c90f3ac60001fa1208</guid><category><![CDATA[bash]]></category><dc:creator><![CDATA[TvK]]></dc:creator><pubDate>Tue, 19 Dec 2017 22:08:09 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>When you want to get notified every half hour how long you are already working, you can use this simple script, run it in terminal.</p>
<p>Notice however, that it won't save your life nor make the time go faster, but at least it will distract you with little pop-ups :)</p>
<p>Here's the code. It's really a one-liner, just broken into lines for better readability.</p>
<pre><code class="language-bash">while [ 1 ]; do \
    notify-send -u low \
    -t 5000 \
    &quot;You are already working: &quot;$(uptime \
    | awk '{print $3}' \
    | sed 's/,//'); \
    sleep $((30*60)); \
done;
</code></pre>
<p>Notes:<br>
I tested it on Cinnamon and MATE desktops, where it works. If you use something simpler like IceWM, it might not work.</p>
<p>Tags: <a href="https://blog.zztt.eu/tag/bash">#bash</a></p>
</div>]]></content:encoded></item><item><title><![CDATA[Ni - vi]]></title><description><![CDATA[<div class="kg-card-markdown"><p>While I was learning Swedish and Esperanto courses on Duolingo, I noticed how they have opposite meanings for words <em>ni</em> and <em>vi</em>.</p>
<p>So I had to look etymology of them on <a href="https://www.wiktionary.org">Wiktionary</a>.</p>
<h2 id="swedish">Swedish</h2>
<h3 id="niyoupl">ni = you (pl.)</h3>
<p>From verb suffix <em>-(e)n</em> with pronoun <em>I</em>. From Old-Swedish <em>ī</em>, <em>ir</em>.<br>
<em>I</em></p></div>]]></description><link>https://blog.zztt.eu/ni-vi/</link><guid isPermaLink="false">5a38242cce18fd00018c824b</guid><category><![CDATA[languages]]></category><category><![CDATA[duolingo]]></category><category><![CDATA[swedish]]></category><category><![CDATA[esperanto]]></category><category><![CDATA[etymology]]></category><dc:creator><![CDATA[TvK]]></dc:creator><pubDate>Mon, 18 Dec 2017 20:46:08 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>While I was learning Swedish and Esperanto courses on Duolingo, I noticed how they have opposite meanings for words <em>ni</em> and <em>vi</em>.</p>
<p>So I had to look etymology of them on <a href="https://www.wiktionary.org">Wiktionary</a>.</p>
<h2 id="swedish">Swedish</h2>
<h3 id="niyoupl">ni = you (pl.)</h3>
<p>From verb suffix <em>-(e)n</em> with pronoun <em>I</em>. From Old-Swedish <em>ī</em>, <em>ir</em>.<br>
<em>I</em> is an archaic form of <em>you</em>. Also in Danish <em>I</em> is still used.</p>
<h3 id="viwe">vi = we</h3>
<p>From Old Swedish <em>vīr</em>, which comes from Old Norse <em>vér</em>.<br>
Compare also to Norwegian <em>vi</em>, Danish <em>vi</em>, German <em>wir</em> and English <em>we</em>.</p>
<h2 id="esperanto">Esperanto</h2>
<h3 id="niwe">ni = we</h3>
<p>Originating in romance languages - Italian <em>noi</em>, Spanish <em>nos</em>, French <em>nous</em> and Latin <em>nos</em>.</p>
<h3 id="viyoupl">vi = you (pl.)</h3>
<p>Originating in French <em>vous</em> and Italian <em>voi</em> or Russian <em>вы</em> (vy).</p>
<p>Dankon Duolingo kaj Wiktionary!</p>
<p>Sources:</p>
<ul>
<li><a href="https://en.wiktionary.org/wiki/ni#Swedish">https://en.wiktionary.org/wiki/ni#Swedish</a></li>
<li><a href="https://en.wiktionary.org/wiki/ni#Esperanto">https://en.wiktionary.org/wiki/ni#Esperanto</a></li>
<li><a href="https://en.wiktionary.org/wiki/vi#Swedish">https://en.wiktionary.org/wiki/vi#Swedish</a></li>
<li><a href="https://en.wiktionary.org/wiki/vi#Esperanto">https://en.wiktionary.org/wiki/vi#Esperanto</a></li>
</ul>
<p>Tags: <a href="https://blog.zztt.eu/tag/languages/">#languages</a> <a href="https://blog.zztt.eu/tag/duolingo/">#duolingo</a> <a href="https://blog.zztt.eu/tag/swedish/">#swedish</a> <a href="https://blog.zztt.eu/tag/esperanto/">#esperanto</a> <a href="https://blog.zztt.eu/tag/etymology/">#etymology</a></p>
</div>]]></content:encoded></item><item><title><![CDATA[A blog was born]]></title><description><![CDATA[<div class="kg-card-markdown"><p><img src="https://i.imgur.com/wfvVgra.png" alt="Hi All!"></p>
<p>On this blog you'll find for the most part IT stuff, some language oriented topics and who knows what more.</p>
<p>Although English isn't my native language, most of my posts will probably be in this language, because IT posts are supposed to help anybody on the internet.</p>
<p>Feel free to</p></div>]]></description><link>https://blog.zztt.eu/blog-was-born/</link><guid isPermaLink="false">5a3820cbce18fd00018c824a</guid><dc:creator><![CDATA[TvK]]></dc:creator><pubDate>Mon, 18 Dec 2017 20:24:48 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1480506132288-68f7705954bd?ixlib=rb-0.3.5&amp;q=80&amp;fm=jpg&amp;crop=entropy&amp;cs=tinysrgb&amp;w=1080&amp;fit=max&amp;s=3fdb3199fe4c0c8f85d35b4aacf121b7" medium="image"/><content:encoded><![CDATA[<div class="kg-card-markdown"><img src="https://images.unsplash.com/photo-1480506132288-68f7705954bd?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=1080&fit=max&s=3fdb3199fe4c0c8f85d35b4aacf121b7" alt="A blog was born"><p><img src="https://i.imgur.com/wfvVgra.png" alt="A blog was born"></p>
<p>On this blog you'll find for the most part IT stuff, some language oriented topics and who knows what more.</p>
<p>Although English isn't my native language, most of my posts will probably be in this language, because IT posts are supposed to help anybody on the internet.</p>
<p>Feel free to use your grammar-nazi feelings and correct my English.<br>
(or any other language)</p>
<p>- TvK</p>
</div>]]></content:encoded></item></channel></rss>