2019年4月10日 星期三

Win10 的 Windows Update 在哪裡?

今天下午要用筆電時發覺藍芽滑鼠不動了, 我想會不會是今天有系統更新導致藍芽出問題? 但控制台怎麼找就是沒有, 奇怪 Win10 把 Windows Update 藏哪去了? 後來查網路才知道在 "電腦設定" 裡 :






點下方的 "進階設定" 可以選擇關閉自動更新, 改為手動更新 :




自動更新的好處是方便, 壞處是可能成為更新白老鼠.

完成系統更新後藍芽滑鼠還是無法連線, 我看恐怕是滑鼠本身有問題了. 還是買羅技的品質好, 我以前搭配 Inhon 筆電的 M545 現在都還很好用, 目前就暫時用這個吧 (要占用一個 USB 埠).

目前有看到下面兩個 M337 還不錯, 600 元左右 :

Logitech 羅技 M337 藍芽滑鼠(黑色) $570
羅技(原廠盒裝) M337藍牙滑鼠(藍) $600

270 元買來的中國製藍芽滑鼠, 不到三個月就 GG 了.

ACER Swift 5 筆電續航力紀錄

我這台 Swift 5 筆電 (SF515-51T) 1 月底買來已近三個月, 覺得很滿意, 15.6 吋大螢幕看起來很舒服, 效能對於上網寫程式等文書作業很 OK, 最重要的是非常輕, 不到 1 公斤零負擔. 參考 :

購買新筆電 ACER SF515

今天開會時順便紀錄了一下電池續航力, 從 9 點離開充電器起算, 到 10 點 35 分時電量由 80% 掉到 63%, 亦即 17% 的電量撐了 95 分鐘, 所以大約 1% 可以撐 95/17=5.6 分鐘左右. 推估 80% 掉到 10% 可撐 70*5.6=391 分鐘, 約 6.5 小時左右. 若充飽至 100%, 則掉到 10 可撐 90*5.6=504 分=8.4 小時. 以上都是在開啟 WiFi 連線情況測量的.

在樹莓派上編譯執行 Java 程式

最近安裝新版樹莓派 Raspbian Stretch (2018-11-13) 後注意到 Raspbian 除了內建 Python2 與 Python3 外, 也內建了 JDK 8, 版本是 1.8.0_65 :

pi@raspberrypi:~ $ java -version   
java version "1.8.0_65"
Java(TM) SE Runtime Environment (build 1.8.0_65-b17)
Java HotSpot(TM) Client VM (build 25.65-b01, mixed mode)
pi@raspberrypi:~ $ javac -version 
javac 1.8.0_65

我自 2014 年後就沒有再碰 Java 了 (記得那年六月陪姊姊去南二中參加美術班術科考試時我正忙著測試 Java Swing 的 Data Grid 呢), 因為後來都在用 Javascript 與 Python, 五年多沒用 Java 真的變生疏了. 原本想說就此與 Java 說掰掰分道揚鑣, 但後來覺得藝不嫌多, 已經有的又何必丟掉呢?

既然樹莓派必載 Java, 那麼今天就來複習一下 Java 吧!

首先用 nano 編輯一個 HelloWorld.java 如下 :

pi@raspberrypi:~ $ nano HelloWorld.java 
pi@raspberrypi:~ $ cat HelloWorld.java 
public class HelloWorld {
  public static void main(String[] args) {
    System.out.println("Hello, world!");
    }
  }

然後馬上用 javac 編譯為 HelloWorld.class, 再用 java 執行它 :

pi@raspberrypi:~ $ javac HelloWorld.java 
pi@raspberrypi:~ $ java HelloWorld   
Hello, world! 

參考 :

葉難: Raspberry Pi與Java 8:Hello World

下面測試 Swing 功能, 參考之前的文章 :

# Java Swing 測試 : JOptionPane 對話框

開啟 nano 貼入範例程式 JOptionPane7.java :

pi@raspberrypi:~ $ nano JOptionPane7.java
pi@raspberrypi:~ $ cat JOptionPane7.java 
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;

public class JOptionPane7 implements ActionListener {
  JFrame f;
  JMenuBar mb;
  JMenu jop,messages,options;
  JMenuItem[] dialog;
  JRadioButtonMenuItem[] mType;
  JRadioButtonMenuItem[] oType;
  public static void main(String argv[]) {
    new JOptionPane7();
    }
  public JOptionPane7() {
    //Setup JFrame
    JFrame.setDefaultLookAndFeelDecorated(true);
    JDialog.setDefaultLookAndFeelDecorated(true);
    f=new JFrame("JOptionPane Test");
    f.setSize(400,300);
    f.setLocationRelativeTo(null);
    Container cp=f.getContentPane();
    cp.setLayout(null);
    f.setVisible(true);

    //Build Elements
    mb=new JMenuBar();
    jop=new JMenu("JOptionPane");
    messages=new JMenu("Message Type");
    options=new JMenu("Option Type");
    dialog=new JMenuItem[4];
    dialog[0]=new JMenuItem("setMessageDialog()");
    dialog[1]=new JMenuItem("setConfirmDialog()");
    dialog[2]=new JMenuItem("setInputDialog()");
    dialog[3]=new JMenuItem("setOptionDialog()");
    mType=new JRadioButtonMenuItem[5];
    mType[0]=new JRadioButtonMenuItem("ERROR_MESSAGE");
    mType[1]=new JRadioButtonMenuItem("INFORMATION_MESSAGE");
    mType[2]=new JRadioButtonMenuItem("WARNING_MESSAGE");
    mType[3]=new JRadioButtonMenuItem("QUESTION_MESSAGE");
    mType[4]=new JRadioButtonMenuItem("PLAIN_MESSAGE");
    oType=new JRadioButtonMenuItem[4];
    oType[0]=new JRadioButtonMenuItem("DEFAULT_OPTION");
    oType[1]=new JRadioButtonMenuItem("YES_NO_OPTION");
    oType[2]=new JRadioButtonMenuItem("YES_NO_CANCEL_OPTION");
    oType[3]=new JRadioButtonMenuItem("OK_CANCEL_OPTION");
    for (int i=0; i<dialog.length; i++) {
      jop.add(dialog[i]);
      dialog[i].addActionListener(this);
      }
    jop.addSeparator();
    ButtonGroup mgroup=new ButtonGroup();
    for (int i=0; i<mType.length; i++) {
      messages.add(mType[i]);
      mgroup.add(mType[i]);
      mType[i].addActionListener(this);
      if (i==0) {mType[i].setSelected(true);}
      }
    ButtonGroup ogroup=new ButtonGroup();
    for (int i=0; i<oType.length; i++) {
      options.add(oType[i]);
      ogroup.add(oType[i]);
      oType[i].addActionListener(this);
      if (i==0) {oType[i].setSelected(true);}
      }
    jop.add(messages);
    jop.add(options);
    mb.add(jop);
    f.setJMenuBar(mb);
 
    //Close JFrame     
    f.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
    f.addWindowListener(new WindowHandler(f));
    }
  public void actionPerformed(ActionEvent e) {
    String cmd=e.getActionCommand();
    if (cmd.equals("setMessageDialog()")) {
      int mtype=getMessageType();
      JOptionPane.showMessageDialog(f,"Hello World! 您好","資訊",mtype);
      }
    if (cmd.equals("setConfirmDialog()")) {
      int mtype=getMessageType();
      int otype=getOptionType();
      int opt=JOptionPane.showConfirmDialog(f,cmd,"確認",otype,mtype);
      showSelectedOption(opt);
      }
    if (cmd.equals("setInputDialog()")) {
      int mtype=getMessageType();
      String input=JOptionPane.showInputDialog(f,cmd,"輸入",mtype);
      JOptionPane.showMessageDialog(f,"您輸入的是 : " + input);
      }
    if (cmd.equals("setOptionDialog()")) {
      String[] options={"接受","不接受","取消"};
      int mtype=getMessageType();
      int otype=getOptionType();
      int opt=JOptionPane.showOptionDialog(f,cmd,"請選擇",otype,mtype,null,
                                           options,"接受");
      showSelectedOption(opt);
      }
    }
  public int getMessageType() {
    int type=1;
    for (int i=0; i<mType.length; i++) {
      if (mType[i].isSelected()) {
        switch (mType[i].getText()) {
          case "ERROR_MESSAGE" : type=0;break;
          case "INFORMATION_MESSAGE" : type=1;break;
          case "WARNING_MESSAGE" : type=2;break;
          case "QUESTION_MESSAGE" : type=3;break;
          case "PLAIN_MESSAGE" : type=-1;break;
          }
        }
      }
    return type;
    }
  public int getOptionType() {
    int type=1;
    for (int i=0; i<oType.length; i++) {
      if (oType[i].isSelected()) {
        switch (oType[i].getText()) {
          case "DEFAULT_OPTION" : type=-1;break;
          case "YES_NO_OPTION" : type=0;break;
          case "YES_NO_CANCEL_OPTION" : type=1;break;
          case "OK_CANCEL_OPTION" : type=2;break;
          }
        }
      }
    return type;
    }
  public void showSelectedOption(int opt) {
    if (opt==JOptionPane.YES_OPTION) {
      JOptionPane.showMessageDialog(f,"您按了 YES (是) " + opt);
      }
    else if (opt==JOptionPane.NO_OPTION) {
      JOptionPane.showMessageDialog(f,"您按了 NO (否) " + opt);
      }
    else if (opt==JOptionPane.CANCEL_OPTION) {
      JOptionPane.showMessageDialog(f,"您按了 CANCEL (取消) " + opt);
      }
    else if (opt==JOptionPane.CLOSED_OPTION) {
      JOptionPane.showMessageDialog(f,"您按了 CLOSE (關閉) " + opt);
      }
    else if (opt==JOptionPane.OK_OPTION) {
      JOptionPane.showMessageDialog(f,"您按了 OK (確定) " + opt);
      }
    }
  }
class WindowHandler extends WindowAdapter {
  JFrame f;
  public WindowHandler(JFrame f) {this.f=f;}
  public void windowClosing(WindowEvent e) {
    int result=JOptionPane.showConfirmDialog(f,
               "確定要結束程式嗎?",
               "確認訊息",
               JOptionPane.YES_NO_OPTION,
               JOptionPane.WARNING_MESSAGE);
    if (result==JOptionPane.YES_OPTION) {System.exit(0);}
    } 
  }
