alexkras.com

  • Home
  • YouTube
  • Tech News TLDR
  • Top Posts
  • Resume
    • Projects
  • Contact
    • About

Archives for July 2017

Building a Simple Stopwatch App with Electron

July 28, 2017 by Alex Kras 14 Comments

Share this:

Few days ago I decided to find a Stopwatch app for my Mac. I went over to the App Store and noticed that there were no good free options available.

I thought to myself, how hard would it be to make one with Electron? Turns out, it was very easy.


Getting an Electron shell running

As you probably already know, Electron is a very popular open source framework that makes developing cross platform Desktop GUI apps very easy. It works as a wrapper around Chrome browser, so all Electron apps are just regular web apps wrapped in some magic.

Since Chrome runs on most platforms, so does Electron. Electron powers Slack, Atom, Visual Studio Code, Hyper and many other apps.

I’ve read various Electron tutorials a number of times, but never got around to building an actual app myself. I was pleasantly surprised that it took less than 2 minutes to get and run an Electron shell on my computer.

I used the Electron Quick Start project with the following steps:

1
2
3
4
5
git clone https://github.com/electron/electron-quick-start
cd electron-quick-start/
npm install
npm start
 

This opened an Electron shell that looked as such:

Looking inside the index.html file, I noticed the following code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Hello World!</title>
  </head>
  <body>
    <h1>Hello World!</h1>
    <!-- All of the Node.js APIs are available in this renderer process. -->
    We are using Node.js <script>document.write(process.versions.node)</script>,
    Chromium <script>document.write(process.versions.chrome)</script>,
    and Electron <script>document.write(process.versions.electron)</script>.
  </body>
 
  <script>
    // You can also require other files to run in this process
    require('./renderer.js')
  </script>
</html>
 

So the Electron shell above was just using the content of this index.html file. All I had to do to make the stopwatch app, was to add some HTML, CSS and JavaScript inside the index.html file.


Getting the Stopwatch code

There are a lot of stopwatch examples available online. For inspiration I went to codepen.io and searched for stopwatch there. As a proof of concept I copy/pasted a random example into the index.html file (making sure to wrap it into proper <body></body>, <style></style> and <script></script> tags) and it just worked.

While other people’s example were great, I wanted to write my own version. You can see it bellow running inside Codepen. I also forked the Electron Quick Start and tracked my development in Simple Stopwatch repo on Github. There you can see the final index.html file, as well as the app.js where I implemented all of the JavaScript logic and style.css file with all of the CSS.

See the Pen stop-watch by Alex (@akras14) on CodePen.

I noticed that the default electron window was a little too big for my use case, so I modified the mainWindow = new BrowserWindow({width: 500, height: 300}) line inside main.js file to make it a little smaller.

I believe the code is fairly self explanatory so I am not going to go over it in detail in this post. Please let me know in the comment area if you would like to see a more detailed walk through and I’ll make sure to write one.

Building a native application wrapper

I used another repo called Electron Packager to generate an actual app bundle. I installed it via npm install --save-dev electron-packager. Once installed, I added the following npm script into my package.json file:

1
2
"build": "electron-packager ./ simple-stopwatch --icon=icon/stopwatch.icns --overwrite"
 

The parameters are:

  • The folder my app is in
  • Name that I want to use for the app
  • Icon that I want to use for the app
  • Force over-write the old app on build re-run

Running this command with npm run build would generate a /simple-stopwatch-darwin-x64 folder, inside of which I’ll have the generated simple-stopwatch.app. Finally, I just had to move the generated app into the /Applications folder and I was done.

Few additional notes. In order to generate the app icon I downloaded a free stopwatch image from pixabay.com and converted it to icns format via iconverticons.com.

Also electron-packager was smart enough to generate an app for the right system (Mac OS in my case). I have not tried it, but I am sure that it would be just as easy to generate a working app for Windows or Linux. The only thing that would vary between platforms is the icon format. More information is available in electron-packager’s documentation.

The final product

I am pretty happy with the final product. It feels and act like a native app.

The UI is not polished, but UX does what I want it to do. It will be very easy to make it even better, since it’s just a regular web app.

Most importantly, I can see why Electron is such a popular project and why so many companies are choosing to build OS specific apps with it.

Update 07/28/2017: Some people criticized me for calling Electron a “native” app. By that I simply meant that I could run the app without having to open a browser. There are a lot of “in browser” stopwatches available, but I wanted to be able to use my stopwatch via regular app hotkeys like “Command + Tab”. Electron project describes itself as follows:

