Languages

[Regex] Lookarounds

  • Positive lookahead
Regex: \d+(?=apples)
String: "666apples"
Match: "666"
  • Negative lookahead
Regex: \d+(?!apples)
String: "666bananas"
Match: "666"
  • Positive lookbehind
Regex: (?<=apples)\d+
String: "apples666"
Match: "666"
  • Negative lookbehind
Regex: (?<!apples)\d+
String: "bananas666"
Match: "666"

[CSS] Text related CSS properties

  • white-space: Control how space characters behave
  • word-break: Control how the words are being broken
word-break: normal;
word-break: break-all;
word-break: keep-all;
word-break: break-word; /* deprecated */
  • word-wrap / overflow-wrap: Same as word-break but only apply when the remaining space is not enough
overflow-wrap: normal;
overflow-wrap: break-word;
overflow-wrap: anywhere;
  • text-overflow: Specify the appearance when the text is being wrapped
text-overflow: clip;
text-overflow: ellipsis ellipsis;
text-overflow: ellipsis " [..]";

[SQL] Common syntax

  • DISTINCT
SELECT DISTINCT state FROM airports;
  • COUNT / SUM / AVG / MAX / MIN
SELECT COUNT(DISTINCT state) AS state_count
  FROM airports;

SELECT s.sname, s.age
  FROM sailors AS s
 WHERE s.age =
       (SELECT MAX(s2.age)
          FROM sailors AS s2);

/* NULL is counted in COUNT, but ignored in other aggregate operators */
  • WHERE & Conditions
SELECT *
  FROM airports
 WHERE state = 'NY' 
   AND (city = 'Perry' OR city != 'Middletown');
  • LIKE
SELECT *
  FROM airports
 WHERE city LIKE '%er%';
/* % is 0 or more arbitrary char, _ is one arbitrary char */
  • BETWEEN
SELECT *
  FROM airports
 WHERE lat BETWEEN 30 AND 30.5;
  • ORDER BY & ASC & DSC & LIMIT
SELECT *
FROM airports
ORDER BY lat, city DESC
LIMIT 20;
  • UNION / INTERSECT / EXCEPT
SELECT r.sid
  FROM boats AS b JOIN reserves AS r
    ON r.bid = b.bid AND b.color = 'red'
INTERSECT
SELECT r.sid
  FROM boats AS b JOIN reserves AS r
    ON r.bid = b.bid AND b.color = 'green';

/* INTERSECT (and EXCEPT) can be written as follow */
/* Method No.1 */
SELECT s.sid
  FROM sailors AS s
       JOIN boats AS b1 JOIN reserves AS r1
       JOIN boats AS b2 JOIN reserves AS r2
    ON s.sid = r1.sid AND r1.bid = b1.bid
   AND s.sid = r2.sid AND r2.bid = b2.bid
   AND (b1.color = 'red' AND b2.color = 'green');

/* Method No.2 */
SELECT s.name
  FROM sailors AS s
       JOIN boats AS b
       JOIN reserves AS r
    ON s.sid = r.sid AND r.bid = b.bid AND b.color = 'red'
   AND s.sid IN 
       (SELECT r2.sid
          FROM boats AS b2 JOIN reserves AS r2
            ON r2.bid = b2.bid
           AND b2.color = 'green');
  • IN / EXISTS / UNIQUE
SELECT s.sname
  FROM sailors AS s
 WHERE EXISTS
       (SELECT *
          FROM reserves AS r
         WHERE r.bid = 103
           AND s.sid = r.sid);

SELECT s.sname
  FROM sailors AS s
 WHERE s.sid IN (12, 13, 14, 15);
  • ALL / ANY
SELECT *
  FROM sailors AS s
 WHERE s.rating > ALL 
       (SELECT s2.rating
          FROM sailors AS s2
         WHERE s2.sname = 'Horatio');
  • GROUP BY / HAVING
SELECT s.rating, MIN(s.age) AS min_age
  FROM sailors AS s
 WHERE s.age >= 18
GROUP BY s.rating
HAVING COUNT(*) > 1;

/* 
- HAVING clause must be aggregation among each group 
  or attributes listed in GROUP BY.
- Aggregation operations cannot be nested like MIN(AVG(...)).
*/
  • INSERT INTO
