2024年12月4日 星期三

[樹藝:micro:bit] 時尚兔玩AI

 

主要材料:樹藝、micro:bit、Smart AI Lens

MakeCode程式碼:


Python程式:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
def on_button_pressed_a():
    global ID
    ID = (ID + 1) % 6
    basic.show_string("" + str((ID)))
    if ID == 0:
        PlanetX_AILens.switchfunc(PlanetX_AILens.FuncList.CARD)
    else:
        PlanetX_AILens.switchfunc(PlanetX_AILens.FuncList.THINGS)
    basic.pause(3000)
input.on_button_pressed(Button.A, on_button_pressed_a)

def doLight():
    if RUN == 0 or (RUN == 5 or RUN == 11):
        pins.digital_write_pin(DigitalPin.P1, 1)
        pins.digital_write_pin(DigitalPin.P2, 0)
        pins.digital_write_pin(DigitalPin.P13, 0)
        pins.digital_write_pin(DigitalPin.P14, 0)
        pins.digital_write_pin(DigitalPin.P15, 0)
    elif RUN == 1 or (RUN == 6 or RUN == 12):
        pins.digital_write_pin(DigitalPin.P1, 0)
        pins.digital_write_pin(DigitalPin.P2, 1)
        pins.digital_write_pin(DigitalPin.P13, 0)
        pins.digital_write_pin(DigitalPin.P14, 0)
        pins.digital_write_pin(DigitalPin.P15, 0)
    elif RUN == 2 or (RUN == 7 or RUN == 13):
        pins.digital_write_pin(DigitalPin.P1, 0)
        pins.digital_write_pin(DigitalPin.P2, 0)
        pins.digital_write_pin(DigitalPin.P13, 1)
        pins.digital_write_pin(DigitalPin.P14, 0)
        pins.digital_write_pin(DigitalPin.P15, 0)
    elif RUN == 3 or (RUN == 8 or RUN == 14):
        pins.digital_write_pin(DigitalPin.P1, 0)
        pins.digital_write_pin(DigitalPin.P2, 0)
        pins.digital_write_pin(DigitalPin.P13, 0)
        pins.digital_write_pin(DigitalPin.P14, 1)
        pins.digital_write_pin(DigitalPin.P15, 0)
    elif RUN == 4 or (RUN == 9 or RUN == 15):
        pins.digital_write_pin(DigitalPin.P1, 0)
        pins.digital_write_pin(DigitalPin.P2, 0)
        pins.digital_write_pin(DigitalPin.P13, 0)
        pins.digital_write_pin(DigitalPin.P14, 0)
        pins.digital_write_pin(DigitalPin.P15, 1)
def checkCard():
    global RUN
    if PlanetX_AILens.number_card(PlanetX_AILens.numberCards.ZERO) and RUN != 0:
        RUN = 0
        radio.send_number(10)
        basic.show_number(0)
    elif PlanetX_AILens.number_card(PlanetX_AILens.numberCards.ONE) and RUN != 1:
        RUN = 1
        radio.send_number(1)
        basic.show_number(1)
    elif PlanetX_AILens.number_card(PlanetX_AILens.numberCards.TWO) and RUN != 2:
        RUN = 2
        radio.send_number(2)
        basic.show_number(2)
    elif PlanetX_AILens.number_card(PlanetX_AILens.numberCards.THREE) and RUN != 3:
        RUN = 3
        radio.send_number(3)
        basic.show_number(3)
    elif PlanetX_AILens.number_card(PlanetX_AILens.numberCards.FOUR) and RUN != 4:
        RUN = 4
        radio.send_number(9)
        basic.show_number(4)
    elif PlanetX_AILens.number_card(PlanetX_AILens.numberCards.FIVE) and RUN != 5:
        RUN = 5
        radio.send_number(5)
        basic.show_number(5)
    elif PlanetX_AILens.number_card(PlanetX_AILens.numberCards.SIX) and RUN != 6:
        RUN = 6
        radio.send_number(4)
        basic.show_number(6)
    elif PlanetX_AILens.number_card(PlanetX_AILens.numberCards.SEVEN) and RUN != 7:
        RUN = 7
        radio.send_number(8)
        basic.show_number(7)
    elif PlanetX_AILens.number_card(PlanetX_AILens.numberCards.EIGHT) and RUN != 8:
        RUN = 8
        radio.send_number(7)
        basic.show_number(8)
    elif PlanetX_AILens.number_card(PlanetX_AILens.numberCards.NINE) and RUN != 9:
        RUN = 9
        radio.send_number(6)
        basic.show_number(9)

