2023年5月26日 星期五

北歐極光旅行:Day 1

這天是市區的行程:斯德哥爾摩。

斯德哥爾摩是瑞典的首都,瑞典的首都及最大城市,亦是斯德哥爾摩省首府。瑞典王國政府、國會以及瑞典王室的官方宮殿都設在斯德哥爾摩。(來源:維基百科)

抵達後的第一餐(午餐),領隊帶我們到Restaurang Prinsen用餐,據說是一家瑞典人們在重要節日會來吃的餐廳,一入座就被高高的麵包柱吸引了目光,就是很歐(堅)式(硬)的麵包,搭配上奶油還不錯,但我個人還是比較喜歡飛機上那種軟軟的餐包XD
而前菜是放在脆餅上的塔塔醬魚肉(吃起來很像麥香魚),而主餐則是超大塊的漢堡排配上綿密的馬鈴薯泥(肉排吃起來感覺就是好多Ikea肉丸組合,看來Ikea餐廳是有忠於原味的),點心則是一顆巧克力配上咖啡,北歐人中午就在喝酒,餐後又會問你要不要來一杯咖啡,是酒醉然後馬上給妳醒酒飲料的概念嗎?


吃完後,就有一位合作的當地導遊跟我們一起去斯德哥爾摩市政廳參觀。
遊覽車沿著河邊開,可以看到許多風帆及遊艇停在岸邊,導遊提到這裡的人承襲了維京海盜的個性,無論男女都很勇敢不怕風浪,很多少年們小小年紀就常常獨自駕著風帆在水上馳騁,讓我不禁想起在東北大學交換的時候同實驗室的瑞典同學,原來他說他的興趣是風帆是真的沒有亂誇!

斯德哥爾摩市政廳,是每年諾貝爾獎的頒獎典禮場地(除了和平獎外),整棟建築物我覺得其實滿樸實的,而他的二樓金色房間四面有各式各樣的彩繪,包含歷史與神話,其中我最喜歡的是主牆上的梅拉湖女神,光是看著她的表情,就覺得很開心:D。
另外也參觀了他們的議會場,小小一間房間,應該塞不下王X堅的木馬,感覺在他們的立法場域並不會看到像台灣立院那樣的火爆現場XD
觀的過程中導遊向我們介紹瑞典人的精神:Lagom,意思是剛剛好,恰如其分,所有東西都希望是恰到好處,不少也不多。另外他們也注重平等,這是維京海盜時期所留下來的文化與心態,因此他們稅收高,再拿這些稅收去建設,及保護較弱勢的人(當然也是有躺平族,但他們也不會因噎廢食)。

結束市政廳巡禮後,就是放風逛街時間~因為市政廳剛好在皇后大街不遠,因此我們就地解散。我的第一站是Ikea,都來到瑞典了沒道理不去朝聖吧!不過可能因為是市區,所以這裡的Ikea面積不大,也只有兩層樓,而且他們也不太對鯊鯊瘋狂,玩偶籃裡面只有鯊鯊兩三隻,不像台灣的都是一座又一座的鯊鯊山....
逛完Ikea後我們又到另一個商場的無印良品找指甲剪,到了北歐想逛的店依舊是Ikea & MUJI,真的滿好笑的哈哈。可惜無印良品的指甲剪賣完了,所以我們只好隨意找一間藥店買貴鬆鬆指甲剪。


一天(半天)的行程結束了,我們回到飯店Radisson Blu Waterfront Hotel, Stockholm,並在飯店內享用晚餐,晚餐的風格跟午餐有點像,前菜是鹹派、主餐是羊肉...排(?),點心則是巧克力布朗尼。吃完後我們到飯店對面的車站地下街晃晃,不過其實很多店很早就打烊了,所以只能在便利商店隨手抓一些瑞典特產的小點心就打道回府。


我很喜歡瑞典人Lagom的精神,回台後還去借了這一本書來看。

剛剛好,最完美!向瑞典人學過幸福日常、不加班也富有的自由Fika人生

雖然去完瑞典看完這本書還是繼續當社畜,但我也漸漸體會到很多事真的是剛剛好就好,目前還在拿捏剛剛好的分寸!


Day1的紀錄就到這邊~很建議大家有機會去瑞典斯德哥爾摩看一看逛一逛!






2023年4月1日 星期六

北歐極光旅行:Overall

