Recent in Recipes

如何使用bot framework來建造多平台的ChatBot

前幾天稍微打了一個關於.net部屬在AWS的文章其實是在研究是否AWS會
"無痛"支援Microsoft一些服務(我似乎聽到笑聲了)!別這樣!部屬網站或是架虛擬機器當然是可以的啦!但是要做一些會使用不同廠商的平台功能就有可能吃閉門羹,所以今天要大家分享以及當作學習的筆記囉!。
今天要分享的是使用Microsoft 提供的bot framework來建造多平台的ChatBot,Microsoft建置了bot framework提供使用者簡單製造自己的機器人,大家要先到他的官網: https://dev.botframework.com/
※先註冊Microsoft帳號喔!

其中可以看看他的documentation詳細說明了使用方法,如果要看寫得很好的網站我推薦http://aihelpwebsite.com/Blog/EntryId/6/Creating-a-Hello-World-Bot-Using-The-Microsoft-Bot-Framework
這網站寫得很清楚,可能比官網還清楚...噓!!!,那小弟就稍微介紹一下Bot Framework:
11
※Bot Framework圖
Bot Builder是說我們可以透過一些開發者元件與人家寫好的工具來撰寫你的機器人,可以使用C#、Node.js...等等來開發
Developer Portal這裡是說明撰寫好的機器人,透過他來跟使用者端做溝通,現在的Bot Framework:並不是所有平台都支援,而現在有哪些平台有支援呢?如下圖所示囉!
12

※Bot Framework所支援的平台
Bot Directory是指你有那些機器人並做管理。
簡單介紹完之後我們開始先準備工具吧!
首先我們要準備的工具有:
  1. Virtual Studio 2015(建議使用 不建議2013)因為小弟是2013所以有些問題
  2. 下載Bot Builder SDK 網址: https://github.com/Microsoft/BotBuilder
  3. 模擬器 網址: https://github.com/Microsoft/BotFramework-Emulator#download
  4. 準備一個Web server(不強制 如果只想在本機試試的話就不用了)

假設現在你的本機已經有了Virtual Studio,我們把下載下來的Bot Builder SDK解壓縮至%USERPROFILE%\Documents\Visual Studio 2015
(按照使用的版本)\Templates\ProjectTemplates\Visual C#

接下來打開你的Virtual Studio會發現你多了一個機器人開發選項如下圖所示
13
※機器人開發選項

建立完以後來檢視一下裡面有什麼東西吧!
其實裡面最重要的兩個檔案是MessagesController.cs Web.config如下兩張圖
14
Web.config
15
MessagesController.cs

  Web.config 是用來設定機器人使用的,MessagesController.cs是機器人程式端,也就是說你想要機器人說什麼做什麼事都是在這裡做的。

其實你什麼都不做這個程式就可以跑囉!(小弟有做一個小小的修改,activity.CreateReply(Hello!);)接著打開模擬器與執行專案,並在模擬器的網址列輸入http://localhost:3979/api/messages 然後就可以跟他說話囉!!如下圖所示:
16
因為小弟的Port3979所以就輸入3979!但是如果要上線的話,網址的協定要從http改成https!

接下來要說明如何部屬與設定你的專案為機器人所使用首先先建立一個機器人
進入
https://dev.botframework.com/之後點選Register a bot,然後進入頁面如下圖所示:
17
Name是機器人名稱,可以自己取名,但是Bot handle必須要記一下,設完他以後他是唯一值,接下來要創建Bot ID 與 password,如下圖:
18
點選create Microsoft app id and password,進來以後會出現以下頁面:
19
這裡要注意一下,密碼要記起來,因為他只出現這一次爾以,而且找不到喔! 好了以後按Finish按鈕如下所示:
20
好的!這裡初步的都設定好囉!
接下來回到主頁面看看
21
剛剛所設定的資訊,除了密碼以外都在上面了!
接下來就是部屬你的機器人專案囉!回到Web.config頁面如下:
22
我們把剛剛的資料都打上去:BotId 就是Bot handle,AppId跟AppPassword就是剛剛按鈕生成的資訊,隨後把資訊Key上。 在來就是要部屬發行了不過要有Microsoft Azure的帳號如果大家想試試的話可以申請一個試用版的(有一個月的6300額度)
我們在專案右方點右建按發行,如下圖所示:
23

