Monday, 11 May 2020

Print Templated String in Python

Python 3.6+ has the new 'f' string prefix to use in place of the .format function for string, it is neat and useful.

Prior to Python 3.6:

Foo = "bar";
print("Foo value is {}".format(Foo));

Python 3.6+:

Foo = "bar";
print(f"Foo value is {Foo}");

Try it on:
https://repl.it/languages/python3

How to Do Coding on Android

Some may say coding on Android is nonsense, but it's wrong. Coding on Android can be done as usual, but not the tiny display on mobile device; install BlueStacks and one of these code editors:

Friday, 8 May 2020

Quick Setup for CentOS and Ubuntu Servers

The website toolset.sh provides quick setup scripts for CentOS and Ubuntu with essential software installation. It is useful when in need of setting up multiple servers with the same basic packages.

Install generic tools:
curl toolset.sh | bash

Install classic tools:
curl toolset.sh/classic | bash

Thursday, 7 May 2020

JavaScript and How It Is Not Much Related to Java

JavaScript was created in 1995 at the beginning of Internet era. It is called JavaScript because it was first created using all Java keywords, but the 2 languages are totally different, one is threaded, one is event-based.

JavaScript has evolved much, and with ES6 (ECMAScript6), JavaScript comes with threading, and classes too.

Example class in ES6 (the file name must be .mjs):
class some_class {
  Some_Property = null;
  
  some_function(Some_Param){
  }

  static some_static_function(Some_Param){
  }

  async some_function2(Some_Param){
  }

  static async some_static_function2(Some_Param){
  }
}

//Static block for static properties
{
  some_class.Some_Static_Prop = null;
}

//ES6 export
export default some_class;
//EOF

Import class to use:
//Static import
import some_class from "./some_class.mjs";

//Dynamic import
(async function(){
  var some_class = await import("./some_class.mjs").default;
})();

Run Node.js with ES6 and multi-threading:
node --experimental-modules --experimental-worker \
app.js

Add the 'require' function to ES6:
npm install mjs-require --save
node --experimental-modules --experimental-worker -r mjs-require \
app.js

Run Node.js ES6 with heredoc in Bash:
node --experimental-modules --experimental-worker \
--input-type module <<'HEREDOC'
  console.log(Date.now());
HEREDOC

Wednesday, 6 May 2020

Get the Selector for Using with Stylish Extension (userstyles.org) to Customise Websites

Many websites may not look suitable with personal style, the Chrome extension called Stylish can help browser users customise any CSS.

Get the CSS selector directly for an HTML element:
1) Right-click on the UI element on web page, choose 'Inspect'
2) DevTools panel is opened, right-click on highlighted tag, choose 'Copy > Copy selector' 
3) Create or edit a Stylish style
4) Paste the selector and enter CSS properties

However, many websites/webapps use generated element ids and class names, the CSS selector above won't work when these websites are built (daily for example) and deployed. Use the XPath solution below.

Get the CSS selector by converting XPath to CSS selector:
1) Right-click on the UI element on web page, choose 'Inspect'
2a) DevTools panel is opened, right-click on highlighted tag, choose 'Copy > Copy full XPath
2b) Open website toolset.sh, there's a tool there to convert XPath to CSS selector
3) Create or edit a Stylish style
4) Paste the selector and enter CSS properties

How to Enable 'Administrator' Account on Windows 10 or Set Its Password

The 'Administrator' account is not enabled by default on Windows 10 but it is necessary sometimes. Use the following steps to enable 'Administrator' account and set a password for it.

1) List out Windows accounts
Right-click on 'cmd', choose 'More' >> 'Run as administrator'

Type this command to see available users:
net user

2) Enable 'Administrator' account on log-on screen
Type this command in cmd:
net user administrator /active:yes

3) See updated info the the user 'Administrator'
Type this command:
net user administrator

4) Set password for 'Administrator' account:
Type this command:
net user administrator *

Note:
Change the 'yes' to 'no' in step 2 to disable 'Administrator' account.

Reference:

How to Disable Windows UAC (User Account Control) Using Registry (Regedit)

The new update from Windows 10 is rather annoying, it enables UAC password prompt every time, eg. when using 'Run as administrator' on right-click on some app, specially Steam Big Picture that needs to be 'administrator' to send keys and mouse signals to games.

Disable UAC using regedit:
1) Win+R
2) Type 'regedit', press Enter
3) Go to: HKEY_LOCAL_MACHINE > SOFTWARE > Microsoft > Windows > CurrentVersion > Policies > System
4) Right-click 'EnableLUA', click 'Modify'
5) Set the value to 0 (zero) instead of 1
6) Windows will prompt to restart to disable UAC
7) Click the notification to restart and enjoy!