“If you can build a website, you can build a desktop app. Electron is a framework for creating native applications with web technologies like JavaScript, HTML, and CSS.”

I believe that whether Electron apps should be called “native” depends mainly on how “native” is defined.

Another criticism is that Electron apps are very bloated, since they have to package and run a full browser to execute something as simple as a stopwatch. This is true and Electron’s performance implications should be carefully consider when deciding to use it for a production app.

Please Share:

Wanna see my pretty face and hear me ramble? Check out my YouTube channel 🙂

P.S. Check out Disrupted: My Misadventure in the Start-Up Bubble by Dan Lyons a co-producer and writer for the HBO series Silicon Valley (sponsored).


P.P.S. Let's connect on Twitter, Facebook or LinkedIn. You can also get updates via RSS Feed or the Email Form Bellow.
Follow @akras14

Subscribe to Blog via Email

Enter your email address to subscribe to this blog and receive notifications of new posts by email.

You may also like:
Share this:

Filed Under: Front End, JavaScript, Node.Js, Software Engineering

One Month Without AMP

July 26, 2017 by Alex Kras 5 Comments

Share this:

One month ago I decided to disable Accelerated Mobile Pages (AMP) support on my site. This is a quick follow up on my experience so far and some metrics. In summary, I like it.

Proof that it’s gone

The following image captured in Google Webmaster’s Search Console indicates that the total count of AMP pages on my site went from about 60 to 0.

Count of AMP Pages


The following image indicate that AMP impressions went down from 7K to less than 150, when compared to a similar time period a month ago. The 150 count likely indicates that it took some time from AMP results for my site to clear out from Google search.

AMP Impressions

Effect on Search Traffic

It seems that Google in fact does NOT penalize websites for NOT having AMP support.

Here is my traffic according to Google Analytics, filtered to only show results that came from Google Search. The results are displayed for the past month and compared to a similar time period in the prior month.

Traffic rate appears to stay roughly the same and all metrics appear to improve. To be fair, I did publish four new articles since I disabled AMP, so my numbers could have had a nice bump from the new content.

Google Analytics Traffic

Last but not least, here are the stats that I have from Google Webmaster’s Search Console.

Webmaster’s Search Console Traffic

My Click Through Rate (number of clicks / number of impressions) actually went DOWN from 4.74% to 3.15%. My average position also went down from 26.5 to 44.4. But my number of impressions went UP from 166K to 252K.

As I mentioned earlier, that shift could be due to new content that I published, including Reverse Engineering One Line of JavaScript, which showed up in Google more, but at a much lower positions, skewing the numbers. I am not sure if these numbers co-relate directly with the removal of AMP, especially considering that AMP traffic accounted for only 7K visits, as can be seen at the top of this post.


To further confirm that my existing search rankings were not penalized, I filtered metrics for the top three search terms from the previous month.

Git Tips – Average position declined from 2.4 to 2.9

Angular Performance – Average position improved from 2.4 to 2.3

Node JS Memory Leak – Average position improved from 3.4 to 2.9

All in all, these numbers appears to show a “regular” fluctuation due to whatever magic Google’s search algorithm is doing. I feel confident that removing AMP did not affect my search result rankings.

Effect on Me

Believe it or not, but I feel happier. I enabled AMP on my site because I felt that it would make Google happy and would help my search rankings. At the same time I did not like my (default for WordPress) implementation of AMP. I knew there were a lot of issues with it, which I didn’t have time to fix. So every time I would see an AMP result in Google Search on my mobile, I would cringe, because it would remind me of all the troubles that I had with AMP.

Now AMP does not upset me nearly as much. I even found myself liking an AMP version of a site that otherwise had a lot of ads on it. Knowing that I don’t have to support AMP as a publisher, makes me hate it less as a user.

Another benefit of not having AMP serve as an excuse for my site being “mobile friendly”, is that I began to care more about my site ACTUALLY being mobile friendly. I was able to identified a number of performance bottlenecks, which I am now addressing.

Conclusion

AMP is not for everyone. I will repeat. AMP IS NOT FOR EVERYONE.

If you are going to implement AMP, make sure to implement it right. You can read my other article on the subject for practical advice and some pitfalls to avoid.

Ironically, the only sites that can benefit from AMP are the sites that have the resources needed to implement a highly optimized mobile version. For example, BBC has a great AMP page that feels almost like a native site. At the same time BBC’s mobile site is so great, that I don’t really need the AMP version to have a good experience.