進入選後Microsoft Azure Web應用程式,接下來就是設定一些東西囉!如下圖:
24

設定完成後會載入帳號以及網域的資訊按下發行,如下圖
25
之後輸入網域後結果如下:
26

表示我們機器人專案已經部屬成功了!再來回到機器人管理頁面點開編輯,如下圖所示:
27
點擊後在下圖地方填上網域,以下圖範例:https://botkevintest01.azurewebsites.net/api/messages
28
與測試不一樣的點是http要改成https

最後到機器人頁面之後點擊Test後看到是Endpoint authorization succeeded,表示你的機器人可以測試了!如下圖
29
30
大致上差不多是這樣子,其實沒有想像中的複雜,接下來就可以玩玩看裡面的平台囉!

如何使用Vistual Studio上傳至AWS部屬

小弟最近想研究一些東西的緣故,先寫這篇當作前導文吧,雖然是小東西但是當個筆記用吧!
在這篇開始之前先貼上參考網站,謝謝這個網站!
這網站已經幫我解決大部分的問題了,雖然是外國網站但是有圖片交著做,所以蠻好懂的,那開始進入正題囉!
首先我們要先有以下幾個準備工作:
1.準備AWS(amazon web server)帳號
3.Vistual Studio(小弟是2013版)
 1
(AWS Toolkit)下載頁面圖

 下載完AWS Toolkit後執行安裝,位置可以自己決定,安裝完成後打開Vistual Studio會發現多了一些選項如下圖:17092861_1870096956609196_424950151_o
 表示安裝成功了!基本的前置作業完成了就開始打開Vistual Studio選取想要上傳的檔案,小弟就來這幾天做的範例來示範一下:
 17035966_1870101506608741_1144997101_o
打開以後先測試一下可不可以執行如下圖所示:
17035847_1870119949940230_1087128344_o

  這個表示本機端的網址,如果沒有顯示錯誤資訊可以顯示程式結果,表示程式的部分是沒問題的,檢查完之後就要上傳AWS囉!
 首先在專案上點右鍵,找到 Publish to AWS Elastic Benstalk...
17036530_1870103533275205_787940386_o

點擊後如下圖,按下框起來的按鈕:
17091321_1870114476607444_634470123_o
點擊後再紅色框號地方打DeploymentProf
17035847_1870114996607392_1233584617_o
下面就是要打AWS金鑰資訊,我們先暫停一下,回到AWS中有個IAM,點擊後到Users畫面接著點選Add user如下:
17036715_1753798761300819_83054215_o
進入新增的程序頁面後,輸入自訂的User name以及勾選第一個存去型態
17036726_1753799151300780_2139580131_o
下一頁有一個大圖示的選項Attach existing policies directly,這是要增加一些權限的地方,我們需要以下兩個權限
( AmazonEC2FullAccess 和AWSElasticBeanstalkFullAccess)如下圖:
17016631_1753802094633819_1847820155_o
17016298_1753820094632019_667805886_o選擇完連續下一步兩次到最後一個步驟如下:
17093228_1753803214633707_1474743236_o
會顯示與下載金鑰密碼(公開鑰與私密鑰),記得要載下來,之後回到Vistual studio
補上金鑰資訊後按確定後按確定,下一頁會顯示環境設定如下圖所示:
17036544_1870118366607055_1055416147_o
如果顯示綠色的表示設定成功了!如果不是可能需要回到AWS看看權限是否設定正確。

接下來就可以設定你的Server硬體需求,小弟選了一個小一點的如下圖:
17091302_1870118636607028_135198886_o


接下來可以持續下一步到最後一步
17015118_1870119019940323_1253747376_o
17093227_1870118993273659_1498247266_o
17091086_1870119116606980_1493600057_o
底下是勾選只要server停止後就會自動重建,因為網站的的服務不能中斷,所以當server有問題時自動重建。

最後按下部屬後顯示資訊如下圖:
17016185_1870119649940260_101407653_o
框起來的地方就是server提供的網址囉!這時候輸入網址看看:
17036976_1870121166606775_1564821793_o
我們之前測試的網站就上架囉!!

