bloggerads

2017年10月3日 星期二

Python : struct

這篇說明 Python 要如何像C/C++一樣,將struct資料以binary的形式寫入檔案。
參考以下範例:

#! python2
""" Author: Martin Lee """
import struct
with open('out.bin','wb') as f:
    f.write(struct.pack('B8sHHL', 22, 'Hi World', 1, 2, 0x3322))

fin = open("out.bin", "rb")
i = struct.unpack('B8sHHL', fin.read())
fin.close()

2017年9月17日 星期日

Python : 使用 py2exe 打包 py檔成執行檔

Windows下將py檔打包成執行檔, 以python 2.7為範例

基本上是參考 http://www.py2exe.org/index.cgi/Tutorial

試過import 第三方模組、內建的GUI 模組(Tkinter)、自定義的模組, py2exe 都能打包。以下是流程:

1.安裝 py2exe

2.在要打包的py檔目錄下,新增一個'setup.py'檔,其內容為
  • from distutils.core import setup
  • import py2exe
  • setup(console=['要打包的檔名.py'])
3.python setup.py py2exe

4.會在同目錄下產生兩個資料夾,其一個新增的資料夾'dist'內會產生一個同檔名的exe檔

Linux下將py檔打包成執行檔, 以python 2.7為範例

1. 安裝 pyinstaller (pip install pyinstaller)
2. pyinstaller --onefile filename.py
3. 在同目錄下的dist資料夾內產生可執行檔 filename

2017年9月14日 星期四

Python : JSON

鑒於JSON愈來愈普及, 很多數據都要求使用JSON的格式,因此特別在這篇做個紀錄, 了解JSON以及如何用Python處理JSON。  

了解 JSON 的 format可以從這個
網站開始: http://jsoneditoronline.org/



#  JSON的規則:

1.  key:value
2.  value 型態可以是 數字, 字串, 布林, 陣列[], 物件{}, NULL, 但key一定是要字串
3.  同一個物件內的key不可重複, 如以下的 Age 就重複了
{
    "Martin": {
        "Age":33,
        "Age":5,
     }
}

2017年9月10日 星期日

Python : regular expression

re module的一些紀錄, 持續update

### Common use of the regular expression

\w   [a-zA-Z0-9_]
\d    [0-9]
\s    space
\\     '\'
.       ''
+     1 or more than 1
.\     everything

### Code

>>> import re
>>> string = 'Age=20'
>>> re.search('\d+', string).group()
20

>>> import re
>>> string = 'Beautiful, is; better*than\nugly'
>>> # 分隔符號:,  ;  *  \n
>>> list= re.split(',|; |\*|\n', string)
>>> list
['Beautiful', 'is', 'better', 'than', 'ugly']

2017年9月5日 星期二

Python : Combobox 範例

距離上次Python文,不知不覺又過了兩三個星期了。 時間過得真快,這段時間除了工作外,還去了花蓮玩兩天! 雖然工作上每天都在改code, 但使用到Python的機會很少,本著學海無涯,惟勤是岸的精神,隔一段時間就來po 一下,以免生疏了。今天介紹Combobox,搭配Button作範例,話不多說,馬上端上code:

#! python2
# coding: utf-8

import Tkinter as tk
import ttk   

def clickOkButton():
    print 'Select ' + str(numberChosen.current()) # 丟出選到的index number

win = tk.Tk()
win.title("Python Combobox example") 

2017年8月14日 星期一

Python : 透過字串與數字轉換來做"進制轉換"

所有的非10進制數字都要以字串的型式表達而數字一律是10進制表示

因此進制轉換就只是字串轉數字或數字轉字串的差別。以下就針對這兩種狀況來說明。

● 字串轉數字

>>> int ('0x10', 16)  #必須告訴直譯器字串是哪種進制
16

2017年8月13日 星期日

Python : Tkinter (Button, Label, Entry, Listbox)

Tkinter 並不是一個很強大的GUI library, 但優點是, 他是Python官方支援的module, 且大部分的OS都有預先安裝它<Note 1>。 之後陸續出現的第三方GUI library相信都是由他啟發的。因此如果不是開發太複雜的GUI tool, 又想了解這個歷史悠久的library, 那就值得來了解他。

話不多說,直接上code:

step 1. 先來創一個空的視窗

from Tkinter import *
    
win = Tk()
win.title("Tk Gui")
win.resizable(width=False, height=False)
win.geometry("500x250")