def on_button_pressed_b():
    if ID == 1:
        PlanetX_AILens.learn_object(PlanetX_AILens.learnID.ID1)
    elif ID == 2:
        PlanetX_AILens.learn_object(PlanetX_AILens.learnID.ID2)
    elif ID == 3:
        PlanetX_AILens.learn_object(PlanetX_AILens.learnID.ID3)
    elif ID == 4:
        PlanetX_AILens.learn_object(PlanetX_AILens.learnID.ID4)
    elif ID == 5:
        PlanetX_AILens.learn_object(PlanetX_AILens.learnID.ID4)
    basic.pause(6000)
input.on_button_pressed(Button.B, on_button_pressed_b)

def checkLOGO():
    global RUN
    if PlanetX_AILens.object_check(PlanetX_AILens.learnID.ID1) and RUN != 11:
        RUN = 11
        basic.show_string("A")
        radio.send_number(16)
    elif PlanetX_AILens.object_check(PlanetX_AILens.learnID.ID2) and RUN != 12:
        RUN = 12
        basic.show_string("B")
        radio.send_number(17)
    elif PlanetX_AILens.object_check(PlanetX_AILens.learnID.ID3) and RUN != 13:
        RUN = 13
        basic.show_string("C")
        radio.send_number(18)
    elif PlanetX_AILens.object_check(PlanetX_AILens.learnID.ID4) and RUN != 14:
        RUN = 14
        basic.show_string("D")
        radio.send_number(19)
    elif PlanetX_AILens.object_check(PlanetX_AILens.learnID.ID5) and RUN != 15:
        RUN = 15
        basic.show_string("E")
        radio.send_number(20)
RUN = 0
ID = 0
basic.show_icon(IconNames.HEART)
PlanetX_AILens.init_module()
PlanetX_AILens.switchfunc(PlanetX_AILens.FuncList.CARD)
ID = 0
basic.show_leds("""
    . # . . #
    # . # . #
    # # # . #
    # . # . #
    # . # . #
    """)
RUN = 0
radio.set_group(49)
pins.digital_write_pin(DigitalPin.P1, 0)
pins.digital_write_pin(DigitalPin.P2, 0)
pins.digital_write_pin(DigitalPin.P13, 0)
pins.digital_write_pin(DigitalPin.P14, 0)
pins.digital_write_pin(DigitalPin.P15, 0)
Old_Run = 0
count = 12
LED_status = 0

def on_every_interval():
    global LED_status, count, Old_Run
    if Old_Run == RUN:
        if count > 10:
            if LED_status == 0:
                LED_status = 1
                pins.digital_write_pin(DigitalPin.P1, 1)
                pins.digital_write_pin(DigitalPin.P2, 1)
                pins.digital_write_pin(DigitalPin.P13, 1)
                pins.digital_write_pin(DigitalPin.P14, 1)
                pins.digital_write_pin(DigitalPin.P15, 1)
            else:
                LED_status = 0
                pins.digital_write_pin(DigitalPin.P1, 0)
                pins.digital_write_pin(DigitalPin.P2, 0)
                pins.digital_write_pin(DigitalPin.P13, 0)
                pins.digital_write_pin(DigitalPin.P14, 0)
                pins.digital_write_pin(DigitalPin.P15, 0)
        else:
            count = count + 1
    else:
        Old_Run = RUN
        count = 0
loops.every_interval(500, on_every_interval)

