網頁

2017年7月21日 星期五

[AWS] run dynamodb example locally on macOS

目標:

run dynamodb example locally on macOS

環境:

macOS Sierra 10.12.5
node js

步驟:

1. install aws-sdk for node
npm install aws-sdk

2. install java (do not use oracle website to install or fail)
brew update;brew cask install java;

3. download dynamodb jar file
http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBLocal.html

4. run dynamodb locally
java -Djava.library.path=./DynamoDBLocal_lib -jar DynamoDBLocal.jar -sharedDb

5. edit js file named MoviesCreateTable.js
http://docs.aws.amazon.com/amazondynamodb/latest/gettingstartedguide/GettingStarted.NodeJs.01.html

6. run js
node MoviesCreateTable.js

來源:

http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBLocal.html

遇到的問題:
some api will not work

2017年6月2日 星期五

how to use synology docker gitlab and use xcode to commit and push code ?

step1. on Synology DSM, install "docker gitlab"
step2. login "docker gitlab"
step3. create project in "docker gitlab" (e.g. xxxx)
step4. open xcode and "source control > xxxx - master > configure xxxx > Remote (+)":
         [your DSM IP]:3000/root/xxxx.git

step5. commit code in xcode: "source control > commit..."
step6. push code in xcode: "source control > push..."

2017年4月17日 星期一

git grep for a pattern

假如想要找某一行 code 這樣的 pattern 在某個 commit 的 log
可以這樣下:

git grep '[pattern]' [sha]

如果想要找全 history 可以這樣下:

git grep '[pattern]' [sha] $(git rev-list --all)


如果還想要檢查前面 20 行 可以這樣下:

git grep -B20 '[pattern]' [sha] $(git rev-list --all)

2017年4月15日 星期六

[C++] Any input type template function

主題 : Any input type template function

引言 : C++ 11 引入了此功能,讓 function 可以吃同類型任何型態的參數進來,並且還保持原來 type 的樣子。

描述 :
這名字我亂取的,我只是想要說明這樣的 pattern 的寫法可以讓你寫出一個 template function 可以吃所有同類型的 TYPE, TYPE&, TYPE&& ...

這真的很強大,不必再 for reference input 寫一個 function,for right value input 再寫一個 function。

已經有文章寫得很好了,請參照
http://thbecker.net/articles/rvalue_references/section_01.html
~
http://thbecker.net/articles/rvalue_references/section_08.html

一句話解釋,"當你想把 type 忠實的傳入到 func 內使用請使用以下的 pattern"
細節請讀 section_01~section_08

以下是 section_01~section_08 給的 factory design pattern 的範例,
這個 factory template function 的 arg 可能吃 1. value 2. reference 3. right value ...
因為 C++ 很在意 type,type 不對就 compile error
那我們要怎麼寫一個任何 type 都能傳入的 function 呢 ? 如下 function,


template<typename T, typename Arg> 
shared_ptr<T> factory(Arg&& arg)
{ 
  return shared_ptr<T>(new T(std::forward<Arg>(arg)));
} 

當 Arg 是 X 則 new T(X)
當 Arg 是 X& 則 new T(X&)
當 Arg 是 X&& 則 new T(X&&)

很神奇吧,我的說明肯定不會比 section_01~section_08 還好。
如果你想知道為什麼,耐著性子看完你就會知道為什麼了。

2017年4月14日 星期五

[App] iTunes Connect Screenshot Sizes for iPhone and iPad

image:
iPhone 6 Plus(5.5 Inch): 1242 x 2208 px

iPad Pro (12.9 Inch): 2732 x 2048 px

video: (in 15 or 30 seconds)
iPhone 6 Plus(5.5 Inch): 1080 x 1920 (Portrait)

https://developer.apple.com/support/app-previews/

2017年4月8日 星期六

[App] 如何一鍵刪除 iPhone/iPad 裡面所有的照片 ?

【軟體名稱】Photo Trash Can
【程式開發】Chun-Pai Yang
【軟體類別】工具
【軟體大小】13.5MB
【軟體售價】0.99 鎂
【下載連結】點我