win.mainloop()


Python : 調用模組的語法比較

以調用random模組中randint函數,印出隨機數字0~10來作範例

1. 函數呼叫透過: 模組.函數() 
    import random
    print random.randint(0,10)

2. 直接呼叫函數(), 但必須告訴直譯器調用模組中的哪個函數
    from random import randint
    print randint(0,10)  

3. 直接呼叫函數(), 直接告訴直譯器要引用模組中所有的函數。 會有函數名稱衝突的風險!
    from random import *
    print randint(0,10)

4. 在script中定義模組的新名稱, 呼叫方式: 模組新名稱.函數()
    import random as newname
    print newname.randint(0, 10)

2017年8月11日 星期五

Python : tuple, list, set, dict 整理與比較


python常用的四種container types: tuple, list, set dictionary

tuple: ()
    - save in order
    - read only
list: []
    - save in order
set: {}

dictionary: {key:value}

NOTE:
t = tuple([1,2,3])
>>>t[0]
1



Python : Use dictionary to simulate multi-dimension array

Since there is no array in Python. Use dictionary instead.

Follows are the example to initialize a 2x2 array

>>>a={}
>>>for i in range(4):
. . .      a[i/2, i%2] = i
>>> a
{ (0,1):1, (1,0):2, (0,0):0, (1,1):3 }
>>>a[0,1]
1

2017年8月9日 星期三

Python : string related

### Demonstrate join

>>> list = ['Nice', 'to', 'meet', 'you']
>>> ''.join(list)
Nicetomeetyou

>>> ' '.join(list)
Nice to meet you

>>>'_'.join(list)
Nice_to_meet_you

2017年8月6日 星期日

Python : Exception Handling

以parsing文字檔的內容來做例外處理的範例, parsing過程中其它列的內容可能和原本預設格式不同, 此時就會有例外產生:

with open('a.txt', 'r') as f:
    badLine = 0
    goodLine = 0
    totalLine = 0

    for line in f:
        try:
            d1, d2, d3 = line.split()
        except:
            badLine += 1    
        else:
            goodLine += 1
        finally:  
            totalLine += 1   

    print('totalLine : {}, badLine: {}, goodLine: {}'.format(str(totalLine), str(badLine), str(goodLine)))

2017年8月4日 星期五

Python : class method / static method / method

This is a good example for showing the difference between class method, static method and method in Python.


class Demo:     
    y=1 # class (or static) variable
    def __init__(self,z):
        self.z = z

    @classmethod
    def class_method(cls, x):
        return x + cls.y

    @staticmethod
    def static_method(x):
        return x  #cannot invoke cls.z

    def method(self, x):
        return x + self.z


print Demo.class_method(2)  # show 3
print Demo.static_method(2)  # show 2

#print Demo.method(2) #Error, must declare first
demo = Demo(2)
print demo.method(2) # show 4

2017年8月3日 星期四

Python : dictionary

Follows are the Dictionary example. Key and value can be string or number.

● Initial a dictionary
>>> d={'a':'Martin', 'b':'John'}

● Add new item
>>> d['c']='Mary'

 Add items
>>> d.update({'d':'Megan', 'e':'May'})

 Check item in a dictionary (return True/False)
>>> 'd' in d
True
>>> 'f' in d
False

 Enumerate the items in a dictionary
>>> for id, name in d.items():
...         print id, name

 Delete an item
>>> del d['a']

2017年7月31日 星期一

Python : list

In Python, We have list and and dictionary, similarly as the container list and map in C++, follows are the list example.

● Init a list in even numbers from 0 to 6


>>>list = [i for i in range(8) if i%2==0]
>>>list
[0, 2, 4, 6]

● Append data:2 to the tail

>>>list.append(2)

>>>list
[0, 2, 4, 6, 2]

● Insert data:3 to index: 2



>>>list.insert(2, 3)
>>>list
[0, 2, 3, 4, 6, 2]

● Remove data:3 

>>>list.remove(3)

>>>list
[0, 2, 4, 6, 2]


2017年7月29日 星期六

Python : Some notes

(1) How to import a user's defined module 't1.py' in 't.py' ?

@t1.py
def watchout():
  print "Did you call me?"

@t.py
#! python2
import t1
t1.watchout()

=========Output===========
> t.py
Did you call me?
==========================

(2) Popen, same as C++