Reference (Go to 'Way 2: Disable User Account Control on Windows 10 by Registry Editor', it's the only working one):

Tuesday, 5 May 2020

Web Trick: CSS Relative Positioning inside Absolute Positioning


CSS:
*     { box-sizing:border-box; }
table { border-collapse:collapse; }

td { 
  margin:0; padding:0; width:100px; height:100px; text-align:left;
  vertical-align:top;
}

HTML:
<table>
  <tr>
    <td style="background:red;">1</td>
    <td style="background:green;">2</td>
    <td style="background:blue;">3</td>
  </tr>
  <tr>
    <td style="background:yellow;">4</td>
    <td style="background:cyan;">
      <span id="Parent" style="position:absolute; display:inline-block; 
      width:0; height:0;">
        <span id="Child" style="position:relative; left:50px; top:50px;
        display:inline-block; width:50px; height:50px; background:white;">5</span>
      </span>
    </td>
    <td style="background:purple;">6</td>
  </tr>
  <tr>
    <td style="background:pink;">7</td>
    <td style="background:olive;">8</td>
    <td style="background:lightblue;">9</td>
  </tr>
</table>

Monday, 4 May 2020

CSS nth-child versus nth-of-type

Consider this HTML structure:
<body>
  <div>foobar</div>
  <span>foo</span>
  <span>bar</span>
</body>

To select the last (the second) span using nth-child:
document.querySelector("body >span:nth-child(3)");

To select the last (the second) span using nth-of-type:
document.querySelector("body >span:nth-of-type(2)");

How to Reorder Elements in HTML Using CSS Only

CSS is not only for styling with colours, etc, CSS can change the order of elements in HTML. The basic idea is to use 'flex' in CSS:
  • Set parent CSS
    • display:flex;
    • flex-direction:column;
  • Set child 1 CSS (order from 1)
    • order:1;
  • Set child 2 CSS
    • order:2;
  • Set child N CSS:
    • order:...

How to Add Custom CSS and JS Code to Any Website

Customise CSS in any website with Stylish

Create custom CSS for website:
1) Click Stylish extension icon on address bar
2) Click the triple-dot button on top-right corner
3) Click 'Create New Style'
4) Type CSS code in the main code box
5) Click 'Specify' button below, choose 'URLs on the domain', enter the website domain
6) On top-left corner, enter style name
7) Click 'Save' button
8) Open the website to see it customised.

Append additional JS to any website with Tampermonkey

Create additional JS for website:
1) Click Tampermonkey extension icon on address bar
2) Click 'Create a new script...'
3) Modify @name to any name
4) Modify @match URL to @include http://domain.name/*
5) Add @license MIT to top
6) Add new JS code into the self-exec function
7) Click Menu >> File >> Save
8) Open the website to see it with additional JS.

Online storage for Stylish:

Online storage for Tampermonkey:

Wednesday, 29 April 2020

Top Rated FTP Service for Linux: proftpd

Many are using 'vsftpd', however, it isn't as good and simple as 'proftpd'. vsftpd requires complex config after installation and may be even not working.

proftpd is simple, install and run immediately by using available system users.

Installation:
sudo yum install proftpd -y
sudo systemctl start proftpd
sudo systemctl enable proftpd

Make sure the username is not listed in /etc/ftpusers
Use any FTP client to connect.

Get SSL/TLS from a Website and Identify the Expiry Date

Install utility executables:
sudo yum install gnutls-utils -y
sudo apt install gnutls-bin -y

Get the cert:
true | gnutls-cli --print-cert $Domain 2>/dev/null | \
openssl x509 >temp.pem;

"true" to make 'gnutls-cli' end.
"2>/dev/null" to remove errors.
"openssl x509" to extract the cert only.

Get the expiry date:
openssl x509 -enddate -noout -in temp.pem;

Tuesday, 28 April 2020

Suggested Browsers for 2020

In the old days, the world had Netscape, Internet Explorer (now no more, replaced by Edge Legacy, then Edge), Opera, Mozilla (now as Firefox), some have not been lingering on.

Modern browsers of 2020:
  • Vivaldi (Recommended, with mouse gesture)
  • Chrome (Recommended, very popular)
  • Firefox (Recommended, with tabs in full screen, with 'Switch to New Tab' on mobile)
  • Edge (Recommended, Chromium-based, for downloading other browsers)
  • Edge Legacy (Recommended for downloading other browsers)
Headless browser by popularity:
  • Chrome
  • Chromium

