顯示具有 Python 標籤的文章。 顯示所有文章
顯示具有 Python 標籤的文章。 顯示所有文章

2025年6月29日 星期日

AI時代的程式學習思維

 在 AI 時代學習程式設計,我認為我們應該建立一種全新的學習心態。像 ChatGPT 這類生成式 AI 工具,雖然已經被廣泛運用在編程中,但這並不表示我們可以完全依賴它。對初學者來說,最重要的是先培養獨立思考與動手實作的能力,透過親自寫程式來熟悉邏輯與架構。當有了一定基礎之後,再適時引入 AI 工具來協助學習與優化,才能真正建立起紮實的能力。

雖然 AI 功能越來越強大,但在處理複雜、非結構化的大型程式碼,或是在除錯過程中,仍然存在許多限制。因此,我們人類的優勢,應該更加著重於高層次的系統思考、問題分析,以及與他人協作與溝通的能力。

我鼓勵每位學習者,不只是把自己當成「寫程式的人」,而是要用「專案經理」的角色來看待自己的學習與應用。學會整合 AI 資源、分析問題、運用適當工具來解決真實世界的挑戰,這才是程式設計的真正價值所在。

至於資料結構與演算法,我更傾向將它們視為一種「解決問題的思維模式」,而不只是考試科目。像是 Google 地圖預測即時交通狀況,就是結合了資料結構、演算法與機器學習的應用範例,充分展現出這些基本功在現實世界中的重要性。

在這個 AI 快速演進的時代,邏輯思考依然是學習程式的核心,我們也必須不斷調整自己的學習方式,與時俱進,才能真正掌握未來的關鍵能力。




2023年1月14日 星期六

[Python] 動態繪製不同尺寸的ASCII-table


作業描述: 能動態繪製不同尺寸的ASCII-table

Task Decription:

1. Generate a random list of size 50.It contains random values from 1 to 50.
2. Dynamically draw a ASCII table  according to the dimensions  of  table

The end result will look like below



2022年12月1日 星期四

[Python] Python的變數僅僅只是一個tag

 

在python 世界裡, 宣告的變數僅僅只是一個tag。而tag 可以到處貼, 所以當你問 tag 的資料型態時 , 那就是在問tag 當下所貼的位置的物件資料型態為何  ?  

a=3  , 則 type(a)==> int

b=3.14  , 則 type(b)==> float

c="hello"  , 則 type(c)==> str

3, 3.14, "hello" 這都是物件, 佔有空間 ,而a, b, c 就是tag name, 只是一個名字用來存取物件而已。

python 的變數完全不同於C/C++ 變數的概念。C/C++ 變數是佔有空間的, 空間存放著資料, 而空間有多大就決定了資料的數值範圍。

int a=64;   (佔4個bytes)

char ch='A';  (佔1個bytes)





Python 有Garbage collection 的機制, 故物件10沒有任何tag參考, Python 會自己回收。
Python 中的List , 它是一個container ,即它是具有一個空間。 如 a=[3,3,1] , a[0] 這個tag 指向物件3,  a[1] 這個tag 也指向物件3, 而 a[2] 這個tag 指向物件1



你可能會問一個問題, Python 的變數用這樣搞有什麼好處?

用個例子說明好了,  a=[1,2,3] 

若要複製一份給c, 執行 c=a.copy() 就會將a的container 表格複製給c, 因為只是複製了container a 表格, 和資料物件多大沒有關係, 所以可以很快,也不用將相同的資料物件在記憶體中放兩份。若是C/C++ 則a, c 是各別的空間, 因此即使是相同的資料,在記憶體中也得各自存放一份,會比較佔空間,而且在複製資料時也得一個個byte 複製過去 ( memcpy),速度上也比較慢。






相關文章:

2022年11月1日 星期二

[Python] List is not what you think

 

mutable vs immutable



























相關文章: 






References: 

[1]TensorFlow Lite for MCU https://bit.ly/3j2fIIt 
[2]AI機器學習&深度學習 http://bit.ly/2KDZZz4 
[3] AIoT智能聯網運算實戰(含OpenVINO) http://bit.ly/2IlIUK8 
[4]AI自然語言與推薦系統應用 https://bit.ly/3qnO2Tg 
[5]python程式設計 https://bit.ly/359cz4m

