2015年12月20日 星期日

Python 2.x/3.x 中的 str、bytes 以及 unicode

前言


在初學 Python 時,總是對於Python對於文字編碼的處理,感到疑惑!尤其版本的差異造成認知上的混淆,前一陣子,因為我有中文文字處理的相關需求,發現對於編碼概念以及處理的重要性,浪費了不少時間,故以此篇記錄提醒自己。


Python2.x/3.x 字元序列型別差異

在 python3.x 裡,有兩種型態來表示字元序列:
  1. bytes:原始的八位元值(二進位資料、常見的編碼為 UTF-8)
  2. str:即unicode
而 python2.x 裡,則是另外兩種型態來表示字元序列:
  1. str:原始的八位元值(二進位資料、常見的編碼為 UTF-8)
  2. unicode


編碼(encoding)與解碼(decoding)概念

在 python2.x 中,通常會在檔案的開頭給定 # -*- coding: utf-8 -*- ,因為 python2.x 中會以ASCII 編碼來解讀程式原始碼,所以不給的話,我們打中文會出現錯誤,然而在 python3.x 中則預設原始碼必須是 UTF-8 編碼。

假使我們要將 python3.x 的 str 以及 python2.x 的 unicode 進行二進位資料轉換,必須使用 encode,相反要將二進位資料轉換為 unicode 則需使用 decode。

在一些書籍以及網站上,通常會建議程式的核心應以 unicode 型別,並且不對字元的編碼格式進行預設,因為如此一來才能讓我們接受各種不同的文字編碼,但在輸出時必須確保我們是以 UTF-8 編碼(通常)。

在 python 2.x 我們可以撰寫 helper function 來確保字串型態,如下:

helper function


Python3.x 寫入與讀取檔案可能遇到之問題

因為在 python3.x 版,對於 open 函式有encoding為 utf-8 的預設,因此若要解決 TypeError,請務必使用 rb、wb 等二進位模式開啟檔案,而在 python 2.x 雖然本身已是二進位預設開啟,但若同樣使用 rb、wb,可以減少對於版本差異而發生的錯誤。


進階參考

在Mac上,放置 binary file 的相關概念

前一陣子剛好有一個需求,就是將他人所編譯好的 binary file(我看到的副檔名為 unix executable),在 command-line 執行,傻傻的我一直對著該檔雙擊,結果都因為沒送進任何參數,而立馬結束。

因此開始思考怎麼在 command line 上,讓 binary file 如同指令般被我操作,而所幸找到了一些文章,也更認識了在Mac上環境變數的一些小竅門。

大致上心得如下:在 command line 下,打 echo $PATH,查看路徑變數存了哪一些,每個以 : 為分隔,我們也可以用 export 來設置新變數路徑,而通常可以將 binary file 放在 /usr/local/bin 下,而因為 /usr/local/bin 在 /usr/bin 及 /bin 之後,因此若有相同名稱,會先以系統層級為基準,深入的瞭解與解法可以查看此篇:mac-os-x-conventional-places-where-binary-files-should-live

平常時都是用 Homebrew 來管理電腦上的套件,而像是這種自行下載 binary file 的經驗,感覺也相當不錯 XD

2015年8月19日 星期三

WebRTC 概念筆記

前言


WebRTC是一個建立在瀏覽器協定上的新技術,讓視訊功能不用再安裝額外套件,便可以實現,而他也可以成為許多創新APP上,非常重要的一環,在搜尋許多文件後,發現網路上不乏許多概念清晰的資源,但較為散落,因此寫這一篇論述一下自己所理解的概念,順便將網路學習資源也都放上來!