【Photo Trash Can 介紹】如何一鍵刪除 iPhone/iPad 裡面所有的照片 ?

Photo Trash Can 是一款刪除所有照片/影像的 App。許多用戶在使用完一些備份軟體如: Synology DS Photo 或是 dropbox .. 將 iPhone/iPad 裡面的照片/影片全部備份完後,這些軟體並不會自動地將 iPhone/iPad 裡面的照片/影片刪除。此時就是使用此軟體的時機。

▼ 若沒有此軟體在相片備份完後必須使用 Mac Book 的 Photo App 匯入並且一次刪除所有照片。
相當的麻煩 ...
Inline image 7
Inline image 5

▼ Photo Trash Can 一開始的畫面,意思就是你真的要想清楚才按下此鍵:
Inline image 1▼ 當點下這個紅色的按鈕後,會要求你輸入你 iPhone/Ipad 裡的 相片:影片 數目,以避免誤操作:
Inline image 3

▼ 當做完一些最終的確認後,你所有的照片和影片就全數被刪除了:
Inline image 4

▼ 刪除後其實全部的照片都可以從 Apple 的內建 Photos App 的 "最近刪除" (Recently Deleted) 相簿中。
若想要回復可要一張張的救回來了。
所以在使用此軟體前可要先確保你所有的照片都已經備份了喲。

但對於像是作者平時很懶,會有幾千張照片才會用 Synology DS Photo 備份一次並在備份完想要刪除所有照片的人真的是相當的方便。


如果您喜歡 Photo Trash Can的話,還請您不吝於給予我們五顆星的評價 (馬上前往)
有任何疑問/功能建議,都歡迎聯絡我們喔!
Photo Trash Can Facebook粉絲團:https://www.facebook.com/Photo-Trash-Can-716543165173369
Photo Trash Can 聯絡Email:phototrashcan@gmail.com
Inline image 2

2017年1月18日 星期三

ssh tunnel

記錄一下。
之前都不知道怎麼建,應該說我知道這東西,但沒實際使用的經驗。

最近有一個 support 要我幫 user 看 router 上的設定,但即使開了 remote beckend,仍然是無法連到 router 網頁的阿。

這時候就是 ssh tunnel 使用的時機:

   ssh -L 11111:192.168.1.1:80 -p [port] admin@[public ip]

以上的前提是你有 ssh 的 admin 帳密以及 public ip 在加上你知道 ssh 的 port 是多少並且 ssh port 有被 portforward 出來。
那麼下了以上的指令,你就可以把 [public ip] 內網的 192.168.1.1:80 和 localhost:11111 連在一起了。

以下是示意圖:


   [localhost]:11111 <= ssh tunnel => [public ip]:[port] <= connect & redirect => 192.168.1.1:80


也就是下完以上 command,並用網頁瀏覽器開啟 localhost:11111 就可以進到 router 的網頁介面了。

話說開 ssh tunnel 真的很可怕,內網可以說整個全開了,顆顆。

------------------------------- 2017.02.20 reverse tunnel ----------------------------------------
話說以上是 forward tunnel,
      建 forward tunnel 是想要 " local 這台 ssh client 機器額外開 port 導到 ssh server 端,然後在由 ssh server 再幫我們導向另外一台的某個 port"。
      ssh client (開 port) <================> ssh server =============> forward packet

以下是 reverse tunnel, reverse tunnel 就是幫 ssh server 開後門,
    建 reverse tunnel 是想要 "在 remote ssh server 那台機器上額外開 port,然後希望 remote ssh 的那個 port 收到的東西都幫我們導到 local 這台機器的的某個 port"
    ssh client  <================> ssh server (開 port) <============= receive packet

2016年8月5日 星期五

[gitlab] how to merge request by gitlab

主題:
How to merge request by gitlab

步驟:
1. fork project on gitlab UI, and you will get a git respository location like: git@git.xxxx:[yourname]/[projectname].git
    gitlab -> select project -> fork
    
2. add respository
      git remote add upstream git@git.xxxx:[yourname]/[projectname].git

3. check if the repository is added
      git remote -v

