Saturday, June 3, 2023

my-alpine and docker-compose.yml

 ```

version: '1'

services:
    man:
      build: .
      image: my-alpine:latest
 

``` 


Dockerfile:

```

FROM alpine:latest
ENV PYTHONUNBUFFERED=1
RUN apk add --update --no-cache python3 && ln -sf python3 /usr/bin/python
RUN python3 -m ensurepip
RUN pip3 install --no-cache --upgrade pip setuptools
RUN apk add git
```

Tuesday, May 23, 2023

A Kotlin recursive function

 import kotlin.reflect.full.memberProperties


data class Abc(

    val a: String,

    val b: String,

    val c: String,

    val d: D,

    val e: E

) {

    data class D(

        val e: String,

        val f: String,

        val g: String

    )

    data class E(

        val h: List<String>

    )

}


data class Xyz(

    val a: String,

    val b: String,

    val c: String,

    val d: D,

    val e: E

) {

    data class D(

        val e: String,

        val f: String,

        val g: G

    ){

        data class G(

            val h: String,

            val i: String

        )

    }

    data class E(

        val h: List<String>

    )

}



fun hasContent(inVal: Any): Boolean {

    if (inVal::class.simpleName == "String") {

        if (inVal != "") {

            return true

        }

    } else {

        inVal::class.memberProperties.forEach { ele ->

            if (ele.returnType.classifier == String::class) {

                if (ele.call(inVal) != "") {

                    return true

                }

            }

            else if (ele.returnType.classifier == List::class) {

                val list = ele.call(inVal) as List<*>

                val listCheck = list.map { hasContent(it!!) }

                if (listCheck.contains(true)) {

                    return true

                }

            }

            else {

                if (hasContent(ele.call(inVal)!!)) {

                        return true

                    }

                }

        }

        return false

    }

    return false

}



fun main() {

    // aa has content, should print true

    val aa = Abc("a1", "b2", "c3", Abc.D("e4", "f5", "g6"), Abc.E(listOf("h7", "i8", "j9")))

    println(" aa has content -> ${hasContent(aa)}")


    // bb has no content, should print false

    val bb = Abc("", "", "", Abc.D("", "", ""), Abc.E(listOf("", "", "")))

    println(" bb has content -> ${hasContent(bb)}")


    // cc has content, should print true

    val cc = Abc("", "", "", Abc.D("e4", "", ""), Abc.E(listOf("", "", "j9")))

    println(" cc has content -> ${hasContent(cc)}")


    // dd has content, should print true

    val dd = Abc("", "", "", Abc.D("", "", ""), Abc.E(listOf("", "", "j9")))

    println(" dd has content -> ${hasContent(dd)}")


    // xx has no content, should print false.

    val xx = Xyz("", "", "", Xyz.D("", "", Xyz.D.G("", "")), Xyz.E(listOf("", "", "")))

    println(" xx has content -> ${hasContent(xx)}")


    // yy has content, should print true.

    val yy = Xyz("", "", "", Xyz.D("", "", Xyz.D.G("", "")), Xyz.E(listOf("", "", "blahblah")))

    println(" yy has content -> ${hasContent(yy)}")


    // zz has content, should print true.

    val zz = Xyz("", "", "", Xyz.D("", "", Xyz.D.G("", "blahblah")), Xyz.E(listOf("", "", "")))

    println(" zz has content -> ${hasContent(zz)}")

}


Wednesday, June 29, 2022

A nice alias to check the resources used be each user on a Linux server

 Sometimes on a shared Linux server or AWS EC2, we found out the resources are limited because some other persons are using the machine, and we want to rank order the users by resources used from high to low. This alias does exactly this.


```

alias wtf="ps hax -o rss,user | awk '{a[\$2]+=\$1;}END{for(i in a)print i\"  \"int(a[i]/1024+0.5);}' | sort -rnk2"

```

Friday, October 22, 2021

AWK: count which customer has the most unique accounts

Content of the count_uniq.awk script:


BEGIN {
    FS=",";
}
{
    if ($0 in seen == 0){arr[$2]++} else {seen[$0]=1}
    seen[$0]=1;
}
END {
    for (a in arr) print a, arr[a]
}


What it does?

count how many accounts does each customer has, ignoring duplicated rows. Details as in image below:


Customer "a" has 3 different accounts: [1, 2, 3]

Customer "b" has 1 account: [2]

Customer "c" has 2 accounts: [1, 2]


Thursday, September 30, 2021

Concatenate multiple files with same headers (and only keep one header line in the output file) - Version2

 Put this into an AWK script and call it merge.awk:


BEGIN{

    h=ARGV[1];

    ARGV[1]="";

}



{

    if(FNR==1){print}

    else if($1!~h){print}

}