Micro, the New Superb Code Editor for Linux Terminal

Everybody ever used 'vim', 'nano', 'mcedit'; but for now, Micro is the ultimate superb code editor just like Sublime Text for terminal.

It is the recreation based on Sublime Text for text mode. The editor is very fast, and with lots of features, including file manager panel on the left side installed as plugin.

Install Micro from:
https://micro-editor.github.io

Useful Tools for System Management and Engineering

htop
This htop is the advanced replacement for 'top' command on Linux, htop is not available by default on multiple Linux distros but can be simply installed using OS package manager.

CentOS/Red Hat:
sudo yum install htop -y

Ubuntu/Debian:
sudo apt install htop -y

Netdata
A very useful system monitoring tool with smooth performance charts. The only limitation is that Netdata doesn't show charts per process, shows per machine only. For performance per process, use htop.

Install from:
https://netdata.cloud

WinSCP
A powerful file browser for browsing server files on Windows with multiple protocol, the most important one is SSH ie. SFTP, allows editing server-side files directly and uploads the file on save (Ctrl+S). WinSCP is not available on Mac.

Install from:
https://winscp.net

CyberDuck
Replacement for WinSCP on Mac.

Install from:
https://cyberduck.io

PuTTY
A terminal for Windows to access Linux servers before the era of Windows 10 that comes with LXSS Linux Subsystem (or WSL, Windows Subsystem for Linux) and true Linux terminal. Although WSL terminal is there but PuTTY is still useful for generating .ppk file to use in WinSCP.

Install from:
https://putty.org

TortoiseGit
Use Git with GUI instead of git commands in terminal.

Install from:
https://tortoisegit.org

XMinG
Turns Windows GUI into the combination of Windows+Linux, both Windows apps and Linux apps shown on the same task bar and Task View. XMinG activates a display on local machine and uses X11 forwarding for forwarding graphics from server to the display.

Install from:
https://sf.net/projects/xming

Friday, 24 April 2020

Funny Logic in JavaScript: Type of NaN (Not a Number) is Number

This fun doesn't affect programming in this JavaScript language but it's just funny:

console.log(typeof NaN);
--> "number"

Thursday, 23 April 2020

Tell Doxygen to Skip a Group of Lines

Doxygen documents all lines in a file, however, it's possible to tell Doxygen to ignore some lines when using qdoc commands to make descriptions for items.

Put this before to-be-ignored lines:
/*!\cond SOME_NON_EXISTING_DOXYGEN_VAR*/

Put this after those lines:
/*!\endcond*/

In full:
/*!\cond HIDE*/
CODE LINES HERE...
/*!\endcond*/

How to Add a Website/Webapp as Desktop App

Chrome Browser allows adding any website/webapp as desktop application. It's easy and useful:
  • Desktop app can be pinned to Start Menu/Start Screen
  • Shown in browser app page at chrome://apps
  • Shown in Windows All Apps >> Chrome Apps
  • No tab bar, no address bar
  • Website icon is shown on task bar instead of browser icon.
Add as desktop app with these steps:
  • Click Chrome menu button
  • More tools >> Create shortcut...
  • Enter app name
  • Tick 'Open as window'
Screenshot:

Thursday, 16 April 2020

Minimal Files for a Proper Progressive Web App (PWA)

All 3 files below must be served from HTTPS.

Web contents
app.html:
<!DOCTYPE html>
<html>
  <head>
    <title>App</title>
    <link rel="manifest" href="manifest.json"/>
  </head>
  <body>
    body-contents
  </body>
</html>
<!--EOF-->

Configurations
manifest.json:
{
  "name":       "My App",
  "short_name": "My App",
  "start_url":  "app.html",
  "display":    "standalone",

  "icons": [
    {
      "src":   "/pwa/icon144.png",
      "type":  "image/png",
      "sizes": "144x144"
    }
  ]
}

At least 1 icon (must be 144 on Vivaldi)
and the real image size must be 144x144 too:
icon144.png

Saturday, 7 March 2020

Git Branches and Development/Deployment Model

Model 1: Simple Git development/deployment model:
  • 'dev' branch: Development branch
    • May contain errors, bugs
    • Developers merge in
    • Testers test
      • Fail: No merge to 'master' branch
      • OK: Merge to 'master' branch
  • 'mater' branch: Production branch
    • No errors, no bugs
    • Deploy by schedule