pi@raspberrypi:~ $ javac JOptionPane7.java 
pi@raspberrypi:~ $ java JOptionPane7 




Swing 發展已經非常成熟, 我那時是在 Java 6 上寫的測試程式, 過這麼久了在 Java 8 也是沒問題的.

樹莓派安裝 twder 套件

今天在樹莓派上嘗試安裝 Python 台銀外匯資料擷取套件 twder, 以前只在 PC 上安裝測試過, 參考 :

Python Fintech 學習筆記 : 用 twder 模組擷取台銀外匯報價

直接用 pip3 安裝卻出現找不到相依套件 libxml2 與 libxslt 的錯誤 :

pi@raspberrypi:~ $ pip3 install twder 
Collecting twder
  Downloading https://files.pythonhosted.org/packages/79/44/9d25944c500732f10cde648b86be297449eb3d2c9608699f744e75d9361f/twder-0.1.4-py3-none-any.whl
Collecting requests (from twder)
  Using cached https://files.pythonhosted.org/packages/7d/e3/20f3d364d6c8e5d2353c72a67778eb189176f08e873c9900e10c0287b84b/requests-2.21.0-py2.py3-none-any.whl
Collecting lxml (from twder)
  Using cached https://files.pythonhosted.org/packages/7d/29/174d70f303016c58bd790c6c86e6e86a9d18239fac314d55a9b7be501943/lxml-4.3.3.tar.gz
Collecting idna<2.9,>=2.5 (from requests->twder)
  Using cached https://files.pythonhosted.org/packages/14/2c/cd551d81dbe15200be1cf41cd03869a46fe7226e7450af7a6545bfc474c9/idna-2.8-py2.py3-none-any.whl
Collecting urllib3<1.25,>=1.21.1 (from requests->twder)
  Using cached https://files.pythonhosted.org/packages/62/00/ee1d7de624db8ba7090d1226aebefab96a2c71cd5cfa7629d6ad3f61b79e/urllib3-1.24.1-py2.py3-none-any.whl
Collecting chardet<3.1.0,>=3.0.2 (from requests->twder)
  Using cached https://files.pythonhosted.org/packages/bc/a9/01ffebfb562e4274b6487b4bb1ddec7ca55ec7510b22e4c51f14098443b8/chardet-3.0.4-py2.py3-none-any.whl
Collecting certifi>=2017.4.17 (from requests->twder)
  Using cached https://files.pythonhosted.org/packages/60/75/f692a584e85b7eaba0e03827b3d51f45f571c2e793dd731e598828d380aa/certifi-2019.3.9-py2.py3-none-any.whl
Building wheels for collected packages: lxml
  Running setup.py bdist_wheel for lxml ... error
  Complete output from command /usr/bin/python3 -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-x2ow03f4/lxml/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" bdist_wheel -d /tmp/tmpijs4zby1pip-wheel- --python-tag cp35:
  Building lxml version 4.3.3.
  Building without Cython.
  ERROR: b'/bin/sh: 1: xslt-config: not found\n'
  ** make sure the development packages of libxml2 and libxslt are installed **

  Using build configuration of libxslt
  running bdist_wheel
  running build
  running build_py
  creating build
  creating build/lib.linux-armv7l-3.5
  creating build/lib.linux-armv7l-3.5/lxml

  .... (略) ....

  arm-linux-gnueabihf-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -g -fdebug-prefix-map=/build/python3.5-6waWnr/python3.5-3.5.3=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -DCYTHON_CLINE_IN_TRACEBACK=0 -Isrc -Isrc/lxml/includes -I/usr/include/python3.5m -c src/lxml/etree.c -o build/temp.linux-armv7l-3.5/src/lxml/etree.o -w
  In file included from src/lxml/etree.c:687:0:
  src/lxml/includes/etree_defs.h:14:31: fatal error: libxml/xmlversion.h: 沒有此一檔案或目錄
   #include "libxml/xmlversion.h"
                                 ^
  compilation terminated.
  Compile failed: command 'arm-linux-gnueabihf-gcc' failed with exit status 1
  creating tmp
  cc -I/usr/include/libxml2 -c /tmp/xmlXPathInit3sx4_qt3.c -o tmp/xmlXPathInit3sx4_qt3.o
  /tmp/xmlXPathInit3sx4_qt3.c:1:26: fatal error: libxml/xpath.h: 沒有此一檔案或目錄
   #include "libxml/xpath.h"
                            ^
  compilation terminated.
  *********************************************************************************
  Could not find function xmlCheckVersion in library libxml2. Is libxml2 installed?
  *********************************************************************************
  error: command 'arm-linux-gnueabihf-gcc' failed with exit status 1

  ----------------------------------------
  Failed building wheel for lxml
  Running setup.py clean for lxml
Failed to build lxml
Installing collected packages: idna, urllib3, chardet, certifi, requests, lxml, twder
  Running setup.py install for lxml ... error
    Complete output from command /usr/bin/python3 -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-x2ow03f4/lxml/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record /tmp/pip-jxkmwzj0-record/install-record.txt --single-version-externally-managed --compile --user --prefix=:
    Building lxml version 4.3.3.
    Building without Cython.
    ERROR: b'/bin/sh: 1: xslt-config: not found\n'
    ** make sure the development packages of libxml2 and libxslt are installed **

    Using build configuration of libxslt
    running install
    running build
    running build_py
    creating build
    creating build/lib.linux-armv7l-3.5
    creating build/lib.linux-armv7l-3.5/lxml
    copying src/lxml/sax.py -> build/lib.linux-armv7l-3.5/lxml

  .... (略) ....

    building 'lxml.etree' extension
    creating build/temp.linux-armv7l-3.5
    creating build/temp.linux-armv7l-3.5/src
    creating build/temp.linux-armv7l-3.5/src/lxml
    arm-linux-gnueabihf-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -g -fdebug-prefix-map=/build/python3.5-6waWnr/python3.5-3.5.3=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -DCYTHON_CLINE_IN_TRACEBACK=0 -Isrc -Isrc/lxml/includes -I/usr/include/python3.5m -c src/lxml/etree.c -o build/temp.linux-armv7l-3.5/src/lxml/etree.o -w
    In file included from src/lxml/etree.c:687:0:
    src/lxml/includes/etree_defs.h:14:31: fatal error: libxml/xmlversion.h: 沒有此一檔案或目錄
     #include "libxml/xmlversion.h"
                                   ^
    compilation terminated.
    Compile failed: command 'arm-linux-gnueabihf-gcc' failed with exit status 1
    cc -I/usr/include/libxml2 -c /tmp/xmlXPathInitzd492hbe.c -o tmp/xmlXPathInitzd492hbe.o
    /tmp/xmlXPathInitzd492hbe.c:1:26: fatal error: libxml/xpath.h: 沒有此一檔案或目錄
     #include "libxml/xpath.h"
                              ^
    compilation terminated.
    *********************************************************************************
    Could not find function xmlCheckVersion in library libxml2. Is libxml2 installed?
    *********************************************************************************
    error: command 'arm-linux-gnueabihf-gcc' failed with exit status 1

    ----------------------------------------
Command "/usr/bin/python3 -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-x2ow03f4/lxml/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record /tmp/pip-jxkmwzj0-record/install-record.txt --single-version-externally-managed --compile --user --prefix=" failed with error code 1 in /tmp/pip-build-x2ow03f4/lxml/

總之就是缺了 libxml2 與 libxslt 這兩個相依模組.

直接用 pip3 安裝 libxml2 結果找不到此套件 :

pi@raspberrypi:~ $ pip3 install libxml2
Collecting libxml2
  Could not find a version that satisfies the requirement libxml2 (from versions: )
No matching distribution found for libxml2 

搜尋 "fatal error: libxml/xmlversion.h: 沒有此一檔案或目錄" 找到下面文章 :


原來 libxml2 與 libxslt 的安裝指令是 :

sudo apt-get install libxml2-dev libxslt-dev     

pi@raspberrypi:~ $ sudo apt-get install libxml2-dev libxslt-dev   
正在讀取套件清單... 完成
正在重建相依關係
正在讀取狀態資料... 完成
Note, selecting 'libxslt1-dev' instead of 'libxslt-dev'
libxml2-dev is already the newest version (2.9.4+dfsg1-2.2+deb9u2).
下列【新】套件將會被安裝:
  libxslt1-dev
升級 0 個,新安裝 1 個,移除 0 個,有 0 個未被升級。
需要下載 488 kB 的套件檔。
此操作完成之後,會多佔用 2,246 kB 的磁碟空間。
是否繼續進行 [Y/n]? [Y/n] Y
下載:1 http://mirror.ossplanet.net/raspbian/raspbian stretch/main armhf libxslt1-dev armhf 1.1.29-2.1 [488 kB]
取得 488 kB 用了 2s (173 kB/s)
選取了原先未選的套件 libxslt1-dev:armhf。
(讀取資料庫 ... 目前共安裝了 134098 個檔案和目錄。)
Preparing to unpack .../libxslt1-dev_1.1.29-2.1_armhf.deb ...
Unpacking libxslt1-dev:armhf (1.1.29-2.1) ...
Processing triggers for man-db (2.7.6.1-2) ...
設定 libxslt1-dev:armhf (1.1.29-2.1) ...

然後再次安裝 twder 即可 :

pi@raspberrypi:~ $ pip3 install twder
Collecting twder
  Using cached https://files.pythonhosted.org/packages/79/44/9d25944c500732f10cde648b86be297449eb3d2c9608699f744e75d9361f/twder-0.1.4-py3-none-any.whl
Collecting lxml (from twder)
  Using cached https://files.pythonhosted.org/packages/7d/29/174d70f303016c58bd790c6c86e6e86a9d18239fac314d55a9b7be501943/lxml-4.3.3.tar.gz
Collecting requests (from twder)
  Using cached https://files.pythonhosted.org/packages/7d/e3/20f3d364d6c8e5d2353c72a67778eb189176f08e873c9900e10c0287b84b/requests-2.21.0-py2.py3-none-any.whl