2022年10月7日 星期五

[Python] Why do we need frozenset ?

(1) 用frozenset 才可以用集合當作Key

Example:

itemsets=[{'B','C'},{'D'}] 

count[{'B','C'}]+=1  # Error : "unhashable type: 'set'"

in this case, we can use frozenset to make 'set' as a key

count[frozenset({'B','C'})]=1   

(2) 用frozenset 才可以做集合包含集合

  S=set()

e={'A','B','C'}

S.add (e)  ==> 想要表示 S={{'A'},{'B'},{'C'}} --> TypeError: unhashable type: 'set'    

S.add (frozenset(e))  -->OK   S={frozenset({'A', 'B', 'C'})}


2020年5月24日 星期日

[Notepad++]縮排改成4個Space




用 Notepad++ 開 Python程式預設縮排是是用 Tab,若要改成以4個 SPACE 空白縮排,可以從Settings -> Preferences 進行修改









2020年4月25日 星期六

Spyder IDE 使用撇步

Spyder 是一個使用Python語言的開放原始碼跨平台科學運算整合開發環境(IDE)。Spyder整合了NumPy,SciPy,Matplotlib與IPython,以及其他開源軟體。可以透過安裝Anaconda 就可以同時連Spyder也一併裝好。


1.) Spyder編輯器中更改程式縮排為Tab
當用Spyder 來開發Python 程式時, 預設縮排 (indentation)是用4個SPACE, 若要改為TAB鍵可以在此修改

Tools -> Preference -> Editor -> Advanced settings -> Indentation characters




2.) Spyder編輯器中更改背景顏色

3.)   Spyder Console 調整字體大小



4.)   Variable Explorer 

View->Panes-> Variable explorer





程式一旦執行, 在 Variable explorer 視窗, 只能看到global 變數, 無法看到函式內的變數, 一個簡單的方法就是 return 變數出來, 然後就能直接檢檢視或者使用 [Debug]模式

def main():
    a = 2
    b = 4
    c = a+b

    return a, b, c

a, b, c = main()
4.)   快速多行註解
框選要註解的程式行,接著可以切換 CRTL-1 可以註解/取消註解程式行.
5.)   使用 [Debug]模式
想要看到函式內的變數,可以使用[Debug]模式執行程式, 進入函數 Variable explorer 視窗會自動出現區域變數, 一旦離開函數則區域變也會消失於Variable explorer視窗。 
設定中斷點, 可以滑鼠直接點程式碼旁邊的行號, Debug Run (Ctrl+F5) 時就會停在那一行(還沒執行該行). 接下來可以一直Step (Ctrl+F10)  一行行逐步執行, 若也想要trace到函數細節, 則可以 Step Into (Ctrl+F11)






2019年12月30日 星期一

[python] Why Enclosing Function?




有時候函式某些參數, 可能只要第一次代入後,

而之後呼叫時參數都是相同的, 不希望每次呼叫都要一直代入相同的參數… 



  1. 使用global 變數 ? 程式結構不佳
  2. 使用預設參數? 但預設的又不是我想要的, 也是等於每一次呼叫都要代入
  3. 拿掉該參數? 但因為至少第一次呼叫時可能要代入不同的值, 但拿掉後此函數後就無法有代入參數的能力了


.


更多python程式設計請參考 Python 程式設計

2019年11月20日 星期三

[python] dict 依據value排序

不使用內建的sorted()函式, 例如

new_data=sorted(data.items(), key=lambda x: x[1],reverse=True) 


將dict依照value 進行排序 new_data=sort_dict_by_value(data,reverse=True)



2019年9月6日 星期五

常用數學符號的 LaTeX 表示方法


在jupyter notebook 插入LaTeX數學公式, 前後要包 $$..............$$


## Euclidean and Cosine distance
Euclidean:  $$d(x,y)=\sqrt{\sum^n_{i=1}(x_i - y_i)^2}$$