def on_forever():
    PlanetX_AILens.camera_image()
    if ID == 0:
        checkCard()
    else:
        checkLOGO()
    if count < 10:
        doLight()
    basic.pause(200)
    basic.show_leds("""
        . # . . #
        # . # . #
        # # # . #
        # . # . #
        # . # . #
        """)
basic.forever(on_forever)

[樹藝micro:bit]歡樂蛙聽語音

 

主要材料:樹藝、micro:bit、語音辨識IC
MakeCode程式碼:


Python程式碼:
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
def on_asr_vocabulary_list_learning_entry_7():
    strip.show_rainbow(1, 360)
    radio.send_number(16)
    basic.show_string("Craft")
asr.on_asr(asr.vocabularyList.LEARNING_ENTRY_7,
    on_asr_vocabulary_list_learning_entry_7)

def on_asr_vocabulary_list_learning_entry_6():
    strip.show_rainbow(1, 360)
    radio.send_number(17)
    basic.show_string("NFU")
asr.on_asr(asr.vocabularyList.LEARNING_ENTRY_6,
    on_asr_vocabulary_list_learning_entry_6)

def on_button_pressed_a():
    asr.set_asr_learn()
    basic.show_leds("""
        # . . . .
        # . . . .
        # . . . .
        # . . . .
        # # # # .
        """)
input.on_button_pressed(Button.A, on_button_pressed_a)

def on_asr_vocabulary_list_learning_entry_8():
    strip.show_rainbow(1, 360)
    radio.send_number(19)
    basic.show_string("Smart")
asr.on_asr(asr.vocabularyList.LEARNING_ENTRY_8,
    on_asr_vocabulary_list_learning_entry_8)

def on_asr_vocabulary_list_learning_entry_10():
    strip.show_rainbow(1, 360)
    radio.send_number(20)
    basic.show_string("Tree Art")
asr.on_asr(asr.vocabularyList.LEARNING_ENTRY_10,
    on_asr_vocabulary_list_learning_entry_10)

def on_asr_vocabulary_list_learning_entry_4():
    basic.show_leds("""
        # # . # #
        # # . # #
        # . # . #
        # . . . #
        . # # # .
        """)
    strip.show_color(neopixel.colors(NeoPixelColors.PURPLE))
    strip.show()
asr.on_asr(asr.vocabularyList.LEARNING_ENTRY_4,
    on_asr_vocabulary_list_learning_entry_4)

def on_button_pressed_b():
    asr.del_asr_learn()
    basic.show_leds("""
        . # # # .
        # . . . .
        # . . . .
        # . . . .
        . # # # .
        """)
input.on_button_pressed(Button.B, on_button_pressed_b)

def on_asr_vocabulary_list_learning_entry_5():
    basic.show_leds("""
        # . . . #
        # . # . #
        # . # . #
        # . . . #
        . # # # .
        """)
    strip.show_color(neopixel.colors(NeoPixelColors.GREEN))
    strip.show()
asr.on_asr(asr.vocabularyList.LEARNING_ENTRY_5,
    on_asr_vocabulary_list_learning_entry_5)

def on_asr_vocabulary_list_learning_entry_9():
    strip.show_rainbow(1, 360)
    radio.send_number(18)
    basic.show_string("STEAM")
asr.on_asr(asr.vocabularyList.LEARNING_ENTRY_9,
    on_asr_vocabulary_list_learning_entry_9)

def on_asr_vocabulary_list_learning_entry_2():
    basic.show_leds("""
        . # # # .
        # . . . #
        # . . . #
        # . . . #
        . # # # .
        """)
    strip.show_color(neopixel.colors(NeoPixelColors.BLACK))
    strip.show()
asr.on_asr(asr.vocabularyList.LEARNING_ENTRY_2,
    on_asr_vocabulary_list_learning_entry_2)

def on_asr_vocabulary_list_learning_entry_3():
    basic.show_leds("""
        . # # # .
        # # # # #
        # # # # #
        # # # # #
        . # # # .
        """)
    strip.show_color(neopixel.colors(NeoPixelColors.RED))
    strip.show()