Unless you run a News site that HAS to compete for a spot in Google Carousel enabling AMP is not worth the effort. AMP is an alternative publishing format and most small site can’t afford to maintain two (quality) versions of itself.

Since not having AMP support does not result in a Google Search penalty, why bother?

Please Share:

Wanna see my pretty face and hear me ramble? Check out my YouTube channel 🙂

P.S. Check out Disrupted: My Misadventure in the Start-Up Bubble by Dan Lyons a co-producer and writer for the HBO series Silicon Valley (sponsored).


P.P.S. Let's connect on Twitter, Facebook or LinkedIn. You can also get updates via RSS Feed or the Email Form Bellow.
Follow @akras14

Subscribe to Blog via Email

Enter your email address to subscribe to this blog and receive notifications of new posts by email.

You may also like:
Share this:

Filed Under: AMP, SEO

Reverse Engineering One Line of JavaScript

July 13, 2017 by Alex Kras 26 Comments

Share this:

Few months ago I saw an email asking if someone could unwrap this one line of JavaScript.

1
2
<pre id=p><script>n=setInterval("for(n+=7,i=k,P='p.\\n';i-=1/k;P+=P[i%2?(i%2*j-j+n/k^j)&1:2])j=k/i;p.innerHTML=P",k=64)</script>
 


This line will render just like the image below. You can see it in your browser here. It was created by Mathieu ‘p01’ Henri, author of www.p01.org where you can find this and many other cool demos.


Challenge accepted!

Reverse Engineering One Line of JavaScript
#javascript https://t.co/a1JheNcJSq

— Alex Kras (@akras14) July 13, 2017

Part 1. Making the code readable

First things first, I kept HTML in the HTML and moved JavaScript into a code.js file. I also wrapped p in the id="p" in quotes.

index.html

1
2
3
<script src="code.js"></script>
<pre id="p"></pre>
 

I noticed that there was a variable k, which was just a constant, so I moved it out of the line, and renamed it as delay.

code.js


1
2
3
4
var delay = 64;
var draw = "for(n+=7,i=delay,P='p.\\n';i-=1/delay;P+=P[i%2?(i%2*j-j+n/delay^j)&1:2])j=delay/i;p.innerHTML=P";
var n = setInterval(draw, delay);
 

Next, the var draw was just a string, that was being executed as eval within setInterval, since setInterval can accept a function or a string to be evaluated. I moved it to an actual function. I kept the old line there, though, for reference.

Another thing that I noticed was that element p was actually referring to the DOM element with id p that was declared in HTML, the one I recently wrapped in quotes. Turns out elements can be referenced by their id name from JavaScript, as long as the id name is made up of alpha-numeric characters only. I added the document.getElementById("p") to make it more intuitive.

1
2
3
4
5
6
7
8
9
10
var delay = 64;
var p = document.getElementById("p"); // < --------------
// var draw = "for(n+=7,i=delay,P='p.\\n';i-=1/delay;P+=P[i%2?(i%2*j-j+n/delay^j)&1:2])j=delay/i;p.innerHTML=P";
var draw = function() {
    for (n += 7, i = delay, P = 'p.\n'; i -= 1 / delay; P += P[i % 2 ? (i % 2 * j - j + n / delay ^ j) & 1 : 2]) {
        j = delay / i; p.innerHTML = P;
    }
};
var n = setInterval(draw, delay);
 

Next, I declare the variables i, p, and j, and moved them to the top of the function.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var delay = 64;
var p = document.getElementById("p");
// var draw = "for(n+=7,i=delay,P='p.\\n';i-=1/delay;P+=P[i%2?(i%2*j-j+n/delay^j)&1:2])j=delay/i;p.innerHTML=P";
var draw = function() {
    var i = delay; // < ---------------
    var P ='p.\n';
    var j;
    for (n += 7; i > 0 ;P += P[i % 2 ? (i % 2 * j - j + n / delay ^ j) & 1 : 2]) {
        j = delay / i; p.innerHTML = P;
        i -= 1 / delay;
    }
};
var n = setInterval(draw, delay);
 

