or

Concepts

Programming

Programming


Built-in Types

Built-in Types


Python

img/PYTypes.svg

Javascript

img/JSTypes.svg

Flow Control

Flow Control


Condition

Python

img/PYCondition.svg

Show/Hide Code

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
if type(x) in [int,float,str,bool]:
    y = float(x)
elif type(x) == list:  # x = [1,2,3]
    y = float(x[0])    # y = 1.0
elif type(x) == set:   # x = {1,2,3}
    y = float(x.pop()) # y = 1.0
elif type(x) == dict:  # x = {'a':1,'b':2,'c':3}
    y = float(list(x.values())[0]) # y = 1.0
else:
    y = None

Javascript

img/JSCondition.svg

Show/Hide Code

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
if (["boolean","number","string"].indexOf(typeof x) > -1) {
    y = parseFloat(x)
} else if (Array.isArray(x)) {
    y = x[0] // first value of array
} else if (typeof x == "object") {
    y = x[Object.keys(x)[0]] // first value of object
} else if (x.constructor.name == "Set") {
    y = x.values().next().value // first value of set
} else {
    y = NaN
}
Loop

Python

img/PYLoop.svg

Show/Hide Code

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
x = 'abc123def456'
y = 0
while len(x)>0:
    if (y>0) and not x[0].isdigit():
        break
    elif y == 0 and not x[0].isdigit():
        x = x[1:]
        continue
    y = 10*y + int(x[0])
    x = x[1:]

Javascript

img/JSLoop.svg

Show/Hide Code

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
x = 'abc123def456'
y = 0
while (x.length>0) {
    if ((y>0) && isNaN(x[0])) {
        break
    }
    else if ((y == 0) && isNaN(x[0])) {
        x = x.substr(1)
        continue
    }
    else {
        y = 10*y + parseInt(x[0])
        x = x.substr(1)
    }
}

Functions

Functions


Python

img/PYFunction.svg

Show/Hide Code

 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
54
55
56
57
58
59
60
61
62
import functools

# decorator to register all operations
def register_calls(func):
    @functools.wraps(func)
    def wrapper_register_calls(*args, **kwargs): #**
        if args[0].__name__ == 'show_registry':
            return wrapper_register_calls.registry
        else:
            result = func(*args, **kwargs)
            wrapper_register_calls.registry[ \
                len(wrapper_register_calls.registry)]=\
                    (args[0].__name__,result)
            return result
    wrapper_register_calls.registry = dict()
    return wrapper_register_calls

def show_registry():
    pass

@register_calls
def call_with_reg(func,x):
    return func(x)

# recursive function mixing two strings
def mixer(string1, string2):
    if min(len(string1),len(string2)) == 0:
        return ''
    else:
        return string1[0]+string2[0]+ \
        mixer(string1[1:],string2[1:])

# function with other functions as input & output
def func_builder(sample, *args, casefunc = str.upper, **kwargs):
    def dic_builder(x):
        x = call_with_reg(casefunc,x)
        for arg in args:
            x = call_with_reg(arg,x)
        output_dic = {}
        for kw in kwargs:
            output_dic[kw]=call_with_reg(kwargs[kw],x)
        return output_dic
    return {'function':dic_builder,'sample_result':dic_builder(sample)}

args_dict = {'lstrip' : str.lstrip, 'rstrip' : str.rstrip}
fb_output = func_builder('zyxwvutsrqp', lambda x:mixer(x,'1234567890 '),**args_dict)
# >> {'function': <function __main__.func_builder.<locals>.dic_builder(x)>,
# >> 'sample_result': {'lstrip': 'Z1Y2X3W4V5U6T7S8R9Q0P ',
# >> 'rstrip': 'Z1Y2X3W4V5U6T7S8R9Q0P'}}

fb_output['function'](' abcdefghij')
# >> {'lstrip': '1A2B3C4D5E6F7G8H9I0J ', 'rstrip': ' 1A2B3C4D5E6F7G8H9I0J'}

call_with_reg(show_registry)
#{0: ('upper', 'ZYXWVUTSRQP'),
# 1: ('<lambda>', 'Z1Y2X3W4V5U6T7S8R9Q0P '),
# 2: ('lstrip', 'Z1Y2X3W4V5U6T7S8R9Q0P '),
# 3: ('rstrip', 'Z1Y2X3W4V5U6T7S8R9Q0P'),
# 4: ('upper', ' ABCDEFGHIJ'),
# 5: ('<lambda>', ' 1A2B3C4D5E6F7G8H9I0J '),
# 6: ('lstrip', '1A2B3C4D5E6F7G8H9I0J '),
# 7: ('rstrip', ' 1A2B3C4D5E6F7G8H9I0J')}