今年228連假參加了北歐極光旅行團當作蜜月旅行(報名加利利旅行社),10天7夜的旅行,十分奇幻,但也很冷,真的建議怕冷的人發熱衣與大衣要穿夠呀!接下來幾篇網誌會記錄一些旅遊的心情與照片,避免金魚腦忘記了,看到照片還不知道去了哪裡。

這次花比較多錢參加「加利利旅行社」的北歐雪鑽極光十日,深深體會到一分錢一分貨的道理,第一個經驗的點是加利利有免費提供一人一台wifi機,讓人省去了很多爬文比較以及自己去訂wifi機或sim卡的時間(雖然我一開始不曉得有這項服務,還到處貨比三家),領隊服務也很周到,每餐都會詢問大家有沒有需要點酒水,盡量滿足大家的需求,另外若有機會也會先到飯店協助大家處理大件行李,雖然他一直說是因為北歐人動作比較慢(?)另外在車上時,也會幽默地講解一些當地的風土民情。說到講解,旅行社還提供一人一台無線電導覽機,前後兩天在市區時有邀請當地華裔導遊,他們就可以透過導覽機講解各個建築的歷史以及當地人的個性與民族性,不需要大聲嚷嚷。

旅行社提供的wifi機

最後想介紹此行讓我驚豔的小地方,那就是土耳其航空的飛機餐餐具不是塑膠免洗餐具!而是不銹鋼餐具,而且後來發現上面還有一些清洗過的刮痕,代表真的有清洗後重複使用,這一點對我這個環保魔人來說真是大大加分!!!好感度大增!!!

希望我在這幾週能夠不偷懶把網誌好好的生出來XDD


2021年6月13日 星期日

[筆記][C/C++]Class之間使用Callback Function

前言

最近工作需要想辦法優化架構,因此設計了兩個類別各自負責自己工作,但有些資訊是B類別動作後,A類別需要進行更新。

最直覺想到的寫法,是讓B物件認識A物件,但是這樣A物件就跟B物件產生了關聯性(耦合)。

第二種想到寫法,是A物件需要這個資訊的時候,檢查資訊有沒有更新。但這樣A物件需要多些判斷,且每個需要資訊的地方都需要加這個判斷式,後續維護不容易。

有沒有什麼辦法是,B不需要認識A,A也不需要一直檢查呢?

最後想到的解法是:使用Callback Function!!!!!

什麼是Callback Function?

一般Function是主動執行,比如說前言中提到最直覺的寫法,B物件呼叫A的方法,主動執行A更新的動作(或是可以想成是動態執行);至於Callback Function,則是B先記得A的更新Method的位址(指標),要動作時再呼叫這個函式指標對應到的Function(靜態執行)。

簡單的說,一般Call Function是直接呼叫Function,而Callback function則是記得function的位址,需要時再執行該Pointer指向的函式。

常見的Callback Function

Callback Function其實滿常見的,以下列出幾個可以看到Callback Function的API
  1. std::sort
  2. openCV MouseCallback
  3. gstreamer AppSink

Callback Function怎麼用?

Function Pointer

首先,先聊一下函式指標怎麼寫呢?

C++函式指標寫法如下:

void (*func )(int, int)

這一段翻譯成人類的語言就是:func是一個函式指標,這個指標指向的函式引數為兩個int,回傳值則為void。

不過為了使用上的便利性,通常會用typedef的方式給他名字,例如:

typedef void (*FUNC )(int, int)

後續就能宣告FUNC並給予別名。

宣告及使用Callback Function

先來一段範例程式碼

#include <iostream>
using namespace std;

typedef void (*CALLBACK)( int, int, void* );

class A{
public:
    A( void );
    // constructor

    static void UpdateCallback( int, int, void* );
    // callback function pointer pointed to

    void PrintMember( void ) const;
    // show the member
private:
    int a;
    int b;
};

class B{
public:
    B( void );
    // constructor

    void RegisterCallback( CALLBACK, void* );
    // register callback and the callee

    void CallFunction( void );
    // call by main

private:
    CALLBACK pFunc;

    void *m_pCallee;
};

A::A( void )
// constructor
{
    a = 0;
    b = 0;
}

void A::UpdateCallback( int inputA, int inputB, void *Self )
// callback function pointer pointed to
{
    // cast user data to A
    A* pA = (A*)Self;

    // update with input value
    pA->a = inputA;
    pA->b = inputB;
}