Model 2: Safe (2 times no errors, no bugs) Git development/deployment model:
  • 'dev' branch: Development branch
    • May contain errors, bugs
    • Developers merge in
    • Developers merge to 'staging'  branch (Extra step compared to Model 1)
  • 'staging' branch: QA/QC branch
    • No errors, no bugs (Extra safety compared to Model 1)
    • Testers test
      • Fail: Revert those commits from 'dev' branch
      • OK: Merge to 'master' branch
  • 'master' branch: Production branch
    • No errors, no bugs
    • Deploy by schedule

HTTP Response Codes and Possible Failure Issues

HTTP response codes from 1xx to 5xx and their possible failure issues:

Out-going request:
  • Own server --> ISP proxies --> Customer proxy (Nginx) -->  Customer server
Inward request:
  • Customer server --> ISP proxies --> Own proxy (Nginx) --> Own server
1xx:
  • Exactly a response from server
  • No failures, informational response
2xx:
  • Exactly a response from server
  • Successful response from server
3xx:
  • Response from server or proxies
  • HTTP redirect
  • Possible issues:
    • Bad redirect by server, for example, infinite redirection
    • Bad redirect by proxies, for example, inifinite redirection
4xx:
  • Exactly a response from server
  • Error due to client request data
  • Possible issues:
    • Bad headers
    • Bad parameters in URL
    • Bad data in POST body
5xx:
  • Response from server or proxies
  • Error due to server side
  • Possible issues:
    • Server code error, exception, crash, etc.
    • Proxy (Nginx) fails to proxy_pass to a service
Timeout:
  • Target IP, domain, subdomain don't exist
  • Target machine having firewall that dropouts connections
  • No internet connection
  • Server doesn't respond
Reference:
https://en.wikipedia.org/wiki/List_of_HTTP_status_codes

Wednesday, 4 March 2020

RAM Usage Display: Free, Cached, Used

Notes about RAM usage on computer:
  • Free RAM: 
    • The amount of RAM never been used
  • Cached RAM: 
    • The amount of RAM ever been used to load programmes, but OS doesn't want to free them, OS keeps them to avoid loading programmes from disk again.
    • When free RAM is not available, OS will throw away some of the Cache RAM to make free space for allocation.
  • Used RAM: 
    • The amount of RAM allocated to programmes, can't be used for other ones.

Tuesday, 3 March 2020

Redirect All Tornado Logs to stdout and stderr

Tornado by default steals all stdout and stderr to its logging. This is crazy, one can't even do 'print'.

Redirect all back to stdout and stderr:
import logging
import sys

import tornado.log
from tornado.options import options

def setup_logging_to_stream(stream, log_level):
  logger = logging.getLogger()
  channel = logging.StreamHandler(stream)
  channel.setLevel(log_level)
  channel.setFormatter(tornado.log.LogFormatter())
  logger.addHandler(channel)


def setup_logging(log_level=None):
  if log_level is None:
    log_level = getattr(logging, options.logging.upper())

  logger = logging.getLogger()
  logger.setLevel(log_level)

  setup_logging_to_stream(stream=sys.stdout, log_level=log_level)
  setup_logging_to_stream(stream=sys.stderr, log_level=logging.ERROR)

setup_logging();

Reference:
https://gist.github.com/malexer/06fd8f6530a02fddc5feb7c1f2628799

Monday, 2 March 2020

ML Libraries

TensorFlow 2:
  • Popular, big community, fast, by Google, works with CPU, GPU, TPU
  • Recommended!
PyTorch:
  • Somehow wrong design, activation functions should be inside layers
  • Recommended if accepting the wrong design.
Chainer:
  • Similar to PyTorch, Japanese library, mostly only Japanese people use.
Theano:
  • In maintenance mode, no longer development.
  • Avoid using this library, no longer active.
CNTK:
  • Works with Ubuntu 16 only, relies on a lib that exists only on Ubuntu 16, or build the lib by oneself otherwise.
  • Is Microsoft abandoning this lib? should work out-of-the-box on any platform.

Wednesday, 26 February 2020

The Rise of Canvas and WebAssembly

Before the time of Canvas and WebAssembly there were these kinds of web embeds:
  • ActiveX - C/C++ code, for browsers on Windows only
  • Flash/Flex - ActionScript code, for all platforms
  • Java Applet - Java code, for all platforms
  • Java FX - Java code, for all platforms
  • And some more
Since the introduction of Canvas in HTML5, most of all embeds can be done with 'canvas' tag and JavaScript; browsers JIT-compile JS to native code but no types, so it's slow.

However, for high performance, WebAssembly is, near-native performance. WebAssembly works in its own embed (window). WebAssembly has a drawback: no simple way to access DOM presently.