and use an argument:

cat *.csv | awk -f merge.awk "<header>" > output.csv

Wednesday, September 8, 2021

git: find string in a certain branch

 So, today I cloned a repo and it has many branches. I know one of the branches has a file that is updated and contains the word "token". This is how I find out which branch it is:

git branch -a | cut -c3- | cut -d' ' -f 1 | xargs git grep "token" 

Thursday, August 12, 2021

cron.allow

If a user on Linux can't run "crontab -l" or "corntab -e", add the user name to /etc/cron.allow, and then it should work. 

Wednesday, August 11, 2021

WOE

 #http://lazynight.me/4048.html

import math

import numpy as np
from scipy import stats
from sklearn.utils.multiclass import type_of_target


class WOE(object):
    def __init__(self):
        self._WOE_MIN = -20
        self._WOE_MAX = 20

    def processing(self, X, y, event=1):
        self.check_target_binary(y)
        X1 = self.feature_discretion(X)

        res_woe = []
        res_iv = []
        for i in range(0, X1.shape[-1]):
            x = X1[:, i]
            woe_dict, iv1 = self.woe_single_x(x, y, event)
            res_woe.append(woe_dict)
            res_iv.append(iv1)
        return np.array(res_woe), np.array(res_iv)

    def woe_single_x(self, x, y, event=1):
        self.check_target_binary(y)

        event_total, non_event_total = self.count_binary(y, event=event)
        x_labels = np.unique(x)
        woe_dict = {}
        iv = 0
        for x1 in x_labels:
            y1 = y[np.where(x == x1)[0]]
            event_count, non_event_count = self.count_binary(y1, event=event)
            rate_event = 1.0 * event_count / event_total
            rate_non_event = 1.0 * non_event_count / non_event_total
            if rate_event == 0:
                woe1 = self._WOE_MIN
            elif rate_non_event == 0:
                woe1 = self._WOE_MAX
            else:
                woe1 = math.log(rate_event / rate_non_event)
            woe_dict[x1] = woe1
            iv += (rate_event - rate_non_event) * woe1
        return woe_dict, iv

    def woe_replace(self, X, woe_arr):
        if X.shape[-1] != woe_arr.shape[-1]:
            raise ValueError('WOE dict array length must be equal with features length')

        res = np.copy(X).astype(float)
        idx = 0
        for woe_dict in woe_arr:
            for k in woe_dict.keys():
                woe = woe_dict[k]
                res[:, idx][np.where(res[:, idx] == k)[0]] = woe * 1.0
            idx += 1

        return res

    def combined_iv(self, X, y, masks, event=1):
        if masks.shape[-1] != X.shape[-1]:
            raise ValueError('Masks array length must be equal with features length')

        x = X[:, np.where(masks == 1)[0]]
        tmp = []
        for i in range(x.shape[0]):
            tmp.append(self.combine(x[i, :]))

        dumy = np.array(tmp)
        # dumy_labels = np.unique(dumy)
        woe, iv = self.woe_single_x(dumy, y, event)
        return woe, iv

    def combine(self, list):
        res = ''
        for item in list:
            res += str(item)
        return res

    def count_binary(self, a, event=1):
        event_count = (a == event).sum()
        non_event_count = a.shape[-1] - event_count
        return event_count, non_event_count

    def check_target_binary(self, y):
        y_type = type_of_target(y)
        if y_type not in ['binary']:
            raise ValueError('Label type must be binary')

    def feature_discretion(self, X):
        temp = []
        for i in range(0, X.shape[-1]):
            x = X[:, i]
            x_type = type_of_target(x)
            if x_type == 'continuous':
                x1 = self.discrete(x)
                temp.append(x1)
            else:
                temp.append(x)
        return np.array(temp).T

    def discrete(self, x):
        res = np.array([0] * x.shape[-1], dtype=int)
        for i in range(5):
            point1 = stats.scoreatpercentile(x, i * 20)
            point2 = stats.scoreatpercentile(x, (i + 1) * 20)
            x1 = x[np.where((x >= point1) & (x <= point2))]
            mask = np.in1d(x, x1)
            res[mask] = (i + 1)
        return res

    @property
    def WOE_MIN(self):
        return self._WOE_MIN

    @WOE_MIN.setter
    def WOE_MIN(self, woe_min):
        self._WOE_MIN = woe_min

    @property
    def WOE_MAX(self):
        return self._WOE_MAX

    @WOE_MAX.setter
    def WOE_MAX(self, woe_max):
        self._WOE_MAX = woe_max

my-alpine and docker-compose.yml

 ``` version: '1' services:     man:       build: .       image: my-alpine:latest   ```  Dockerfile: ``` FROM alpine:latest ENV PYTH...