Javascript

img/JSFunction.svg

Show/Hide Code

 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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
Object.size = function(obj) {
    var size = 0, key;
    for (key in obj) {
        if (obj.hasOwnProperty(key)) size++;
    }
    return size;
};

function register_calls(func=undefined) {
    if (func == undefined) {
        return registry
    } else {
      registry = {};
      return function() {
        result = func.apply(this,arguments)
        registry[Object.size(registry)] = arguments[0].name + ":" + result
        return result
      };
    }
}

function call_with_reg(func,x){
    return func(x)
}
call_with_reg = register_calls(call_with_reg)

function mixer(string1, string2){
    if (Math.min(string1.length,string2.length) == 0) {
        return ''
    }
    else {
        return string1[0]+string2[0]+
        mixer(string1.substr(1),string2.substr(1))
    }
}
function func_builder(sample, casefunc = (a => a.toUpperCase()),...args) {
    function dic_builder(x) {
        x = call_with_reg(casefunc,x)
        output_dic = {}
        args.forEach(function (item, index) {
            if (item.constructor.name == "Function") {
                x = call_with_reg(item,x)
            } else if ((typeof item) == "object") {
                for (var key of Object.keys(item)) {
                    output_dic[key] = call_with_reg(item[key],x)
                }
            }
        })
        return output_dic
    }
    return {'function':dic_builder,'sample_result':dic_builder(sample)}
}
fb_output = func_builder('zyxwvutsrqp',(a => a.toUpperCase()),(x => mixer(x,'1234567890 ')),
                  {'lstrip': (a => a.replace(/^\s+/, '')),'rstrip': (a => a.replace(/\s+$/, ''))})
//{"sample_result": {"lstrip": "Z1Y2X3W4V5U6T7S8R9Q0P ", "rstrip": "Z1Y2X3W4V5U6T7S8R9Q0P"}}

fb_output['function'](' abcdefghij')
// {"lstrip": "1A2B3C4D5E6F7G8H9I0J ", "rstrip": " 1A2B3C4D5E6F7G8H9I0J"}

register_calls()
//{"0": ":ZYXWVUTSRQP",
// "1": ":Z1Y2X3W4V5U6T7S8R9Q0P ",
// "2": "lstrip:Z1Y2X3W4V5U6T7S8R9Q0P ",
// "3": "rstrip:Z1Y2X3W4V5U6T7S8R9Q0P",
// "4": ": ABCDEFGHIJ",
// "5": ": 1A2B3C4D5E6F7G8H9I0J ",
// "6": "lstrip:1A2B3C4D5E6F7G8H9I0J ",
// "7": "rstrip: 1A2B3C4D5E6F7G8H9I0J"}

Objects

Objects


Python

Meta Classes & Inheritance

img/PYObject.svg

Show/Hide Code

 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
class Recorder: # class defined without any attributes
    pass        # attributes are set externaly later

class Meta(type): # meta class defined to track new, init & call methods
    def __new__(meta, name, bases, dct): # called when new class defined
        Recorder.record += name+'(n)'
        return super(Meta, meta).__new__(meta, name, bases, dct)
    def __init__(cls, name, bases, dct): # called when new class initialized
        Recorder.record += name+'(i)'
        super(Meta, cls).__init__(name, bases, dct)
    def __call__(cls, *args, **kwds): # called when class is called
        Recorder.record += cls.__name__+'(c)'
        return type.__call__(cls, *args, **kwds)

# builds parent with or without super().__init__() call
def parent_builder(name,init=True):
    if init:
        def parent_init(self):
            Recorder.record += name+'<'
            super(globals()[name],self).__init__()
            Recorder.record += name+'>'
    else:
        def parent_init(self):
            Recorder.record += name+'<'
            Recorder.record += name+'>'
    return Meta(name, (),{'__init__':parent_init})

# builds children of various parents
def child_builder(name,*args):
    def child_init(self):
        super(globals()[name],self).__init__()
    return Meta(name, args,{'__init__':child_init})

Recorder.record = ''
globals()["P1"]=parent_builder('P1')
globals()["P2"]=parent_builder('P2')
globals()["P3"]=parent_builder('P3',init=False)
globals()["P4"]=parent_builder('P4',init=False)
## Recorder.record << 'P1(n)P1(i)P2(n)P2(i)P3(n)P3(i)P4(n)P4(i)'
globals()["C1"]=child_builder('C1',P1,P2)
globals()["C2"]=child_builder('C2',P1,P4)
globals()["C3"]=child_builder('C3',P3,P2)
globals()["C4"]=child_builder('C4',P3,P4)
## Recorder.record << 'C1(n)C1(i)C2(n)C2(i)C3(n)C3(i)C4(n)C4(i)'