I factored out for loop into a while loop. Keeping only the CHECK_EVERY_LOOP part of for‘s 3 parts: (RUNS_ONCE_ON_INIT; CHECK_EVERY_LOOP; DO_EVERY_LOOP), and moving everything else in or outside of the body of the loop.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var delay = 64;
var p = document.getElementById("p");
// var draw = "for(n+=7,i=delay,P='p.\\n';i-=1/delay;P+=P[i%2?(i%2*j-j+n/delay^j)&1:2])j=delay/i;p.innerHTML=P";
var draw = function() {
    var i = delay;
    var P ='p.\n';
    var j;
    n += 7;
    while (i > 0) { // <----------------------
        //Update HTML
        p.innerHTML = P;
 
        j = delay / i;
        i -= 1 / delay;
        P += P[i % 2 ? (i % 2 * j - j + n / delay ^ j) & 1 : 2];
    }
};
var n = setInterval(draw, delay);
 

I unroll ternary operator ( condition ? do if true : do if false) in P += P[i % 2 ? (i % 2 * j - j + n / delay ^ j) & 1 : 2];.

i%2 was checking if i was even or odd. If i was even, it was just returning 2. If i was odd, it was returning the magic value of (i % 2 * j - j + n / delay ^ j) & 1; (more on that in a bit).

Finally that index was used to offset into string P, so it became P += P[index];.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
var delay = 64;
var p = document.getElementById("p");
// var draw = "for(n+=7,i=delay,P='p.\\n';i-=1/delay;P+=P[i%2?(i%2*j-j+n/delay^j)&1:2])j=delay/i;p.innerHTML=P";
var draw = function() {
    var i = delay;
    var P ='p.\n';
    var j;
    n += 7;
    while (i > 0) {
        //Update HTML
        p.innerHTML = P;
 
        j = delay / i;
        i -= 1 / delay;
 
        let index;
        let iIsOdd = (i % 2 != 0); // <---------------
 
        if (iIsOdd) { // <---------------
            index = (i % 2 * j - j + n / delay ^ j) & 1;
        } else {
            index = 2;
        }
 
        P += P[index];
    }
};
var n = setInterval(draw, delay);
 

I factored out & 1; in index = (i % 2 * j - j + n / delay ^ j) & 1 into another if statement.

This one is a clever way of checking if the result in parentheses is odd or even, and returning 0 for even and 1 for odd. & is a bitwise AND operator. Logic for AND is as follows:

  • 1 & 1 = 1
  • 0 & 1 = 0

Hence something & 1 will convert “something” to a binary representation, it will also pad 1 with as many 0 in the front as needed, to match the length of something, and will return just an AND of the last bit. For example, 5 in binary is 101, if we AND it with 1 will get the following:

1
2
3
4
    101
AND 001
    001
 

In other words, 5 is odd, and result of 5 & 1 is 1. It’s easy to confirm that this logic holds in a JavaScript console.

1
2
3
4
5
6
7
0 & 1 // 0 - even return 0
1 & 1 // 1 - odd return 1
2 & 1 // 0 - even return 0
3 & 1 // 1 - odd return 1
4 & 1 // 0 - even return 0
5 & 1 // 1 - odd return 1
 

Note that I also renamed rest of index to magic, so the code with unrolled &1 will looks as follows.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
var delay = 64;
var p = document.getElementById("p");
// var draw = "for(n+=7,i=delay,P='p.\\n';i-=1/delay;P+=P[i%2?(i%2*j-j+n/delay^j)&1:2])j=delay/i;p.innerHTML=P";
var draw = function() {
    var i = delay;
    var P ='p.\n';
    var j;
    n += 7;
    while (i > 0) {
        //Update HTML
        p.innerHTML = P;
 
        j = delay / i;
        i -= 1 / delay;
 
        let index;
        let iIsOdd = (i % 2 != 0);
 
        if (iIsOdd) {
            let magic = (i % 2 * j - j + n / delay ^ j);
            let magicIsOdd = (magic % 2 != 0); // &1 < --------------------------
            if (magicIsOdd) { // &1 <--------------------------
                index = 1;
            } else {
                index = 0;
            }
        } else {
            index = 2;
        }
 
        P += P[index];
    }
};
var n = setInterval(draw, delay);
 