asr.on_asr(asr.vocabularyList.LEARNING_ENTRY_3,
    on_asr_vocabulary_list_learning_entry_3)

def on_asr_vocabulary_list_hi_shaun():
    basic.show_icon(IconNames.HEART)
    radio.send_number(0)
asr.on_asr(asr.vocabularyList.HI_SHAUN, on_asr_vocabulary_list_hi_shaun)

def on_asr_vocabulary_list_learning_entry_1():
    basic.show_leds("""
        . # . # .
        # . # . #
        . # . # .
        # . # . #
        . # . # .
        """)
    strip.show_rainbow(1, 360)
    radio.send_number(1)
asr.on_asr(asr.vocabularyList.LEARNING_ENTRY_1,
    on_asr_vocabulary_list_learning_entry_1)

strip: neopixel.Strip = None
basic.show_icon(IconNames.HAPPY)
strip = neopixel.create(DigitalPin.P0, 32, NeoPixelMode.RGB)
strip.show_rainbow(1, 360)
radio.set_group(49)

def on_forever():
    strip.rotate(1)
    strip.show()
    basic.pause(sonar.ping(DigitalPin.P1, DigitalPin.P2, PingUnit.CENTIMETERS) * 10)
basic.forever(on_forever)

[樹藝micro:bit] 唱唱鼠說故事

 

主要零件:樹藝材料、micro:bit、MP3播放器

MakeCode程式碼:


Python程式碼:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
def sayStory():
    basic.show_number(count)
    basic.pause(1000)
    mp3Player.set_tracking(count + 1, mp3Player.repeatList.NO)
    mp3Player.set_volume(volumn)
    mp3Player.execute(mp3Player.playType.PLAY)

def on_received_number(receivedNumber):
    global count
    if receivedNumber == 10:
        count = 0
        sayStory()
    elif receivedNumber == 6:
        count = 9
        sayStory()
    elif receivedNumber == 7:
        count = 8
        sayStory()
    elif receivedNumber == 8:
        count = 7
        sayStory()
    elif receivedNumber == 9:
        count = 4
        sayStory()
    elif receivedNumber >= 16 and receivedNumber <= 20:
        count = receivedNumber - 1
        sayStory()
    elif receivedNumber == 1:
        count = 1
        sayStory()
    elif receivedNumber == 2:
        count = 2
        sayStory()
    elif receivedNumber == 3:
        count = 3
        sayStory()
    elif receivedNumber == 4:
        count = 6
        sayStory()
    elif receivedNumber == 5:
        count = 5
        sayStory()
radio.on_received_number(on_received_number)

# 0.歡樂蛙
# 1.歡樂猪
# 2.智齡鳥
# 3.酷烗猪
# 4.行動牛
# 5.亮亮鼠
# 6.彩虹鳥
# 7.蓪草燈
# 8.先知鳥
# 9.時尚兔

def on_button_pressed_a():
    global count
    mp3Player.execute(mp3Player.playType.STOP)
    count = (count + 1) % 20
    sayStory()
input.on_button_pressed(Button.A, on_button_pressed_a)

def on_button_pressed_b():
    global volumn
    volumn = (volumn + 1) % 30
    basic.show_number(volumn)
    mp3Player.set_volume(volumn)
input.on_button_pressed(Button.B, on_button_pressed_b)

def on_pin_pressed_p1():
    global count
    mp3Player.execute(mp3Player.playType.STOP)
    count = (count + 1) % 20
    sayStory()
input.on_pin_pressed(TouchPin.P1, on_pin_pressed_p1)

volumn = 0
count = 0
basic.show_icon(IconNames.HEART)
count = 0
volumn = 15
mp3Player.mp3_set_serial(SerialPin.P2)
mp3Player.execute(mp3Player.playType.STOP)
loud_sound = 1
radio.set_group(49)

2024年11月25日 星期一