WebRTC 重要的三大API


  1. MediaStream:支持大多數瀏覽器,使用 getUserMedia() 獲取 audio and webcam stream。
  2. RTCPeerConnection: Caller & Calle 必需互相傳送 Session Description,透過 Session Description Protocol 所定義的 offer 與 answer 來交換多媒體相關的資訊(例如解析度與 codec 等),而此交換的機制稱為 JavaScript Session Establishment Protocol(JSEP)。但由於可能會遇到 NAT 或者 防火牆的關係,因此要靠 ICE 來解決,因此可以使用 Stun/Turn Server來解決,Stun伺服器功能很簡單,就是要讓在 NAT 中的Client取得自己本身公開的 IP/Port,嘗試順序為 UDP -> TCP , Http -> Https ,若直接連線都失敗了,這時後 Turn Server 就會來扮演將全部資料轉送的角色,而前述所提的嘗試順序,會形成不同的連線狀態也稱為 ICE Candidate,然而在進行 p2p 連線時,就會進行這樣的嘗試過程,並在當中選擇最好的 ICE Candidate來使用,而常用的有 google's stun => stun:stun.l.google.com:19302。上述兩者所要最後則要透過信號通道/服務來傳送 RTCPeerConnection 會負責解決其餘的多媒體串流問題。
  3. RTCDataChannel:可以使兩個 browser 直接傳送檔案,不用再透過Server當作中介。負責一般性資料之傳送。PubNub有提供相關服務:然而WebRTC協定很遺憾地沒有提供儲存機制,但有許多的資料例如:聊天的歷史記錄等等,因此也有像 PubNub 這種公司提供一些付費的Solution來給需要使用的人。


運作流程


我們可以去想像 WebRTC是兩個瀏覽器之間的互動,而呼叫者與被呼叫者的過程如下:
  1. 欲呼叫的原瀏覽器(caller)會提供一個 offer 包含 session description
  2. 被呼叫的瀏覽器(callee)會接收呼叫者的資訊並且回覆一個 session description
  3. 呼叫的原瀏覽器(caller)得到呼叫對象的回覆後
  4. 雙方開始交換 ICE candidate 候選人
  5. 當足夠且據連線力的候選人出線後,就開始進行 Peer Connection


Signaling issues(有許多的方法)


  1.  Codelab上有一份資源: bitbucket.org/webrtc/codelab 利用 socket.io 建設signaling server, 也在教材中運用 RTCPeerConnection 協定,實作一個簡易的視訊系統。
  2. 網路上有許多開源的資源如 easyRTC (full stack) 或者是 Signalmaster (signaling server created for SimpleWebRTC)。
  3. 此網站 apprtc.appspot.com 使用 XHR and the Google App Engine Channel API 來處理 signaling。
  4. HTML5 Websocket - ex. WebSocket 簡單介紹與 jQuery 實作應用 , WebSocket 通訊協定簡介:比較 Polling、Long-Polling 與 Streaming 的運作原理

參考



2015年8月7日 星期五

Laravel 5.1 廣播事件 - 利用 redis & socket.io (事件實作)

主要參考 Step by Step Guide to Installing Socket.io and Broadcasting Events with Laravel 5.1 此篇教學,因此寫下步驟提醒自己,若要詳細的圖文配置請自行參閱。

Step1. 安裝新的 npm pakage & 更新 composer.json
  • npm install express ioredis socket.io --save
  • composer require predis/predis
Step2. 創建廣播事件
  • php artisan make:event EventName
注意得去實作 ShouldBroadcast 介面,且注意又用 public 的方法去實作序列化&送資料。

Step3. 創建 View & Route

注意在client頁面 socket.io.js 的引入,若沒有可以去抓下來放 assets/js 或者直接用 cdn。

Step4. 建立 node Server 端 socket.js

redis 必須去 subsrcibe 與 EventName.php 相同的 channel。
修改 .env 的 BROADCAST_DRIVER,因為原本是用 pusher。

Step5. 啟動 node server&redis-server
  • node socket.js
  • redis-server --port 3001