C1() ## Recorder.record << 'C1(c)P1<P2<P2>P1>'
C2() ## Recorder.record << 'C2(c)P1<P4<P4>P1>'
C3() ## Recorder.record << 'C3(c)P3<P3>'
C4() ## Recorder.record << 'C4(c)P3<P3>'

Javascript

Proxies & Prototypes

img/JSObject.svg

Show/Hide Code

  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
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
///////////////// Function /////////////////////

const handler = {
  getPrototypeOf: (target) => {
    console.log('getPrototype called');
    return Reflect.getPrototypeOf(target)
  },
  setPrototypeOf: (target, proto) => {
    console.log('setPrototype called');
    return Reflect.setPrototypeOf(target, proto)
  },
  construct(target, argumentsList, newTarget) {
    console.log('construct called');
    return Reflect.construct(target, argumentsList, newTarget);
  },
  get(target, propertyKey, receiver){
    console.log('get called');
    return Reflect.get(target, propertyKey, receiver)
  },
  set(target, propertyKey, value, receiver){
    console.log('set called');
    return Reflect.set(target, propertyKey, value, receiver)
  }
}

function extend(sup, base) {
  var descriptor = Object.getOwnPropertyDescriptor(
    base.prototype, 'constructor'
  );
  base.prototype = Object.create(sup.prototype);
  var handler = {
    construct: function(target, args) {
      var obj = Object.create(base.prototype);
      this.apply(target, obj, args);
      return obj;
    },
    apply: function(target, that, args) {
      sup.apply(that, args);
      base.apply(that, args);
    }
  };
  var proxy = new Proxy(base, handler);
  descriptor.value = proxy;
  Object.defineProperty(base.prototype, 'constructor', descriptor);
  return proxy;
}

function parent1(value1) {
  this.param1 = value1;
}

const proto = new Proxy(parent1,handler );

obj1 = new proto('object1-1') //construct called get called
obj2 = new proto('object2-1')//construct called get called

obj3 = extend(parent1, function(value1, value2) {
  this.param2 = value2;
});

obj2.__proto__ = obj1
obj1.param2 = 'object1-2'

console.log(proto.__proto__) //get called getPrototype called [Function (anonymous)]
console.log(obj2.__proto__) //parent1 { param1: 'object1-1', param2: 'object1-2' }
console.log(obj3.__proto__) //[Function (anonymous)]

///////////////// Class /////////////////////

const RecorderInstanceHandler = {
  get(target, prop, receiver) {
    const val = target[prop];
    if (typeof target[prop] === "function") {
      return function(...args) {
        try { console.log(target.name+"(f:" + prop + ")"); }
        catch (error) { console.log("(f:prop)"); }
        return val.apply(this, args);
      };
    } else {
      return val;
    }
  }
}

const RecorderClassHandler = {
  construct(target, args, newTarget) {
    const instance = Reflect.construct(target, args, newTarget);
    console.log(target.name + "(c)")
    return new Proxy(instance, RecorderInstanceHandler);
  }

}
class Parent2 {
    constructor(value1) {
        this.param1 = value1
    }
  }

class Child2 extends Parent2{
    test() {
        print('test')
    }
}

child2 = new Proxy(Child2, RecorderClassHandler)

obj = new child2('object1') //Child2(c)

print(obj.param1) //"object1"

obj.test() //undefined(f:test) "test"

Python

Iterables

img/PYIterable.svg

Show/Hide Code

 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
import string
import random
import statistics

def random_character_generator():
    chars_to_remove = ""
    while True:
        if chars_to_remove is not None:
            chars = string.ascii_lowercase
            for char in chars_to_remove:
                chars = chars.replace(char,"")
            char_to_yield = random.choice(chars)
        chars_to_remove = (yield char_to_yield)

class RandomWord:
    def __init__(self):
        self._string = ''
        self._dict = dict()
        for l in string.ascii_lowercase:
            self._dict[l] = 0

    def add_letter(self,l):
        self._string += l
        self._dict[l] += 1

    def __getitem__(self,index):
        return self._string[index]

    def highfreqelems(self):
        chars_to_remove = ''
        for l in string.ascii_lowercase:
            if self._dict[l] > statistics.mean(self._dict.values())*1.5:
                chars_to_remove += l
        return chars_to_remove