Next I unrolled P += P[index]; into a switch statement. By now it’s clear that index can only be one of three values – 0, 1, or 2. It’s also clear that P always gets initialized with the following values – var P ='p.\n';. Where 0 points to p, 1 points to . and 2 points to \n – a new line character.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
var delay = 64;
var p = document.getElementById("p");
// var draw = "for(n+=7,i=delay,P='p.\\n';i-=1/delay;P+=P[i%2?(i%2*j-j+n/delay^j)&1:2])j=delay/i;p.innerHTML=P";
var draw = function() {
    var i = delay;
    var P ='p.\n';
    var j;
    n += 7;
    while (i > 0) {
        //Update HTML
        p.innerHTML = P;
 
        j = delay / i;
        i -= 1 / delay;
 
        let index;
        let iIsOdd = (i % 2 != 0);
 
        if (iIsOdd) {
            let magic = (i % 2 * j - j + n / delay ^ j);
            let magicIsOdd = (magic % 2 != 0); // &1
            if (magicIsOdd) { // &1
                index = 1;
            } else {
                index = 0;
            }
        } else {
            index = 2;
        }
 
        switch (index) { // P += P[index]; <-----------------------
            case 0:
                P += "p"; // aka P[0]
                break;
            case 1:
                P += "."; // aka P[1]
                break;
            case 2:
                P += "\n"; // aka P[2]
        }
    }
};
 
var n = setInterval(draw, delay);
 

I cleaned up the var n = setInterval(draw, delay); magic. Set interval returns an integer starting with 1, and increments it by one every time setInterval is called. That integer can be used to clearInterval (cancel it). In our case, setInterval was being called just one time, and n was simply getting set to 1.

I also rename delay to DELAY to remind that it was just a constant.

Last but not least, I put parentheses in i % 2 * j - j + n / DELAY ^ j to point out that ^ bitwise XOR has lower precedence then %, *, -, +, and / operators. In other words all of the computations above will be conducted first, before ^ is evaluated. Resulting in (i % 2 * j - j + n / DELAY) ^ j).

Update: It was pointed out to me, that I mistakenly placed p.innerHTML = P; //Update HTML inside the while loop, so I moved it out.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
const DELAY = 64; // approximately 15 frames per second 15 frames per second * 64 seconds = 960 frames
var n = 1;
var p = document.getElementById("p");
// var draw = "for(n+=7,i=delay,P='p.\\n';i-=1/delay;P+=P[i%2?(i%2*j-j+n/delay^j)&1:2])j=delay/i;p.innerHTML=P";
 
/**
* Draws a picture
* 128 chars by 32 chars = total 4096 chars
*/
var draw = function() {
    var i = DELAY; // 64
    var P ='p.\n'; // First line, reference for chars to use
    var j;
 
    n += 7;
 
    while (i > 0) {
 
        j = DELAY / i;
        i -= 1 / DELAY;
 
        let index;
        let iIsOdd = (i % 2 != 0);
 
        if (iIsOdd) {
            let magic = ((i % 2 * j - j + n / DELAY) ^ j); // < ------------------
            let magicIsOdd = (magic % 2 != 0); // &1
            if (magicIsOdd) { // &1
                index = 1;
            } else {
                index = 0;
            }
        } else {
            index = 2;
        }
 
        switch (index) { // P += P[index];
            case 0:
                P += "p"; // aka P[0]
                break;
            case 1:
                P += "."; // aka P[1]
                break;
            case 2:
                P += "\n"; // aka P[2]
        }
    }
    //Update HTML
    p.innerHTML = P;
};
 
setInterval(draw, 64);
 

You can see the final result in action here.

Part 2. Understanding what the code does

So what is going on here? Let’s see.