Collecting idna<2.9,>=2.5 (from requests->twder)
  Using cached https://files.pythonhosted.org/packages/14/2c/cd551d81dbe15200be1cf41cd03869a46fe7226e7450af7a6545bfc474c9/idna-2.8-py2.py3-none-any.whl
Collecting urllib3<1.25,>=1.21.1 (from requests->twder)
  Using cached https://files.pythonhosted.org/packages/62/00/ee1d7de624db8ba7090d1226aebefab96a2c71cd5cfa7629d6ad3f61b79e/urllib3-1.24.1-py2.py3-none-any.whl
Collecting certifi>=2017.4.17 (from requests->twder)
  Using cached https://files.pythonhosted.org/packages/60/75/f692a584e85b7eaba0e03827b3d51f45f571c2e793dd731e598828d380aa/certifi-2019.3.9-py2.py3-none-any.whl
Collecting chardet<3.1.0,>=3.0.2 (from requests->twder)
  Using cached https://files.pythonhosted.org/packages/bc/a9/01ffebfb562e4274b6487b4bb1ddec7ca55ec7510b22e4c51f14098443b8/chardet-3.0.4-py2.py3-none-any.whl
Building wheels for collected packages: lxml
  Running setup.py bdist_wheel for lxml ... |    (這部分跑很久, 要耐心等)
                                                                              done

  Stored in directory: /home/pi/.cache/pip/wheels/e4/d1/de/8e0e572dddb1a0e96c480b2a01ef9dbbc4fa86456cdd5a303a
Successfully built lxml
Installing collected packages: lxml, idna, urllib3, certifi, chardet, requests, twder


Successfully installed certifi-2019.3.9 chardet-3.0.4 idna-2.8 lxml-4.3.3 requests-2.21.0 twder-0.1.4 urllib3-1.24.1

安裝過程跑很久, 會讓人誤以為是當機了, 但只要耐心等待, 最後會顯示成功訊息. 其實還有一個做法是, 乾脆在 PyPi 網站下載原始程式來編譯會比較快  (注意, libxml2 與 libxslt 還是要先安裝, 再編譯 twder 原始碼) : 


pi@raspberrypi:~ $ wget  https://files.pythonhosted.org/packages/d9/f6/c8c8683aa1c3599d0168bb9476d94af43f0248c0be86b53e2c796614a120/twder-0.1.4.tar.gz  

下載的壓縮檔是 twder-0.1.4.tar.gz, 用 tar 解壓 : 

pi@raspberrypi:~ $ tar -xvf twder-0.1.4.tar.gz    
twder-0.1.4/
twder-0.1.4/PKG-INFO
twder-0.1.4/LICENSE
twder-0.1.4/requirements.txt
twder-0.1.4/MANIFEST.in
twder-0.1.4/README.md
twder-0.1.4/setup.py   
twder-0.1.4/setup.cfg   
twder-0.1.4/twder.egg-info/
twder-0.1.4/twder.egg-info/PKG-INFO
twder-0.1.4/twder.egg-info/SOURCES.txt
twder-0.1.4/twder.egg-info/requires.txt
twder-0.1.4/twder.egg-info/top_level.txt
twder-0.1.4/twder.egg-info/dependency_links.txt
twder-0.1.4/twder/
twder-0.1.4/twder/__init__.py
twder-0.1.4/twder/api.py

可見解壓後的目錄 twder-0.1.4 內有安裝程式 setup.py, 切換至此目錄, 用 sudo 執行安裝, 注意, 一定要用 sudo 安裝, 否則會有權限問題 :

pi@raspberrypi:~ $ cd twder-0.1.4   
pi@raspberrypi:~/twder-0.1.4 $ sudo python3 setup.py install        
/usr/lib/python3.5/distutils/dist.py:261: UserWarning: Unknown distribution option: 'long_description_content_type'
  warnings.warn(msg)
running install
running bdist_egg
running egg_info
writing top-level names to twder.egg-info/top_level.txt
writing twder.egg-info/PKG-INFO
writing dependency_links to twder.egg-info/dependency_links.txt
writing requirements to twder.egg-info/requires.txt
reading manifest file 'twder.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
writing manifest file 'twder.egg-info/SOURCES.txt'
installing library code to build/bdist.linux-armv7l/egg
running install_lib
running build_py
creating build/lib
creating build/lib/twder
copying twder/api.py -> build/lib/twder
copying twder/__init__.py -> build/lib/twder
creating build/bdist.linux-armv7l/egg
creating build/bdist.linux-armv7l/egg/twder
copying build/lib/twder/api.py -> build/bdist.linux-armv7l/egg/twder
copying build/lib/twder/__init__.py -> build/bdist.linux-armv7l/egg/twder
byte-compiling build/bdist.linux-armv7l/egg/twder/api.py to api.cpython-35.pyc
byte-compiling build/bdist.linux-armv7l/egg/twder/__init__.py to __init__.cpython-35.pyc
creating build/bdist.linux-armv7l/egg/EGG-INFO
copying twder.egg-info/PKG-INFO -> build/bdist.linux-armv7l/egg/EGG-INFO
copying twder.egg-info/SOURCES.txt -> build/bdist.linux-armv7l/egg/EGG-INFO
copying twder.egg-info/dependency_links.txt -> build/bdist.linux-armv7l/egg/EGG-INFO
copying twder.egg-info/requires.txt -> build/bdist.linux-armv7l/egg/EGG-INFO
copying twder.egg-info/top_level.txt -> build/bdist.linux-armv7l/egg/EGG-INFO
zip_safe flag not set; analyzing archive contents...
creating 'dist/twder-0.1.4-py3.5.egg' and adding 'build/bdist.linux-armv7l/egg' to it
removing 'build/bdist.linux-armv7l/egg' (and everything under it)
Processing twder-0.1.4-py3.5.egg
Copying twder-0.1.4-py3.5.egg to /usr/local/lib/python3.5/dist-packages
Adding twder 0.1.4 to easy-install.pth file

Installed /usr/local/lib/python3.5/dist-packages/twder-0.1.4-py3.5.egg
Processing dependencies for twder==0.1.4
Searching for requests==2.12.4
Best match: requests 2.12.4
Adding requests 2.12.4 to easy-install.pth file

Using /usr/lib/python3/dist-packages
Searching for lxml==3.7.1
Best match: lxml 3.7.1
Adding lxml 3.7.1 to easy-install.pth file

Using /usr/lib/python3/dist-packages
Finished processing dependencies for twder==0.1.4

Bingo! 終於搞定 twder 安裝了! 

接下來測試一下資料擷取功能 :