最後如果不想要繼續部屬要怎麼取消呢?
這裡要回到AWS到EC2選單,在左邊尋找Auto Scaling Group刪除剛建的群組即可(找時間最近的就是了)
17036591_1753836431297052_1715541809_o
好囉!筆記就到這邊結束囉!如果有不清楚的地方歡迎留言討論一下喔!!

簡介Java - ArrayList



因為小弟某些原因開始研讀集合物件(Collection Framework),首先先介紹一下比較容易了解的ArrayList

首先根據  API 說明書中 https://docs.oracle.com/javase/7/docs/api/
ArrayList 是實作  List 這個介面,也可以在  List 介面中發現許多集合物件有實作此類別  EX: LinkedList Vector ...等等

其中實作List介面的集合物件有幾個特性:
1.存進去的資料可以重複
2.具有順序性

因為這篇針對  ArrayList 做解說, List 就稍微介紹到這,ArrayList 說明白的就是存放資料用,可能這邊會有人說:可以用陣列就好了啊為什麼還要  ArrayList !?
首先這裡帶著大家回憶一下陣列宣告時
陣列宣告的時候:
1.png
我們需要給他指定的型態、指定資料或資料大小,如果今天是資料庫的資料,多少筆我根本不可能一個一個數,這時候  ArrayList 可以改善這特性,因為  ArrayList 可以動態配置。

再來,因為陣列宣告比資料多,或是要再重新配置,會導致記憶體與效能的浪費,所以這裡簡單整理ArrayList優於陣列的 幾個要點:
1.可以動態配置空間
2.減少記憶體與效能的浪費

接下來談談ArrayList存入的型態,因為不需要指定資料型態,所以什麼資料都可以存入,所以  ArrayList 裡面的資料型態叫(Object)

當要處理資料時就要進行轉型

接下來就帶著大家實作  ArrayList:
1.png



這圖是APIArrayList的建構子使用方式,整理出一個表格給大家:

ArrayList 建構子
說明
ArrayList()
建立一個空的ArrayList
ArrayList(int capacity)
建立一個指定容量的ArrayList
ArrayList(Collection<? extends E> c)
使用實作的interface建立ArrayList

看完建構子我們列幾個常用的方法:
方法
說明
boolean add(E e)
照順序增加元素
boolean add(int index , E element)
指定索引值增加元素
void clear()
清空list所有元素
E get(int index)
取得索引值中的資料
E remove(int index)
移除指定索引值的資料
boolean remove(Object object)
移除相同內容的資料
Int size()
List中資料數量

我們實作一段程式如下:
 
public class Test01 { public static void main(String[] args) { ArrayList test = new ArrayList(); test.add("Hello"); test.add("Java"); test.add("Have"); test.add("Fun"); test.add("Java"); System.out.println(test.get(0)); for (int i = 0; i <test.size(); i++) { System.out.println("data:"+test.get(i)); } System.out.println("data size:"+test.size()); } }

其結果如下:
1.png

其型態乍看之下好像是字串對吧!?因為剛剛我們存進去是存字串,可是我們換一種寫法看看:

 
public class Test01 { public static void main(String[] args) { ArrayList test = new ArrayList(); test.add("Hello"); test.add("Java"); test.add("Have"); test.add("Fun"); test.add("Java"); System.out.println(test.get(0)); for (Object object : test) { System.out.println("data:"+object); } System.out.println("data size:"+test.size()); } }
我們把迴圈改成for-each看到承接的是Object
所以說他的型態是Object!!!
顯示結果如下:
1.png
其實是完全一樣的,可是往後存的是一個類別,必須要轉型,其實是非常麻煩的事情,這時候我們可以用"<>"(泛型)來指定存進去的型態是什麼型態,這時候把程式再改一下:

 
public class Test01 {
    public static void main(String[] args) {
        ArrayList<String> test = new ArrayList();
        
        test.add("Hello");
        test.add("Java");
        test.add("Have");
        test.add("Fun");
        test.add("Java");
        
        System.out.println(test.get(0));
        
        for (String object : test) {
            System.out.println("data:"+object);
        }
        
        System.out.println("data size:"+test.size());
          
    }
    
}

我們在建造物件時指定<String>型態,所以for-each改變承接型態為String,其顯示結果如下:
1.png
其實因為都是字串所以看起來都一樣!但型態已經改成String!!
再來是我們指定好ArrayList大小再搭配remove()做使用看看,其程式如下:

 