Initial value of i is set to 64 via var i = DELAY;, and it’s decremented by 1/64 (0.015625) on every loop via i -= 1 / DELAY;. The loop goes on until i is no longer greater than 0 while (i > 0) {. Every run of the loop, i is decremented by 1/64th, so it will take 64 loops for i to decrement by 1 (64/64 = 1). In total then i would have to be decremented 64 x 64 = 4096 times, to become below 0.

The image consist of 32 rows, with 128 chars in every row. Conveniently 64 x 64 = 32 x 128 = 4096. i will only be even (not odd let iIsOdd = (i % 2 != 0);) when i is strictly an even number. We’ll get it to happen 32 times, when i is 64, 62, 60 etc. These 32 times, the index will be set to 2 index = 2; and a new line character will be added to the line P += "\n"; // aka P[2]. The rest 127 character per row will either be set to p or ..

But when do we set p and when do we set .?

Well, for starters we know that we will set it to . when magic let magic = ((i % 2 * j - j + n / DELAY) ^ j); is odd, and we’ll set it to p when magic is even.

1
2
3
4
5
6
7
8
9
10
var P ='p.\n';
 
...
 
if (magicIsOdd) { // &1
    index = 1; // second char in P - .
} else {
    index = 0; // first char in P - p
}
 

But when is magic odd and when is it even? That’s a million dollar question. Before we talk about that though, let’s establish one more thing.

If we remove + n/DELAY from let magic = ((i % 2 * j - j + n / DELAY) ^ j);, we’ll end up with the following static layout, that will not be moving at all.

For now let’s look at the magic with + n/DELAY removed. How do we end up with the pretty picture above?

(i % 2 * j - j) ^ j

Note that for every loop we have:

1
2
3
j = DELAY / i;
i -= 1 / DELAY;
 

In other words we can express j in terms of the final i as j = DELAY/ (i + 1/DELAY) but since 1/DELAY is such a small number, for illustration purposed we can drop + 1/DELAY and simplify it to j = DELAY/i = 64/i.

Given that we can rewrite (i % 2 * j - j) ^ j as (i % 2 * 64/i - 64/i) ^ 64/i.

Let’s use an online graphing calculator to plot some of these functions.

First of all, let’s plot i%2.

This results in a nice graph, with value of y ranging form 0 to 2.

If we plot 64/i will get a graph that looks like this.

If we plot the full left side, we’ll get a graph that looks kind of like combination of the 2.

Finally, if we plot 2 functions side by side we get the following.

What do all these graphs tell us?

Let’s remind ourselves what question we are trying to answer, and that is how did we ended with a pretty static image like this:

Well, we know that if the magic (i % 2 * j - j) ^ j results in an even number we’ll have to add p and for an odd value number we’ll have to add ..

Let’s zoom in on the first 16 rows of our chart, with i values ranging from 64 to 32.

Bitwise XOR in JavaScript will drop all the values to the right of decimal point, so it’s kind of like taking a Math.floor of a number.

It will return 0 when both bits are 1s or both bits are 0s.

Our j will start as 1 and will slowly make its way to 2, staying right below it, so we can treat it as 1 (Math.floor(1.9999) === 1), and we’ll need another 1 on the left side, to get the result to be 0 (meaning even), giving us a p.

In other words, each diagonal green line represents one row in our chart. Since j is always above 1 but below 2 for the first 16 rows, the only way we can get odd value is if left side of (i % 2 * j - j) ^ j aka i % 2 * i/64 - i/64 aka diagonal green line is also above 1 or below -1.

Here are some output from JavaScript console to drive this point home, 0 or -2 means result is even, 1 means result is odd.

1
2
3
4
5
6
7
1 ^ 1 // 0 - even p
1.1 ^ 1.1 // 0 - even p
0.9 ^ 1 // 1 - odd .
0 ^ 1 // 1 - odd .
-1 ^ 1 // -2 - even p
-1.1 ^ 1.1 // -2 - even p
 

If we look at our graph, we’ll see that the right most diagonal line barely goes above 1 or below -1 (few evens – few ps), the next line goes a bit more, and the one after that even more etc. Line number 16 barely stays under 2 and above – 2. After line 16 we can see our static chart shifts a pattern.

After line 16 j crosses the line of 2, and the expected result flips. Now we’ll get an even number when our green diagonal line is above 2, below -2, or within but not equal to 1 and -1. That is why we see two or more groups of ps from line 17 onward.

If you look closely at the bottom few lines of the moving image, you’ll notice that they no longer follow the same pattern, due to wide fluctuation of the graph.

Let’s comeback to + n/DELAY now. In code we can see that n starts out at 8 (1 from setInteval plust 7 on every interval being called). It is then incremented by 7 every time set interval fires.

When n becomes 64, the graph changes to look as follows.

Note that j is still ~1 (~ here means approximately), but now left half of red diagonal line around 62-63 is ~0 and right half around 63-64 is ~1. Since our chars get populated in decreasing order from 64 to 62, we would expect the 63-64 side of the diagonal line (1 ^ 1 = 0 // even) to append bunch of p and left 62-63 side to append bunch of (1^0 = 1 // odd) ., that would be growing left to right as normal English words.

Rendered HTML for that condition will look as follows ( you can hard code value for n in codepen to see for yourself). Which in fact matches our expectations.

At this point number of ps has grown to its constant value. For example, for the first row half of all values will always be even. From now on ps and .s will only shift their position.

To illustrate, when n grows by 7 on the next setInterval, the graph will change slightly.

Note that diagonal line for the first row (around 64 mark) has move roughly 1 small square up. Assuming that 4 larger square represent 128 chars, 1 large square would represent 32 chars, and 1 small square would represent 32/5 = 6.4 chars (an approximation). If we look at the rendered HTML, we’ll see that first row did in fact move right by 7 chars.

One last example. Here is what happens when setInterval gets called 7 more times with n now equal 64+9×7.

For 1st row j is still equal to 1. Now the top half of red diagonal line around 64 is ~2, and the bottom one ~1. This flips the picture, since now
1^2 = 3 // odd - . and 1 ^ 1 = 0 //even - p. So we would expect bunch of dots, followed by ps.

Which renders as such.

The graph continues to loop indefinitely in a similar manner.

I hope this makes sense. I don’t think I would have ever been able to come-up with something like this on my own, but it was fun trying to understand it.

Please Share:

Wanna see my pretty face and hear me ramble? Check out my YouTube channel 🙂

P.S. Check out Disrupted: My Misadventure in the Start-Up Bubble by Dan Lyons a co-producer and writer for the HBO series Silicon Valley (sponsored).


P.P.S. Let's connect on Twitter, Facebook or LinkedIn. You can also get updates via RSS Feed or the Email Form Bellow.
Follow @akras14

Subscribe to Blog via Email

Enter your email address to subscribe to this blog and receive notifications of new posts by email.

You may also like:
Share this:

Filed Under: JavaScript

Writing Good Code is a lot Like Writing Prose

July 6, 2017 by Alex Kras 7 Comments

Share this:

Introduction

I love to write prose. I also love to write code.

Different people have different approaches to writing code. I had a co-worker whose criteria for writing good Software was to make sure that one block of code can be read without having to scroll.


My criteria for writing good code can be summarized with the following quote:

Any fool can write code that a computer can understand. Good programmers write code that humans can understand.
Martin Fowler

In other words, as Nicholas Zakas pointed out in his talk Maintainable JavaScript, if you open an editor and it’s blank – you are writing new code, if something is already there – you are maintaining code. We spend very little time writing new code and a lot of time maintaining existing code. For me, a good code is the code that I can understand without having to run a debugger.

I believe that there is a strong overlap between writing prose and writing code. For example, adding a small comment at the top of a module is a lot like adding an introductory paragraph at the top of a post.

Outline

I like to start writing my prose with an outline. It doesn’t have to be perfect, nor does it have to be final, but I find it to be a great tool for organizing my thoughts. Once an outline is in place, the rest of the writing becomes easy.

I believe that an “outline” is also a great tool for writing software. It is kind of like Test Driven Development (TDD), but without a big upfront investment. I like to take some time to investigate what functionality I am adding, what interface it might have, and what are some of the most probable use cases. Sometimes I can do it with an actual outline, sometimes I create a flow chart, and sometimes I just draw some thing by hand. The key is to take some time to think through what I am trying to build, before sitting down to build it.

Draft

After my outline is in place, I try to write everything I have to say to connect my bullet points. I am not worried about the quality just yet. I know that I will be able to proofread my writing at a later time.


I like to take the same approach with code. Once I have a general idea of what I am trying to build, I check out a new branch and just go for it. My biggest issue with TDD is that I find it too restrictive. Half of the time when I sit down to write something, I don’t know how things will end up working out. A different branch that I can easily throw away gives me the freedom to experiment.

Proofreading

After my draft is done, I like to go back and read my prose slowly out loud. I strive for my writing to roll of the tongue as if I am having a conversation. Often I end up rewriting full sentences and paragraphs. Sometimes I throw away large portions of text. I cut out filler words that add no value.

I like to do similar things with my code. I find this time ideal for writing tests. I already know how and what I am trying to build, yet I still have the freedom to refactor things, making them easier to test.

It is also a great time to rename variables and function names. During this time, I like to imagine myself reading my code for the first time. Can I tell what my code is doing?

I am not afraid of adding extra variables, if I think they will make my code more readable. At the same time I am not afraid of removing extra variables, that add no value.

My general rule of thumb is that a good name is better than a good comment, but a good comment is better than nothing: Names > Comments > Nothing.

Second pair of eyes

I do my best proofreading after I get some time away from my writing, but no mater how many times I review my prose I always miss something. My chances of having a typo-free prose increase exponentially with every person that gets to read it. (Special shout-out to my wife for proofreading my countless scribbles).

Same thing can be said about my code. That is why I find pull-requests and code reviews so invaluable. My reviewers are always able to find something that I’ve missed or give me a new perspective.

Fixing errors

My writing is never perfect. I always welcome feedback, both positive and negative, because it gives me a chance to do better.

Same is the case with software. While I try hard not to blow up a production database, I accept that I will make mistakes. In writing, I monitor what people are saying about my work. In code, I monitor what users are saying about my software and audit logs. I try to throw errors when unexpected things happen.

Conclusion

I couldn’t find a good parallel between a conclusion in prose and a conclusion in code. Perhaps someone can help me out in comments 🙂

I’ve read somewhere, that if we were writing code for computers we would write it in ones and zeros. Instead, we write code in high level languages, because we are writing code for humans to maintain.

I’d like to conclude with my favorite quote of all time.

"Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live." https://t.co/pCd30nccHG

— Alex Kras (@akras14) July 6, 2017

Please Share:

Wanna see my pretty face and hear me ramble? Check out my YouTube channel 🙂

P.S. Check out Disrupted: My Misadventure in the Start-Up Bubble by Dan Lyons a co-producer and writer for the HBO series Silicon Valley (sponsored).


P.P.S. Let's connect on Twitter, Facebook or LinkedIn. You can also get updates via RSS Feed or the Email Form Bellow.
Follow @akras14

Subscribe to Blog via Email

Enter your email address to subscribe to this blog and receive notifications of new posts by email.

You may also like:
Share this:

Filed Under: Software Engineering, Writing

Firefox Marketing Declares a War on Chrome

July 3, 2017 by Alex Kras 3 Comments

Share this:

It appears that Firefox has gone all-in with a new marketing campaign aiming at presenting Google Chrome as a big brother/browser that is watching your every step.

They kicked it off with the following billboard posted somewhere in San Francisco.


Firefox also appears to be a running ads on various sites targeting similar message.

A Stuff Software Engineer from Mozilla hinted that more messaging like this is coming.

This move by Firefox has sparked some criticism, including the following exchange (where Verizon’s customer support (bot?) showed up to help, lol).
Note: Mozilla, the maker of Firefox, makes most of it’s revenue from Yahoo, for setting Yahoo as their default search engine. Yahoo is now owned by Verizon.

To be fair, when Chrome was a young browser, Google deployed a similar marketing strategy, aimed at Firefox and Internet Explorer.

In my opinion Chrome ad does look more “classy”, since it does not call out the competition directly. Neither does Mozilla, but the coloring kind of gives it away.

I can appreciate this risky move by Mozilla. “Private” is the new “Fast” and they want to capitalize on this market change. Prior to this campaign, for example, they release Firefox Focus a “private browser for iOS”. It is also worth noting that Brave with ad and tracking blocking and Opera with a free VPN (both browsers build on top of Chrome) have been making strong emphasis on privacy before Firefox did. Firefox does have a unique angle though, since it is a completely stand alone browser.


In any case, a lot of Google engineers seem to be upset by this attack and a lot of Mozilla engineers seem to be embarrassed by it. Two companies have a long history of working together and Firefox has received a lot of support from Google over the years. At the same time, it did seem for a while that Firefox was just hiding in Chrome’s shadows. Perhaps Mozilla leadership decided it was time to show some teeth and gain market share.

What do you think? Is it just business as usual? Has Firefox gone too far?

Update 07/06/2017: Here is another one.

New Ad by Firefox https://t.co/VXNj16SBUo pic.twitter.com/Ugb2YgHzGc

— Alex Kras (@akras14) July 7, 2017

Update 12/02/2017: And another

@firefox marketing is at it again 🙂 pic.twitter.com/p1njt13BOy

— Alex Kras (@akras14) December 3, 2017

Please Share:

Wanna see my pretty face and hear me ramble? Check out my YouTube channel 🙂

P.S. Check out Disrupted: My Misadventure in the Start-Up Bubble by Dan Lyons a co-producer and writer for the HBO series Silicon Valley (sponsored).


P.P.S. Let's connect on Twitter, Facebook or LinkedIn. You can also get updates via RSS Feed or the Email Form Bellow.
Follow @akras14

Subscribe to Blog via Email

Enter your email address to subscribe to this blog and receive notifications of new posts by email.

You may also like:
Share this:

Filed Under: Privacy, Random Thoughts

Copyright © 2018 · eleven40 Pro Theme on Genesis Framework · WordPress · Log in