INSERT INTO albums (title, release_date, recording_date)
VALUES ('Charcoal Lane', '1990-01-01 01:01:01.00000', '1990-01-01 01:01:01.00000'),
       ('The New Danger', '2008-01-01 01:01:01.00000', '1990-01-01 01:01:01.00000');
  • UPDATE
UPDATE staff
   SET salary = salary * 1.3, vacation = vacation + 5
 WHERE title = 'Manager';
  • DELETE FROM
DELETE FROM albums
 WHERE title = 'Charcoal Lane';
  • LEFT JOIN / RIGHT JOIN / FULL JOIN (outer joins)
/* Preserve all entries in either side or both sides after join */
SELECT s.sid, r.bid
  FROM reserves AS r 
       RIGHT JOIN sailors AS s
       on r.sid = s.sid
          AND s.rating > 3;
  • CHECK & CONSTRAINT
CREATE TABLE staff (
    PRIMARY KEY (staff_num),
    staff_num      INT(5)       NOT NULL,
    first_name     VARCHAR(100) NOT NULL,
    pens_in_drawer INT(2)       NOT NULL,
                   CONSTRAINT pens_in_drawer_range
                   CHECK(pens_in_drawer BETWEEN 1 AND 99)
);
  • ASSERTION
CREATE ASSERTION small_club
 CHECK ((SELECT COUNT(s.sid) FROM sailors AS s)
       + (SELECT COUNT(b.bid) FROM boats AS b) < 100);
  • TRIGGER
CREATE TRIGGER young_sailor_update
AFTER INSERT ON sailors
REFERENCING NEW TABLE new_sailors
FOR EACH STATEMENT
INSERT INTO young_sailors (sid, name, age, rating)
     SELECT sid, name, age, rating
       FROM new_sailors as n
      WHERE n.age <= 18;
  • Division example

A / B means “selecting the keys of A which contain all the values of B”.
For example, find sailors who’ve reserved all boats.

sailors: (*sid, sname, rating, age)
boats: (*bid, bname, color)
reserves: (*sid, *bid, day)

SELECT s.name
  FROM sailors AS s
 WHERE NOT EXIST
       ((SELECT b.bid
           FROM boats AS b)
        EXCEPT
        (SELECT r.bid
           FROM reserves AS r
          WHERE r.sid = s.sid)
       );

* We can actually write EXCEPT using IN as described previously.

[Python] Quick sort

def quick_sort(nums, left=None, right=None):
    def _partition(nums, left, right, pivot_idx):
        pivot = nums[pivot_idx]
        nums[pivot_idx], nums[right] = nums[right], nums[pivot_idx]
        tmp_idx = left
        for idx in range(left, right):
            if nums[idx] <= pivot:
                nums[tmp_idx], nums[idx] = nums[idx], nums[tmp_idx]
                tmp_idx += 1
        nums[tmp_idx], nums[right] = nums[right], nums[tmp_idx]
        return tmp_idx

    if left is None:
        left = 0
    if right is None:
        right = len(nums)-1
    if left >= right:
        return

    new_pivot_idx = _partition(nums, left, right, left)
    quick_sort(nums, left, new_pivot_idx-1)
    quick_sort(nums, new_pivot_idx+1, right)


# inputs = input()
# inputs = [int(c) for c in inputs.split()]
inputs = [3, 5, 1, 2, 6, 4, 7]
quick_sort(inputs)
print(inputs)

[Python] Multiprocessing task with tqdm

We can use tqdm and multiprocessing together by utilizing imap.

import multiprocessing as mp
from tqdm import tqdm

def parallel_work(args):
    my_arg_a= args['my_arg_a']
    my_arg_b= args['my_arg_b']
    result = do_things(my_arg_a, my_arg_b)
    return result

if __name__ == '__main__':
    # Build a list with objects containing desired arguments
    parallel_work_args = [{'my_arg_a': 'a', 'my_arg_b': 'b'}, ...]  

    # If you encounter deadlock issue, try using the 'spawn' method for children forking
    # with mp.get_context("spawn").Pool(mp.cpu_count()) as pool:
    with mp.Pool(mp.cpu_count()) as pool:
        # Parallel work each arg object
        # list() and total are required 
        results = list(tqdm(pool.imap(parallel_work, parallel_work_args), total=len(parallel_work_args)))