public class Test01 {
    public static void main(String[] args) {
        ArrayList<String> test = new ArrayList(10);
        
        test.add("Hello");
        test.add("Java");
        test.add("Have");
        test.add("Fun");
        test.add("Java");
        
        test.remove("Java");
        
        for (String object : test) {
            System.out.println("data:"+object);
        }
        
        System.out.println("data size:"+test.size());
        test.remove("Java");
          
    }
    
}

我們先指定好容量大小以及在增加完資料後移除"Java"資料,其顯示結果如下:
1.png
我們發現size是根據ArrayList的資料多寡來呈現數量,remove("Java")他是移除最先加入的那筆資料,請大家要記一下喔※如果要考OCP的這個很重要!!


以上就是ArrayList簡單的介紹,用一種簡單的例子來解說希望對大家有幫助XD

簡單使用JSoup抓取xml網站資料(含android範例)

  關於抓資料,第一個想法應該是python,不過因為學了java,想透過java抓取資料,於是開啟我查詢java爬資料的資料,除了查到ETL外,jsoup應該是最方便的"套件"了。
  jsoup說明白他就是java的library(jar),也就是人家寫好的套件然後造福我們這些寫程式的人用,這真的是很厲害的地方!我在網路上參考了
【JAVA】使用JSOUP讓JAVA取得網頁上的文字 (Example for download)這篇文章雖然寫得很簡單但是語法跟解說很清楚謝謝大大 =D,那我的廢話到這裡開始解說我的程式囉!

  jsoup方便的原因是因為不管是html,還是xml都是屬於標籤語言,而jsoup就是根據標籤抓取裡面的資訊,在打程式之前我們有些前置作業要做:
1.前往官方網站 http://jsoup.org/download 下載jar
2.開啟java專案匯入jar(這裡使用netbean)
12
其實netbean和eclipse匯入的方法差不多所以大家不用太擔心。
本篇文章是抓取政府opendata的資料放置本機伺服器,其資料格式為xml,
下載網址如下:
程式碼:CWBTSU.xml

<br data-mce-bogus="1">

CWB-TSU10300101-2014-0920-073000

CWB_SC@scman.cwb.gov.tw

2014-09-20T07:30:00+08:00

Actual

Issue

CWB

Public

海嘯資訊

zh-TW

2014-09-20T07:30:00+08:00

2014-09-20T15:30:00+08:00

海嘯警報

103001

第1報

頃獲太平洋海嘯警報中心通知,103年09月20日07時21分(臺灣時間),在震央東經137﹒41度、北緯9﹒19度,發生規模8﹒7地震。該中心研判可能引發海嘯,經初步推算,海嘯湧浪預計臺灣時間103年09月20日09時41分到達臺灣,請臺灣沿海地區提高警覺嚴加防範。

橙色

http://scweb.cwb.gov.tw/GraphicContent.aspx?ItemId=3&amp;fileString=10300101

2014-09-20T07:21:00+08:00

137.41

9.19

亞普海溝

10.0

8.7

美國太平洋海嘯警報中心

東南沿海地區

臺東縣成功鎮至屏東縣滿州鄉沿岸

1至3公尺

2014-09-20T09:41:00+08:00

橙色

predict

東部沿海地區

宜蘭縣南澳鄉至臺東縣長濱鄉沿岸

1至3公尺

2014-09-20T09:51:00+08:00

橙色

predict

東北沿海地區

宜蘭縣頭城鎮至蘇澳鎮沿岸

1至3公尺

2014-09-20T09:51:00+08:00

橙色

predict

西南沿海地區

臺南市至屏東縣恆春鎮沿岸

1至3公尺

2014-09-20T10:01:00+08:00

橙色

predict

北部沿海地區

新北市及基隆市沿岸

1至3公尺

2014-09-20T10:11:00+08:00

橙色

predict

海峽沿海地區

桃園縣至嘉義縣沿岸,以及澎湖縣、金門縣與連江縣等離島區域

小於1公尺

2014-09-20T10:51:00+08:00

黃色

predict



其實這裡都已經定義好資料了,每個標籤都有他們所呈現的資訊,所以在抓取資料時會相對的單純很多!
接下來直接來看程式碼