void A::PrintMember( void ) const
// show the member
{
    cout << "a = " << a << endl;
    cout << "b = " << b << endl;
}

B::B( void )
// constructor
{
    // do nothing
}

void B::RegisterCallback( CALLBACK FuncCB, void* pCallee )
// register callback and the callee
{
    pFunc = FuncCB;
    m_pCallee = pCallee;
}

void B::CallFunction( void )
// call by main
{
    cout << "execute function pointer" << endl;
    pFunc( 2, 3, m_pCallee ); 
}


int main( void )
{
    A instanceA;
    B instanceB;
    // register callback to B
    instanceB.RegisterCallback( instanceA.UpdateCallback, &instanceA );

    cout << "Before run B::CallFunction: " << endl;
    instanceA.PrintMember();

    instanceB.CallFunction();

    cout << "After run B::CallFunction: " << endl;
    instanceA.PrintMember();

    return 0;
}

從程式碼中可以看到,一開始要將A類別的UpdateCallback註冊到B類別,也就是告訴B類別Callback Function的位址以及該Callback function的使用者(Callee,傳進一個void pointer即可)。
要傳進物件A的pointer的原因是因為Callback Function中需要修改到A,如果沒有傳進A物件本身,那將無法直接修改到A物件中的值。(可能有其他更好的寫法,還要再研究)

另外要注意實作功能的Callback Function必須是static。
(註:C++11以後用function跟bind好像就可以不用宣告為static)

註冊Callback Function後,B物件執行CallFunction的時候,就會執行Callback指向的函式,也就是A的UpdateCallback,並將Callee傳入(在這個情境下是instanceA的pointer),在UpdateCallback中,會將void pointer轉型成class A的pointer,並將值填入A的pointer中。

可以發現class B並不需要知道class A(只需要傳入一個void pointer),也就是說透過Callback Function的機制,就達成B類別不需要認識A類別,就可以叫A做事情的目的!

另外以程式碼擴展性來說,Callback Function增加了更多彈性~如果我後續修改需求,有一個新的類別C,也是要進行類似的動作(比如說使用B傳入兩個int進行相加,再存進member),那我只要在C類別中實作Callback Function,然後註冊進B就可以了,完全不需要修改B。

結論

Callback Function的實用性很高,對於程式碼擴展性有很大的幫助。希望整理完後,之後可以用得更爐火純青~
另外也要找時間去熟悉C#的delegate,因為好像是類似的概念!

參考資料:

https://dangerlover9403.pixnet.net/blog/post/83880061-%5B%E6%95%99%E5%AD%B8%5Dc-c++-callback-function-%E7%94%A8%E6%B3%95-%E7%AF%84%E4%BE%8B-(%E5%85%A7%E5%90%ABfunctio

https://openhome.cc/Gossip/CppGossip/FunctionPointer.html

2019年7月24日 星期三

[筆記][macOS] Anaconda 安裝 Intel RealSense Python package on Mac

之前介紹過如何在windows上的anaconda安裝realsense的python套件
https://jennyli6079633.blogspot.com/2019/01/anaconda-intel-realsense-python-package.html
不過其實macOS才是最需要自己編譯library的系統啊...(Linux應該也是)
因為直接pip是沒辦法安裝的
官方是說還沒開發出適用Unix平台的pypi安裝法

在這邊介紹一下如何在mac上用cmake編譯pyrealsense並使用:
1. 下載cmake
google一下應該很多資料
連結是我參考的文章
https://blog.csdn.net/baimafujinji/article/details/78588488
照著做直到terminal輸入cmake是可以執行的就行了


2. 下載source code
直接從github clone下來最快
$git clone https://github.com/IntelRealSense/librealsense.git

3. 編譯pyrealsense2
在terminal中進入剛剛clone下來的realsense資料夾
輸入下面的指令
$mkdir build
$cd build
$cmake ../ -DBUILD_PYTHON_BINDINGS=TRUE
$make -j4
*如果environment的python版本不一樣
   在cmake指令後面再加上這個argument就可以了
   -DPYTHON_EXECUTABLE=[full path to the exact python executable]

接著讓電腦跑(伴隨mac的悲鳴??)
都沒有error就OK了

其實跟windows系統的大同小異
不過不用像windows的cmake需要那麼多設定