pi@raspberrypi:~ $ python3    
Python 3.5.3 (default, Sep 27 2018, 17:25:39)
[GCC 6.3.0 20170516] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import twder                             #匯入套件
>>> twder.currencies()                     #列出台銀可交易之外幣代號
['MYR', 'JPY', 'GBP', 'NZD', 'VND', 'ZAR', 'HKD', 'USD', 'CHF', 'KRW', 'SGD', 'IDR', 'CNY', 'CAD', 'AUD', 'EUR', 'SEK', 'THB', 'PHP']
>>> twder.currency_name_dict()    #列出台銀可交易之外幣代號
{'MYR': '馬來幣 (MYR)', 'JPY': '日圓 (JPY)', 'GBP': '英鎊 (GBP)', 'NZD': '紐元 (NZD)', 'VND': '越南盾 (VND)', 'ZAR': '南非幣 (ZAR)', 'HKD': '港幣 (HKD)', 'USD': '美金 (USD)', 'CHF': '瑞士法郎 (CHF)', 'KRW': '韓元 (KRW)', 'SGD': '新加坡幣 (SGD)', 'IDR': '印尼幣 (IDR)', 'CNY': '人民幣 (CNY)', 'CAD': '加拿大幣 (CAD)', 'AUD': '澳幣 (AUD)', 'EUR': '歐元 (EUR)', 'SEK': '瑞典幣 (SEK)', 'THB': '泰幣 (THB)', 'PHP': '菲國比索 (PHP)'}
>>> twder.now('USD')                      #查詢指定貨幣即時報價
('2019/04/08 16:00', '30.41', '31.1', '30.78', '30.88')
>>> twder.now_all()                          #查詢全部貨幣即時報價
{'MYR': ('2019/04/08 16:00', '6.426', '8.056', '-', '-'), 'JPY': ('2019/04/08 16:00', '0.2674', '0.2802', '0.2747', '0.2787'), 'GBP': ('2019/04/08 16:00', '39.06', '41.18', '40.06', '40.48'), 'SGD': ('2019/04/08 16:00', '22.16', '23.07', '22.65', '22.83'), 'IDR': ('2019/04/08 16:00', '0.00183', '0.00253', '-', '-'), 'NZD': ('2019/04/08 16:00', '20.29', '21.14', '20.67', '20.87'), 'CAD': ('2019/04/08 16:00', '22.55', '23.46', '22.94', '23.16'), 'KRW': ('2019/04/08 16:00', '0.02517', '0.02907', '-', '-'), 'ZAR': ('2019/04/08 16:00', '-', '-', '2.13', '2.21'), 'AUD': ('2019/04/08 16:00', '21.51', '22.29', '21.78', '22.01'), 'THB': ('2019/04/08 16:00', '0.8413', '1.0293', '0.9499', '0.9899'), 'CNY': ('2019/04/08 16:00', '4.489', '4.651', '4.561', '4.611'), 'HKD': ('2019/04/08 16:00', '3.761', '3.977', '3.897', '3.957'), 'EUR': ('2019/04/08 16:00', '33.8', '35.14', '34.42', '34.82'), 'PHP': ('2019/04/08 16:00', '0.5178', '0.6508', '-', '-'), 'USD': ('2019/04/08 16:00', '30.41', '31.1', '30.78', '30.88'), 'VND': ('2019/04/08 16:00', '0.00096', '0.00146', '-', '-'), 'CHF': ('2019/04/08 16:00', '30.03', '31.23', '30.69', '30.98'), 'SEK': ('2019/04/08 16:00', '2.93', '3.45', '3.27', '3.37')}
>>> twder.past_day('USD')              #查詢指定貨幣昨日全部報價
[('2019/04/08 09:00:50', '30.395', '31.085', '30.765', '30.865'), ('2019/04/08 09:05:23', '30.4', '31.09', '30.77', '30.87'), ('2019/04/08 09:14:08', '30.405', '31.095', '30.775', '30.875'), ('2019/04/08 09:25:06', '30.4', '31.09', '30.77', '30.87'), ('2019/04/08 09:34:23', '30.4', '31.09', '30.77', '30.87'), ('2019/04/08 09:35:29', '30.4', '31.09', '30.77', '30.87'), ('2019/04/08 09:41:51', '30.4', '31.09', '30.77', '30.87'), ('2019/04/08 09:47:12', '30.395', '31.085', '30.765', '30.865'), ('2019/04/08 09:57:28', '30.395', '31.085', '30.765', '30.865'), ('2019/04/08 10:00:25', '30.4', '31.09', '30.77', '30.87'), ('2019/04/08 10:02:58', '30.4', '31.09', '30.77', '30.87'), ('2019/04/08 10:10:48', '30.4', '31.09', '30.77', '30.87'), ('2019/04/08 10:15:11', '30.4', '31.09', '30.77', '30.87'), ('2019/04/08 10:16:55', '30.4', '31.09', '30.77', '30.87'), ('2019/04/08 10:18:39', '30.405', '31.095', '30.775', '30.875'), ('2019/04/08 10:23:17', '30.405', '31.095', '30.775', '30.875'), ('2019/04/08 10:25:13', '30.4', '31.09', '30.77', '30.87'), ('2019/04/08 10:32:03', '30.4', '31.09', '30.77', '30.87'), ('2019/04/08 10:32:37', '30.4', '31.09', '30.77', '30.87'), ('2019/04/08 10:35:07', '30.4', '31.09', '30.77', '30.87'), ('2019/04/08 10:54:25', '30.4', '31.09', '30.77', '30.87'), ('2019/04/08 10:55:51', '30.4', '31.09', '30.77', '30.87'), ('2019/04/08 11:03:38', '30.395', '31.085', '30.765', '30.865'), ('2019/04/08 11:10:30', '30.4', '31.09', '30.77', '30.87'), ('2019/04/08 11:14:39', '30.4', '31.09', '30.77', '30.87'), ('2019/04/08 11:20:59', '30.4', '31.09', '30.77', '30.87'), ('2019/04/08 11:26:03', '30.395', '31.085', '30.765', '30.865'), ('2019/04/08 11:27:28', '30.395', '31.085', '30.765', '30.865'), ('2019/04/08 11:32:35', '30.395', '31.085', '30.765', '30.865'), ('2019/04/08 11:35:21', '30.395', '31.085', '30.765', '30.865'), ('2019/04/08 11:45:02', '30.4', '31.09', '30.77', '30.87'), ('2019/04/08 11:57:11', '30.4', '31.09', '30.77', '30.87'), ('2019/04/08 12:21:05', '30.4', '31.09', '30.77', '30.87'), ('2019/04/08 12:39:39', '30.4', '31.09', '30.77', '30.87'), ('2019/04/08 12:46:18', '30.405', '31.095', '30.775', '30.875'), ('2019/04/08 12:58:35', '30.405', '31.095', '30.775', '30.875'), ('2019/04/08 13:14:20', '30.405', '31.095', '30.775', '30.875'), ('2019/04/08 13:43:19', '30.405', '31.095', '30.775', '30.875'), ('2019/04/08 13:59:57', '30.405', '31.095', '30.775', '30.875'), ('2019/04/08 14:00:42', '30.405', '31.095', '30.775', '30.875'), ('2019/04/08 14:23:52', '30.405', '31.095', '30.775', '30.875'), ('2019/04/08 14:25:16', '30.41', '31.1', '30.78', '30.88'), ('2019/04/08 14:33:11', '30.405', '31.095', '30.775', '30.875'), ('2019/04/08 15:03:18', '30.405', '31.095', '30.775', '30.875'), ('2019/04/08 15:12:05', '30.41', '31.1', '30.78', '30.88'), ('2019/04/08 15:32:12', '30.41', '31.1', '30.78', '30.88'), ('2019/04/08 15:39:11', '30.41', '31.1', '30.78', '30.88'), ('2019/04/08 15:42:54', '30.415', '31.105', '30.785', '30.885'), ('2019/04/08 16:00:10', '30.41', '31.1', '30.78', '30.88')]
>>> twder.past_six_month('USD')    #查詢指定貨幣近半年收盤價
[('2019/04/08', '30.41', '31.1', '30.78', '30.88'), ('2019/04/03', '30.39', '31.08', '30.76', '30.86'), ('2019/04/02', '30.415', '31.105', '30.785', '30.885'), ('2019/04/01', '30.375', '31.065', '30.745', '30.845'), ('2019/03/29', '30.4', '31.09', '30.77', '30.87'), ('2019/03/28', '30.425', '31.115', '30.795', '30.895'), ('2019/03/27', '30.43', '31.12', '30.8', '30.9'), ('2019/03/26', '30.41', '31.1', '30.78', '30.88'), ('2019/03/25', '30.4', '31.09', '30.77', '30.87'), ('2019/03/22', '30.375', '31.065', '30.745', '30.845'), ('2019/03/21', '30.39', '31.08', '30.76', '30.86'), ('2019/03/20', '30.41', '31.1', '30.78', '30.88'), ('2019/03/19', '30.41', '31.1', '30.78', '30.88'), ('2019/03/18', '30.41', '31.1', '30.78', '30.88'), ('2019/03/15', '30.455', '31.145', '30.825', '30.925'), ('2019/03/14', '30.47', '31.16', '30.84', '30.94'), ('2019/03/13', '30.48', '31.17', '30.85', '30.95'), ('2019/03/12', '30.48', '31.17', '30.85', '30.95'), ('2019/03/11', '30.48', '31.17', '30.85', '30.95'), ('2019/03/08', '30.475', '31.165', '30.845', '30.945'), ('2019/03/07', '30.445', '31.135', '30.815', '30.915'), ('2019/03/06', '30.425', '31.115', '30.795', '30.895'), ('2019/03/05', '30.42', '31.11', '30.79', '30.89'), ('2019/03/04', '30.4', '31.09', '30.77', '30.87'), ('2019/02/27', '30.35', '31.04', '30.72', '30.82'), ('2019/02/26', '30.36', '31.05', '30.73', '30.83'), ('2019/02/25', '30.37', '31.06', '30.74', '30.84'), ('2019/02/23', '30.4', '31.09', '30.77', '30.87'), ('2019/02/22', '30.4', '31.09', '30.77', '30.87'), ('2019/02/21', '30.405', '31.095', '30.775', '30.875'), ('2019/02/20', '30.405', '31.095', '30.775', '30.875'), ('2019/02/19', '30.415', '31.105', '30.785', '30.885'), ('2019/02/18', '30.42', '31.11', '30.79', '30.89'), ('2019/02/15', '30.43', '31.12', '30.8', '30.9'), ('2019/02/14', '30.41', '31.1', '30.78', '30.88'), ('2019/02/13', '30.41', '31.1', '30.78', '30.88'), ('2019/02/12', '30.41', '31.1', '30.78', '30.88'), ('2019/02/11', '30.38', '31.07', '30.75', '30.85'), ('2019/02/01', '30.315', '31.005', '30.685', '30.785'), ('2019/01/31', '30.315', '31.005', '30.685', '30.785'), ('2019/01/30', '30.34', '31.03', '30.71', '30.81'), ('2019/01/29', '30.39', '31.08', '30.76', '30.86'), ('2019/01/28', '30.37', '31.06', '30.74', '30.84'), ('2019/01/25', '30.4', '31.09', '30.77', '30.87'), ('2019/01/24', '30.46', '31.15', '30.83', '30.93'), ('2019/01/23', '30.47', '31.16', '30.84', '30.94'), ('2019/01/22', '30.47', '31.16', '30.84', '30.94'), ('2019/01/21', '30.425', '31.115', '30.795', '30.895'), ('2019/01/19', '30.415', '31.105', '30.785', '30.885'), ('2019/01/18', '30.42', '31.11', '30.79', '30.89'), ('2019/01/17', '30.425', '31.115', '30.795', '30.895'), ('2019/01/16', '30.405', '31.095', '30.775', '30.875'), ('2019/01/15', '30.395', '31.085', '30.765', '30.865'), ('2019/01/14', '30.42', '31.11', '30.79', '30.89'), ('2019/01/11', '30.375', '31.065', '30.745', '30.845'), ('2019/01/10', '30.36', '31.05', '30.73', '30.83'), ('2019/01/09', '30.375', '31.065', '30.745', '30.845'), ('2019/01/08', '30.415', '31.105', '30.785', '30.885'), ('2019/01/07', '30.385', '31.075', '30.755', '30.855'), ('2019/01/04', '30.435', '31.125', '30.805', '30.905'), ('2019/01/03', '30.455', '31.145', '30.825', '30.925'), ('2019/01/02', '30.365', '31.055', '30.735', '30.835'), ('2018/12/28', '30.295', '30.985', '30.665', '30.765'), ('2018/12/27', '30.37', '31.06', '30.74', '30.84'), ('2018/12/26', '30.39', '31.08', '30.76', '30.86'), ('2018/12/25', '30.38', '31.07', '30.75', '30.85'), ('2018/12/24', '30.41', '31.1', '30.78', '30.88'), ('2018/12/22', '30.4', '31.09', '30.77', '30.87'), ('2018/12/21', '30.375', '31.065', '30.745', '30.845'), ('2018/12/20', '30.41', '31.1', '30.78', '30.88'), ('2018/12/19', '30.385', '31.075', '30.755', '30.855'), ('2018/12/18', '30.44', '31.13', '30.81', '30.91'), ('2018/12/17', '30.445', '31.135', '30.815', '30.915'), ('2018/12/14', '30.435', '31.125', '30.805', '30.905'), ('2018/12/13', '30.42', '31.11', '30.79', '30.89'), ('2018/12/12', '30.445', '31.135', '30.815', '30.915'), ('2018/12/11', '30.47', '31.16', '30.84', '30.94'), ('2018/12/10', '30.445', '31.135', '30.815', '30.915'), ('2018/12/07', '30.41', '31.1', '30.78', '30.88'), ('2018/12/06', '30.42', '31.11', '30.79', '30.89'), ('2018/12/05', '30.38', '31.07', '30.75', '30.85'), ('2018/12/04', '30.28', '30.97', '30.65', '30.75'), ('2018/12/03', '30.31', '31', '30.68', '30.78'), ('2018/11/30', '30.41', '31.1', '30.78', '30.88'), ('2018/11/29', '30.41', '31.1', '30.78', '30.88'), ('2018/11/28', '30.48', '31.17', '30.85', '30.95'), ('2018/11/27', '30.47', '31.16', '30.84', '30.94'), ('2018/11/26', '30.455', '31.145', '30.825', '30.925'), ('2018/11/23', '30.475', '31.165', '30.845', '30.945'), ('2018/11/22', '30.465', '31.155', '30.835', '30.935'), ('2018/11/21', '30.465', '31.155', '30.835', '30.935'), ('2018/11/20', '30.48', '31.17', '30.85', '30.95'), ('2018/11/19', '30.48', '31.17', '30.85', '30.95'), ('2018/11/16', '30.465', '31.155', '30.835', '30.935'), ('2018/11/15', '30.42', '31.11', '30.79', '30.89'), ('2018/11/14', '30.49', '31.18', '30.86', '30.96'), ('2018/11/13', '30.475', '31.165', '30.845', '30.945'), ('2018/11/12', '30.46', '31.15', '30.83', '30.93'), ('2018/11/09', '30.38', '31.07', '30.75', '30.85'), ('2018/11/08', '30.275', '30.965', '30.645', '30.745'), ('2018/11/07', '30.33', '31.02', '30.7', '30.8'), ('2018/11/06', '30.35', '31.04', '30.72', '30.82'), ('2018/11/05', '30.335', '31.025', '30.705', '30.805'), ('2018/11/02', '30.3', '30.99', '30.67', '30.77'), ('2018/11/01', '30.495', '31.185', '30.865', '30.965'), ('2018/10/31', '30.535', '31.225', '30.905', '31.005'), ('2018/10/30', '30.555', '31.245', '30.925', '31.025'), ('2018/10/29', '30.57', '31.26', '30.94', '31.04'), ('2018/10/26', '30.575', '31.265', '30.945', '31.045'), ('2018/10/25', '30.565', '31.255', '30.935', '31.035'), ('2018/10/24', '30.52', '31.21', '30.89', '30.99'), ('2018/10/23', '30.54', '31.23', '30.91', '31.01'), ('2018/10/22', '30.495', '31.185', '30.865', '30.965'), ('2018/10/19', '30.53', '31.22', '30.9', '31'), ('2018/10/18', '30.53', '31.22', '30.9', '31'), ('2018/10/17', '30.41', '31.1', '30.78', '30.88'), ('2018/10/16', '30.485', '31.175', '30.855', '30.955'), ('2018/10/15', '30.5', '31.19', '30.87', '30.97'), ('2018/10/12', '30.44', '31.13', '30.81', '30.91'), ('2018/10/11', '30.68', '31.37', '31.05', '31.15')]
>>> twder.specify_month('USD', 2018, 10)  #查詢指定月份收盤價
[('2018/10/31', '30.535', '31.225', '30.905', '31.005'), ('2018/10/30', '30.555', '31.245', '30.925', '31.025'), ('2018/10/29', '30.57', '31.26', '30.94', '31.04'), ('2018/10/26', '30.575', '31.265', '30.945', '31.045'), ('2018/10/25', '30.565', '31.255', '30.935', '31.035'), ('2018/10/24', '30.52', '31.21', '30.89', '30.99'), ('2018/10/23', '30.54', '31.23', '30.91', '31.01'), ('2018/10/22', '30.495', '31.185', '30.865', '30.965'), ('2018/10/19', '30.53', '31.22', '30.9', '31'), ('2018/10/18', '30.53', '31.22', '30.9', '31'), ('2018/10/17', '30.41', '31.1', '30.78', '30.88'), ('2018/10/16', '30.485', '31.175', '30.855', '30.955'), ('2018/10/15', '30.5', '31.19', '30.87', '30.97'), ('2018/10/12', '30.44', '31.13', '30.81', '30.91'), ('2018/10/11', '30.68', '31.37', '31.05', '31.15'), ('2018/10/09', '30.54', '31.23', '30.91', '31.01'), ('2018/10/08', '30.505', '31.195', '30.875', '30.975'), ('2018/10/05', '30.405', '31.095', '30.775', '30.875'), ('2018/10/04', '30.36', '31.05', '30.73', '30.83'), ('2018/10/03', '30.24', '30.93', '30.61', '30.71'), ('2018/10/02', '30.245', '30.935', '30.615', '30.715'), ('2018/10/01', '30.11', '30.8', '30.48', '30.58')]