@c.cpp, compile it to c.exe
#include <stdio.h>
int main()
{
    printf("Hi Martin\nHi Megan\n");
    return 0;
}

@p.py
#! python2
import os
output = os.popen('c.exe')
print output.read()

=========Output===========
> p.py
Hi Martin
Hi Megan
==========================

Python : 指定不同版本(Python 2 或 Python 3) 執行

若 PC上同時有 Python 2 及Python 3 才需要做以下動作。

● 進 python console
py -2
py -3

●  在 command prompt 執行.py檔
py -2 xxx.py
py -3 xxx.py

● 在檔案中說明該用哪種版本執行
#! python2
#! python3

● python2 使用中文時要在檔案頭宣告
#! python2
# coding: utf-8

●  pip
py -2 -m pip install XXXX
py -3 -m pip install XXXX


Python : Introduction


這篇是部落格的第一篇Python文。。。

最近空閒的時間都在玩Python, 一開始只是隨手看到公司的project中有很多附檔名為.py的tool, 好奇自己動手玩玩後, 就迷上這個語言了。決定把Python當做我的第二語言。

Python 為何風靡全球? 尤其在現今以C style (C/C++/JAVA/C#) 為主的分圍下仍然擁有眾多死忠的支持者,使用者人數排行過去多年來居高不下,想必他一定是有兩把刷子。 以下是Python 的特色 (個人心得):

1. Simple and easy to learn (語法簡單易學啊)
2. Object Oriented Programming (支援物件導向)
3. Versatile libraries (library非常多, 寫C的人最懂沒有library的痛!)
4. Massive communities support and massive population (廣大的社群支持, 就是粉絲團夠力)
5. As known Google/Youtube/N.A.S.A. use Python (一流的大公司都用Python)
6. Easy to package to an executable file (Without Python Interpreter) (打包成執行檔沒問題)
7. Python is everywhere (Preinstall on most Linux distribution) (大部分的Linux內建都有Python)

長期以來都有一個小問題困擾著我, 我是吃韌體這行飯的,高階語言對我來說只是用來分析log, 寫寫小tool方便工作用的。 過去我都是用C++, 如果需要GUI則用C#,  但是實在無法喜歡上這兩種語言。而 Python的哲學, 「優雅」、「明確」、「簡單」, 的確很和我胃口,人生應該要簡單一點,看了程式的一些介紹後就決定好好來認識他。

2017年5月7日 星期日

NVMe : Compare to AHCI

這篇列出AHCI / NVMe的差異


PCIe 2.0: 5GT/s    4Gb/s      500MB/s
PCIe 3.0: 8GT/s    8Gb/s      1GB/s

2017年4月19日 星期三

C : 好用的parsing 數字字串函式 strtol

strol (Convert string to long integer)

須include stdlib.h, 他的原型是 

long int strtol (const char* str, char** endptr, int base);

return value 是 轉換後的十進位值

第一個引數 str 是待轉換的數字字串指標

第二個引數 endptr 則是提供回傳parsing整串字串中, 空白字元分隔的下一個數字字串位址。 如果不用回傳,則給 NULL 即可

第三個引數是說明以什麼格式來 parsing 這個數字字串,  如 2 進位就給 2, 16 進位就給 16, 0 就是 自動偵測數字字串的格式。 (ps.) 16 進位可接受開頭為0x, 亦可接受大小寫

2017年4月16日 星期日

NVMe : Command flow

以下是發送一個NVMe admin/Io command 的流程。相關driver source code 可參考NVMe official website

1. Host Adds a command in the submission queue's tail entry

2. Host rings the submission queue's Tail Doorbell
3. Device fetch the command
4. Device process the command (done)
5. Device adds the completion result in the completion queue's tail entry (Completion result has its relevant command id)
6. Device send a Interrupt(Probably MSI-X)
7. Host reads the completion queue
  7.1 Host has received the completion command 
8. Host rings the completion queue's Head Doorbell


NVMe : Queue Size / Queue entry Size

Queue 相關 size 的 configuration

  • Admin Queue
  1. Completion Queue 和 Submission Queue 各只有一組
  2. Initial 時需設定Queue Size, 即AQA.ACQS, AQA.ASQS, controller 應support 2~4096個entry
  •  I/O Queue 
  1. Initial 時需設定每個entry的Size, 即 CC.IOSQES = 6 (64 Byte), CC.IOCQES = 4 (16 Byte), 這是NVM command的size。
  2. 透過 CAP.MQES (Maximum Queue Entries Supported)得到 I/O Submission/Completion Queue support 的最大entry數量(最少兩個entry)。 在使用Admin Command Create I/O Queue時不要超過他
  3. 透過 Set Feature (Feature Id 07h) 設定host driver所需的Submission/Completion Queues數量 (最大64K個), 從completion queue 回來的資料可以得到Controller 所能allocate 的Submission/Completion Queue數量

2017年4月8日 星期六

利用C語言的正規表達功能來Parsing 傳入程式中的引數

這篇介紹 C 的 sscanf 函數來做到類似 C++11 正規表達的效果,並以 Parsing 傳入程式中的引數做範例
// c.cpp

int main(int argc, char* argv[])
{
    char s0[30], s1[30];
    int ret;
    for (int i=argc-1; i>0; i--) {
        s0[0] = s1[0] = 0;
        //sscanf(argv[i], "%*[^:]:%s", s0); //[^:]代表在':'處設斷點但不包含':', '*'代表忽略'%'起始的字串
        sscanf(argv[i], "-%29[^:]:%29s", s0, s1); 
        if (s0[0] == 0 || s1[0] == 0) 
            puts("Wrong type!");
        else            
            printf("%s : %s\n", s0, s1);
    }   
  return 0;
}

----------------------Output---------------------------
> g++ -o c c.cpp
> c -name:John -age:20
age : 20
name : John

2017年2月5日 星期日

DOS : Legacy Graphic Output Control

在Dos下想輸出文字到螢幕上,除了呼叫C/C++提供的函數 printf, cout 或 Bios提供的軟體中斷 int 10, 是否有直接控制硬體的方法呢?  答案是有的,可以直接把要顯示的資料搬到A/B Segment。用以下的code來做範例 (Compile using Watcom)

typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned int DWORD;

 enum Colour{ BLACK=0, BLUE, GREEN, CYAN, RED, MAGNETA, BROWN, LGRAY, \
   DGRAY=8, LBLUE, LGREEN, LCYAN, LRED, LMAGNETA, YELLOW, WHITE};
 
#define COLOUR(forecolour, backcolour)  ((backcolour) << 4 | (forecolour) & 0x0F)

 void WriteString(int y, int x, BYTE colour, char *string)
 {
     volatile WORD *pvram;
     
     for (DWORD i=0;string[i]!=0; x++, i++) {
       pvram = (volatile WORD *)0xB8000 + y * 80 + x;
       *pvram = (BYTE)string[i] | colour << 8;
     }
 }
 

 void WriteCharacter(int y, int x, BYTE colour, BYTE ch)
 {
      volatile WORD * pvram;
      pvram = (volatile WORD *)0xB8000 + (y * 80 + x) ;
      *pvram = ch | (colour << 8);
 }

 int main()
{
     WriteCharacter(1,0, COLOUR(RED, BLACK), 'H');    
     WriteCharacter(1,1, COLOUR(RED, BLACK), 'i');
     WriteString(1, 3, COLOUR(GREEN, BLACK), "Martin.");
}

在螢幕座標(y,x) = (1, 0) 秀出 Hi Martin.


ps. 如果想畫一個點陣圖請參考 mode 13h, 解析度為320*200, 256色, 透過寫入A000:0來完成


題外話, 我用了以上的技巧寫了一個Dos版的source code Editor, 名稱叫E editor (下圖)。 平常工作時都會開個Dos模擬器跑Dos tool,享受Dos單純的美。



Key:
F1: Copy Line
F2: Paste Line
F3: Delete Line
F10: Save File

下載: (password: martinlee)

E Editor

2017年1月13日 星期五

DOS : Increase Dosbox screen size in Windows

Step 1. Find dosbox-0.74.conf

Step 2. Modify the SDL part in the dosbox-0.74.conf


[SDL]

fullscreen=false 
fulldouble=false 
fullresolution=original 
windowresolution=1024x768 
output=ddraw 
autolock=true 
sensitivity=100 
waitonerror=true 
priority=higher,normal 
mapperfile=mapper.txt 
usescancodes=true 

ps. Some Dos application may consume lot of CPU usage. Fix it by Setting a fixed CPU cycles, for example, 16000.
[CPU]
cycles=auto 
cycles=16000