[JS] Regex related functions usage

String.prototype.match()

  • Result format depends on whether the regex has ‘g’ flag.
  • Use for a single match or global matches without group information.
let x = '123abcdef123';
x.match(/(123)/);
// [full_matched, 
//  group1, group2, ..., groupN, 
//  index: index_of_first_match, 
//  input: original_input_string, 
//  groups: named_groups] 

// ["123", 
//  "123", 
//  index: 0, 
//  input: "123abcdef123", 
//  groups: undefined] 

x.match(/(123)/g); 
// NO GROUPS IN RESULTS!!! 
// [first_match, second_match, ..., Nth match] 
// ["123", "123"]

String.prototype.matchAll()

  • Use for global matches where group results are needed.
let x = '123abcdef123'; 
[...x.matchAll(/(123)/g)]; 
// [[first_full_matched, 
//  group1, group2, ..., groupN, 
//  index: index_of_first_match, 
//  input: original_input_string, 
//  groups: named_groups], 
//  [second_full_matched, ...], ...]

RegExp.prototype.exec()

  • Similar use case as String.prototype.match(), but when a sticky flag is used, the regex becomes stateful, calling exec() multiple times on the same string will continue the matching. If global matching is needed, String.prototype.matchAll is preferred for its cleaner code.

RegExp.prototype.test()

String.prototype.search()

  • Both can be used for testing if a string satisfies a regex.

[Python] import 機制要點

  • https://docs.python.org/3/reference/import.html#package-relative-imports
  • script和module不同,script通常在package外執行
  • package內部,相鄰的module需使用relative import或是absolute import。例如:
package/A.py:
import package.B
from . import B
import package.B.func
from .B import func
# 若只使用”from B import func”會導致”找不到模組”
  • 執行script時,該script的所在位置會被加入path中,因此同階級的script之間是能直接互相import的。

[Python] Gunicorn

Basic usage

gunicorn -k gevent -t 300 -w 4 -b 0.0.0.0:9500 main:app

—Gevent: asynchronous request handling

—Timeout: 300 sec

# of worker processes: 4

Deploy with nginx

/etc/systemd/system/myapi.service

[Unit]
Description=Gunicorn instance for flask API
Requires=myapi.socket
After=network.target

[Service]
User=hubert
Group=hubert
WorkingDirectory=/home/hubert/projectdir
ExecStart=/home/hubert/miniconda3/bin/gunicorn -k gevent -t 300 -w 2 myapp:app
ExecReload=/bin/kill -s HUP $MAINPID
KillMode=mixed
TimeoutStopSec=5
PrivateTmp=true

[Install]
WantedBy=multi-user.target

/etc/systemd/system/myapi.socket

[Unit]
Description=Gunicorn socket for my API.

[Socket]
ListenStream=/run/myapi.sock
# Our service won't need permissions for the socket, since it
# inherits the file descriptor by socket activation
# only the nginx daemon will need access to the socket
User=nginx
# Optionally restrict the socket permissions even more.
# Mode=600

[Install]
WantedBy=sockets.target

nginx site conf file

server {
        listen       9800;
        location / {
            proxy_pass http://unix:/run/myapi.sock;
        }
    }

[Python] Multiprocessing example

import multiprocessing as mp

def task(x):
    # Do something
    return x

if __name__ == '__main__':
    with mp.Pool(mp.cpu_count()) as pool:
        results = []
        # Using apply_async
        for i in range(cpu_count):
            result = pool.apply_async(task, args=(i,))
            results.append(result)
        for result in results:
            print(result.get())

        # Using map_async
        result = pool.map_async(task, range(cpu_count))
        print(result.get())

[Python] unittest template for python script

import unittest
import subprocess

def execute_command(command):
    """Execute a shell command and return its printed value."""
    return subprocess.run(command, stdout=subprocess.PIPE).stdout.decode('utf-8').strip()

class TestTemplate(unittest.TestCase):
    def test_case1(self):
        result = 1
        expected_result = 1
        self.assertEqual(result, expected_result)

if __name__ == '__main__':
    unittest.main(verbosity=2)