嗯, 大功告成!

總結以上經驗, 樹莓派安裝 twder 的程序是 :

sudo apt-get install libxml2-dev libxslt-dev   (相依套件)
pip3 install twder    (比較久)

或安裝好 libxml2 與 libxslt 後編譯 twder 原始碼 :

wget  https://files.pythonhosted.org/packages/d9/f6/c8c8683aa1c3599d0168bb9476d94af43f0248c0be86b53e2c796614a120/twder-0.1.4.tar.gz     (下載原始碼)
tar -xvf twder-0.1.4.tar.gz           (解壓縮)
cd twder-0.1.4                              (切換目錄)
sudo python3 setup.py install     (安裝) 

2019年4月9日 星期二

R 語言學習筆記索引

R 語言之前是機器學習的好物, 但這兩年熱度被 Python 超越, 我對 R 的熱情似乎也冷了下來. 其實 R 是 Python 很好的兄弟, 有些用 Python 較麻煩的地方, 用 R 就很輕易解決了. 目前已整理的學習筆記如下 :

R 語言安裝
在樹莓派上安裝 R 語言
R 語言學習筆記 (一) : 基本語法與向量
R 語言學習筆記 (二) : 矩陣
R 語言學習筆記 (三) : 陣列
R 語言學習筆記 (四) : 因子
# R 語言學習筆記 (六) : 串列
# R 語言學習筆記 (七) : 日期時間
# R 語言學習筆記 (八) : 函數
# R 語言學習筆記 (九) : 檔案處理
# R 語言學習筆記 (十) : 套件

~ 進行中 ~

Node.js 學習筆記索引

Node.js 是我非常喜歡的技術, 我原本要用它來作為樹莓派的後台, 雖然最終選擇了 Python, 但以後還是會在一台樹莓派上佈署 Node.js 的, 目前先將學習筆記做成索引如下 :

關於 Node.js
如何更新樹莓派的 Node.js
# Node.js 學習筆記 (一) : 安裝 Node.js
Node.js 學習筆記 (二) : console 模組 (控制台) 測試
Node.js 學習筆記 (三) : 檔案模組 fs 測試
樹莓派 NodeJS 升版為 11.3.0 版
Node.js 學習筆記 (四) : http 模組測試
Node.js 學習筆記 : 套件管理工具 npm

~ 未完 ~

2019年4月8日 星期一

MicroPython on ESP8266 學習筆記索引

我最愛的 MicroPython + ESP8266/ESP32 是物聯網最棒的組合, 我投注在 MicroPython 的心力遠比 Arduino 還多 (原因是我的 C 程式能力較弱). 茲將目前已做過的 MicroPython 實驗筆記索引如後 :

MicroPython on ESP8266 (一) : 燒錄韌體
MicroPython on ESP8266 (二) : 數值型別測試
MicroPython on ESP8266 (三) : 序列型別測試
MicroPython on ESP8266 (四) : 字典與集合型別測試
MicroPython on ESP8266 (五) : WiFi 連線與 WebREPL 測試
MicroPython on ESP8266 (六) : 檔案系統測試
MicroPython on ESP8266 (七) : 時間日期測試
MicroPython on ESP8266 (八) : GPIO 測試
MicroPython on ESP8266 (九) : PIR 紅外線移動偵測
MicroPython v1.9.1 版韌體測試
MicroPython on ESP8266 (十) : socket 模組測試
MicroPython on ESP8266 (十一) : urllib.urequest 模組測試
MicroPython on ESP8266 (十二) : urequests 模組測試
MicroPython on ESP8266 (十三) : DHT11 溫溼度感測器測試
MicroPython 使用 ampy 突然無法上傳檔案問題
MicroPython on ESP8266 (十四) : 網頁伺服器測試
WeMOS D1 Mini 開發板測試
MicroPython on ESP8266 (十五) : 光敏電阻與 ADC 測試
MicroPython on ESP8266 (十六) : 蜂鳴器測試
MicroPython on ESP8266 (十七) : 液晶顯示器 1602A 測試
MicroPython on ESP8266 (十八) : SSD1306 液晶顯示器測試
MicroPython v1.9.2 版釋出
MicroPython on ESP8266 (十九) : 太陽能測候站與移動偵測控制照明
MicroPython on ESP8266 (二十) : 從 ThingSpeak 讀取資料
MicroPython on ESP8266 (二十一) : 使用 ThingTweet 傳送推文
MicroPython on ESP8266 (二十二) : UART 串列埠測試
MicroPython on ESP8266 (二十三) : 超音波模組 HC-SR04 測試
MicroPython on ESP8266 (二十四) : 掃描無線基地台 (AP)
MicroPython on ESP8266 的看門狗 WDT 無法設定時限問題
使用 Arduino IDE 開發 ESP8266 應用 (一) : 環境設定與韌體上傳 (暫寄)
使用 Arduino IDE 開發 ESP8266 應用 (二) : 在網頁上控制 LED (暫寄)

樹莓派安裝 twstock 套件

今天嘗試在鄉下的樹莓派 Pi3 上安裝台股資料擷取套件 twstock, 以前只在 PC 上安裝測試過都很順利, 參考 :

