Document
Bash JavaScript C++ Python PL/SQL
Hello World
#!/bin/bash
printf "%s\n" "Hello World"
console.log('Hello World');
#include <iostream>

int main(){ //this is main
    std::cout << "Hello World" << std::endl;
    return 0;
}
# -*- coding: UTF-8 -*-

print('Hello World')
TBD
Data Type
# String - this is the default type
declare str="hello world"
echo $str

# Integer, 
# use (( ... )) for calculation
# support + - * / % # << >> & | ^
declare -i num
(( num = `ps -ef | wc -l` ))
echo $num        #329
(( num=num+100 ))
echo $num        #429

# Constant
declare -r con="stone"

# Array
declare –a integer num
num[0]=100
num[1]=200
num[2]=300
echo ${num[*]}     #100 200 300
echo ${#num[*]}    #3

arr[0]=big
arr[1]=small
arr[2]="medium sized"
echo ${arr[*]}    #big small medium sized

unset num
unset arr
string number boolean undefined null object symbol
"use strict";                //force declar before using
var myVar = 10;                //es5
let myName = "martin";        //es6, better scoping
const pi = 3.14;            //es6, avoid unwanted change
console.log(typeof myName); //string
var i = parseInt(str)        //string to int
var obj2 = obj1;            //refer
var obj3 = JSON.parse(JSON.stringify(obj1));//deep copy

//string template literal, multi lines, dyn vars.
const cat = { name: "Tom", age: 5 };
const greeting = `Hello, my name is ${cat.name}
                    and ${cat.age} years old.`;
//TypeScript
let list1: number[] = [1, 2, 3];            //array
let list2: Array<number> = [1, 2, 3];        //array
let person: [string, number] = ['Tom', 22];    //tuple
enum Color { Red = 5, Green, Blue };        //enum
let c: Color = Color.Green;
let myVar: any = 10;                        //any
myVar = 'Hello';
let myVar : unknown = 10;                    //unknown
myVar = 'abc';
(myVar as string).toUpperCase();            //cast
let mTyp: number | boolean;            //type union
mTyp = 20;
mTyp = true;
//integer types
short size{5};
int count{365};
long distance{80'000L};
long long superlong{15'000'000LL};

unsigned int age{20U};   //unsigned
int hex_num{0xFF};       //hexadecimal
int oct_num{0377};       //octal
int bin_num{0b10101010}; //binary

//floating types
float price{3.45F};
double pi{3.1415926};
long double root2{1.4142135623730950488L};

//character type
char yes{'Y'};

//string type
string str{"hello"};
char* cstr1 = str.c_str();
char* cstr2 = str.data();

const char* c_str{"hello"};
std::string str{c_str};
std::string_view vw_str{c_str};

string rstr{R"(can be 
                multi lines)"};

//auto types
auto m{10};      //int
auto n{200UL};   //unsigned long
auto p{3.14159}; //double

//type casting
float vf{12.3};
int vi{static_cast<int>(vf)};
TBD
TBD
Data Structures
TBD
//Array
const arr = new Array(2, 1, 3);
arr.push(5, 4);
for (let e of arr) {
    console.log(e);
}

//Set
const set = new Set();

const arr = [1, 2, 2, 3, 3, 3, 4];
for (let e of arr) {
    set.add(e);
}
set.forEach(
    (e) => console.log(e)
);

const arr = [1, 2, 2, 3, 3, 3, 4];
const arr2 = [...new Set(arr)];    //de-dup

//Map
const map = new Map();
map.set('bj', 'Beijing');
map.set('sh', 'Shanghai');
map.set('gz', 'Guangzhou');
for (let [k, v] of map) {
    console.log(`Key: ${k}, Value: ${v}`);
}
// Array - Triditional
std::string cities[]{"bj", "sh", "gz", "sz"};

//Sequential Containers, can use [], scope, or iterator
std::array<std::string, 5> a_cities{"bj", "sh", "gz", "sz"};
std::vector<std::string> v_cities{"bj", "sh", "gz", "sz"}; //Best
std::list<std::string> l_cities{"bj", "sh", "gz", "sz"};
std::deque<std::string> d_cities{"bj", "sh", "gz", "sz"};

//Un-Sequential Containers, 
//Can NOT use [], can use scope or iterator
//Stack & Queue, no common init list; 
std::stack<std::string> s_cities{}; //LIFO
s_cities.push("bj");
s_cities.pop();
std::queue<std::string> q_cities{}; //FIFO
q_cities.push("bj");
q_cities.pop();
//Set
std::set<std::string> set_cities{"bj", "sh", "gz", "sz"}; //No Dup
for (const auto &c : set_cities) {
    std::cout << c << std::endl;
}
//Map
std::map<std::string, std::string> dict_cities{
    std::pair("bj", "bejing"),
    std::pair("sh", "shanghai"),
    std::pair("gz", "guangzhou"),
    std::pair("sz", "shenzhen")};
for (const auto &[c, city] : dict_cities) {
    std::cout << c << ':' << city << std::endl;
}
for (const auto &ct : dict_cities) {
    std::cout << ct.first << ':' << ct.second << std::endl;
}
TBD
TBD
Decision
# test command execution
if grep root /etc/passwd >/dev/null; then
    echo "root found!"
else
    echo "root not found!"
fi

# test string with [[ $var == "val" ]]
# compare with ==, !=, <, >, -z, -n
name="lucy"
if [[ "$name" == "snoopy" ]]; then
    echo "It was a dark and stormy night."
elif [[ "$name" == "lucy" ]]; then
    echo "The doctor is in."
else
    echo "Not a Snoopy character."
fi

# test num with [[ $var -eq val ]] or (( $var == val ))
# compare with -eq, -ne, -lt, -gt, -le, -ge
declare -i num=101
declare -i rem
(( rem = num % 2 ))
# if [[ $rem -eq 0 ]] ; then
if (( $rem == 0 )) ; then
    printf "%d is an even\n" "$num"
else
    printf "%d is an odd\n" "$num"
fi

# case statements
name=lucy
case $name in
"snoopy")
    echo "It was a dark and stormy night."
    ;;
"lucy")
    echo "The doctor is in."
    ;;