Cosine:  $$\theta(x,y)=\frac{x \bullet y}{ \sqrt{x \bullet x} \sqrt{y \bullet y}}$$


常用數學符號的 LaTeX 表示方法
http://mohu.org/info/symbols/symbols.htm

Online LaTeX Equation Editor - create, integrate and download
https://latex.codecogs.com/eqneditor/editor.php
About LaTeX 
很多論文及科學文章都會用到LaTeX。它是一個公式編輯系統,使用簡單的指令構建出專業的數學公式。


Markdown Cell內容




輸出結果




如果公式不要換行,則只要使用一個$去包,Letex

$\alpha$ 愈小等同於Linear Regression

在Jupyter Notebook 輸出會像這樣



2015年7月2日 星期四

Raspberry Pi2: 用 Python 透過 I2C 控制 16 頻道 PWM 模組 (PCA9685)


==========
前言:
==========


PWM訊號是一個非常重要的主題,MCU 透過 PWM 訊號來控制馬達轉速、 LED 亮度、伺服馬達的角度控制。在 Maker 的角度來看,幾乎是重中之重的主題。馬達要轉動車輪,螺旋槳要拉起四軸飛行器,伺服機要帶動機械手臂...難怪 Arudino 和 Raspberry Pi 上的PWM模組向來是熱銷項目。

PWM 的輸出,在 Raspberry Pi 上面只有一組,Arduino 上面似乎有六個...不夠不夠不夠~~~~好用的東西怎麼都不夠~~~~。所以這篇文章裡面介紹了一個好東西,PCA9685,它是一個
具有16個PWM頻道12-bit PWM控制器 (I2C界面)。PAC9685 內建oscillator為25 MHz且具有 4096 steps (12-bit PWM)



介紹:
============

Raspberry Pi 的 Linux 系統要使用 Python 去存取 I2C 介面的話要先載入核心模組 i2c-bcm2708 和 i2c-dev 這兩個模組,讓和i2c介面溝通的系統裝置檔 /dev/i2c-1 出現。

> sudo modprobe i2c-bcm2708

> sudo modprobe i2c-dev




--------------
Python & I2C:
--------------


Python 操作 I2C 通訊介面需要用到 smbus 這個模組,所以沒有安裝的話記得用apt-get 指令安裝 python-smbus。

> sudo apt-get install python-smbus

下面的 Python 範例 code 主要是透過使用 


read_i2c_block_data(addr, cmd, len) 

和 

write_i2c_block_data(addr,cmd,[data,...])

這兩個 API 來讀寫 PCA9685 裡面的暫存器數值控制 16 個 PWM。
=============
控制 PCA9685:
=============

從官方 Datasheet 所述,PCA9685 的 I2C 位置預設為 x40。在知道 I2C 位置之後,控制 PCA9685就只剩下三個重點:

  設定PWM訊號頻率 (PWM Frequency)

  進入與離開睡眠模式

  分別設定 16 個 PWM 頻道

----------------
設定PWM訊號頻率:
----------------

PCA9685 的 16 個 PWM 
頻道的 PWM 頻率是一樣的,設定 PWM 頻率(PWM Frequency) 的方法為直接設定 PCA9685 的 PRESCALE 暫存器。 

PRESCALE 暫存器位置為 0xFE

PRESCALE 暫存器設定值和 PWM 頻率 (Hz) 的換算公式為:

PRESCALE_value = 25000000 / ( 4096 * PWM_Frequency - 1.0)

所以這裡我們使用 PWM 頻率為 50Hz (用來控制伺服馬達),換算 PRESCALE 值約為 121。所以利用smbus提供的API的設定方法如下:

bus.write_i2c_block_data(addr , 0xFE, [121])

---------------
進入與離開睡眠模式
---------------

PCA9685 接上電之後的狀態會是處在
睡眠模式(SLEEP)之下。SLEEP模式之下,所有的PWM頻道輸出都會被關掉。所以一開始在設定好PRESCALE的值之後,必順離開SLEEP模式 PCA9685 才會有辦法輸出PWM訊號。