<Java程式端>
public static void main(String[] args) throws Exception {

URL url = new URL("server位置+檔名,以本機為例EX:http://127.0.0.1/ CWBTSU.xml ");

Document xmlc =  Jsoup.parse(url, 3000); //使用Jsoup解析網頁

try {

Elements datas = xmlc.select("warningArea"); //解析的元素為warningArea的標籤

for(Element data : datas){

System.out.println(data.text());

}

//使用for each取出資料並顯示

System.out.println("Is "+datas.get(0).text());

//這裡是取出warningArea標籤的第一個內容,即get(0),如果要取第二個內容為get(1)

} catch (Exception e) {

}
}


其執行結果為
3
表示我們已經把warningArea標籤內容取出了,大家可以參考一下。
如果程順利的顯示結果就表示完成了!那如果要搭配android的話如果java程式框架已經出來了,不過要使用執行緒來執行,因為有牽涉網路存取,可能會導致程式timeout,接下來附上程式碼。
首先是畫面的layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.jsouptest.MainActivity">

<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Hello World!"
android:id="@+id/hi"
android:layout_above="@+id/button"
android:textAllCaps="false"
android:textAlignment="center" />

<Button
android:text="Button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentStart="true"
android:id="@+id/button" />
</RelativeLayout>
再來是權限檔我們需要網路存取權限
 ※<uses-permission android:name="android.permission.INTERNET" /></pre>
所以所有程式碼如下
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.jsouptest">
<uses-permission android:name="android.permission.INTERNET" />

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>
最後就是java檔了
 

 import android.app.Activity;
 import android.support.v7.app.AppCompatActivity;
 import android.os.Bundle;
 import android.util.Log;
 import android.view.View;
 import android.widget.Button;
 import android.widget.TextView;

 import org.jsoup.Jsoup;
 import org.jsoup.nodes.Document;
 import org.jsoup.nodes.Element;
 import org.jsoup.select.Elements;

 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.net.InetAddress;
 import java.net.Socket;
 import java.net.URL;
 import java.util.HashMap;
 import java.util.Map;

public class MainActivity extends Activity {
  TextView hi;
  URL url;
  Thread go;
  StringBuilder tmp = new StringBuilder();
  int i = 1;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.activity_main);
     Button button = (Button) findViewById(R.id.button);
     hi = (TextView) findViewById(R.id.hi);

     button.setOnClickListener(new Button.OnClickListener() {
       @Override
       public void onClick(View v) {
         go = new Thread(readData);
         go.start();
       }
     });

 }

 private Runnable readData = new Runnable() {
   public void run() {
   try {
   //(要解析的文件,timeout)

      url = new URL("在這裡輸入server位置與檔案(這裡檔案名為上面的xml) ");

      Document xmlDoc =&nbsp; Jsoup.<em>parse</em>(url,3000);
      Elements title = xmlDoc.select("warningArea"); <em>//要解析的tag元素為warningArea這標籤</em>

      //Elements tables = xmlDoc.select("center&gt;table");
      tmp.delete(0,tmp.length());
      for(int i =0; i&lt;title.size() ; i++){
        Log.<em>e</em>("Kevin Test",title.text());
        tmp.append(i+1+title.get(i).text()+"&nbsp;&nbsp;&nbsp; "+"\n\n");

      }
    hi.setText(tmp);
    //System.out.println("Is "+title.get(0).text());
    } catch (Exception e) {
  }
 }
 };
 }



其顯示結果如下:
messageImage_1485014148608.jpg
這是一開始的畫面
messageImage_1485014154111.jpg
當按下按鈕時,會把xml中所有標籤資訊解譯出來
  jsoup是一個很好用的套件,其實他可以運用的功能很多,這裡只是冰山一角而已,至於想要如何呈現或是在資料中得知有用的資訊又是一項艱難的任務了。
  所以這是為什麼資料分析會那麼火紅的原因之一,小弟不是做資料分析的,但是在爬資料的時候都有先預設說爬什麼資料與想知道什麼資訊,從爬到的資料中尋找出我想知道的答案,所以大家也可以想想,自己手上的資料是否也有貨真價實的資訊等著我們發覺、探究和解惑。