i = 0
agg_string = RandomWord()
letter_count = dict()
rcg = random_character_generator()
for c in rcg:
    agg_string.add_letter(c)
    # excludes the overly frequent letters from choices
    d = rcg.send(agg_string.highfreqelems())
    i+=1
    if i == 100:
        break

''.join(list(agg_string))

Javascript

Iterables

img/JSIterable.svg

Show/Hide Code

 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
54
55
56
57
58
59
60
61
62
63
64
65
function* random_character_generator() {
    chars_to_remove = "A"
    while (true) {
        chars = [...Array(26)].map(_=>(++i).toString(36),i=9).join``
        if (chars_to_remove) {
            for (var i = 0; i < chars_to_remove.length; i++) {
                chars = chars.replace(chars_to_remove.charAt(i),""); }
        }
        char_to_yield = chars[Math.floor(Math.random() * chars.length)]
        chars_to_remove = (yield char_to_yield)

    }
}

const average = arr => arr.reduce((a,b) => a + b, 0) / arr.length

class RandomWord {
    constructor(){
        this._string = ''
        this._map = new Map()
        this.index = 0
        var i = 9
        for (var char of [...Array(26)].map(_=>(++i).toString(36),i=9)){
            this._map.set(char,0)
        }
    }
    add_letter(l){
        this._string += l
        this._map.set(l,this._map.get(l)+1)
    }

    highfreqelems(){
        var chars_to_remove = ""
        var i = 9
        var average_value = average(Array.from(this._map.values()))
        for (var char of [...Array(26)].map(_=>(++i).toString(36),i=9)){
            if (this._map.get(char) > average_value * 1.5) {
                chars_to_remove = chars_to_remove.concat(char)
            }
        }
        return chars_to_remove
    }
    [Symbol.iterator]() {
        return this;
    }
    next() {
        if (this.index < this._string.length) {
            return { value: this._string[this.index++] };
        } else {
            return { done: true };
        }
    }
}

agg_string = new RandomWord()
rcg = random_character_generator()

var counter = 0

while (counter<10){
  d = rcg.next(agg_string.highfreqelems())
  agg_string.add_letter(d.value)
  counter = counter + 1
}
console.log(Array.from(agg_string).join(","))

Data Processing

Data Processing


Python

Selection & Reshaping

img/PYDataReshaping.svg

Show/Hide Code

 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
import pandas as pd
from tabulate import tabulate


df = pd.DataFrame( [[11, 12, 13], [14, 15, 16],
                    [17, 18, 19], [20, 21, 22]],
                  index=pd.MultiIndex.from_product(
                      [['A','B'],[1,2]], names=['N','V']),
                  columns=pd.MultiIndex.from_tuples(
                      [('c',3),('c',4),('d',4)], names=['n','v']))
idx = pd.IndexSlice

print(tabulate(
    df.loc[idx['B',:],[('c',4)]]
    , headers='keys', tablefmt='psql'))

#print(tabulate(
#    df.iloc[2:4,[1]]
#    , headers='keys', tablefmt='psql'))

#+----------+------------+
#|          |   ('c', 4) |
#|----------+------------|
#| ('B', 1) |         18 |
#| ('B', 2) |         21 |
#+----------+------------+

dg = pd.melt(df.reset_index(),id_vars=['N','V'])
#dg = df.stack().stack().reset_index().rename(columns={0:'value'})
dg = dg.pivot_table(index=['N','V'],columns=['n','v'],values=['value'])
#dg = dg.groupby(['N','V','v','n']).agg('sum').unstack().unstack().dropna(axis=1, how='all')
dg.columns = dg.columns.droplevel(0)

all(df == dg)
# True

SQL

Selection & Reshaping

img/SQLDataReshaping.svg

Show/Hide Code

 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
CREATE DATABASE db;

USE db;

CREATE TABLE df (
  df_index VARCHAR(20) NOT NULL,
  c_3 INT,
  c_4 INT,
  d_4 INT,
  UNIQUE (df_index)
);

INSERT INTO df
    (df_index, c_3, c_4, d_4)
VALUES
    ("A_1",11,12,13),
    ("A_2",14,15,16),
    ("B_1",17,18,19),
    ("B_2",20,21,22);

SELECT c_4 from df where df_index in ("B_1","B_2");