Solutions to choose:
  • JS/Canvas: Draw UI with something like Zebkit, or raw canvas APIs
  • C++(Emscripten)/Canvas: Draw UI with Qt, or raw OpenGL (browser renders as WebGL)
  • Basically go for these canvases only when complex graphics, or native performance needed.
Compile to WebAssembly with:
  • C/C++: Emscripten (WebGL, Qt, etc.)
  • Python, Rust: Google will tell :)
Hello World in Emscripten:

1) Download
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
./emsdk install latest
./emsdk activate latest
source ./emsdk_env.sh

2) Check version
em++ -v

3) Hello World (hello.cpp)
#include <iostream>
using namespace std;
int main(int Argc,char* Args[]){
  cout <<"Hello!" <<endl;
}

4) Build (output files: .wasm, .js, .html)
em++ hello.cpp -o hello.html

5) Config web server
micro /etc/nginx/mime.types
#Add 1 line to types:
application/wasm wasm;

6) Edit /etc/hosts, create .conf file in /etc/nginx/conf.d
127.0.0.1 hello.local

7) Clone hello.html to show canvas only
cp hello.html hello.custom.html

8) Open web browser to http://hello.local/hello.custom.html

Reference:

Monday, 24 February 2020

The Easy Understanding of YAML

YAML compared to JSON is like Python compared to JavaScript. YAML is smarter with tree of nodes instead of opening and closing blocks.

For a parent-child relation, it is read with the parent first in JSON:
  • Starting with { is an object
  • Starting with [ is an array
However, with the same parent-child relation, it is read with the child first in YAML:
  • A node followed by ':' (colon) means the parent is an object
  • A node starts with '- ' (dash and space) means the parent is a list
  • A node starts with '- ' (dash and space) and followed by ':' (colon) means it's starting key of an object and the parent is a list.
  • Indent below an object key to make child object key.
Examples of YAML
Example 1. Root is object
Foo: "value1"
Bar: "value2"

Example 2: Root is list
- "value1"
- "value2"

Example 3: Object (root) of objects
Foo:
  Child1: "value1"
  Child2: "value2"

Example 4: Object (root) of lists
Foo:
  Child1:
  - "value1"
  - "value2"
  Child2:
  - "value3"
  - "value4"

Example 4: List of items
List:
- "value1"
- "value2"

Example 5: List of objects
List:
- Foo: "value1"
  Bar: "value2"
- Foo: "value3"
  Bar: "value4"

Friday, 21 February 2020

Change Jupyter (Not JupyterLab) Terminal Background Colour and Foreground Colour

Jupyter (Classic), not the new JupyterLab has black background terminal. The terminal is a canvas and stuff are drawn inside, CSS won't work. To change the terminal:

1) Install Tampermonkey for browser

2) Go to OpenUserJS.org and create account

3) Add this script:
// ==UserScript==
// @name     localhost:8888
// @include  http://localhost:8888/*
// @run-at   document-start
// @license  MIT
// ==/UserScript==

setTimeout(()=>{
  terminal.term.setOption(
    "theme",
    {background:"#bbbbbb",foreground:"black"}
  );
},3000);
//EOF

Public Tampermonkey script:
https://openuserjs.org/scripts/datdinhquoc/localhost8888

Thursday, 20 February 2020

Work with 2D Array and Floating-point Numbers in Bash

Bash supports only 1D array, however, there's a work-around, for example:

List=("value00 value01" "value10 value11" "value20 value21");

#Example I,J
I=1;
J=1;
Row=(${List[I]}); #Wrap in parentheses
Cell=${Row[J]};

Bash supports only integers, the work-around to do floating-point maths is creating new functions based on something like Perl:

function + {
  perl -e "print($1 + $2)";
}

function - {
  perl -e "print($1 - $2)";
}

function x { #Can't use *, Bash expands * to files
  perl -e "print($1 "'*'" $2)";
}

function / {
  perl -e "print($1 / $2)";
}

function p { #A to power B
  perl -e "print(($1) ** $2)"; #Parentheses for negative values
}

function random {
  printf $(/ $RANDOM 32767);
}

#Examples of using those functions:
echo $(+ $(random) $(random));
echo $(- $(random) $(random));
echo $(x $(random) $(random));
echo $(/ $(random) $(random));
echo $(p $(random) $(random));

Tuesday, 18 February 2020

SSH Port Forwarding for Jupyter without Wasting a Terminal Just to Channel

When launching Jupyter on server, Jupyter generates a token and it is used as access token to the Jupyter notebook.

However, the URL with the generated token is accessed through 'localhost' (at the server), and Google Colab only supports adding 'localhost' at desk machine.