4. 移動.so並建立symbolic link
跑完之後在librealsens/build/wrappers/python 資料夾中會有這些檔案


我們要建立pyrealsense2與pybackend2移到python的lib並建立的sybolic link
系統才找得到

將pybackend2.2.24.0.cpython-37m-darwin.so
與pyrealsense2.2.24.0.cpython-37m-darwin.so
複製到anaconda3⁩/⁨envs⁩/⁨(Env name)/⁨lib⁩/python3.7/site-packages
並在這個資料夾
然後使用下面的command
$ln -s pyrealsense2.2.24.0.cpython-37m-darwin.so pyrealsense2.so
$ln -s pybackend2.2.24.0.cpython-37m-darwin.so pybackend2.so

目前測試在anaconda的virtual env可行
如果沒有裝虛擬環境
在python的site-package加入也可以

另外還有一個方式是用make install
但是我不想直接裝在我的系統上所以我沒有使用這方法

5. 測試(可import但無法測試是否真的能跑)
進入你的虛擬環境
然後import pyrealsense2
沒有跳出找不到的錯誤就可以了


可惜我的mac沒有usb 3.0可以插所以不能測能不能真的跑起來
看有沒有人可以幫忙測的XDD

歡迎留言討論

Reference:




2019年5月21日 星期二

[語言]一個月新制多益935分!!!我如何準備

為了求職更順利
而且高三時考的多益證照(825分)其實也已經過期了
所以三月的時候決定去考新制多益

考慮到口試完之後會有另一波求職
因此我報考2019/04/28的場次

5/20懷著忐忑的心查成績
結果竟然出乎我預料


(人生的高峰所以請讓我炫耀一下><)

太開心的PO文之後滿多人跑來問我做了什麼準備
所以整理一下我讀了那些書用了什麼資源
讓想準備的人可以參考

1. 刷題
練習題目是最重要的一環
原因是要練習控制時間以及專注度
雖然練習時的時間掌控狀況跟實際考試上一定有落差(比如說練習時都可以剩10分鐘結果實戰時最後十分鐘還剩兩個題組)
不過如果你練習時都寫不完
就要嘗試找出是哪一個部分是弱項最拖時間

我使用的題本是這一本:

New TOEIC多益新制黃金團隊5回全真試題+詳解(附2MP3+防水書套)


我個人覺得他的單字難度與題目方向跟真的多益考試差不多
詳解本有附帶題目也是很棒的設計
PS: 阿滴有推薦這一本的樣子

因為覺得自己閱讀比較弱(考出來之後的確是閱讀比較弱)
我有另外刷閱讀的題目:


但是這一本的題目與單字就有點偏難
直接寫可能會造成自信心低落
時間不夠所以我也只有寫+檢討三回


2. 閱讀的準備
閱讀的部分我覺得我的弱項是一開始的文法與單字部分
所以我用這一本書補強文法:

不過我覺得這一本其實比較適合有多一點時間準備的人
因為他內容真的超多(而且超級重)
基本上我只有翻完他的文法部分而已

3. 聽力的準備(其實沒什麼準備)
聽力的部分我個人認為是無法速成
所以我也沒有特別練習
頂多有空檔的時候看TED(而且還選不是商業的影片哈哈)
考前一天突然想起成大有Eazy Test這個資源
所以就用它的多益訓練課程來練聽力
課程內容提供了滿紮實的考試技巧訓練
(如果我早一點拿出來用或許閱讀會更高分)

4. 單字
單字我也是有空就背
前半個月我用百詞斬(中國大陸的APP)
後半個月我有空就會翻

他的編排方式是單元式
每一單元約40個單字
單元後面會有分級的單字表
可以視自己的程度去選擇要背什麼單字

檢討的時候我也會把不會單字抄下來
好處是很多常出卻不會的單字會因此印象更深刻

5. 檢討
檢討也是很重要的一環
我會在檢討的時候把不會的單字片語或常用句子整理起來
容易搞錯或不會的文法也會再抄寫一遍或自己想例句


以上是我一個月準備新制多益的方法與資源
當然其實我覺得能考成這樣有一部分也是運氣不錯
畢竟我很幸運地坐在撥放器前面
聽力聽得超級清楚

還在徬徨如何準備的朋友可以參考看看
祝福大家都拿到金色證書