淺談MapReduce,用ChatGPT來產生中英文字詞統計程式

以下的文章和程式都是用ChatGPT產生,本篇文章主要是探討字詞統計程式。

本篇程式是統計單字出現次數,並且可以處理多次輸入,具有廣泛的應用場景。以下是幾個常見的應用領域:

文字分析與自然語言處理 (NLP)

  • 詞頻分析 (Word Frequency Analysis): 用於分析文本中單字的出現次數,挖掘出重要的關鍵字或熱門話題。
  • 情感分析 (Sentiment Analysis): 藉由詞頻統計,了解使用者的情緒傾向,例如正面或負面的用詞。
  • 生成詞雲 (Word Cloud): 統計詞頻後用來生成詞雲,作為可視化展示工具。

2. 學術與教育

  • 閱讀理解測驗: 統計學生在文章中使用或理解的單字,幫助教師評估學生的詞彙能力。
  • 語言學研究: 用於語料庫中詞頻的分析,協助研究某一語言的使用特性。
  • 作文輔助: 幫助學生或作家了解某篇文章中重複使用的詞,改善文字表達。

3. 企業與市場研究

  • 客戶回饋分析: 分析客戶評論中的詞頻,快速找出客戶最常提到的關鍵點(如問題或優點)。
  • 社群媒體監控: 統計用戶在社群媒體上提到某品牌或主題的頻率,追蹤流行趨勢。
  • SEO 優化: 統計網站文章中的關鍵字,優化搜尋引擎排名。

4. 數據處理與監控

  • 日誌分析 (Log Analysis): 分析伺服器或應用程式日誌中的關鍵字,排查錯誤或監控異常活動。
  • 大數據預處理: 將海量文本資料切割、分類,統計詞頻,作為機器學習的特徵輸入。

5. 遊戲與娛樂

  • 文字遊戲: 用於開發文字相關的遊戲,例如文字拼圖或詞頻挑戰遊戲。
  • 劇本分析: 統計劇本中角色的對話詞頻,分析角色的重要性或語言風格。

6. 法律與媒體

  • 法律文件分析: 統計法律文本中關鍵術語的頻率,用於案件的準備或合同分析。
  • 新聞文章分析: 分析新聞文本中的詞頻,判斷媒體報導的重點和角度。

總結:

這樣的程式對任何涉及文字數據處理分析的場合都非常實用,尤其適合需要快速統計並提取信息的場景。

範例一、一個簡單的 Python 程式,可以從終端機讀取使用者輸入的字串並將其顯示

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 從終端機讀取字串並輸出
def main():
    # 提示使用者輸入
    user_input = input("請輸入一段文字:")
    
    # 輸出使用者輸入的文字
    print(f"您輸入的文字是:{user_input}")

if __name__ == "__main__":
    main()

執行結果:
請輸入一段文字:今天天氣很好
您輸入的文字是:今天天氣很好

範例二、從終端機讀取一段文字,將其切割成單字,並輸出結果

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# 從終端機讀取字串並切割成單字
def main():
    # 提示使用者輸入
    user_input = input("請輸入一段文字:")
    
    # 切割文字為單字(以空白為分隔符)
    words = user_input.split()
    
    # 輸出切割結果
    print("切割後的單字為:")
    for word in words:
        print(word)

if __name__ == "__main__":
    main()

ChatGPT給出的測試句字和執行結果:

執行結果:
請輸入一段文字:今天天氣很好,我想去散步。
切割後的單字為:
今天天氣很好,我想去散步。

改輸入英文,執行結果:
請輸入一段文字:The weather is nice today and I want to go for a walk.
切割後的單字為:
The
weather
is
nice
today
and
I
want
to
go
for
a
walk.