Python 學習筆記 : 台股資料擷取模組 twstock 測試 (一)
Python 學習筆記 : 台股資料擷取模組 twstock 測試 (二)
Python 學習筆記 : 台股資料擷取模組 twstock 測試 (三)

twstock 目前是 1.2.1 版, 我下載 ARM 版 whl 檔後放在 Dropbox 備份 :

https://www.dropbox.com/s/6v0v5uhdv0o7u29/twstock-1.2.1-py3-none-any.whl?dl=0

安裝過程出乎意料非常順利, 只要用 pip3 安裝即可 :


1. 安裝 twstock (成功) :

pi@raspberrypi:~ $ pip3 install twstock 
Collecting twstock
  Downloading https://files.pythonhosted.org/packages/a2/82/5c37e9cf30322845a3a39e05d01f8300adcec27a32095865637b486beacd/twstock-1.2.1-py3-none-any.whl (1.9MB)

Collecting requests (from twstock)
  Downloading https://files.pythonhosted.org/packages/7d/e3/20f3d364d6c8e5d2353c72a67778eb189176f08e873c9900e10c0287b84b/requests-2.21.0-py2.py3-none-any.whl (57kB)

Collecting chardet<3.1.0,>=3.0.2 (from requests->twstock)
  Downloading https://files.pythonhosted.org/packages/bc/a9/01ffebfb562e4274b6487b4bb1ddec7ca55ec7510b22e4c51f14098443b8/chardet-3.0.4-py2.py3-none-any.whl (133kB)

Collecting urllib3<1.25,>=1.21.1 (from requests->twstock)
  Downloading https://files.pythonhosted.org/packages/62/00/ee1d7de624db8ba7090d1226aebefab96a2c71cd5cfa7629d6ad3f61b79e/urllib3-1.24.1-py2.py3-none-any.whl (118kB)

Collecting certifi>=2017.4.17 (from requests->twstock)
  Downloading https://files.pythonhosted.org/packages/60/75/f692a584e85b7eaba0e03827b3d51f45f571c2e793dd731e598828d380aa/certifi-2019.3.9-py2.py3-none-any.whl (158kB)

Collecting idna<2.9,>=2.5 (from requests->twstock)
  Downloading https://files.pythonhosted.org/packages/14/2c/cd551d81dbe15200be1cf41cd03869a46fe7226e7450af7a6545bfc474c9/idna-2.8-py2.py3-none-any.whl (58kB)

Installing collected packages: chardet, urllib3, certifi, idna, requests, twstock
Successfully installed certifi-2019.3.9 chardet-3.0.4 idna-2.8 requests-2.21.0 twstock-1.2.1 urllib3-1.24.1

可見 twstock 有五個相依模組 : chardet, urllib3, certifi, idna, requests.

但匯入 twstock 卻出現錯誤 : 

pi@raspberrypi:~ $ python3   
Python 3.5.3 (default, Sep 27 2018, 17:25:39)
[GCC 6.3.0 20170516] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from twstock import Stock    
Traceback (most recent call last):
  File "/home/pi/.local/lib/python3.5/site-packages/twstock/stock.py", line 15, in <module>
    from .codes import codes
  File "/home/pi/.local/lib/python3.5/site-packages/twstock/codes/__init__.py", line 1, in <module>
    from .fetch import __update_codes
  File "/home/pi/.local/lib/python3.5/site-packages/twstock/codes/fetch.py", line 14, in <module>
    from lxml import etree
ImportError: No module named 'lxml'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/pi/.local/lib/python3.5/site-packages/twstock/__init__.py", line 3, in <module>
    from twstock import stock
  File "/home/pi/.local/lib/python3.5/site-packages/twstock/stock.py", line 17, in <module>
    import analytics
ImportError: No module named 'analytics'

可見還缺 lxml 與 analytics 這兩個套件, 先安裝 analytics :


2. 安裝 analytics (成功) :

pi@raspberrypi:~ $ pip3 install analytics    
Collecting analytics
Collecting redis>=2.7.2 (from analytics)

Collecting nydus>=0.10.6 (from analytics)
Collecting python-dateutil==1.5 (from analytics)

Installing collected packages: redis, nydus, python-dateutil, analytics
Successfully installed analytics-0.6.5 nydus-0.11.0 python-dateutil-1.5 redis-3.2.1  

可見 analytics 又還有 4 個相依套件.


3. 用 pip3 安裝 lxml (失敗) :

接下來補安裝 lxml, 結果失敗 :

pi@raspberrypi:~ $ pip3 install lxml
Collecting lxml
  Downloading https://files.pythonhosted.org/packages/7d/29/174d70f303016c58bd790c6c86e6e86a9d18239fac314d55a9b7be501943/lxml-4.3.3.tar.gz (4.4MB)
Building wheels for collected packages: lxml
  Running setup.py bdist_wheel for lxml ... error
  Complete output from command /usr/bin/python3 -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-6h5wkzuy/lxml/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" bdist_wheel -d /tmp/tmpoy7tokj1pip-wheel- --python-tag cp35:
  Building lxml version 4.3.3.
  Building without Cython.
  ERROR: b'/bin/sh: 1: xslt-config: not found\n'
  ** make sure the development packages of libxml2 and libxslt are installed **
  Using build configuration of libxslt
  running bdist_wheel
  running build
  running build_py
  creating build
  creating build/lib.linux-armv7l-3.5
  creating build/lib.linux-armv7l-3.5/lxml
  ....... (略) .......
  building 'lxml.etree' extension
  creating build/temp.linux-armv7l-3.5
  creating build/temp.linux-armv7l-3.5/src
  creating build/temp.linux-armv7l-3.5/src/lxml
  arm-linux-gnueabihf-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -g -fdebug-prefix-map=/build/python3.5-6waWnr/python3.5-3.5.3=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -DCYTHON_CLINE_IN_TRACEBACK=0 -Isrc -Isrc/lxml/includes -I/usr/include/python3.5m -c src/lxml/etree.c -o build/temp.linux-armv7l-3.5/src/lxml/etree.o -w
  In file included from src/lxml/etree.c:687:0:
  src/lxml/includes/etree_defs.h:14:31: fatal error: libxml/xmlversion.h: 沒有此一檔案或目錄
   #include "libxml/xmlversion.h"
                                 ^
  compilation terminated.
  Compile failed: command 'arm-linux-gnueabihf-gcc' failed with exit status 1
  creating tmp
  cc -I/usr/include/libxml2 -c /tmp/xmlXPathInits6b7t0q3.c -o tmp/xmlXPathInits6b7t0q3.o
  /tmp/xmlXPathInits6b7t0q3.c:1:26: fatal error: libxml/xpath.h: 沒有此一檔案或目錄
   #include "libxml/xpath.h"
                            ^
  compilation terminated.
  *********************************************************************************
  Could not find function xmlCheckVersion in library libxml2. Is libxml2 installed?
  *********************************************************************************
  error: command 'arm-linux-gnueabihf-gcc' failed with exit status 1

  ----------------------------------------
  Failed building wheel for lxml
  Running setup.py clean for lxml
Failed to build lxml
Installing collected packages: lxml
  Running setup.py install for lxml ... error
    Complete output from command /usr/bin/python3 -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-6h5wkzuy/lxml/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record /tmp/pip-b8h0w1ek-record/install-record.txt --single-version-externally-managed --compile --user --prefix=:
    Building lxml version 4.3.3.
    Building without Cython.
    ERROR: b'/bin/sh: 1: xslt-config: not found\n'
    ** make sure the development packages of libxml2 and libxslt are installed **

    Using build configuration of libxslt
    running install
    running build
    running build_py
    creating build
    creating build/lib.linux-armv7l-3.5
    creating build/lib.linux-armv7l-3.5/lxml
  ....... (略) .......
    running build_ext
    building 'lxml.etree' extension
    creating build/temp.linux-armv7l-3.5
    creating build/temp.linux-armv7l-3.5/src
    creating build/temp.linux-armv7l-3.5/src/lxml
    arm-linux-gnueabihf-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -g -fdebug-prefix-map=/build/python3.5-6waWnr/python3.5-3.5.3=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -DCYTHON_CLINE_IN_TRACEBACK=0 -Isrc -Isrc/lxml/includes -I/usr/include/python3.5m -c src/lxml/etree.c -o build/temp.linux-armv7l-3.5/src/lxml/etree.o -w
    In file included from src/lxml/etree.c:687:0:
    src/lxml/includes/etree_defs.h:14:31: fatal error: libxml/xmlversion.h: 沒有此一檔案或目錄
     #include "libxml/xmlversion.h"
                                   ^
    compilation terminated.
    Compile failed: command 'arm-linux-gnueabihf-gcc' failed with exit status 1
    cc -I/usr/include/libxml2 -c /tmp/xmlXPathInit6reid1bf.c -o tmp/xmlXPathInit6reid1bf.o
    /tmp/xmlXPathInit6reid1bf.c:1:26: fatal error: libxml/xpath.h: 沒有此一檔案或目錄
     #include "libxml/xpath.h"
                              ^
    compilation terminated.
    *********************************************************************************
    Could not find function xmlCheckVersion in library libxml2. Is libxml2 installed?
    *********************************************************************************
    error: command 'arm-linux-gnueabihf-gcc' failed with exit status 1

    ----------------------------------------
Command "/usr/bin/python3 -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-6h5wkzuy/lxml/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record /tmp/pip-b8h0w1ek-record/install-record.txt --single-version-externally-managed --compile --user --prefix=" failed with error code 1 in /tmp/pip-build-6h5wkzuy/lxml/

似乎是編譯時出錯, 但密密麻麻不知從何查起. 搜尋 "raspberry pi 3 lxml" 找到下面這篇 : 


從回應中得知安裝 lxml 最簡單的方法是用下面的指令 :


3. 用 apt-get install 安裝 python3-lxml (成功) :

sudo apt-get install python3-lxml python-lxml  (其實只要 python3-lxml 即可)

pi@raspberrypi:~ $ sudo apt-get install python3-lxml python-lxml 
正在讀取套件清單... 完成
正在重建相依關係
正在讀取狀態資料... 完成
下列的額外套件將被安裝:
  python-bs4 python-html5lib python-webencodings python3-bs4 python3-html5lib
  python3-webencodings