4. fetch the repository
     git fetch upstream

5. push your commit to the repository instead of 'origin' repository
    git push upstream master

6. create merge request on gitlab UI
    gitlab -> select [merge requests] -> click [New merge request] ....

7. wait project owner to merge the code

8. delete the repository on gitlab UI

2016年5月11日 星期三

use c++ regex parse string enclosed in double quote

主題:

use c++ regex parse string enclosed in double quote

難處:

考慮 escaped quote


範例:

如果是 std::string s = "\"\\\"aaa\"\"bbb\"";   要 parse 成  \"aaa & bbb
以下我直接貼 code, 後面註解是想要 parse 的結果

std::string s = "\"\\\\\"aaa\"\"bbb\"";       // \\"aaa & bbb
std::string s = "\"aa\\\"a\" \"bbb\"";        // aa\"a  & bbb
std::string s = "\"aa\\\\\"a\" \"bbb\"";      // aa\\"a & bbb
std::string s = "\"\"\"aaa\"\t \"bbb\"";     // empty & aaa & bbb



怎麼寫:

std::regex e ("\"((([^\\\\]*\\\\.)|([^\"]*))*)\"");
std::smatch sm;
std::string line = s;
while (std::regex_search (line, sm, e)) {
    std::cout << "range with " << sm.size() << " matches\n";
    std::cout << "the matches were: ";
    for (unsigned i=0; i<sm.size(); ++i) {
        std::cout << "[" << sm[i] << "] ";
    }
    line = sm.suffix().str();
    std::cout << std::endl << "line: " << line;
    std::cout << std::endl;
}

// 裡面印出的 sm[1] 就是我們想要的結果

參考: 

http://stackoverflow.com/questions/21658860/how-to-use-regex-c
http://www.cplusplus.com/reference/regex/match_results/suffix/
http://stackoverflow.com/questions/6863518/regex-match-one-of-two-words
http://stackoverflow.com/questions/249791/regex-for-quoted-string-with-escaping-quotes (Guy BedFord 的寫法再改良)


2015年7月23日 星期四

[vim] display trailing white space

in vim

:highlight ExtraWhitespace ctermbg=red guibg=red
:match ExtraWhitespace /\s\+$/                

2015年7月17日 星期五

[data base] mariadb install for python

Env:

Ubuntu 14.10
python 2.7


Commands:

import MySQLdb needs
apt-get install python2.7-mysqldb

import mysql.connector as mariadb needs
http://dev.mysql.com/downloads/connector/python/

2015年7月15日 星期三

[vimdiff] diffg

在vimdiff下我們可以用好用的diffg來同步

當我們用vimdiff時左右兩邊視窗不一致時,我們可以在左邊視窗用 "大寫V" 選擇要左右sync的區塊,然後再按下 :diffg ,就會把右邊視窗所選的同步到左邊。

如果是按下 :diffget,就會把左邊同步到右邊。

NOTE: 通常不額外設定 git difftool 使用的也是vimdiff。

2015年7月13日 星期一

[opencv] install

主題: opencv install


很難安裝, 筆記一下

Ubuntu 14.10

- pre install QT4

apt-get install qt4-default libqt4-dev qtchooser qt4-designer

- git clone opencv

git clone https://github.com/Itseez/opencv.git

cd opencv
mkdir release
cd release

cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D WITH_TBB=ON -D BUILD_NEW_PYTHON_SUPPORT=ON -D WITH_V4L=ON -D INSTALL_C_EXAMPLES=ON -D INSTALL_PYTHON_EXAMPLES=ON -D BUILD_EXAMPLES=ON -D WITH_QT=ON -D WITH_OPENGL=ON ..

sudo make
sudo make install

成功

MAC OS Yosemite 10.10.4

直接brew install opencv會有問題

- 一樣要先裝QT, 但要brew要多下"build-from-source"的option

brew install qt --build-from-source

- git clone opencv(這邊就和上面一樣)

失敗... 

2015年7月9日 星期四

[Python] hook function for self.x, self.x = 3, delete self.x