In order to have server-based Jupyter added as run-time to Colab, pipe the port between desk machine and server:

ssh -L 8888:localhost:8888 SOMESERVER

However, the command above will waste a whole terminal just to do port forwarding (port channelling), 2 lines below save a whole terminal :)

#!/bin/bash
sudo pkill -f localhost:8888 & wait $!;
ssh -fNL 8888:localhost:8888 SOMESERVER;
#EOF

The option 'L' is for port forwarding as usual.
The option 'f' is to but the 'ssh' to background.
The option 'N' is a must to go along with option 'f'.

Use Colab with Private Server Instead of Free Run-time Environment

Google Colab by default provides free run-time environment, in order to connect to personal or private servers, do these:
  1. Install jupyterlab on server:
    1. ssh MYSERVER
    2. sudo yum install jupyterlab
  2. Open terminal, create SSH port channelling:
    1. ssh -L 8888:localhost:8888 MYSERVER
    2. Leave this terminal open
  3. Open another terminal, start Jupyter
    1. ssh MYSERVER
    2. jupyter notebook [THIS WON'T WORK]
    3. jupyter notebook like in this guide:
      https://research.google.com/colaboratory/local-runtimes.html
    4. Get the localhost URL shown
  4. Switch to Colab to connect
    1. Click the run-time box at top-right
    2. Click 'Connect to local run-time'
    3. Use the URL gotten above.
    4. Edit the IPython notebook as usual
  5. To edit other files:
    1. Open new browser tab
    2. Paste the localhost link above
    3. Navigate and click a file to edit.

Use 'expect' in Bash Script to Automate Entering Inputs

expect <<HEREDOC
  spawn some long command;

  expect {
    "some text 1" {
      set timeout -1;
      send "some input\r";
      exp_continue;
    }
    "some text 2" {
      set timeout -1;
      send "some input\r";
      exp_continue;
    }
    "some text 3" {
      set timeout -1;
      send "some input\r";
      exp_continue;
    }
  }
HEREDOC

Nginx Config File for Web Service with HTTPS Cert Provided by Let's Encrypt

Certbot has a few modes to create free certs:
  • --standalone
    • Certbot needs port 80 to start a temporary server for domain verification
    • Nginx will need to be shut down for a while
    • Not suggested method, big down time during creating or renewing certs
  • --webroot
    • Certbot won't start temporary server
    • Nginx stays intact
    • Suggested method, fast verification, no down time.
  • --certbot-dns-SOMESERVICE
    • Certbot supports domain verification by DNS
    • Some supported plugins available fro Google Cloud, Amazon AWS, etc.
      • --certbot-dns-route53
      • --certbot-dns-google
      • --certbot-dns-digitalocean
      • etc.
    • Not suggested method, DNS verification is slow
Nginx config file for HTTP/HTTPS with cert by Let's Encrypt, using --webroot method,
File /etc/nginx/conf.d/MYDOMAIN.EXT.conf:
server {
  listen 80;
  server_name MYDOMAIN.EXT;

  listen 443 ssl;
  ssl_certificate /etc/letsencrypt/live/MYDOMAIN.EXT/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/MYDOMAIN.EXT/privkey.pem;

  location /.well-known/acme-challenge {
    alias /usr/share/nginx/html/.well-known/acme-challenge;
  }

  location / {
    if ($scheme = "http"){
      return https://$host$request_uri;
    }

    root /some/dir;
    #OR:
    #proxy_pass http://localhost:SOMEPORT;

    #OR:
    #if ($host = "...")         { proxy_pass ... }
    #if ($host ~ "(...)|(...)") { proxy_pass ... }
  }
}


1) Create the file above, comment out the 3 SSL lines, and restart Nginx:
sudo systemctl restart nginx

2) Get cert, and run:
sudo certbot certonly --webroot --webroot-path /usr/share/nginx/html \
--cert-name MYDOMAIN.EXT --domains MYDOMAIN.EXT

3) Got the cert, enable back the 3 SSL lines, and restart Nginx:
sudo systemctl restart nginx

4) Renew cert any time later with:
sudo certbot renew --webroot --webroot-path /usr/share/nginx/html \
--cert-name MYDOMAIN.EXT --expand --domains MYDOMAIN.EXT

Monday, 17 February 2020

Route Domains to Different Service Ports Using Pure Google Cloud Balancer or Nginx