建議套件:
  python-genshi python-lxml-dbg python-lxml-doc python3-genshi
  python3-lxml-dbg
下列【新】套件將會被安裝:
  python-bs4 python-html5lib python-lxml python-webencodings python3-bs4
  python3-html5lib python3-lxml python3-webencodings
升級 0 個,新安裝 8 個,移除 0 個,有 0 個未被升級。
需要下載 1,954 kB 的套件檔。
此操作完成之後,會多佔用 8,187 kB 的磁碟空間。
是否繼續進行 [Y/n]? [Y/n] Y
下載:1 http://mirror.ossplanet.net/raspbian/raspbian stretch/main armhf python-bs4 all 4.5.3-1 [86.7 kB]
下載:2 http://mirror.ossplanet.net/raspbian/raspbian stretch/main armhf python-webencodings all 0.5-2 [10.3 kB]
下載:3 http://mirror.ossplanet.net/raspbian/raspbian stretch/main armhf python-html5lib all 0.999999999-1 [88.0 kB]
下載:4 http://mirror.ossplanet.net/raspbian/raspbian stretch/main armhf python-lxml armhf 3.7.1-1 [793 kB]
下載:5 http://mirror.ossplanet.net/raspbian/raspbian stretch/main armhf python3-bs4 all 4.5.3-1 [86.6 kB]
下載:6 http://mirror.ossplanet.net/raspbian/raspbian stretch/main armhf python3-webencodings all 0.5-2 [10.4 kB]
下載:7 http://mirror.ossplanet.net/raspbian/raspbian stretch/main armhf python3-html5lib all 0.999999999-1 [86.3 kB]
下載:8 http://mirror.ossplanet.net/raspbian/raspbian stretch/main armhf python3-lxml armhf 3.7.1-1 [792 kB]
取得 1,954 kB 用了 9s (200 kB/s)
選取了原先未選的套件 python-bs4。
(讀取資料庫 ... 目前共安裝了 133437 個檔案和目錄。)
Preparing to unpack .../0-python-bs4_4.5.3-1_all.deb ...
Unpacking python-bs4 (4.5.3-1) ...
選取了原先未選的套件 python-webencodings。
Preparing to unpack .../1-python-webencodings_0.5-2_all.deb ...
Unpacking python-webencodings (0.5-2) ...
選取了原先未選的套件 python-html5lib。
Preparing to unpack .../2-python-html5lib_0.999999999-1_all.deb ...
Unpacking python-html5lib (0.999999999-1) ...
選取了原先未選的套件 python-lxml。
Preparing to unpack .../3-python-lxml_3.7.1-1_armhf.deb ...
Unpacking python-lxml (3.7.1-1) ...
選取了原先未選的套件 python3-bs4。
Preparing to unpack .../4-python3-bs4_4.5.3-1_all.deb ...
Unpacking python3-bs4 (4.5.3-1) ...
選取了原先未選的套件 python3-webencodings。
Preparing to unpack .../5-python3-webencodings_0.5-2_all.deb ...
Unpacking python3-webencodings (0.5-2) ...
選取了原先未選的套件 python3-html5lib。
Preparing to unpack .../6-python3-html5lib_0.999999999-1_all.deb ...
Unpacking python3-html5lib (0.999999999-1) ...
選取了原先未選的套件 python3-lxml。
Preparing to unpack .../7-python3-lxml_3.7.1-1_armhf.deb ...
Unpacking python3-lxml (3.7.1-1) ...
設定 python3-webencodings (0.5-2) ...
設定 python3-lxml (3.7.1-1) ...
設定 python3-bs4 (4.5.3-1) ...
設定 python-bs4 (4.5.3-1) ...
設定 python3-html5lib (0.999999999-1) ...
設定 python-lxml (3.7.1-1) ...
設定 python-webencodings (0.5-2) ...
設定 python-html5lib (0.999999999-1) ...

可見連 bs4, htmlib 等套件都順便安裝了. 


5. 匯入 twstock 擷取資料 :

經過以上處理 twstock 才算完整安裝完畢, 即可順利匯入套件進行資料擷取了, 以 2019/04/08 盤後為例 :