PCA9685 進入睡眠模式的方法為設 MODE1 暫存器(暫存器位置:0x00)的 SLEEP bit (第4個 bit)為 1 ,將其設為 0 的話就醒來。

--code--
def set_sleep(addr): reg_mode1 = 0x00 sleep_bit = 0x01 << 4 old_mode1_val = bus.read_i2c_block_data(addr, reg_mode1, 1) bus.write_i2c_block_data(addr, reg_mode1, [old_mode1_val | sleep_bit]) def unset_sleep(addr): reg_mode1 = 0x00 sleep_bit = 0x01 << 4 old_mode1_val = bus.read_i2c_block_data(addr, reg_mode1, 1) bus.write_i2c_block_data(addr, reg_mode1, [old_mode1_val &~(sleep_bit)]) --code--


-------------------
設定 16 個 PWM 頻道

-------------------

PCA9685 控制每個 PWM 訊號需要設定兩個值: 訊號電壓上升(ON: 由0V變5V)時間點、訊號電壓下降(OFF: 由5V變0V)時間點。



PWM 為一個固定週期的方形電波,而在PCA9685模組裡面透過PRESCALE設定時間週期的長短,而一個週期會被分成 4096 等份。所以 
PWM 訊號電壓上升(ON)和下降(OFF)兩個時間點設定值的範圍均為 0 ~ 4095。然而,要儲存這樣的值需要 12 個 bit 的記憶體空間。

所以一個時間點的設定值需要用到兩個暫存器,一個用來存放值的第 0 ~ 7 bit 稱之為 low byte (L)暫存器,另一個用來存放值的第 8 ~ 11 bit 稱之為 high byte (H)暫存器。而 high byte 暫存器的第0~3 bit 被拿來存放值的第 8 ~ 11 bit,所以high byte 暫存器還剩下第 4 ~ 7 bit ,其中第 4 bit 如果被設為1的話該頻道的PWM輸出會被關掉,剩下的第 5 ~ 7 bit 則棄之不用。

所以每個PWM訊號的暫存器名稱(定義在datasheet中):

LEDx_ON_L : PWM訊號電壓上升時間點的low byte暫存器。x值(0~15)為PWM頻道的號碼。
LEDx_ON_H : PWM訊號電壓上升時間點的high byte暫存器。x值(0~15)為PWM頻道的號碼。
LEDx_OFF_L: PWM訊號電壓下降時間點的low byte 暫存器。x值(0~15)為PWM頻道的號碼。 
LEDx_OFF_H: PWM訊號電壓下降時間點的high byte暫存器。x值(0~15)為PWM頻道的號碼。

這一系列的暫存器是按照 LEDx_ON_L, LEDx_ON_H, LEDx_OFF_L, LEDx_OFF_H 的順序照PWM頻道號碼依 0 ~ 15 的順序排列下去。 而 LED0_ON_L 暫存器位置為 0x06,所以剩下的暫存器位置可以用下面四個簡單的公式算出來:

LEDx_ON_L  = 0x06 + 4 * x
LEDx_ON_H  = 0x07 + 4 * x
LEDx_OFF_L = 0x08 + 4 * x
LEDx_OFF_H = 0x09 + 4 * x

下面寫成兩個 function 來方便設定:
--
def set_PWM_ON(addr , ch, value): low_byte_val = value & 0x00FF high_byte_val = ( value & 0x0F00 ) >> 8 reg_low_byte = 0x06 + 4 * ch bus.write_i2c_block_data(addr, reg_low_byte , [low_byte_val ]) bus.write_i2c_block_data(addr, reg_low_byte + 1, [high_byte_val]) def set_PWM_OFF(addr, ch, value): low_byte_val = value & 0x00FF high_byte_val = ( value & 0x0F00 ) >> 8 reg_low_byte = 0x08 + 4 * ch bus.write_i2c_block_data(addr, reg_low_byte , [low_byte_val ]) bus.write_i2c_block_data(addr, reg_low_byte + 1, [high_byte_val])
--