Solution 1: Use Google Balancer for simple mapping domains to service ports:
  1. Create different backends for different service ports
  2. Create host and path rules for mapping domains to backends
  3. Create the frontend (proxy) to receive requests
  4. Notes:
    1. Client -> Proxy -> Host/path rules -> Backend:Port
    2. Use SSL/TLS cert on frontend, not necessary elsewhere
  5. Pros:
    1. Multiple healthchecks for multiple services
  6. Cons:
    1. No advanced config on proxy
Solution 2: Use Google Balancer + Nginx for advanced mapping domains to service ports:
  1. Create a single backend to Nginx at port 80
  2. No need host/path rules
  3. Create frontend (proxy) to receive requests
  4. Config Nginx on all instances to add custom configurations, e.g. HTTP Upgrade for socket.io, etc.
  5. Notes:
    1. Client -> Frontend (Proxy) -> Skip:Host/path rules --> Nginx --> Service:Port
    2. Use SSL/TLS cert on frontend, not necessary elsewhere.
  6. Pros:
    1. Advanced config on Nginx proxy
  7. Cons:
    1. Only a single healthcheck, when deploying services on an instance, shutting down Nginx is required to notify the healthcheck; all services on this instance is down at the same time. When all services on this instance are up back, turn on Nginx to notify healthcheck again.

Saturday, 15 February 2020

XMinG for Local Use and XMinG for X11 Forwarding

Windows 10 has WSL (Windows Subsystem Linux) and it launches a terminal by default. Here's how to run Linux GUI apps from that terminal:
  • On Windows, install XMinG
  • In terminal:
    • Open ~/.bashrc
    • Add a line: 
      • export DISPLAY=0.0
    • Run: 
      • source ~/.bashrc
    • Test: 
      • sudo yum install xclock -y && xclock
VNC is boring with all remote apps shown in a virtual display rectangle, here's how to use X11 Forwarding to open remote apps in separate windows:
  • Install and test XMinG as above.
  • Enable X11 Forwarding on server:
    • ssh someserver
    • sudo micro /etc/ssh/sshd_config
    • Find and set these:
      • X11UseLocalhost no
      • X11Forwarding yes
    • sudo systemctl restart sshd
    • sudo yum install xauth -y
    • logout
  • Run test:
    • ssh -Xv someserver
    • It says: ".Xauthority does not exist", run again:
    • ssh -Xv someserver
    • xclock

SSH Port Tunnelling Example

Run this command to tunnel server port SERVERPORT to localhost port LOCALPORT:
sudo ssh -L LOCALPORT:localhost:SERVERPORT myserver.com

For example, tunnel server port 80 to localhost port 8080:
sudo ssh -L 8080:localhost:80 myserver.com

Now, instead of opening:
http://myserver.com:80

Open:
http://localhost:8080

Friday, 14 February 2020

DNN: Number of Neurons, Number of Params, and Number of Combinations

Consider a DNN with 2 dense layers of 10 neurons and 10 neurons.

Number of neurons:
10 + 10 = 20

Number of params:
10*10 + 10*10 = 100 + 100 = 200

Number of combinations:
100 * 100 = 10,000

The DNN should be big enough to fit (but don't overfit, no use):
  • More layers enough to fit desired number of  separations
  • More neurons in layers enough to fit number of input combinations

YAML Syntax and Conversion to JSON

YAML is a good markup lang for config, it's simpler than JSON, and it has comments, although JSON5 allows comments too.

Tool:
https://codebeautify.org/yaml-to-json-xml-csv

YAML syntax:
1) Colon, newline, indent, key --> Object
2) Colon, newline, indent, dash, value --> List of values
3) Colon, newline, indent, dash, key, colon, value --> List of objects

Example YAML:
#Object
objkey:
  subkey1: "foo"
  subkey2: "bar"
  
#List of values
listkey1:
  - "foo"
  - "bar"
  
#List of objects
listkey2:
  - foo1: "foo1"
    foo2: "foo2"
  - bar1: "bar1"
    bar2: "bar2"

#Shorthands    
#List of values (single line)
listkey3: ["foo","bar"]

Conversion to JSON:
{
  "objkey": {
    "subkey1": "foo",
    "subkey2": "bar"
  },

  "listkey1": [
    "foo",
    "bar"
  ],

  "listkey2": [
    {
      "foo1": "foo1",
      "foo2": "foo2"
    },
    {
      "bar1": "bar1",
      "bar2": "bar2"
    }
  ],
  "listkey3":["foo","bar"]
}

Wednesday, 12 February 2020

Fortran & Lisp: The First High-level Structured Language and Functional Language