*)
    echo "Not a Snoopy character."
    ;;
esac
console.log(5 == '5'); //true, value same
console.log(5 === '5');//false, but type diff

if (score == 5) {
    console.log("excellent");
} else if (score == 4) {
    console.log("good");
} else {
    console.log("bad");
}

switch (day) {
    case 1: case 2: case 3: case 4: case 5:
        console.log("workday"); break;
    case 0: case 6:
        console.log("holiday"); break;
    default:
        console.log("wrong"); break;
}
//if...else...
if (std::isalnum(letter)) {
    std::cout << "it's a letter/digit." << std::endl;
} else {
    std::cout << "not a letter/digit." << std::endl;
}

//logical AND
if (letter >= 'A' && letter <= 'Z') {
    std::cout << "an uppercase letter." << std::endl;
}

//logical OR
if (income >= 100'000.00 || capital >= 1'000'000.00) {
    std::cout << "ok, how much to borrow?" << std::endl;
}

//conditional operator
c = a > b ? a : b; 

//switch...case...
switch (ticket_number)
{
case 147:
    std::cout << "You win first prize!";
    break;
case 387:
    std::cout << "You win second prize!";
    break;
default:
    std::cout << "Sorry, you lose.";
    break;
}
TBD
TBD
Looping
for fruit in apple orange banana peach kiwi; do
    echo "current fruit is: $fruit"
done

for arg in $*; do
    echo "current arg is: $arg"
done

# export IFS=":"
for item in $(cat data.txt); do
    echo "current item is: $item"
done

