身為一個專業的C/C++工程師如果不懂 constant of pointer 真的就太鳥了。
各位大神肯定了解,就容小弟整理出來。
If I write,
char *const *const *const test1 = ppstr;
only ***test1 can be modified.
so,
char *const *const *const test1 = ppstr;
char const * *const *const test2 = ppstr;
char const *const * *const test3 = ppstr;
char const *const *const * test4 = ppstr;
***test1 = NULL; //OK
**test2 = NULL; //OK
*test3 = NULL; //OK
test4 = NULL; //OK
//**test1 = NULL; //compile error
...
The method is viewing from right to left, and see if any const in the lefthand of to modified obj, if there is, this obj can not be modified or compile error.
e.g.
char const *const *const * test4 = ppstr;
^4 ^3 ^2 ^1
// test4 can be modified, due to there is no 'const' in the lefthand of ^1.
// This also means test4 is pointer of pointer of pointer of char which can be modified
2017年9月1日 星期五
2017年7月21日 星期五
[AWS] run dynamodb example locally on macOS
目標:
run dynamodb example locally on macOS環境:
macOS Sierra 10.12.5node js
步驟:
1. install aws-sdk for nodenpm 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.jshttp://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..."
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)
可以這樣下:
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,
引言 : 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/
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 鎂
【下載連結】點我
▼ 當點下這個紅色的按鈕後,會要求你輸入你 iPhone/Ipad 裡的 相片:影片 數目,以避免誤操作:
如果您喜歡 Photo Trash Can的話,還請您不吝於給予我們五顆星的評價 (馬上前往)
有任何疑問/功能建議,都歡迎聯絡我們喔!
Photo Trash Can Facebook粉絲團:https://www.facebook.com/Photo-Trash-Can-716543165173369
Photo Trash Can 聯絡Email:phototrashcan@gmail.com
【程式開發】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 匯入並且一次刪除所有照片。
相當的麻煩 ...
▼ Photo Trash Can 一開始的畫面,意思就是你真的要想清楚才按下此鍵:
▼ 當做完一些最終的確認後,你所有的照片和影片就全數被刪除了:
▼ 刪除後其實全部的照片都可以從 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
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
之前都不知道怎麼建,應該說我知道這東西,但沒實際使用的經驗。
最近有一個 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-chttp://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\+$/
:highlight ExtraWhitespace ctermbg=red guibg=red
:match ExtraWhitespace /\s\+$/
2015年7月17日 星期五
[data base] mariadb install for python
Env:
Ubuntu 14.10python 2.7
Commands:
import MySQLdb needsapt-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。
當我們用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, ina = 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, inb = 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日 星期三
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, inb.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)
訂閱:
文章 (Atom)