範例三、讀取一段文字,切割成單字,並使用映射將每個單字及其出現次數存入字典

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
# 從終端機讀取字串,切割成單字,並計算每個單字的出現次數
def main():
    # 提示使用者輸入
    user_input = input("請輸入一段文字:")
    
    # 切割文字為單字(以空白為分隔符)
    words = user_input.split()
    
    # 使用字典計算單字出現次數
    word_count = {}
    for word in words:
        word_count[word] = word_count.get(word, 0) + 1  # 如果單字不存在,預設為 0
    
    # 輸出結果
    print("單字出現次數:")
    for word, count in word_count.items():
        print(f"{word}: {count}")

if __name__ == "__main__":
    main()

執行結果:
請輸入一段文字:The weather is very good today. I went for a walk today. I had a great time walking.
單字出現次數:
The: 1
weather: 1
is: 1
very: 1
good: 1
today.: 2
I: 2
went: 1
for: 1
a: 2
walk: 1
had: 1
great: 1
time: 1
walking.: 1

歸約(Reduce)可以將資料進一步簡化或統合,例如計算單字總數。以下是整合 Map 和 Reduce 的程式範例,使用 Python 的 functools.reduce 進行歸約。

範例四、計算所有單字的總出現次數

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
from functools import reduce

# 從終端機讀取字串,切割成單字,計算單字出現次數並進行歸約
def main():
    # 提示使用者輸入
    user_input = input("請輸入一段文字:")
    
    # 切割文字為單字(以空白為分隔符)
    words = user_input.split()
    
    # 使用字典計算單字出現次數
    word_count = {}
    for word in words:
        word_count[word] = word_count.get(word, 0) + 1  # 如果單字不存在,預設為 0
    
    # 使用 Reduce 計算單字的總出現次數
    total_count = reduce(lambda acc, count: acc + count, word_count.values(), 0)
    
    # 輸出結果
    print("單字出現次數:")
    for word, count in word_count.items():
        print(f"{word}: {count}")
    
    print(f"單字總出現次數:{total_count}")

if __name__ == "__main__":
    main()

執行結果:
請輸入一段文字:The weather is very good today. I went for a walk today. I had a great time walking.
單字出現次數:
The: 1
weather: 1
is: 1
very: 1
good: 1
today.: 2
I: 2
went: 1
for: 1
a: 2
walk: 1
had: 1
great: 1
time: 1
walking.: 1
單字總出現次數:18

以下是一個完整的程式,允許使用者重複輸入文字,直到輸入空字串為止。程式會將輸入的文字切割成單字,計算每個單字的出現次數,並在結束時輸出結果:

範例五、完整的程式

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
from functools import reduce

def main():
    print("請開始輸入文字(輸入空字串以結束):")
    
    # 用來存儲所有輸入的文字
    all_words = []
    
    while True:
        user_input = input("> ")
        if user_input.strip() == "":  # 空字串結束條件
            break
        # 切割並加入總單字列表
        words = user_input.split()
        all_words.extend(words)
    
    # 使用字典計算單字出現次數
    word_count = {}
    for word in all_words:
        word_count[word] = word_count.get(word, 0) + 1  # 累加單字次數
    
    # 使用 Reduce 計算單字的總出現次數
    total_count = reduce(lambda acc, count: acc + count, word_count.values(), 0)
    
    # 輸出結果
    print("\n單字出現次數統計:")
    for word, count in word_count.items():
        print(f"{word}: {count}")
    
    print(f"\n單字總出現次數:{total_count}")

if __name__ == "__main__":
    main()

執行結果:
請開始輸入文字(輸入空字串以結束):
> The weather is very good today.
> I went for a walk today.
> I had a great time walking.

單字出現次數統計:
The: 1
weather: 1
is: 1
very: 1
good: 1
today.: 2
I: 2
went: 1
for: 1
a: 2
walk: 1
had: 1
great: 1
time: 1
walking.: 1

單字總出現次數:18

上述程式使用的是基於空白分隔的 split() 方法來分割文字,這在處理英文或其他以空白分隔單詞的語言時非常有效。然而,中文並沒有空白來分隔單詞,因此需要使用專門的中文斷詞工具

改進方法:使用中文斷詞工具