for file in /etc/*.conf; do
    echo "current file is: $file"
done
var days = ["MON", "TUE", "WED"];
//for loop
for (var i = 0; i < days.length; i++) {
    console.log(days[i]);
}
for (let day of days) {
    console.log(day);
}
//while loop
while (day = days.shift()) {
    console.log(day);
}
//do...while
var day = days.shift();
do {
    console.log(day);
} while (day = days.shift());
//forEach - just traverse,
days.forEach((d) => d + "2");
days.forEach((d) => console.log(`today is ${d}`));
//map - copy and return new
const days2 = days.map((d) => d + "2");
days2.forEach((d) => console.log(`today is ${d}`));
//filter - filter and return new
const days3 = days.filter((d) => d.startsWith('T'));
days3.forEach((d) => console.log(`today is ${d}`));
//classic for loop 
unsigned int scores[]{85, 92, 76}, total{};
for (size_t i{}; i < std::size(scores); ++i){
    total += scores[i];
}
std::cout << "total scores: " << total << std::endl;

//modern range-based for loop
std::vector<std::string> cities{"bj", "sh", "gz", "sz"};
for (const auto &city : cities) {
    std::cout << city << std::endl;
}

//modern iterator-based for loop
std::vector<std::string> cities{"bj", "sh", "gz", "sz"};
for (auto iter{cities.begin()}; iter != cities.end(); ++iter) {
    std::cout << *iter << std::endl;
}

//while loop
unsigned int n{},limit{21};
unsigned long long factorial{1ULL};
while (++n <= limit) {
    factorial *= n; // Calculate n! for current n
    std::cout << factorial << std::endl;
}

//do...while loop
char reply{};         
int count{};         
double temperature{},total{};
do {
    std::cout << "Enter a temperature: ";
    std::cin >> temperature;
    total += temperature;
    ++count;
    std::cout << "enter another? (y/n): ";
    std::cin >> reply;
} while (tolower(reply) == 'y');
std::cout << "average temperature is " 
          << total / count << std::endl;

//skip current iteration and go to next
continue;

//break the whole loop
break;
TBD
TBD
Array
TBD
var myArr = ["John", 23];
var myArr = [ 50, 60, 70];
var myVar = myArr[2];       //70
myArr[1] = 65;              //ok
myArr.push(80);             //append tail     [...]<--
myArr.unshift(40);          //append head  -->[...]
myArr.pop();                //remove tail     [...]-->
myArr.shift();              //remove head  <--[...]

const arr = [1, 2, 3];
arr = [4, 5, 6];         //cannot assign another array
arr[0] = 4;                //but ok to operate internal value
arr[1] = 5
arr[2] = 6;

Object.freeze(arr);        //freeze it
arr[1] = 5                //no error and no effect

//spread opr [...arr] is deep copy
const arr1 = [10, 20, 30, 40, 50];
let arr2 = arr1;                //just a ref
let arr3 = [...arr1];           //full copy
let [, , ...arr4] = [...arr1];  //parial copy
arr1[2] = 35;
console.log(arr1);    //[10, 20, 35, 40, 50 ]
console.log(arr2);    //[10, 20, 35, 40, 50 ]
console.log(arr3);    //[10, 20, 30, 40, 50 ]
console.log(arr4);    //[30, 40, 50 ]

//destructive assignment
const [a,b,c] = [1,2,3,4,5,6];         //1,2,3
const [a,b,,,c] = [1,2,3,4,5,6];    //1,2,5
const [,, ...arr] = [1,2,3,4,5,6];  //[3,4,5,6]

let x=10,y=20;
[x,y]=[y,x];                        //swapped
//char array, end with '\0'
char name[]{"martin"};  
std::cout << name << std::endl;

//multi-dim char array
char cities[][3]{"bj", "sh", "gz", "sz"};
for (const auto &city : cities) {
    std::cout << city << std::endl;
}

//multi-dim num array
double carrots[][4]{
    {2.5, 3.2, 3.7, 4.1},   //first dim can be empty
    {4.1, 3.9, 1.6},        //last one init'ed as 0
    {2.8, 2.3, 0.9, 1.1}    //total dims == rows
};
for (const auto &row : carrots) {
    for (const auto &e : row) {
        std::cout << std::fixed << std::setprecision(1)
                    << std::setw(5) << e;
    }
    std::cout << std::endl;
}

//vector container
std::vector<<std::string>> cities{"bj", "sh", "gz", "sz"};
for (const auto &city : cities) {
    std::cout << city << std::endl;
}

//array container, init num can <= array size
std::array<<std::string>, 4> cities{"bj", "sh", "gz"};
for (const auto &city : cities) {
    std::cout << city << std::endl;
}

//static alloc in stack
int arr[5]{};
int *pInt = arr;
for (int i{}; i < std::size(arr); ++i) {
    *pInt = std::rand() % 10;
    std::cout << *pInt << std::endl;
}

//dyn alloc in heap
int *data{new int[5]{}};
for (int i{}; i < 5; ++i) {
    *(data+i) = std::rand()%10;
    std::cout << *(data+i) << std::endl;
}
delete[] data; //need release explicitly
TBD
TBD
Function
function cman(){
    export LANG="zh_CN.UTF-8"
    man $1
    unset LANG
}

function chelp(){
    export LANG="zh_CN.UTF-8"
    help $1
    unset LANG
}

vi parsepath.sh
function parsepath() {            # define function
    name=$1
    echo "The pathname is: $name"
    while [[ -n $name ]]; do
        echo $name
        name=${name%/*}
    done
}

. parsepath.sh
export -f parsepath                # export function

vi firstfunc.sh
if [ $# -ne 0 ]; then
    echo "Usage: firstfunc.sh"
    exit 1
fi
echo -n "Enter a pathname and I will parse it:"
read pathname junk

while [[ -n $pathname ]]; do
    parsepath $pathname            # call function
    echo -n "Enter a pathname and I will parse it:"
    read pathname junk
done
function add(a, b) {                    //triditional style
    var x = a || 0;    //default 0
    var y = b || 0;    //default 0
    return x + y;
}
var add = (a = 0, b = 0) => a + b;         //fat arrow style

button.addEventListener('click',function(){
    this.style.color = "red";        // Ok, "this" === button
    var addFade = function(){
        this.style.display = "none";// XXX "this" !== button
    }
})

button.addEventListener('click',function(){
    this.style.color = "red";        // Ok, "this" === button
    var addFade = () => {
        this.style.display = "none";// Ok, "this" === button
    }
})

//filter & map
const arr = [1.2, 3.5, 4, 12.3, 5];
const squareNums = (arr) => arr
    .filter(num => Number.isInteger(num))    //4,5
    .map(n => n * n);                        //16,25
console.log(squareNums(arr));

//default param
const incr = (num, val = 1) => num + val;
console.log(incr(5, 2));        //7
console.log(incr(5));           //6

//rest opr ... convert params into array args
const sum = (...args) => args.reduce((a, b) => a + b, 0);
sum(1,2,3);                        //6
sum(1,2,3,4);                    //10

//destructive assignment for parameter within {...}
const stats = { max: 56.78, min: -0.75, avg: 40, med: 38};
const range = ({ max, min }) => (max + min) / 2;
console.log(range(stats));        //pass whole obj

//consise obj literal declaration with simple fields
const crPerson = (name,age,gender) => ({name,age,gender});
console.log(crPerson("Tom", 5, "male"));
//{ name: 'Tom', age: 5, gender: 'male' }
//declare
void func_chg_by_cpy(double);
void func_chg_by_ptr(double *);
void func_chg_by_ref(double &);

int main()
{
  double val{5.0};
  func_chg_by_cpy(val);  
  std::cout << "val = " << val << std::endl;
  func_chg_by_ptr(&val);
  std::cout << "val = " << val << std::endl;
  func_chg_by_ref(val);
  std::cout << "val = " << val << std::endl;
}
//define
void func_chg_by_cpy(double val) {
  val += 10.0;  //only change copy, not orig
}
void func_chg_by_ptr(double *ptr) {
  *ptr += 10.0; //change val itself
}
void func_chg_by_ref(double &ref) {
  ref += 10.0;  //change val itself
}


#include <functional>
//generic code
template <typename T, typename Comparison>
const T *find_optimum(const std::vector<T> &values, 
                      Comparison compare) {
    if (values.empty())
        return nullptr;
    const T *optimum = &values[0];
    for (size_t i = 1; i < values.size(); ++i) {
        if (compare(values[i], *optimum)) {
            optimum = &values[i];
        }
    }
    return optimum;
}

std::vector<int> numbers{91, 18, 92, 22, 13, 43};

//standard function object
std::cout << "Minimum element: " << 
    *find_optimum(numbers, std::less<>{}) << std::endl;
std::cout << "Maximum element: " << 
    *find_optimum(numbers, std::greater<>{}) << std::endl;

//parameterized Function Objects
class Nearer{
public:
    Nearer(int value) : n(value) {}
    bool operator()(int x, int y) const { 
        return std::abs(x - n) < std::abs(y - n); }
private:
    int n;
};
int v_num{50};
std::cout << "num nearest to " << v_num << " is "  << 
    *find_optimum(numbers, Nearer{v_num}) << std::endl;

//lamda expression
std::cout << "Minimum element: " << *find_optimum(
    numbers, [](int x, int y) { return x < y; }) << std::endl;
std::cout << "Maximum element: " << *find_optimum(
    numbers, [](int x, int y) { return x > y; }) << std::endl;

//lamda expression with captured valuable
int v_num{50};
std::cout << "The number nearest to " << v_num << " is "
    << *find_optimum(numbers, [&v_num](int x, int y) { 
    return std::abs(x - v_num) < std::abs(y - v_num); }) 
    << std::endl;
TBD
TBD
Class
TBD
class Person {
    protected name: string;
    protected age: number;
    constructor(name, age) {
        console.log('Person(...)');
        this.name = name;
        this.age = age;
    }
    intro() {
        console.log(`my name is 
            ${this.name} and ${this.age} years old`);
    }
}
class Student extends Person {      //inherit
    private score: number;
    constructor(name, age, score) {
        console.log('Student(...)');
        super(name, age);   //super constructor
        this.score = score;
    }
    exam() {
        console.log(`my score is ${this.score}`);
    }
}
let stu = new Student('Tom', 20, 95);
stu.intro();
stu.exam();

interface Person {                  //interface
    firstName: string;
    lastName?: string;                //optional attr
}
function fullName(person: Person) { //interface param
    console.log(`${person.firstName} ${person.lastName}`);
}
fullName({ firstName: 'Bruce', lastName: 'Lee' });
fullName({ firstName: 'Jack' });
class Person {                  //base class
protected:
    int age{1};                 //data member
public:
    explicit Person(int a) : age{a} {};
    virtual ~Person() = default;
    virtual void talk();
    virtual void play() = 0;    //pure virtual
};
void Person::talk() {
    std::cout << "I'm " 
        << age << " years old." << std::endl;
}

class Man : public Person {     //derived class
private:
    bool beard;
public:
    Man(int a, bool b) : Person{a}, beard{b} {}
    void talk() override;
    void play() override;
};

void Man::talk() {              //override
    Person::talk();
    std::cout << "I have " 
        << ((beard == true) ? "some" : "no")
        << "beard" << std::endl;
}

void Man::play() {              //implement
    std::cout << "I'm playing a game" << std::endl;
}

class Woman : public Person     //derived class
{
private:
    int hair_len;
public:
    Woman(int a, int hl) : Person{a}, hair_len{hl} {};
    void talk() override;
    void play() override;
};
void Woman::talk() {
    Person::talk();
    std::cout << "my hair length is " << hair_len
              << " inches" << std::endl;
}
void Woman::play() {
    std::cout << "I'm do some shopping" << std::endl;
}

Man hasband{30, true};
Woman wife{29, 10};
Woman child{10, 8};
std::vector<Person *> family{&hasband, &wife, &child};
for (const auto &p : family) {
    p->talk();                  //polymorphic
    p->play();
}
TBD
TBD
Misc
#Inter-Ops
# getopts
USAGE="usage: $0 [-d] [-m month]"
year=$(date +%Y)
if (($# == 0)); then
    echo $USAGE
    exit 1
fi
while getopts :dm:h opt_char; do
    case $opt_char in
    d)
        echo "Date: " # -d option given
        date
        ;;
    m)
        cal $OPTARG $year # -m option given with an
        ;;
    h)
        echo "$USAGE"
        ;;
    :)
        echo "The $OPTARG option requires an argument."
        echo "$USAGE"
        ;;
    \?)
        echo "$OPTARG is not a valid option."
        echo "$USAGE"
        ;;
    esac
done
//check prop
obj.hasOwnProperty("prop");
//refer or add prop
obj["prop"];
obj.prop; 
arr[index];
//delete prop
delete obj.prop;
delete obj["prop"];

//desctructive assignment
const cube = { l: 10, w: 20, h: 30 };
let { l: length, w: width } = cube; //can only assign partial
console.log(length);                //10
console.log(width);                    //20

//callback
//define a high-order func (which has flex callback placeholder)
function getData(data, callback) {
    setTimeout(() => {
        console.log("reading data from database");
        callback({ data: data });
    }, 2000);
}
//call the high-order func with a specific callback method
getData(5, (data) => console.log(data));

//promise
const prom = new Promise((resolve, reject) => {
    setTimeout(resolve, 2000, 'succeeded');
    // setTimeout(reject, 2000, 'some error');
});

prom.then((data) => console.log(data))
    .catch((reason) => console.error('Error: ' + reason));

//async await
function long_ops(ms) {
    return new Promise((resolve, reject) => {
        setTimeout(resolve, ms);
    });
}

async function asyncPrint(value, ms) {
    await long_ops(ms);        //wait but not stuck main thread
    console.log(value);
}
asyncPrint('hello world', 2000);
Exceptions
class Trouble {
private:
  <std::string> message;
public:
  Trouble(std::string_view str = "a problem") 
      : message{str} {}
  virtual ~Trouble() = default;
  virtual std::string_view what() const { 
      return message; 
  }
};

class MoreTrouble : public Trouble
{
public:
  MoreTrouble(std::string_view str = "more trouble")
      : Trouble{str} {}
};

class BigTrouble : public MoreTrouble
{
public:
  BigTrouble(std::string_view str = "big trouble") 
      : MoreTrouble{str} {}
};

Trouble trouble;
MoreTrouble moreTrouble;
BigTrouble bigTrouble;

for (int i{}; i < 6; ++i)
{
  try {             //try something which may fail
    try {
      if (i == 1)
        throw trouble;
      else if (i == 3)
        throw moreTrouble;
      else if (i == 5)
        throw bigTrouble;
    }
    catch (...){    //catch any exception
      std::cout << "caught and rethrow." << std::endl;
      throw;        //rethrow current exception
    }
  }
  catch (const Trouble &t) {
    std::cout << "caught a troule: "
              << t.what() << std::endl;
  }
}
TBD