主題: hook function for self.x, self.x = 3, delete self.x


說明:

我們有一個class A,
假設我們想要在"讀取"self.x或在"設定"self.x時或在"刪除"self.x時可以多做一些"額外的事情(某個function)",那麼該怎麼把我們的function插入呢?

實作:

實作一個descriptor, 並安裝到A中成為class member data。

#!/usr/bin/python

class Integer(object):
        def __init__(self, name):
                self.name = name

        def __get__(self, instance, cls):
                if instance is None:
                        return self
                else:
                        return instance.__dict__[self.name]

        def __set__(self, instance, value):
                if not isinstance(value, int):
                        raise TypeError('Expected an int')
                instance.__dict__[self.name] = value

        def __delete__(self, instance):
                del instance.__dict__[self.name]

class A(object):
        x = Integer('x')
        def __init__(self, x, y):
                self.x = x
                self.y = y

a = A(1.0, 2)

結果:

Traceback (most recent call last):
  File "./descriptor.py", line 27, in 
    a = A(1.0, 2)
  File "./descriptor.py", line 24, in __init__
    self.x = x
  File "./descriptor.py", line 15, in __set__
    raise TypeError('Expected an int')
TypeError: Expected an int

無效: 

因為這件事情很重要,再重複一次,
"實作一個descriptor, 並安裝到A中成為class member data。"
如果你實作了一個descriptor,但安裝到class中不是成為class member data而是instance data, 這樣是不起作用的。

class A(object):
        def __init__(self, x, y):
                self.x = Integer('x')
                self.y = y

繼承還是有效: 

class B(A):
        def __init__(self, x, y):
                self.x = x
                self.y = y

b = B(1.0, 2)
繼承還是有效,因為child class繼承了class member data
Traceback (most recent call last):
  File "./descriptor.py", line 32, in 
    b = B(1.0, 2)
  File "./descriptor.py", line 29, in __init__
    self.x = x
  File "./descriptor.py", line 15, in __set__
    raise TypeError('Expected an int')
TypeError: Expected an int

順帶一題: 

property, classmethod, staticmethod, __slots__都是相同概念:
安裝一個descriptor到class上

2015年7月8日 星期三

[linux] add user

主題: 假設想要多個可信認的user共用一台機器,每個user有權限可以轉換身分到root


How to ?

1. 加入一般身分的user
2. 修改visudo

2015年7月6日 星期一

[Python] @staticmethod 和 @classmethod

主題: @staticmethod和@classmethod的差別

說明:

這兩個都是decorator,
一言以蔽之 classmethod的input function第一個參數必須是class,
而staticmethod則第一個參數就是真的參數。

可以參考這邊(staticmethod/classmethod)

另外一提,這兩個的實作方式和@property的做法很像。

[Python] __slots__ 記憶體優化工具

主題: __slots__

範例:



不使用__slots__優化記憶體(內部為一個hash table)
#!/usr/bin/python
from pympler import asizeof

class A(object):
        #__slots__ = ['year', 'month', 'day']
        def __init__(self, year, month, day):
                self.year = year
                self.month = month
                self.day = day

a = A(1,2,3)
print asizeof.asized(a, detail=1).format()
<__main__ data-blogger-escaped-.a="" data-blogger-escaped-0x7f15e50e9cd0="" data-blogger-escaped-at="" data-blogger-escaped-object=""> size=552 flat=64
    __dict__ size=488 flat=280
    __class__ size=0 flat=0
使用__slots__優化記憶體(不存table, 分開以更節省記憶體的方式存)
#!/usr/bin/python
from pympler import asizeof

class A(object):
        __slots__ = ['year', 'month', 'day']
        def __init__(self, year, month, day):
                self.year = year
                self.month = month
                self.day = day

a = A(1,2,3)
print asizeof.asized(a, detail=1).format()
<__main__ data-blogger-escaped-.a="" data-blogger-escaped-0x191f6c8="" data-blogger-escaped-at="" data-blogger-escaped-object=""> size=224 flat=72
    __slots__ size=80 flat=80
    month size=24 flat=24
    day size=24 flat=24
    year size=24 flat=24
    __class__ size=0 flat=0