SELECT df_index
     , SUM(CASE WHEN df_column =  "c_3" THEN df_value END) AS c_3
     , SUM(CASE WHEN df_column =  "c_4" THEN df_value END) AS c_4
     , SUM(CASE WHEN df_column =  "d_4" THEN df_value END) AS d_4
  FROM
    (SELECT df_index, "c_3" as df_column, c_3 as df_value FROM df
    UNION SELECT df_index, "c_4" as df_column, c_4 as df_value FROM df
    UNION SELECT df_index, "d_4" as df_column, d_4 as df_value FROM df
    ORDER BY df_value) unpvt
GROUP BY df_index

/*SELECT df_index, [c_3], [c_4], [d_4]
FROM
(   SELECT df_index, df_column, df_value
    FROM (SELECT df_index, c_3, c_4, d_4 FROM df) p
    UNPIVOT
    (df_value FOR df_column IN (c_3, c_4, d_4))AS unpvt;
    ) AS unpvt
PIVOT
( sum(df_value) FOR df_column IN ([c_3], [c_4], [d_4])
) AS pvt; */

Python

Merging

img/PYDataMerging.svg

Show/Hide Code

 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
df = pd.DataFrame({'a':[1,2],'b':[3,4]},index=['A','B'])
dg = pd.DataFrame({'b':[4,5],'c':[6,7]},index=['C','A'])

print(tabulate(
    pd.concat([df,dg])
    , headers='keys', tablefmt='psql'))
#+----+-----+-----+-----+
#|    |   a |   b |   c |
#|----+-----+-----+-----|
#| A  |   1 |   3 | nan |
#| B  |   2 |   4 | nan |
#| C  | nan |   4 |   6 |
#| A  | nan |   5 |   7 |
#+----+-----+-----+-----+
print(tabulate(
    pd.concat([df,dg],axis=1)
    , headers='keys', tablefmt='psql'))
#+----+-----+-----+-----+-----+
#|    |   a |   b |   b |   c |
#|----+-----+-----+-----+-----|
#| A  |   1 |   3 |   5 |   7 |
#| B  |   2 |   4 | nan | nan |
#| C  | nan | nan |   4 |   6 |
#+----+-----+-----+-----+-----+
print(tabulate(
    pd.merge(df,dg,on='b',how='outer',indicator=True)
    , headers='keys', tablefmt='psql'))
#+----+-----+-----+-----+------------+
#|    |   a |   b |   c | _merge     |
#|----+-----+-----+-----+------------|
#|  0 |   1 |   3 | nan | left_only  |
#|  1 |   2 |   4 |   6 | both       |
#|  2 | nan |   5 |   7 | right_only |
#+----+-----+-----+-----+------------+

SQL

Merging

img/SQLDataMerging.svg

Show/Hide Code

 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
54
CREATE TABLE df (
  df_index VARCHAR(20) NOT NULL,
  a INT,
  b INT,
  UNIQUE (df_index)
);

CREATE TABLE dg (
  dg_index VARCHAR(20) NOT NULL,
  b INT,
  c INT,
  UNIQUE (dg_index)
);

INSERT INTO df
    (df_index, a, b)
VALUES
    ("A",1,3),
    ("B",2,4);

INSERT INTO dg
    (dg_index, b, c)
VALUES
    ("C",4,6),
    ("A",5,7);

SELECT * FROM df
UNION
SELECT * FROM dg;

SELECT concat(IFNULL(df.df_index,'-'),IFNULL(dg.dg_index,'-')),
       df.a,df.b,dg.c FROM df
LEFT JOIN dg ON df.b = dg.b;

SELECT concat(IFNULL(df.df_index,'-'),IFNULL(dg.dg_index,'-')),
       df.a,dg.b,dg.c FROM df
RIGHT JOIN dg ON df.b = dg.b;

/*SELECT concat(IFNULL(df.df_index,'-'),IFNULL(dg.dg_index,'-')),
       df.a,df.b,dg.b,dg.c FROM df
FULL OUTER JOIN dg ON df.b = dg.b;*/

SELECT concat(IFNULL(df.df_index,'-'),IFNULL(dg.dg_index,'-')),
       df.a,df.b,dg.c FROM df
LEFT JOIN dg ON df.b = dg.b
UNION ALL
SELECT concat(IFNULL(df.df_index,'-'),IFNULL(dg.dg_index,'-')),
       df.a,dg.b,dg.c FROM df
RIGHT JOIN dg ON df.b = dg.b
WHERE df.b IS NULL;

SELECT concat(IFNULL(df.df_index,'-'),IFNULL(dg.dg_index,'-')),
       df.a,dg.b,dg.c FROM df
INNER JOIN dg ON df.b = dg.b;