總之,如果只是想要用PWM訊號控制馬達之類的,那可以不用管所有的 LEDx_ON_L 和 LEDx_ON_H 暫存器,都給它用預設值0就好,也就是每一個週期(20ms)一開就會是ON了,接下來是什麼時間點要OFF而已,也就是只要去控制 LEDx_OFF_L 和 LEDx_OFF_H這兩個暫存器就好了。




所以,PCA9685上電後,設好PRESCALE,離開睡眠模式之後就可以開始使用了。

配合上面的範例code 使用如下:

--code--
import smbus pca9685_addr = 0x40 bus = smbus.SMBus(1) def set_PWM_ON(addr , ch, value): low_byte_val = value & 0x00FF high_byte_val = ( value & 0x0F00 ) >> 8 reg_low_byte = 0x06 + 4 * ch bus.write_i2c_block_data(addr, reg_low_byte , [low_byte_val ]) bus.write_i2c_block_data(addr, reg_low_byte + 1, [high_byte_val]) def set_PWM_OFF(addr, ch, value): low_byte_val = value & 0x00FF high_byte_val = ( value & 0x0F00 ) >> 8 reg_low_byte = 0x08 + 4 * ch bus.write_i2c_block_data(addr, reg_low_byte , [low_byte_val ]) bus.write_i2c_block_data(addr, reg_low_byte + 1, [high_byte_val]) # 設定PRESCALE PWM frequency = 50Hz bus.i2c_write_i2c_block_data(pca9685_addr, 0xFE, [121]) # 離開睡眠模式 bus.i2c_write_i2c_block_data(pca9685_addr, 0x00, [0x01]) # 設定第 0 個 PWM 頻道輸出 dutycycle = 1024/4096 set_PWM_OFF(pca9685_addr, 0, 1024) --------

還是覺得太麻煩的話就下載下面這個 github 的專案。

https://github.com/onionys/python_code

裡面有一個寫好的 PCA9685.py 可以在命令列下這樣使用:

    重設並啟動 PCA9685 (i2c 位置設定為 0x40)
> sudo PCA9685.py reset
    顯示目前所有PWM頻道的狀況
> sudo PCA9685.py info
    設定 PWM 頻道 1 其 duty-cycle 為 996/4096
> sudo PCA9685.py ch 1 996


相關文件:
1) PCA9685 DataSheet

2) 關於伺服馬達控制

0°~180° Servo 
利用PWM控制角度

 Most servo motor will work well on 50 Hz of PWM frequency;
this mean the PWM signal should have a period of 20ms.
Servo Angle Schematic 180 3.8 
This servo can operate 180° when given a pulse signal ranging from 600usec to 2400usec. 
#define MIN_PULSE_WIDTH       600     // the shortest pulse sent to a servo
#define MAX_PULSE_WIDTH      2400     // the longest pulse sent to a servo
#define DEFAULT_PULSE_WIDTH  1500     // default pulse width when servo is attached
#define REFRESH_INTERVAL    20000     // minumim time to refresh servos in microseconds
--------------
360° Servo 
利用PWM控制轉的方向與轉速

360° servo 是藉由0.5~2.5ms  HIGH  PULSE
50Hz的脈波訊號做控制霢1.5ms  HIGH  PULSE是
位於停止的狀態;小於1.5ms  時順時霢轉動霢愈
小愈快;大於1.5ms 時霢時霢轉動霢愈大愈快。










2015年4月7日 星期二

使用 Raspberry Pi 操作伺服馬達機械手臂

實驗名稱

使用 Raspberry Pi 操作伺服馬達機械手臂

相關文章:  Raspberry Pi2: 用 Python 透過 I2C 控制 16 頻道 PWM 模組 (PCA9685)

實驗目的

在高度工業化與資訊化的現代,機械人與機械手臂在各方面的應用越來越受到重視,並且在物聯網、大數據所組成的工業4.0的未來世界裡,將扮演一個極度重要的角色。

以往研究控制機械人與機械手臂控制系統是一門高成本且高技術門檻的領域,非相關人員的一般民眾在自行開發與研究上難以入門。但是隨著科技的發展,SoC 嵌入式系統的性能越來越高,價格越來越低,使得進入該領域的門檻開始慢慢降低,而使得一般民眾開始可以在車庫裡發展該方面的應用。