在 Python 中,jieba 是一個強大的中文斷詞庫,可以有效地將中文句子分割成單詞(或詞語)。

以下是針對中文的改良版程式:

範例六、中文字詞統計

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import jieba
from functools import reduce

def main():
    print("請開始輸入文字(輸入空字串以結束):")
    
    # 用來存儲所有輸入的詞語
    all_words = []
    
    while True:
        user_input = input("> ")
        if user_input.strip() == "":  # 空字串結束條件
            break
        # 使用 jieba 將輸入的中文文字斷詞
        words = jieba.lcut(user_input)  # lcut 返回列表
        all_words.extend(words)
    
    # 使用字典計算單詞出現次數
    word_count = {}
    for word in all_words:
        word_count[word] = word_count.get(word, 0) + 1  # 累加單詞次數
    
    # 使用 Reduce 計算單詞的總出現次數
    total_count = reduce(lambda acc, count: acc + count, word_count.values(), 0)
    
    # 輸出結果
    print("\n單字或詞語出現次數統計:")
    for word, count in word_count.items():
        print(f"{word}: {count}")
    
    print(f"\n總詞語數量:{total_count}")

if __name__ == "__main__":
    main()

執行結果:
請開始輸入文字(輸入空字串以結束):
> 今天天氣很好
Building prefix dict from the default dictionary ...
Dumping model to file cache C:\Users\CHENG-~1\AppData\Local\Temp\jieba.cache
Loading model cost 0.526 seconds.
Prefix dict has been built successfully.
> 今天去散步
> 散步讓人開心

單字或詞語出現次數統計:
今天: 2
天氣: 1
很: 1
好: 1
去: 1
散步: 2
讓: 1
人: 1
開心: 1

總詞語數量:11

2024年11月18日 星期一

利用ChatGPT產生訂閱MQTT主題的Python程式

 

訂閱程式碼:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import paho.mqtt.client as mqtt
import json

# MQTT broker 設定
BROKER = "broker.mqttgo.io"
PORT = 1883
TOPIC = "sensor/light"
CLIENT_ID = "LightSensorSubscriber"

# 當接收到消息時的回調函數
def on_message(client, userdata, msg):
    try:
        # 解碼消息並解析光線亮度
        payload = json.loads(msg.payload.decode())
        light_intensity = payload.get("light_intensity", 0)
        print(f"Received light intensity: {light_intensity}")

        # 判斷亮度是否低於 256
        if light_intensity < 256:
            print("點亮電燈")
    except Exception as e:
        print(f"Error processing message: {e}")

# 建立 MQTT 客戶端
client = mqtt.Client(CLIENT_ID)

# 設置回調函數
client.on_message = on_message

def subscribe_to_light_data():
    try:
        client.connect(BROKER, PORT, 60)
        print(f"Connected to MQTT broker: {BROKER}")

        # 訂閱主題
        client.subscribe(TOPIC)
        print(f"Subscribed to topic: {TOPIC}")

        # 進入阻塞循環等待消息
        client.loop_forever()
    except KeyboardInterrupt:
        print("\nDisconnected from broker.")
        client.disconnect()

if __name__ == "__main__":
    subscribe_to_light_data()

說明

  1. on_message 回調函數
    當收到主題上的消息時,會解析 light_intensity 數值。如果亮度低於 256,輸出「點亮電燈」。

  2. JSON 格式處理
    確保發佈的訊息格式正確(如 {"light_intensity": <value>})。訂閱程式使用 json.loads 解析訊息。

  3. 執行訂閱程式
    啟動程式後,它會持續監聽 sensor/light 主題上的數據。

  4. 測試
    啟動發佈程式和訂閱程式後,當亮度低於 256 時,應該在訂閱程式中看到「點亮電燈」的輸出。


如果有其他需求或問題,隨時告訴我!

執行結果:


再問ChatGPT:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import paho.mqtt.client as mqtt
import random
import time
import json  # 用於 JSON 格式化