Fortran: The first high-level structured language
program bubble_test

  implicit none
  integer, dimension(6) :: vec 
  integer :: temp, bubble, lsup, j

  read *, vec !the user needs to put 6 values on the array
  lsup = 6 !lsup is the size of the array to be used

  do while (lsup > 1)
    bubble = 0 !bubble in the greatest element out of order
    do j = 1, (lsup-1)
      if (vec(j) > vec(j+1)) then
        temp = vec(j)
        vec(j) = vec(j+1)
        vec(j+1) = temp
        bubble = j
      endif 
    enddo
    lsup = bubble   
  enddo   
  print *, vec
end program
Lisp: The  first high-level functional language
(defun bubble-sort (lst)
  (loop repeat (1- (length lst)) do
    (loop for ls on lst while (rest ls) do
      (when (> (first ls) (second ls))
        (rotatef (first ls) (second ls)))))
  lst)

Free GPU-enabled General Programming and ML Services

Google Colab:
  • https://colab.research.google.com
  • Pros:
    • Free GPU time
    • Save documents to Google Drive
    • Document outline (headings) available on UI
    • Run any language using %%writefile and %%script bash
    • Install anything with sudo apt install
    • Anything! basically it's a server without public ports
  • Cons:
    • No file manager side panel
    • No opened file tabs
    • Session is not persistent, opening .ipynb files will lead to random environment without previous saved files.
    • No public ports
    • No terminal
Paperspace Gradient:
  • https://paperspace.com
  • Pros:
    • Free GPU time
    • Save documents to the Docker container (or VM?) itself
    • Create/open/run any file, not just %%writefile and %%script bash in .ipynb files
    • Install anything with sudo apt install
    • It's a private server without public ports
    • Persistent saved files, persistent environment, open Gradient again with the same opened file tabs
    • Based on JupyterLab, file manager available, opened file tabs
    • Terminal default in 'sh' but run 'bash' to have Bash terminal
    • Anything! basically it's a persistent server without public ports
  • Cons:
    • No public ports
    • Can't save to Google Drive
    • No .ipynb document outline (headings)

Wednesday, 5 February 2020

Google Sign-in Button, Chatfuel, Their Usefulness and Trade-off

Google Sign-in button:
  • Usefulness: 
    • Visitors don't need to create accounts, visitors are very lazy nowadays. This catch more visitors than enforcing the to register to use, enforcing visitors means losing visitors.
  • Trade-off: 
    • There's a latency below 1 second to have user data ready to render contents.
Chatfuel:
  • Usefulness: 
    • Visitors don't need to create accounts, use Facebook accounts to chat.
    • Direct chat pop-up in current website page without the need to open new tab to chat. Chatfuel is the best app for integrating Facebook chat in a website as Facebook doesn't provide chat HTML embed for websites. Besides, Chatfuel is even better than other apps for Facebook chats that it is AI-powered, although not yet with powerful AI (doesn't pass Turing test, uses text classification to make responses).
  • Trade-off: 
    • No trade-off, perfect chat embed!

Browser History and Good Browsers Now

Early Internet era:
  • Internet Explorer (Winner of the first browser war but now used to download other browsers only)
  • Netscape (Eliminated in the first browser war)
  • Mozilla (Changed name to Firefox later)
  • Opera (Died out with fewer users)
Present time (2020) browsers:
  • Vivaldi (Chromium-based, with mouse gesture and web panels)
  • Chrome (Chromium-based, very popular)
  • Firefox (Gecko-based, better than Chrome with tabs in full-screen mode)
  • Edge (Trident-based, just like IE, for downloading other browsers only)
  • IE: Rested in peace!
Non-Windows browsers:
  • Safari: MacOS only
  • Konqueror: KDE only

Tuesday, 4 February 2020

L1 and L2: Losses, Norms, Regularisations, and Deviations

1. Losses

With Ui is output, Yi is true value,
L1 Loss:
Loss=|U1Y1|+..+|UnYn|N
L2 Loss:
Loss=(U1Y1)2+..+(UnYn)2N

2. Norms

With Wi is weight,
L1 Norm:
Norm=W1+..+Wn
L2 Norm:
Norm=W21+..+W2n

3. Regularisations

L1 Regularisation:
Regularisation=Ratio×L1Norm
L2 Regularisation:
Regularisation=Ratio×L2Norm

4. Bonus: Deviations

L1 Deviation:
L1Variance=|X1Mean|+..+|XnMean|N
MeanDeviation=L1Variance
L2 Deviation:
L2Variance=(X1Mean)2+..+(XnMean)2N
StandardDeviation=L2Variance
Deviations are important, used in generator in GANs. After training an auto-encoder, use the decoder as generator. In the auto-encoder model, additional deviation layer makes it work better.