結論:

使用__slots__優化記憶體 552->224
缺點就是因為內部不存hash table, 所以你也只能使用__slots__指定的那些屬性名稱

2015年7月5日 星期日

[Python] property繼承的寫法

主題: property繼承的寫法


假設我們有一個擁有name property的class A:

class A(object):
        def __init__(self):
                print ("A init")
        @property
        def name(self):
                print ("A name getter")
        @name.setter
        def name(self, x):
                print ("A name setter")
我們想要對A的name property繼承,並且改寫。 改寫的方式想要繼承A原本的一些code再附加新的class的一些code,可以這樣寫:
class B(A):
        def __init__(self):
                print ("B init")

        @property
        def name(self):
                super(B, B).name.fget(self)
                print ("B name getter")

        @name.setter
        def name(self, x):
                super(B, B).name.fset(self, x)
                print ("B name setter")

或者把fget和fset換成__get__和__set__
class B(A):
        def __init__(self):
                print ("B init")

        @property
        def name(self):
                super(B, B).name.__get__(self)
                print ("B name getter")

        @name.setter
        def name(self, x):
                super(B, B).name.__set__(self, x)
                print ("B name setter")

為什麼可以這樣? 有興趣的人可以去研究一下 property這個class

還有一點要注意, 其實這樣的寫法是"定義B的自己版本name property", 換句話說,
B.name和A.name是兩個不同的版本。
也就是如果B只有定義getter或是setter,那麼這個property也只會剩下getter或是setter的能力:


#!/usr/bin/python

class A(object):
        def __init__(self):
                print ("A init")
        @property
        def name(self):
                print ("A name getter")
        @name.setter
        def name(self, x):
                print ("A name setter")


class B(A):
        def __init__(self):
                print ("B init")

        @property
        def name(self):
                super(B, B).name.__get__(self)
                print ("B name getter")

b = B()
b.name
b.name = 3

結果:
B init
A name getter
B name getter
Traceback (most recent call last):
  File "./property.py", line 25, in 
    b.name = 3
AttributeError: can't set attribute

Shell 已返回1

結論:

1. child class要改寫parent class的property最好全部都改寫,除非你知道你在做什麼,你真的想閹割parent class的setter or getter or deleter ?
2. child class若要呼叫parent class的class method(memer data), 那就要用 super(B, B).name的寫法
3. property class有實作"descriptor protocol"(__get__, __set__, __delete__這三個function),
property class的__get__會去呼叫 property class的instance method: fget
property class的__set__會去呼叫 property class的instance method: fset
property class的__delete__會去呼叫 property class的instance method: fdel

2015年7月4日 星期六

[Python] decorator的等價寫法

主題: decorator的等價寫法


class A(object):
    @property
    def func(self):
       ...

同

class A(object):
    def func(self):
       ...
    func = property(func)

換句話說這時候 func經過property之後
1. 從單純的func變成為property
2. func則變為 class variable (不是intance variable)


[Python] property and descriptor protocol

主題: 了解property的概念

簡介: 

假設今天我們有一個需求,我們有一個A class:
a = A()
當寫 a.m 我們希望呼叫到 A.f
當寫 a.m = 3我們希望呼叫到 A.g
當寫 del a.m我們希望呼叫到A.p

那我們該如何實作 ?

答案在這邊 (直接參考property這個class的實作方式)

個人理解:

先說一下規則好了,如果一個有實作 "descriptor protocol"的class,假設叫D好了:
當寫 
d = D()
d  
d = 5
del d
則會觸發
__get__
__set__
__del__

據此,我們可以讓 __get__ 去呼叫A.f
__set__去呼叫A.g
__del__去呼叫A.p
就可以達到題目需求....

但這樣很不彈性,
因此我們再多寫三個function以便有機會可以替換掉
A.f
A.g
A.p

其實以上就是property的概念:
"
Property是一個class擁有fget, fset, fdel這三個function,
我們可以用 getter, setter, deleter去註冊這三個function,
且getter, setter, deleter回傳都是Proptery object。
"