另外也有一篇很棒的參考,而且是中文(Laravel 5.1 Events Broadcasting 實務練習

Laravel 5.1 廣播事件 - 利用 redis & socket.io (環境設置)

筆記


最近因為專案需要學習了 Laravel,也因專案性質的緣故,因此可能會運用到如 socket.io 這一類在 node.js 上的功能,因此廣泛的 search 一下,發現原來在 Laravel 5.1 版釋出時,他的某一項新特色就包含了 Broadcasting, 而 Laravel 的重要元老Taylor Otwell也發表了相關的教學影片,同時在 L5.1穩定版釋出後在 Laracast 上釋出了一篇使用 Redis 替代原本 Pusher 的做法,非常吸引我因此做下此篇筆記。


前置動作


Laravel Homestead + vagrant 是學習 Laravel 的最佳利器,因此我選擇在此環境下建置,網路上也有許多方法(Getting Started with Laravel Homestead)透過 virtualbox 進行安裝。

Step 1.測試環境

安裝完畢後,在 Homestead 目錄使用 vargrant ssh 進入虛擬機,檢查分別檢查:
  • npm -v  => 會回傳版本後
  • redis-cli ping => 會回傳 pong
此時會對 homestead 好感度大大的提升(除了有讓環境跟其他的開發者一樣的優點,同時也解決了許多套件安裝的麻煩)!

Step 2. 創建新專案&站台

創建新的 laravel 專案,在本機端的對應 folder 利用指令創建專案
  • composer create-project laravel/laravel your-project-name
修改 /etc/hosts,並加入以下
  • 192.168.10.10 your-project-name.app
進入 homestead 虛擬機 serve 新站台
  • serve your-project-name.app /home/vagrant/Code/path/to/public/directory 80
最後可以測試一下 your-project-name.app ,如果在瀏覽器出現歡迎頁面就成功了!


2015年6月25日 星期四

Mongo 的 BSON 格式與匯出匯入問題

前些陣子在備份 mongodb 時,遇到了一些格式的問題,然而在看完官方的參考資料(
Import and Export MongoDB Data 和 BSON)後,想以此篇提醒自己。

Mongo在處理的資料格式為 BSON,它看起來的格式如同 JSON 一樣,但要注意的是他不會用 [] 以及 , 來區別每一個 documents 。

舉例來說 JSON 會如此來描述一個結構:

[
    { "_id":"ord123","title":"test1" },
    { "_id":"ord456","title":"test2" },
    { "_id":"ord789","title":"test3" }
]

然而 BSON 會如此來描述:

{ "_id":"ord123","title":"test1" }
{ "_id":"ord456","title":"test2" }
{ "_id":"ord789","title":"test3" }

而 BSON 就是 Mongo import&export 的預設格式,因此 BSON 格式就是 Mongo 所預設接受的檔案格式,這也不代表不能夠匯入JSON格式的檔案,只要在 mongoimport 指令最後加入 --jsonArray,就可以以我們習慣的JSON格式來作為匯入 Mongodb 的檔案格式。

2015年5月23日 星期六

Nodejs實作(3) - Socket.io + MySQL 即時同步訊息

這一個練習是延續上一篇 Nodejs實作(2) - Socket.io 實現多人即時同步聊天室,但是加上了 MySQL,想做訊息儲存,另一方面也是想要模仿例如 Facebook,Twitter 等即時狀況同步的情況。

新增 MySQL Table

status table structure

設置 Node 環境


設置此次運行環境因此先在當前目錄設定  package.json 安裝待會用到的套件及相依性,並且利用 command line 在當前目錄 npm install
package.json


撰寫 server.js


引入套件並且設置好 MySQL 連線資訊,再來設定 route.
撰寫 socket.io function,來處理 client端與server端互動功能,注意以下幾個 socket.io 的用法:
  1. io.sockets.emit:觸發所有 sockets(Client端)。
  2. io.sockets.on:等待所有進入的 sockets(Client端)。
  3. socket.emit:與 socket.on 相搭配,為event driven之用法,但對像為單一特定 socket。
  4. socket.on
可以注意第26行, add_status 所等待的 callback 為 res,而 res 是 MySQL 處理連接以及query成功與否的 callback


撰寫 index.html

可注意第10行,當socket與server連接上後,JQuery去判斷是否 add_status 的按鈕是否被按下,若有的話就將 comment 欄位的資訊當作參數,並且 emit 'status add' 這個事件,然而若 server.js 的 res 為 true的話,則將 status 播送到每個連接上的 sockets(Client端)。


結果

開兩個瀏覽器測試


資料庫現況
最後就成功拉!感覺還滿好玩的,這一次練習就是在釐清 socket.io , event driven , callback 的相關實作。


參考

NodeJs - 事件導向之特色

簡介

NodeJs 相當擅長於在事件的掌控,而在眾多實作當中,我們很常看到某個事件觸發另一事件,然而這就涉及到了 Listener 以及 Emitter 的角色關係。

2015年5月9日 星期六

在 Mac OS X 10.10 上安裝 PHP 套件管理 Composer

先前在  利用 Kudu 協助在 Azure Website 上使用 Composer 安裝 Azure SDK for PHP 有提到 Composer 的相關概念,有興趣可以回去看第一段。

網路上其實有許多高手對於安裝 Composer 有許多方法,然而此篇是寫來做個筆記,因為覺得這個方法不錯,還可以節省往後打指令時間,因此特別撰寫出來。

步驟一:先把 Composer.phar 下載下來,可以在 terminal 透過下列簡單的指令,選擇任一目錄皆可。

curl -sS https://getcomposer.org/installer | php

步驟二:我們都希望在 globally 的在 terminal 使用 composer 這指令,因此我們可以把 composer.phar 移入 /usr/bin/,並且修改 .bash_profile

sudo mv composer.phar /usr/bin/
vim ~/.bash_profile

步驟三:打開 .bash_profile 後在裡頭加個 composer 的 alias

alias composer="php /usr/bin/composer.phar"

步驟四:就是簡單順利的使用 composer 這個指令囉,若您按照以上步驟安裝,即可少打很多 php composer.phar 的前綴,而 composer 指令可以在官方文件找到。

參考

2015年3月28日 星期六

Git 使用流程筆記

最近由於一些專案的管理因素,希望導入git作為版本控制,因此參考許多教學資源,學了一下,順便記錄下來提醒自己。

2015年3月20日 星期五

[整理] 在網站中把文章內容分享至 Facebook 的一些方法 (Sharer.php,PHP SDK,Javascript SDK)


最近剛好在做一個有社群概念的專案,不外乎會有使用者上傳文章或心得在網站中,彼此交流,突然就想到!疑?應該要來個分享至 Facebook 的功能吧?於是開始找方法來做,發現
有一些方法可以執行,如以下:

2015年3月15日 星期日

利用 Kudu 協助在 Azure Website 上使用 Composer 安裝 Azure SDK for PHP

Composer

Composer 是一個管理專案相依性(dependncy)的 PHP 管理工具,若您想過 Ruby On Rails 您會知道 gem 或 Nodejs 您就會認識 npm,簡而言之,我們在撰寫 PHP Application也會用到許多Libraries,然而有些Libraries可能需要另一些 Libraries,所以相依性(dependency)的問題就產生啦!

而救星出現了,也就是 Composer !其實也就是利用 composer.json 宣告專案裡頭,需要安裝哪些版本的 Libraries,然後編譯後就直接幫你把這些檔案下載下來,並存至在 vendor 這個資料夾,並佛心的產生 autoload.php 讓我們自動載入這些 Libraries。

或許有些朋友,聽過梨子先生(Pear),它也可以幫忙管理類似相依性的問題,但其實它還真不是普通的不容易上手 ... 然而在 Composer 除了自己的 Repository,也可以支援 Git,更可以從 Pear 抓取你想安裝的Libraries。

2015年1月22日 星期四

DSP資料科學冬令營@NCCU-Day4

在 NCCU DSP 資料科學冬令營的最後一天,身體已經習慣了每日早起,並自然反應從忠孝新生到政大的路程,然而不同的是今天是帶著非常非常興奮的心情,因為我非常期待我們小組 - “叫我包租婆” 的專案呈現。

2015年1月21日 星期三

DSP資料科學冬令營@NCCU-Day3

第三天的課程一樣由Crystal進行教授,內容是前兩天的整和應用也是整個DSP冬令營最精華的部分,搭配資料思考的思維,並且知曉R語言操作後,下一步當然就是打造預測模型!

2015年1月20日 星期二

DSP資料科學冬令營@NCCU-Day2

第二天終於進行到R語言的基本概念介紹,經由昨日關於資料思考的議題思考與專案構想後,
心中早已有理想的預測模式與預測流程,而DSP就在第二天安排R語言課程!

2015年1月19日 星期一

DSP資料科學冬令營@NCCU-Day1

前言


這應該是我開始寫非技術筆記後,第一次寫有關於生活的日記吧!由於之前被室友提醒,生活不只有程式碼吧 XD,你還有生活啊(其實我也沒有多會寫程式QAQ)因此決定以後有什
麼值得紀錄的事情,那就把它記錄下來吧!

What is DSP?


追本朔源的話是由 Code for tomorrow 之前的一個子計畫所延伸而成的一個組織,目的在於讓資料科學這個新領域,經由其組織的倡導及培訓之後,可以有越來越多不只資訊背景的人員參加,而是希望是跨領域的多元組成,如此讓資料科學有更多價值發揮的可能!


2015年1月1日 星期四

Nodejs實作(2) - Socket.io 實現多人即時同步聊天室

Socket.io

Socket.io 官網
簡單來說Socket,由網路的角度來看,socket就是通訊連結的端點;從程式設計者的角度來看,socket提供了一個良好的介面,使程式設計者不需知道下層網路協定運作的細節便可以撰寫網路通訊程式。