pi@raspberrypi:~ $ python3
Python 3.5.3 (default, Sep 27 2018, 17:25:39)
[GCC 6.3.0 20170516] on linux
Type "help", "copyright", "credits" or "license" for more information.
&glt;&glt;&glt; from twstock import Stock   
&glt;&glt;&glt; tw2330=Stock("2330")     #擷取台積電 2330 近 31 日資料
&glt;&glt;&glt; tw2330.price           #近 31 日收盤價
[229.0, 234.5, 236.5, 236.5, 238.0, 239.5, 239.0, 235.5, 233.0, 234.0, 234.0, 230.0, 230.5, 235.5, 237.0, 234.5, 239.0, 241.0, 240.5, 242.0, 245.5, 248.5, 241.5, 244.0, 241.5, 242.0, 245.5, 245.5, 246.0, 246.5, 253.0]
&glt;&glt;&glt; tw2330.price[0]       #近 1 日收盤價
229.0
&glt;&glt;&glt; tw2330.price[30]     #31 前收盤價
253.0
&glt;&glt;&glt; tw2330.price[-5:]     #近 5 日收盤價
[245.5, 245.5, 246.0, 246.5, 253.0]
&glt;&glt;&glt; tw2330.close             #近 31 日收盤價
[229.0, 234.5, 236.5, 236.5, 238.0, 239.5, 239.0, 235.5, 233.0, 234.0, 234.0, 230.0, 230.5, 235.5, 237.0, 234.5, 239.0, 241.0, 240.5, 242.0, 245.5, 248.5, 241.5, 244.0, 241.5, 242.0, 245.5, 245.5, 246.0, 246.5, 253.0]
&glt;&glt;&glt; tw2330.change         #近 31 日漲跌幅 (元)
[-1.0, 5.5, 2.0, 0.0, 1.5, 1.5, -0.5, -3.5, -2.5, 1.0, 0.0, -4.0, 0.5, 5.0, 1.5, -2.5, 4.5, 2.0, -0.5, 1.5, 3.5, 3.0, -7.0, 2.5, -2.5, 0.5, 3.5, 0.0, 0.5, 0.5, 6.5]
&glt;&glt;&glt; tw2330.open             #近 31 日開盤價
[230.0, 231.5, 235.5, 235.5, 237.5, 239.0, 238.5, 239.5, 234.0, 235.0, 235.0, 231.0, 228.0, 233.0, 234.0, 239.0, 237.0, 239.5, 239.0, 242.0, 242.5, 248.0, 240.5, 243.0, 242.0, 240.5, 243.0, 251.0, 249.5, 249.0, 251.0]
&glt;&glt;&glt; tw2330.low               #近 31 日最低價
[229.0, 231.0, 234.5, 234.0, 236.0, 236.5, 237.0, 234.5, 232.5, 233.5, 233.0, 229.0, 227.5, 232.5, 234.0, 234.0, 235.5, 239.0, 238.0, 239.5, 241.0, 244.5, 240.5, 241.0, 240.5, 240.0, 240.5, 245.0, 246.0, 246.5, 250.5]
&glt;&glt;&glt; tw2330.high              #近 31 日最高價
[230.5, 234.5, 236.5, 236.5, 239.0, 240.0, 239.5, 239.5, 234.5, 235.5, 235.0, 231.5, 230.5, 237.0, 237.0, 239.0, 239.5, 241.0, 240.5, 242.0, 245.5, 248.5, 243.5, 244.0, 242.5, 242.5, 245.5, 251.0, 249.5, 249.0, 253.0]
&glt;&glt;&glt; tw2330.capacity        #近 31 日成交股數
[18423023, 31887710, 34013489, 22032163, 25227138, 24586789, 37947889, 45164513, 23708407, 20811226, 17226192, 22535659, 34282793, 23839972, 22493195, 17281356, 34542729, 27040532, 14620009, 23055971, 27514502, 22996467, 19273254, 21053170, 23622089, 13998054, 31024810, 35330656, 25189053, 28581323, 46426821]
&glt;&glt;&glt; tw2330.turnover       #近 31 日成交金額
[4228108427, 7430197670, 8013908284, 5187054985, 5995746054, 5864298571, 9052540803, 10691130829, 5533050748, 4872352124, 4029782428, 5183171608, 7835079913, 5601351324, 5308051755, 4077045380, 8231572752, 6493129050, 3496720720, 5563557011, 6710510004, 5680726299, 4662705968, 5109273236, 5703467700, 3379510718, 7568601014, 8758161220, 6226523038, 7075597562, 11682512762]
&glt;&glt;&glt; tw2330.transaction      #近 31 日成交筆數
[6471, 14241, 11443, 6913, 8527, 7994, 9931, 13323, 8706, 7090, 5768, 8931, 7451, 9253, 6269, 6564, 8872, 10690, 7105, 6757, 11071, 10485, 8468, 6630, 7603, 3948, 6712, 13292, 9171, 8067, 16430]
&glt;&glt;&glt; tw2330.raw_data          #近 31 日原始資料
[{'stat': 'OK', 'title': '108年02月 2330 台積電           各日成交資訊', 'fields': ['日期', '成交股數', '成交金額', '開盤價', '最高價', '最低價', '收盤價', '漲跌價差', '成交筆數'], 'notes': ['符號說明:+/-/X表示漲/跌/不比價', '當日統計資訊含一般、零股、盤後定價、鉅額交易,不含拍賣、標購。', 'ETF證券代號第六碼為K、M、S、C者,表示該ETF以外幣交易。'], 'date': '20190201', 'data': [Data(date=datetime.datetime(2019, 2, 11, 0, 0), capacity=81360106, turnover=18546167132, open=228.0, high=229.0, low=226.5, close=228.0, change=7.0, transaction=21689), Data(date=datetime.datetime(2019, 2, 12, 0, 0), capacity=30125670, turnover=6921488930, open=230.0, high=230.0, low=229.0, close=230.0, change=2.0, transaction=13313), Data(date=datetime.datetime(2019, 2, 13, 0, 0), capacity=28634925, turnover=6575201825, open=232.0, high=232.0, low=228.5, close=229.0, change=-1.0, transaction=10230), Data(date=datetime.datetime(2019, 2, 14, 0, 0), capacity=23647751, turnover=5392943977, open=229.5, high=230.0, low=226.0, close=227.0, change=-2.0, transaction=6873), Data(date=datetime.datetime(2019, 2, 15, 0, 0), capacity=22369799, turnover=5093773373, open=229.0, high=229.0, low=226.5, close=227.0, change=0.0, transaction=5743), Data(date=datetime.datetime(2019, 2, 18, 0, 0), capacity=18163916, turnover=4169729625, open=229.0, high=230.5, low=228.5, close=230.0, change=3.0, transaction=7035), Data(date=datetime.datetime(2019, 2, 19, 0, 0), capacity=18423023, turnover=4228108427, open=230.0, high=230.5, low=229.0, close=229.0, change=-1.0, transaction=6471), Data(date=datetime.datetime(2019, 2, 20, 0, 0), capacity=31887710, turnover=7430197670, open=231.5, high=234.5, low=231.0, close=234.5, change=5.5, transaction=14241), Data(date=datetime.datetime(2019, 2, 21, 0, 0), capacity=34013489, turnover=8013908284, open=235.5, high=236.5, low=234.5, close=236.5, change=2.0, transaction=11443), Data(date=datetime.datetime(2019, 2, 22, 0, 0), capacity=22032163, turnover=5187054985, open=235.5, high=236.5, low=234.0, close=236.5, change=0.0, transaction=6913), Data(date=datetime.datetime(2019, 2, 25, 0, 0), capacity=25227138, turnover=5995746054, open=237.5, high=239.0, low=236.0, close=238.0, change=1.5, transaction=8527), Data(date=datetime.datetime(2019, 2, 26, 0, 0), capacity=24586789, turnover=5864298571, open=239.0, high=240.0, low=236.5, close=239.5, change=1.5, transaction=7994), Data(date=datetime.datetime(2019, 2, 27, 0, 0), capacity=37947889, turnover=9052540803, open=238.5, high=239.5, low=237.0, close=239.0, change=-0.5, transaction=9931)]}, {'stat': 'OK', 'title': '108年03月 2330 台積電           各日成交資訊', 'fields': ['日期', '成交股數', '成交金額', '開盤價', '最高價', '最低價', '收盤價', '漲跌價差', '成交筆數'], 'notes': ['符號說明:+/-/X表示漲/跌/不比價', '當日統計資訊含一般、零股、盤後定價、鉅額交易,不含拍賣、標購。', 'ETF證券代號第六碼為K、M、S、C者,表示該ETF以外幣交易。'], 'date': '20190301', 'data': [Data(date=datetime.datetime(2019, 3, 4, 0, 0), capacity=45164513, turnover=10691130829, open=239.5, high=239.5, low=234.5, close=235.5, change=-3.5, transaction=13323), Data(date=datetime.datetime(2019, 3, 5, 0, 0), capacity=23708407, turnover=5533050748, open=234.0, high=234.5, low=232.5, close=233.0, change=-2.5, transaction=8706), Data(date=datetime.datetime(2019, 3, 6, 0, 0), capacity=20811226, turnover=4872352124, open=235.0, high=235.5, low=233.5, close=234.0, change=1.0, transaction=7090), Data(date=datetime.datetime(2019, 3, 7, 0, 0), capacity=17226192, turnover=4029782428, open=235.0, high=235.0, low=233.0, close=234.0, change=0.0, transaction=5768), Data(date=datetime.datetime(2019, 3, 8, 0, 0), capacity=22535659, turnover=5183171608, open=231.0, high=231.5, low=229.0, close=230.0, change=-4.0, transaction=8931), Data(date=datetime.datetime(2019, 3, 11, 0, 0), capacity=34282793, turnover=7835079913, open=228.0, high=230.5, low=227.5, close=230.5, change=0.5, transaction=7451), Data(date=datetime.datetime(2019, 3, 12, 0, 0), capacity=23839972, turnover=5601351324, open=233.0, high=237.0, low=232.5, close=235.5, change=5.0, transaction=9253), Data(date=datetime.datetime(2019, 3, 13, 0, 0), capacity=22493195, turnover=5308051755, open=234.0, high=237.0, low=234.0, close=237.0, change=1.5, transaction=6269), Data(date=datetime.datetime(2019, 3, 14, 0, 0), capacity=17281356, turnover=4077045380, open=239.0, high=239.0, low=234.0, close=234.5, change=-2.5, transaction=6564), Data(date=datetime.datetime(2019, 3, 15, 0, 0), capacity=34542729, turnover=8231572752, open=237.0, high=239.5, low=235.5, close=239.0, change=4.5, transaction=8872), Data(date=datetime.datetime(2019, 3, 18, 0, 0), capacity=27040532, turnover=6493129050, open=239.5, high=241.0, low=239.0, close=241.0, change=2.0, transaction=10690), Data(date=datetime.datetime(2019, 3, 19, 0, 0), capacity=14620009, turnover=3496720720, open=239.0, high=240.5, low=238.0, close=240.5, change=-0.5, transaction=7105), Data(date=datetime.datetime(2019, 3, 20, 0, 0), capacity=23055971, turnover=5563557011, open=242.0, high=242.0, low=239.5, close=242.0, change=1.5, transaction=6757), Data(date=datetime.datetime(2019, 3, 21, 0, 0), capacity=27514502, turnover=6710510004, open=242.5, high=245.5, low=241.0, close=245.5, change=3.5, transaction=11071), Data(date=datetime.datetime(2019, 3, 22, 0, 0), capacity=22996467, turnover=5680726299, open=248.0, high=248.5, low=244.5, close=248.5, change=3.0, transaction=10485), Data(date=datetime.datetime(2019, 3, 25, 0, 0), capacity=19273254, turnover=4662705968, open=240.5, high=243.5, low=240.5, close=241.5, change=-7.0, transaction=8468), Data(date=datetime.datetime(2019, 3, 26, 0, 0), capacity=21053170, turnover=5109273236, open=243.0, high=244.0, low=241.0, close=244.0, change=2.5, transaction=6630), Data(date=datetime.datetime(2019, 3, 27, 0, 0), capacity=23622089, turnover=5703467700, open=242.0, high=242.5, low=240.5, close=241.5, change=-2.5, transaction=7603), Data(date=datetime.datetime(2019, 3, 28, 0, 0), capacity=13998054, turnover=3379510718, open=240.5, high=242.5, low=240.0, close=242.0, change=0.5, transaction=3948), Data(date=datetime.datetime(2019, 3, 29, 0, 0), capacity=31024810, turnover=7568601014, open=243.0, high=245.5, low=240.5, close=245.5, change=3.5, transaction=6712)]}, {'stat': 'OK', 'title': '108年04月 2330 台積電           各日成交資訊', 'fields': ['日期', '成交股數', '成交金額', '開盤價', '最高價', '最低價', '收盤價', '漲跌價差', '成交筆數'], 'notes': ['符號說明:+/-/X表示漲/跌/不比價', '當日統計資訊含一般、零股、盤後定價、鉅額交易,不含拍賣、標購。', 'ETF證券代號第六碼為K、M、S、C者,表示該ETF以外幣交易。'], 'date': '20190401', 'data': [Data(date=datetime.datetime(2019, 4, 1, 0, 0), capacity=35330656, turnover=8758161220, open=251.0, high=251.0, low=245.0, close=245.5, change=0.0, transaction=13292), Data(date=datetime.datetime(2019, 4, 2, 0, 0), capacity=25189053, turnover=6226523038, open=249.5, high=249.5, low=246.0, close=246.0, change=0.5, transaction=9171), Data(date=datetime.datetime(2019, 4, 3, 0, 0), capacity=28581323, turnover=7075597562, open=249.0, high=249.0, low=246.5, close=246.5, change=0.5, transaction=8067), Data(date=datetime.datetime(2019, 4, 8, 0, 0), capacity=46426821, turnover=11682512762, open=251.0, high=253.0, low=250.5, close=253.0, change=6.5, transaction=16430)]}]




Bingo! 大功告成!  不過 Yahoo 顯示成交張數是 45133, 但 twstock 抓到的是 46426821 股, 換算是 46426 張, 多了 1293 張, 這是何故?

總結以上安裝經驗, 應該是先安裝相依套件 analytics 與 lxml, 然後再安裝 twstock, 指令如下 : 

pip3 install analytics
sudo apt-get install python3-lxml python-lxml 
pip3 install twstock 

AutoIt 學習筆記索引

我從 2010 年開始使用 AutoIt 幫助例行工作自動化, 也寫了一些函式庫來簡化程式碼, 更曾計畫為 AutoIt 寫一本書, 但寫了兩章就因為忙別的事停頓了. AutoIt 是我唯一使用的 PC 軟體程式語言 (.exe), 以後還會繼續整理筆記, 但排在很後面, 目前只能將已寫的筆記索引如後 :

403forbidden
AutoIt 的雜湊函式庫
AutoIt 的 FTP 功能
AutoIt 學習筆記 : 基本語法
用 AutoIt 搞定煩人的連線 Timeout 問題
AutoIt 內建 SciTE 的字型設定問題
# AutoIt 學習筆記 : 流程控制
AutoIt 學習筆記 : 陣列

~未完~

購買 Sandisk 32GB SD 卡

中午去建國路二段 91 號 (加油站過去一點) 維碁買 2 張 Sandisk MicrSD 卡給 Pi3 用 :

【高雄實體店】SANDISK ULTRA Micro SDHC microsd 32G 32GB 記憶卡 TF 無轉接卡 $134

共 134*2=268 元.

露天有更便宜約 120 元的, 但加運費就要 180 元了更貴.

我誤以為 Sandisk 就是創見 (正解 : Trancend), 老闆說創見沒貨喔! 金士頓或 Sandisk 都有貨, 我說對啊就是 Sandisk! 他說差多了, Sandisk 是世界領導品牌, 攝影專業人士都指定買 Sandisk 或 Toshiba, 他說創見是入門款. 熱心的老闆還說 Sandisk 水貨很多, 他進的是有貼標籤卡片裝的公司貨, 展碁保固七年. 買個東西也長知識了.