# MQTT broker 設定
BROKER = "broker.mqttgo.io"
PORT = 1883
TOPIC = "sensor/light"
CLIENT_ID = "LightSensorPublisher"

# 建立 MQTT 客戶端
client = mqtt.Client(CLIENT_ID)

def publish_light_data():
    try:
        client.connect(BROKER, PORT, 60)
        print(f"Connected to MQTT broker: {BROKER}")

        while True:
            # 模擬光線亮度數據 (0 到 1000 lux)
            light_intensity = random.randint(0, 1000)
            payload = {"light_intensity": light_intensity}
            
            # 將數據轉換為 JSON 字串
            client.publish(TOPIC, json.dumps(payload))
            print(f"Published: {payload} to topic {TOPIC}")

            time.sleep(5)  # 每 5 秒發佈一次
    except KeyboardInterrupt:
        print("\nDisconnected from broker.")
        client.disconnect()

if __name__ == "__main__":
    publish_light_data()

訂閱程式(保持不變)
訂閱程式的解析邏輯已經正確,無需修改。

發佈端執行結果:

接收端執行結果:


MQTTGO的畫面:



利用ChatGPT產生發布MQTT主題的Python程式


 本文利用ChatGPT來產生物聯網MQTT之Python程式,其提示語和所產生的程式如下:


程式碼:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import paho.mqtt.client as mqtt
import random
import time

# MQTT broker 設定
BROKER = "broker.mqttgo.io"
PORT = 1883
TOPIC = "sensor/light"
CLIENT_ID = "LightSensorPublisher"

# 建立 MQTT 客戶端
client = mqtt.Client(CLIENT_ID)

def publish_light_data():
    try:
        client.connect(BROKER, PORT, 60)
        print(f"Connected to MQTT broker: {BROKER}")

        while True:
            # 模擬光線亮度數據 (0 到 1000 lux)
            light_intensity = random.randint(0, 1000)
            payload = {"light_intensity": light_intensity}
            client.publish(TOPIC, str(payload))
            print(f"Published: {payload} to topic {TOPIC}")

            time.sleep(5)  # 每 5 秒發佈一次
    except KeyboardInterrupt:
        print("\nDisconnected from broker.")
        client.disconnect()

if __name__ == "__main__":
    publish_light_data()


把上述程式利用Python IDLE來執行,發生下列錯誤的問題。

把上述問題,詢問ChatGPT,其回答如下:
更新程式碼如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import paho.mqtt.client as mqtt
import random
import time

# MQTT broker 設定
BROKER = "broker.mqttgo.io"
PORT = 1883
TOPIC = "sensor/light"
CLIENT_ID = "LightSensorPublisher"

# 建立 MQTT 客戶端
client = mqtt.Client(client_id=CLIENT_ID, protocol=mqtt.MQTTv311, callback_api_version=5)

def publish_light_data():
    try:
        client.connect(BROKER, PORT, 60)
        print(f"Connected to MQTT broker: {BROKER}")

        while True:
            # 模擬光線亮度數據 (0 到 1000 lux)
            light_intensity = random.randint(0, 1000)
            payload = {"light_intensity": light_intensity}
            client.publish(TOPIC, str(payload))
            print(f"Published: {payload} to topic {TOPIC}")

            time.sleep(5)  # 每 5 秒發佈一次
    except KeyboardInterrupt:
        print("\nDisconnected from broker.")
        client.disconnect()

if __name__ == "__main__":
    publish_light_data()



經測試方法1,發生下列問題。


採用方法2,重新安裝paho-mqtt套件。

執行結果:


MQTTGO broker的畫面如本文最上圖,記得要按下連線鈕,並訂閱sensor/light主題。

2024年11月11日 星期一

wokwi模擬工具:MicroPython MQTT Weather Logger (ESP32)

wokwi這套模擬工具值得推薦,不但可以模擬ESP32,也能模擬Pico、SIM32和Arduno。
網址:https://wokwi.com/
以下是用它來模擬MQTT。


參考網址:https://wokwi.com/projects/322577683855704658