在 Raspberry Pi 的 Linux 環境底下,撰寫程式控制伺服馬達組成的機械手臂。並使用市面上的遊戲機搖桿來操作機械手臂。 藉此研究整個訊號控制流程與程式結構設計,建立相關研究的基礎。


使用材料及設備


六個伺服馬達組成的機械手臂一組。


2015年3月16日 星期一

Python 使用 I2C bus on Raspberry Pi



這篇文章介紹使用 Python 來對i2c介面做簡單的控制。

Python控制i2c會需要用到package "python-smbus" ,沒有的話就用apt來安裝吧。

apt-get install python-smbus 另外在熟悉程式開發期間,可以配合i2c-tools工具package來用,這是一個非常好用的工具。

此文章使用艾鍗學院提供的Pi I/O子板來練習,沒有板子的人也可以去買一顆for i2c 的eeprom晶片並參考下列網址的教學,來做連線。


2015年2月6日 星期五

Raspberry Pi b+ 用 Python 控制 LCD 16x2 (HD44780) 簡介 Part 3 LCD 初始化動作


LCD 開機動作

跟據Datasheet所表示,我們正在用的四條資料線+RS+RW+EN的接線接法是叫做4bit模式,而嫌GPIO太多的八條資料線+RS+RW+EN的接線接法叫做8bit模式。

而在一開始的時候要怎麼樣才能告訴LCD模組我們打算用4bit模式還是8bit模式來操作LCD? 這裡的主題是4bit,所以就不管8bit模式怎麼開機。而且4bit搞定之後,通常也不會想用8bit模式了。






2015年2月5日 星期四

Raspberry Pi b+ 用Python 控制LCD 16x2 (HD44780) 簡介 Part 4 自訂文字或圖示


接續上一篇,在已知如何傳送指令和資料給LCM模組之後,這裡要介紹如何在模組上畫出自已要的圖並顯示出來。

先觀察一下LCM模組的螢幕,如下圖所示,每個"字"是
由左右5個(編號:0~4)、上下8個(編號:0~7),共 5 x 8 = 40 個點所組成成的。




而在LCM模組之中劃分了一塊記憶體空間提供給使用者儲存多達7個自訂字形。每個字都會占用連續8個byte的記憶體空間。言下之意,會有 7 x 8 = 56 個連續 byte 是使用者自行定義的字形檔空間,其中每個字用8個byte來表示,一個字之中的每條左右橫向5個點由一個byte裡面的前5個bit來控制。每一個點都代表著一個 bit 值,而該值則代表了該點黑(1)或不黑(0)。

2015年1月22日 星期四

Raspberry Pi b+ 用 Python 控制 LCD 16x2 (HD44780) 簡介 Part 2 基本指令介紹


LCD 基本動作指令/資料寫入


這邊要先說明一下怎麼透過這些GPIO pin腳來對LCD下達命令或是寫入一個個的8bit(1 byte)資料.

LCD模組一般來說有兩個基本動作--"寫入指令"和"寫入資料"--我們先來看看怎麼寫入指令:

2014年12月29日 星期一

Raspberry Pi b+ 用 Python 控制 LCD 16x2 (HD44780) 教學 Part 1 硬體設定篇


在玩Raspberry Pi的時候,常常會有需要顯示一些簡單文字訊息的需求。像是開機抓到動態IP位置的時候顯示出來,方便遠端ssh登入。

這個時候用LCD螢幕線得太大又太笨重,用UART又需要準備一條USB-TTL的轉接線用電腦來登入,整個弄得非常的繁雜。所以這種時候就需要下面這個東西--兩行十六字的 LCD 顯示模組:

在電子材料行裡可以用便宜的價格輕易買到,去Google的話常常會被提到的型號或關鍵字不是 HD4478 就是 1602 (16x2十六個字兩行)。雖然型號上有點小差異但是控制指令都一樣。而傳輸資料介面除了基本款的 16 pin腳的版本外還有I2C介面。網路上也有人利用位移暫存器來間接控制基本款的 16 pin腳,這種的方式就以後有時間再來寫了。