10^11
開始課程前,請先下載好
線上版本也可以
相信各位都看得懂英文
一定可以自行操作的
啾咪><
姓名:陳芊邑(10^11)
職位:社長x教學
網名:C.Y
綽號:千億姊姊、小清
興趣:休眠、跟數學玩
專長:壓線不遲到、成為瘋子
附註:我的精神狀態有點美麗,見諒一下
然後我很喜歡跟其他瘋資幹部們偷抱抱,但我是異性戀
這是我DC頭像
對這是情頭
TG提倡自由與開放,其程式碼和 API 向所有人公開。透過直觀的操作介面,使用者能輕鬆與機器人互動,完成教學、遊戲、搜尋、提醒,甚至控制物聯網等功能。
這是我的課程介紹,對這是一串贛話:
TG就是跟line很像的社交軟體,但它的隱私性非常強,
且bot的程式碼是完全開放的,
你可以把別人的程式碼修一下然後再上傳,跟DC Bot不太一樣,
然後它功能一堆
我簡單翻譯一下:
對我知道它很醜
但這就是生產機器人專用的帳號
它爸
4. 輸入 /newbot -> 輸入 Bot Name -> 輸入 Bot 的 username
*Emoji、圖片、貼圖都不能作為名稱 !
*Username 可用:
0-9、a-z、A-Z、-,
且要以 "bot" 作為結尾
5. 成功後,會回傳 API token,點一下就可以直接複製
*每個 Token 都對應到一個合法 Bot
*程式要有Token,Bot 才能夠被識別
6. 點選新建的 Bot 連結,並按下start
大概會講這些
如果各大電神覺得這part贛話太多,請幫我指導一下你隊友
這part可能很快就能過去了
print("easy")
#簡單的單行註解
"""
簡單的多行註解
"""然後python不用寫分號
name="瘋子"
print(name)變數名稱=變數值,基本上概念你都學過了
| 型態 | 變數宣告 | 程式 | 執行結果 |
|---|---|---|---|
| 整數 | int | print(int(3.14)) | 3 |
| 浮點數 | float | print(float(1)) | 1.0 |
| 布林值 | bool | print(bool(1)) | True |
算術運算子,基本上都是你學過的
| 運算子 | 說明 | 程式 | 執行結果 |
|---|---|---|---|
| + | 加 | A=5+3 | A=8 |
| - | 減 | A=5-3 | A=2 |
| * | 乘 | A=5*3 | A=15 |
| / | 浮點除法 | A=5/2 | A=2.5 |
| // | 整除 | A=5//2 | A=2 |
| % | 求餘 | A=5%2 | A=1 |
| ** | 次方 | A=5**2 | A=25 |
邏輯運算子,基本上都是你學過的
and 且:連接的兩個敘述都要正確才是 True
or 或:連接的兩個敘述只要有一個正確就是 True
not 非:否定一個敘述
啊丟,python不能用&&這種東西
哭了
常用字串處理方法:
s1 = "楓資是瘋資也是瘋子"
print(s1)
#單行字串
zsisc = '''
楓資
是瘋資
也是瘋子
'''
print(zsisc)
#多行字串常用字串處理方法:
print("Hello World".lower())
# 變成小寫
print("Hello World".upper())
# 變成大寫str.split([分隔字])
將字串按照指定的分隔字分割
text="Hello World"
words=text.split()
print(words)
#['Hello','World']
print(words[0])
# Hello
print(words[1])
# World
date="2008-01-01"
parts=date.split('-')
print(parts)
# ['2008','01','01']額外介紹一個好用的東西,f-string
name="瘋子"
print("楓資幹部都是",name,"很合理")
#輸出:楓資幹部都是 瘋子 很合理name="瘋子"
print(f"楓資幹部都是{name}很合理")
##輸出:楓資幹部都是瘋子很合理first=8
second=9
print(f"楓資幹部都是{first+second}很合理")
##輸出:楓資幹部都是17很合理*使用單引號「'」與雙引號「"」
在Python都會被視為字串
變數=input([提示字串])
name=input("請輸入瘋子:")
print(f"{name}是怪人")
#輸入:吱吱 輸出:吱吱是怪人1.if…
2.if…else…
3.if…elif…else…
4.巢狀 if
比c++多elif、冒號、縮排,少括號
chieh=87
if chieh>90:
print("chieh is gami")
elif chieh>80:
print("chieh is 甲殼類動物")
else:
print("chieh is not human")對,它沒有下放的問題,我可以不用跟我女鵝吵架了
這種時候就會突然覺得Python挺好的
巢狀長這樣:
chieh=87
gami=8+9
if chieh>90:
print("chieh is 企鵝")
else:
if gami>87:
print("gami is 怪人")
elif gami>66:
print("gami is 蜜獾")
else:
print("gami is 甲殼類動物")
#gami is 甲殼類動物跟c++的語法有差,但概念都一樣
for i in range(5):
print("chieh is 企鵝")
# 輸出5次chieh is 企鵝
for i in range(2,10,2):
print(i)
# 輸出2 4 6 81.for 變數 in 序列:
其中,序列中的值可以依序賦值給變數
多數時候會使用range()遍歷,當然也可以是list、dictionary之類的
range(起始值,結束值,公差)
sum=0
i = 3
while i < 13:
sum = sum + i
i = i + 3
print(i)
# 輸出 6 9 12 152.while 條件:
i=初始值
while i <= 終止值:
程式
i=i+-公差
*continue&break 在python的用法與c++同
分別是跳過當前迴圈繼續執行&跳出迴圈
如果各大電神覺得這part贛話太多,請幫我指導一下你隊友
這part可能很快就能過去了
先來解釋資料結構的用途
先來解釋資料結構的用途
如果說變數是一個盒子,我們把值丟在盒子裡
變數
那麼,資料結構就是抽屜
變數
變數
變數
變數
變數
我們把資料結構當成一種整理工具
將相關的資料整合
使程式碼更加簡潔、能更靈活的操作
進而進行資料分析
在製作專案上很常用
變數
變數
變數
變數
變數
更生活一點的說法,就是把書分類,放在書櫃裡
重生文
帶球跑
穿越文
霸道總裁
強制愛
化學
物理
生物
數學
地科
笑鰲江湖
申鵰俠侶
田龍八部
路鼎記
血山飛狐
很明顯他們應該這樣分配(沒有版權問題真好)
重生文
帶球跑
穿越文
霸道總裁
強制愛
化學
物理
生物
數學
地科
笑鰲江湖
申鵰俠侶
田龍八部
路鼎記
血山飛狐
網文
學術
仙俠
list的宣告方式&輸出
# 使用[] 宣告
empty_list=[]
anime_menu=["膽大黨","blue lock","哎咕島","夢幻島","我推"]
anime_like=[5,4,3,2,1]
print(anime_menu)
print(anime_like)
list的宣告方式&輸出
#使用list()將其它資料型態轉換成list
number_list=list(range(1,11))
print(number_list)
#輸出[1,2,3,4,5,6,7,8,9,10]list的宣告方式&輸出
#使用條件式(list comprehensions)
even_number_list=[i for i in range(1,11) if i%2==0]
#符合條件的數字i加入到新的清單中。
print(even_number_list)
#使用迴圈
even_number_list=[]
for i in range(1, 11):
if i % 2 == 0:
even_number_list.append(i)
print(even_number_list)
#輸出[2,4,6,8,10]使用index取用list的值
anime_menu=["膽大黨","blue lock","哎咕島","夢幻島","我推"]
anime_like=[5,4,3,2,1]
print(anime_menu[0])
print(anime_like[-1])
print(anime_menu[0:4:2])
print(anime_like[:])
print(anime_like[::-1])5個print分別輸出?
使用index取用list的值
anime_menu=["膽大黨","blue lock","哎咕島","夢幻島","我推"]
anime_like=[5,4,3,2,1]
print(anime_menu[0])
#膽大黨
print(anime_like[-1])
#1
print(anime_menu[0:4:2])
#['膽大黨','哎咕島']
#[開始:結束:間隔]
print(anime_like[:])
#[5,4,3,2,1]
print(anime_like[::-1])
#[1,2,3,4,5]
#[:n]->前n個元素
#[m:]->跳過前m個元素
使用index取用list的值(迴圈)
anime_menu=["膽大黨","blue lock","哎咕島","夢幻島","我推"]
anime_like=[5,4,3,2,1]
for i in range(5):
print(anime_menu[i])
for i in anime_menu:
print(i)
"""
輸出:
膽大黨
blue lock
哎咕島
夢幻島
我推
"""介紹一些常用的method:
(看看就好)
number_list=[5,4,3,2,1]
number_list.append(6)
#新增值到list的最後->[5,4,3,2,1,6]
number_list.insert(2,7)
#在指定位置新增值->[5,4,7,3,2,1,6]
number_list.remove(7)
#移除指定值->[5,4,3,2,1,6]
del number_list[5]
#移除指定位置的值->[5,4,3,2,1]
number_list.sort()
#排序->[1,2,3,4,5]
number_list.reverse()
#反轉->[5,4,3,2,1]
number_list.pop()
#移除最後一個值->[5,4,3,2]
number_list2=number_list.copy()
#將list複製到list2
number_list.clear()
#清空所有值[]
print(len(number_list2))
#計算list2中的值的數量->4.append()
.insert()
.remove()
del list[]
.reverse()
.pop()
.copy()
.clear()
len(list)
學完這些肯定會想:
那我們是不是可以把list合併呢?
Emmmm......我們先來看看list裡面的list
啊對,就是大家最喜歡的二維
anime_menu=[["膽大黨",5],["blue lock",4],["哎咕島",3],["夢幻島",2],["我推",1]]
print(anime_menu[0])
#輸出['膽大黨',5]
anime_menu[2][1]=5
#修改二維list中的值['哎咕島',5]然後很直接了當的使用zip合併list
anime_menu=["膽大黨","blue lock","哎咕島","夢幻島","我推"]
anime_like=[5,4,3,2,1]
anime_menu_like=list(zip(anime_menu,anime_like))
print(anime_menu_like)
#輸出[('膽大黨',5),('blue lock',4),('哎咕島',3),('夢幻島',2),('我推',1)]小延伸:
a=[1,2,3]
b=a
b.append(4)
print(a)你們覺得這會輸出什麼?
小延伸:
a=[1,2,3]
b=a
b.append(4)
print(a)
#輸出[1,2,3,4]為什麼?
理想上
實際上
使用copy就解決了這個問題
a=[1,2,3]
b=a.copy()
b.append(4)
print(a)
#輸出[1,2,3]每筆資料分別包含{"key":"value"}
key是唯一的,value可以是任何資料型態
舉例來說:
| key | value |
|---|---|
| 動畫 | Hunter × Hunter |
| 作者 | Yoshirin |
| 主角 | 大傑 |
| 我推角 | 奇犽、沒下船那個 |
| 更新速度 | 超慢 |
你們也可以把自我介紹弄成這樣
但由於本人有點害羞所以還是算了
| key | value |
|---|---|
| 動畫 | Hunter × Hunter |
| 作者 | Yoshirin |
| 主角 | 大傑 |
| 我推角 | 奇犽、沒下船那個 |
| 更新速度 | 超慢 |
anime={
"動畫":"Hunter × Hunter",
"作者":"Yoshirin",
"主角":"大傑",
"我推角":["奇犽","沒下船那個"],
"更新速度":"超慢"
}也可以這樣宣告
anime={
"動畫":"Hunter × Hunter",
"作者":"Yoshirin",
"主角":"大傑",
"我推角":["奇犽","沒下船那個"],
"更新速度":"超慢"
}anime=dict(
動畫="Hunter × Hunter",
作者="Yoshirin",
主角="大傑",
我推角=["奇犽","沒下船那個"],
更新速度="超慢"
)輸出方式:
anime={
"動畫":"Hunter × Hunter",
"作者":"Yoshirin",
"主角":"大傑",
"我推角":["奇犽","沒下船那個"],
"更新速度":"超慢"
}
print(anime)
#輸出整個字典
#{'動畫':'Hunter × Hunter','作者':'Yoshirin','主角':'大傑','我推角':['奇犽','沒下船那個'],'更新速度':'超慢'}
print(anime["我推角"])
#['奇犽','沒下船那個']使用方式跟list差不多
也是那幾種方法可以用
anime=dict(
動畫="Hunter × Hunter",
作者="Yoshirin",
主角="大傑",
我推角=["奇犽","沒下船那個"],
更新速度="超慢"
)
anime["更新速度"]="有點慢"
print(anime["更新速度"])
#有點慢
anime.update({"更新速度":"有在更新了"})
print(anime["更新速度"])
#有在更新了
like=anime.pop("我推角")
print(like)
#['奇犽','沒下船那個']如果想
從dict裡面抓取
key或value
該怎麼做?
anime=dict(
動畫="Hunter × Hunter",
作者="Yoshirin",
主角="大傑",
我推角=["奇犽","沒下船那個"],
更新速度="超慢"
)
key=anime.keys()
print(key)
#dict_key(['動畫','作者','主角','我推角','更新速度'])
value=anime.values()
for value in anime.values():
print(value)
"""
Hunter × Hunter
Yoshirin
大傑
['奇犽','沒下船那個']
超慢
"""如果想
兩個一起取得呢?
anime=dict(
動畫="Hunter × Hunter",
作者="Yoshirin",
主角="大傑",
我推角=["奇犽","沒下船那個"],
更新速度="超慢"
)
item=anime.items()
for key,value in item:
print(f"key:{key},value:{value}")
"""
key:動畫,value:Hunter × Hunter
key:作者,value:Yoshirin
key:主角,value:大傑
key:我推角,value:['奇犽', '沒下船那個']
key:更新速度,value:超慢
"""來做個小練習:
name_dic={
"吱吱":"變態",
"嘎米":"怪人",
"葉子":"熬葉",
"切魚":"女鵝",
"起飛":"官配",
"呱呱":"呱"
}
我在路上撿了來路不明的字典
我有點好奇,所以想要設計一個程式
有三個開發要求:
1.查詢此人特色
2.更新此人特色
3.印出此字典
4.結束程式
來做個小練習:
name_dic={
"吱吱":"變態",
"嘎米":"怪人",
"葉子":"熬葉",
"切魚":"女鵝",
"起飛":"官配",
"呱呱":"呱"
}
重視客戶UX體驗的人們,打算提供以下服務:
先詢問使用者選擇哪種操作
再問執行此操作的對象
若是使用者輸入的指令錯誤
可以另外告知他們
這是解答,盡量補藥複製喔啾咪
name_dic={
"吱吱":"變態",
"嘎米":"怪人",
"葉子":"熬葉",
"切魚":"女鵝",
"起飛":"官配",
"呱呱":"呱"
}
while True:
print("1.查詢此人特色")
print("2.更新此人特色")
print("3.印出此字典")
print("4.結束程式")
choice=input("是時候做出選擇了:")
if choice=="1":
name=input("輸入名字:")
if name in name_dic:
print(f"{name}的特色是:{name_dic[name]}")
else:
print("他不是瘋子")
elif choice=="2":
name = input("輸入名字:")
if name in name_dic:
new=input(f"請輸入{name}的新特色:")
name_dic[name]=new
print(f"{name}的特色已更新為:{new}")
else:
print("他不是瘋子")
elif choice=="3":
for name,name_dic[name] in name_dic.items():
print(f"{name}:{name_dic[name]}")
elif choice=="4":
print("結束")
break
else:
print("眼睛不好要去看醫生")
我們還有很多課程
這只是個開始
如果各大電神覺得這part贛話太多,請幫我指導一下你隊友
這part可能很快就能過去了
function的基本架構
def zsisc(parameters1,parameters2):
chyun=parameters1+parameters2
return chyun
print(zsisc(8,9))
"""
def 函數名稱(參數1, 參數2, ...):
函數程式碼
return 返回值
"""匿名函式 lambda:
簡潔的好東西
r=int(input())
#匿名用法
print((lambda r:r*r*3.14)(r))
#不匿名用法
area=lambda r:r*r*3.14
print(area(r))
#輸出圓面積裝飾子Decorator:
裝飾器的本質是一個函數,它接收一個函數作為參數,並返回一個新的函數,從而動態地為原函數添加功能。
這聽起來有點難懂
我舉個栗子
裝飾子Decorator:
簡單來說就是裝飾
腦子(函式)
書(裝飾)
+
裝飾子Decorator:
簡單來說就是裝飾
會讀書的腦子(裝飾後函式)
裝飾子Decorator:先來看看沒有語法蜜糖的情況
這種每用一次就要寫一次有點麻煩
import time
def timing(func):
print("Start...")
t1 = time.time()
func()
t2 = time.time()
print("Elapsed time(secs):", t2 - t1)
def works():
total = 0
for i in range(10000):
total += i
print("total:", total)
timing(works)函式裡面包一個函式
import time
def timing(func):
def wrapper():
print("Start...")
t1 = time.time()
func()
t2 = time.time()
print("Elapsed time(secs):", t2 - t1)
return wrapper
def works():
total = 0
for i in range(10000):
total += i
print("total:", total)
works = timing(works)
#將包裝過的函式再重新命名回原來被包裝的函式名稱
#為原始的函式加上了計時的功能, 同時又可以維持原始的函式名稱
works()有沒有可能更簡潔?
裝飾子Decorator:
import time
def timing(func):
def wrapper():
print("Start...")
t1 = time.time()
func()
t2 = time.time()
print("Elapsed time(secs):", t2 - t1)
return wrapper
@timing
def works():
total = 0
for i in range(10000):
total += i
print("total:", total)
works()用@就解決了
作用域scope:
def zsisc(parameters1,parameters2):
chyun=parameters1+parameters2
return chyun
print(zsisc(8,9))
print(chyun)#報錯global全域變數
local區域變數
作用域scope:
def zsisc(parameters1,parameters2):
global chyun
chyun=parameters1+parameters2
return chyun
print(zsisc(8,9))
print(chyun)global全域變數
local區域變數
如果各大電神覺得這part贛話太多,請幫我指導一下你隊友
這part可能很快就能過去了
什麼是module?
假設你今天穿越異世界
到了農業大國
結果發現那邊的攤販賣了一堆蔬果
但完全沒有分類
有強迫症的你會選擇?
這就是module存在的意義
讓你依照功能整理你的程式
1.整理它
2.再丟一堆蔬果讓它更亂
聰明的你肯定會選1對吧?
對吧?
除非你有密集恐懼症
假設你有一堆程式碼
你又很想要重複利用function?
那就依照功能把你家的程式碼打包成module,
你就不用一行一行看了
什麼是模組(module):
是一個Python檔案,
每一個Python檔案被視為一個模組,
可以在程式中匯入其他Python模組,
模組就可以不斷地被其他程式再利用
什麼是模組(module):
main.py
math.py
typing.py
什麼是模組(module):
main.py
math.py
typing.py
如何使用module?
使用import
1.引入單個模組
2.引入模組內某功能
引入單個模組:
math是內建模組
floor()是取比該數小的最大整數
#語法結構
import <模組>import math
print(math.floor(3.14))
# 3引入模組內的某些功能:
被import的對象可以是
子模組、函式、常數、類別
->可以import模組內任何東西
#語法結構
from <模組> import <模組內任何東西>
from <模組> import <子模組>,<函式>,<常數>,<類別>from math import pi
print(pi)
# 3.141592653589793取別名:
也可以給它新的綽號
方便使用或辨認
import math as m
from math import pi as p
print(m.gcd(21,35))#最大公因數
print(p)常用的模組?
自己翻一下資料
time()常用的:
import time
print(time.time())
#顯示從 1970/1/1 00:00 到此刻的秒數
print(time.sleep(3))
#讓程式停止幾秒
print(time.ctime())
#顯示本地時間
print(time.strftime("%Y年%m月%d日 %H:%M:%S", time.localtime()))
#將時間轉換為可讀的字符串格式->string format time
#(指定格式,默認為當前時間)random()常用的:
import random
print(random.random())
#返回一個0到1之間的隨機浮點數[0.0, 1.0)
print(random.uniform(1, 10))
#返回a和b之間的隨機浮點數[a,b]
print(random.randint(1, 10))
#返回a和b之間的隨機整數[a,b]
print(random.randrange(1, 10, 2))
#返回指定範圍內的隨機整數(選擇1,3,5,7,9)
print(random.choice([1,2,3,4,5]))
#從序列中隨機選擇一個元素
print(random.choices(['a', 'b', 'c'], weights=[1, 2, 3], k=5))
#從序列中隨機選擇k個元素,允許重複選擇
#可以指定權重weights來影響選擇的機率
print(random.sample(range(1, 10), 3))
#從序列中隨機選擇k個不重複的元素如果各大電神覺得這part贛話太多,請幫我指導一下你隊友
這part可能很快就能過去了
如果說module是一個.py檔
那package就是很多個.py檔的資料夾
而__init__.py 是讓電腦將這個資料夾識別為 package,而不是普通的資料夾
package1
package2
1.有效組織多個 module
package 之間命名隔離->
可以出現重複的變數/函數名稱,否則可能產生命名衝突
2.不需要重造輪子
自由下載/上傳寫好的 package
為什麼需要package?
module v.s package?
| Module | Package |
|---|---|
| .py檔 |
__init__.py + 數個 .py 檔 |
| 可被其他 .py 引用 | 可被其他 .py 引用 |
| 定義 class, functions, variables | 管理 Module |
package哪裡來?
1.自己寫:)
2.從 PyPI 或 GitHub 下載
3.自己寫好後上傳讓大家下載使用
如果各大電神覺得這part贛話太多,請幫我指導一下你隊友
這part可能很快就能過去了
json是?
JavaScript Object Notation (JSON)
是一種資料交換的格式
易於人讀寫,同時也易於電腦分析與生成
如何在python使用json?
1.import json
2.json.loads() json.dumps()
在.py中python、json互換
import json
data ="""
{
"楓資幹部": [
{
"姓名": "吱吱",
"個性": "中二怪人",
"習性": {
"食物": "人",
"每日睡眠時間": "24hr"
}
},
{
"姓名": "嘎米",
"個性": "蜜獾",
"習性": {
"興趣": "愛錢"
}
}
]
}
"""
py_dict=json.loads(data)
#將json字串轉換為Python字典
new_json=json.dumps(py_dict,ensure_ascii=False, indent=4,sort_keys=True)
#將Python字典轉換為json字串
print(py_dict)
print(py_dict["楓資幹部"][0])
print(new_json)在.py中開啟&寫入json(記得開一個json檔)
import json
with open("file.json","r",encoding="utf-8") as f:
data=json.load(f)
#不加s->我們這次處理的是file不是string
print(data)
print(data.keys())
with open("file2.json","w",encoding="utf-8") as f2:
json.dump(data,f2,ensure_ascii=False, indent=4)
#將Python的資料結構(data)保存為json格式並寫入文件。檔案讀寫的部分再講一點
開啟模式:
'r':read 唯讀模式,只能讀,不能更改內容
'w':write 寫入模式(覆寫),會直接覆蓋原本檔案
'a':append 寫入模式(續寫),會從原本的檔案繼續寫下去,不會覆蓋掉
這裡有淺顯易懂的解說(按圖片)
(雖然是全英但應該聽得懂)
如果各大電神覺得這part贛話太多,請幫我指導一下你隊友
這part可能很快就能過去了
什麼是物件導向?
物件導向(Object-Oriented programming,簡稱OOP)
一句話總結:
物件(Object)是類別(class)的實例(Instance)
什麼是物件導向?
你想想,我們剛剛學的那些
看起來很難用在生活上吧?
誰會沒事走在路上看到一個東西就幫它寫dict或list?
物件導向就是把生活融入程式
用程式表達生活中會出現的東西
有什麼好處?
1.開發時易於維護,可讀性提高
2.擴充功能時更加方便
3.使語意更為清晰
4.減少重複代碼
在開始之前
先有個概念
類(Class):藍圖
類別屬性(Class Attribute):設計預定的材料
物件(Object):類的實例(Instance)
物件屬性(Object Attribute):實際製作的材料
舉個栗子:
class Club_member:
club_name="zsisc"
def __init__(self,name,style,habit):
self.name=name
self.style=style
self.habit=habit
cheer=Club_member("吱吱","中二怪人","從早睡到晚")
leaf=Club_member("葉子","葉氏集團總裁","不睡覺")
print(cheer.style)
print(leaf.habit)類別變數(Class variable)
實例變數(Instance variable)
吱吱
葉子
社團幹部
zsisc是類別變數
兩人都有各自的實例變數(名字、個性、習性)
補充:
如果好奇TG Bot裡哪些是物件,哪些是類別,哪些是屬性,可以參考一下,等等上課疑惑的時候就拿出來翻
這是chat gpt弄出來的東西
對終於要講正事了
1.打開vs code
2.下載 python (extensions)
3.在終端(terminal)輸入:
pip install pyTelegramBotAPI
檢查一下你的token
https://api.telegram.org/bot<TOKEN>/getme
成功會回傳json檔案
token不小心洩漏出去怎麼辦?
找BotFather,輸入指令/revoke,選擇想要更改的bot
我的token當然已經改掉了,不要想著偷講師的
Token?
https://api.telegram.org/bot<TOKEN>/getUpdates
將自己 Bot 的 Token 替換掉 URL 的<TOKEN>
丟到google
然後你發訊息給你家bot,刷新網頁
好像有什麼東西改變了?
Token?
你會發現裡面多了這些東西
- 你傳送訊息的時間
- 訊息來自哪個使用者
- 訊息在哪個聊天室被傳送
- 傳送的訊息內容
好像有點不太妙?
Token?
所以你要保護好它
剛剛大家應該有注意到,
我們透過把 Token 輸入到 getMe、getUpdate 等 API 中,就能夠得到 Bot 的各種資訊
Token 就像 Bot 的身份證,API 藉此來辨別 Bot
PyTelegramBotAPI ?
就是把剛剛大家體驗過的 getMe、getUpdates
還有其他很多 API 包裝成 Package 來使用
初始化:
import telebot
TOKEN=""
bot=telebot.TeleBot(TOKEN,parse_mode=None)
#None也可以改成html或Markdown
#用來設定訊息的解析模式,影響你發送訊息時如何處理文字中的樣式@bot.message_handler(commands=["start"])
def welcome(message):
bot.reply_to(message,"hi")
bot.infinity_polling()先確認一下有沒有連到:
@bot.message_handler(commands=["start"])
def welcome(message):
bot.reply_to(message,"hi")
bot.infinity_polling()講解一下:
1.PyTelegramBotAPI 把傳入的訊息分類成很多種型別(Ex: text, audio, photo, video)等
2.message_handler有各種不同條件的過濾器,
用於篩選輸入訊息,讓函式拿到我們想要的訊息種類
3.Command 是一個特別的訊息,格式是:/[string]
@bot.message_handler(commands=["start"])
def welcome(message):
bot.reply_to(message,"hi")
bot.infinity_polling()講解一下 bot.infinity_polling():
簡單來說就是可以讓 Bot 不斷地自動接收更新,
並且通知對應的函式有事件發生
@bot.message_handler(commands=["start"])
def welcome(message):
bot.reply_to(message,"hi")
bot.send_message(message.chat.id,f"hi")
bot.infinity_polling()講解一下 reply_to() & send_message() :
reply_to()
就跟我們平常傳訊息會使用的回覆一樣
@bot.message_handler(commands=["start"])
def welcome(message):
bot.reply_to(message,"hi")
bot.send_message(message.chat.id,f"hi")
bot.infinity_polling()講解一下 reply_to() & send_message() :
send_message()是傳送訊息到指定的聊天室中
welcome() 接收聊天室的 message,
這個 message 帶有聊天室 ID的資訊
聊天室 ID讓 send_message() 知道對話發生在哪個聊天室中
@bot.message_handler(commands=["start"])
def welcome(message):
bot.reply_to(message,"hi")
bot.send_message(message.chat.id,f"hi")
bot.infinity_polling()講解一下 reply_to() & send_message() :
reply_to() 因為回覆該訊息,所以接收 message
send_message() 因為要直接傳送訊息在聊天室,所以接收 message.chat.id
接下來是大家期待已久的實作環節~
先講基礎一點的
初學者必學的echo bot:
初學者必學的echo bot:
開發要求:
1./help:描述bot功能
2.接受你輸入的所有訊息,回覆相同的訊息
3.對特定語句有反應
eg.輸入:我愛IZCC四校聯合寒訓
輸出:不要再業配了
初學者必學的echo bot:
小提示:
1.可以用 message.text 來取得輸入訊息的字串
2.利用 @message_handler() 中的 filter(func)來實作
3.可以試看看使用lambda
初學者必學的echo bot:
對我就是不讓你們複製,啾咪
初學者必學的echo bot:
函數過濾器,判斷訊息是否要被接收
輸入聊天室的訊息會被 message_handler() 接收,送入 lambda 函式
不管傳入什麼訊息,都會被接收
初學者必學的報時仔:
開發要求:
初學者必學的報時仔:
開發要求:
輸入/time 回傳目前時間
初學者必學的報時仔:
小提示:
1.from datetime import datetime
2.datetime.now()可以取目前時間
3.strftime: 把結構化的 datetime 轉變成指定格式的字串
初學者必學的報時仔:
除了運用我們已經會的簡單指令以外,來學點有趣的
先來看如何下載使用者所傳送的照片
@bot.message_handler(content_types=['photo'])
def handle_photo(message):
file_id=message.photo[-1].file_id
#取得解析度最高的照片
#取得照片的 file_id
#file_id 是 Telegram 的一個唯一標識符,用於獲取該檔案
file_info=bot.get_file(file_id)
#獲取檔案詳細信息,包括檔案的路徑、大小等
downloaded_file=bot.download_file(file_info.file_path)
#下載檔案
with open("received_image.jpg", "wb") as new_file:
new_file.write(downloaded_file)
#檔案名稱可以根據需要任意修改(.PNG/.jpg)
#"w"是write,"b"是二進位模式(binary mode)開啟檔案(如圖片、音訊等會需要使用)
bot.reply_to(message, "圖片已接收並保存!")
簡單說,流程長這樣
with open("received_image.jpg", "wb")
received_image.jpg(new_file)
創建
以二進位模式寫入資料
簡單說,流程長這樣
downloaded_file
new_file.write(downloaded_file)
二進位數據(圖片內容)寫入
new_file
簡單說,流程長這樣
檔案自動關閉
new_file
成功儲存檔案
再來看看如何將照片傳給使用者
有兩種方法:
1.從本機上傳
2.以連結方式上傳
從本機上傳照片
@bot.message_handler(commands=['send_photo'])
def send_photo_command(message):
with open("檔名", "rb") as photo:
#圖片不能被解釋成文字,使用r
bot.send_photo(message.chat.id, photo, caption="描述圖片")以連結方式上傳照片
@bot.message_handler(commands=['send_photo'])
def send_photo_url(message):
url = "檔案連結"
bot.send_photo(message.chat.id, url, caption="描述圖片")
#就是把中間換成url而已PhotoSize (class)使用:
想要獲取圖片信息?
PhotoSize (class)使用:
想要獲取圖片信息?
@bot.message_handler(content_types=['photo'])
def handle_photo(message):
photo=message.photo[-1]
file_id=photo.file_id
#唯一標識,用於下載圖片。
unique_id=photo.file_unique_id
#永久標識符(不同bot間保持一致)。
width=photo.width
#寬度(像素)
height=photo.height
#高度(像素)
size=photo.file_size
#檔案大小(bytes)
#圖片信息回覆
response=(
f"圖片信息:\n"
f"File ID: {file_id}\n"
f"Unique ID: {unique_id}\n"
f"尺寸: {width}x{height} 像素\n"
f"檔案大小: {size / 1024:.2f} KB"
# 1 KB = 1024 bytes
# 以浮點數格式輸出,並保留小數點後兩位
)
bot.reply_to(message, response)file_unique_id跟file_id差在哪裡?
Emmmmmm.......
好像有哪裡怪怪的?
(無論是圖片、音訊、影片都適用)
file_unique_id跟file_id差在哪裡?
| file_id | file_unique_id | |
|---|---|---|
| 定義 | 唯一標識 | 永久標識 |
| 用途 | 檔案下載和處理 | 檔案比對、 唯一性檢查 |
| 變化 | 不同 bot發送時可能不同 | 永久固定,不隨 bot 變化 |
| 下載文件 | 可以用於下載 | 無法用於下載 |
| 時效性 | 可能會失效 | 永久有效 |
其實音訊也是類似原理:如何下載使用者傳出的音訊?
@bot.message_handler(content_types=['audio'])
def download_audio(message):
file_info = bot.get_file(message.audio.file_id)
downloaded_file = bot.download_file(file_info.file_path)
#保存到本地
with open(message.audio.file_name, 'wb') as audio_file:
audio_file.write(downloaded_file)
bot.reply_to(message, f"音訊已下載並儲存")其實語音也是類似原理:如何下載使用者傳出的語音?
把audio改成voice
把.mp3改成.ogg
那影片呢?
改成video
改成.mp4
聽起來真不戳,對吧
那短影片呢?
對,沒錯,我備課備這裡的時候也很意外
telegram居然有短視頻這種東西?!(圓形影片)
改成video_note就行
現在來教大家一個酷東西:傳送多個檔案
我們有了新工具:
from telebot.types import InputMediaPhoto
InputMediaPhoto(class)
現在來教大家一個酷東西:傳送多個檔案
from telebot.types import InputMediaPhoto
@bot.message_handler(commands=['send_photos'])
def send_photos_group(message):
media_group=[
InputMediaPhoto(media=open("1.jpg","rb"), caption="第一張照片"),
InputMediaPhoto(media=open("2.jpg","rb"), caption="第二張照片"),
InputMediaPhoto(media=open("3.jpg","rb"), caption="第三張照片")
]
bot.send_media_group(message.chat.id, media_group)
再補充一點:
duration():影片和音訊->持續時長(秒)
length():影片的直徑(像素)
TG Bot內建了很多有趣好玩的小工具
來介紹幾個
dice功能:
@bot.message_handler(commands=['dice'])
def roll_dice(message):
sent_message=bot.send_dice(message.chat.id, emoji='🎲')
result=sent_message.dice.value #骰子的結果
time.sleep(5)
bot.reply_to(message, f"你擲出了 {result}!")dice功能:
不只有骰子可以用,同樣的語法可以換不同動畫
大家可以玩看看
🎲 骰子(數字 1 到 6)
🎯 飛鏢(數字 1 到 6,1 表示命中靶心)
🏀 籃球(數字 1 到 5,5 表示投籃成功)
🎳 保齡球(數字 1 到 6)
⚽ 足球(數字 1 到 6)
🎰 老虎机(數字 1 到 64)
poll投票功能:可以做成quiz測驗!
q="楓資最瘋的幹部是?"
opt=["嘎米", "吱吱", "葉子", "起飛", "咕嚕", "呱呱", "C.Y", "以上皆是"]
correct_answer_index=7
@bot.message_handler(commands=['quiz'])
def send_quiz(message):
bot.send_poll(
chat_id=message.chat.id,
question=q,
options=opt,
is_anonymous=False,
allows_multiple_answers=False
)
bot.send_message(message.chat.id, "請選擇正確的答案!")
@bot.poll_answer_handler()
def handle_poll_answer(poll_answer):
user_id = poll_answer.user.id
selected_option = poll_answer.option_ids[0]
# 因為不允許多選,每次只有一個選項
is_correct = selected_option == correct_answer_index
if is_correct:
result = "恭喜你,答對了!"
else:
result = "抱歉,答案錯誤!"
bot.send_message(user_id, result)poll投票功能:可以做成quiz測驗!
但你還有進階班的課哈哈
再講進階一點的
今天要讀哪本書
好煩惱啊
來問問bot好了
來製作讀書計畫小幫手叭!
開發要求:
1./help:讓使用者知道 Bot 有哪些指令可以使用
2./add<書>:將書加入book中,並回傳提示訊息給使用者
3./list:用print()將book中的書本全部印出來
4./read:隨機選擇book中的一種科目,並且回傳給使用者
5./import:將Json檔案匯入book
6./export:將存在book中的資料匯出成Json檔案
來製作讀書計畫小幫手叭!
小提示:
1.開始前先複習List和Json檔案讀寫!
2.用 random.choice() 來選擇 list 中的食物
3.記得book要用global
第一個希望大家都能寫出來
我們要避開"add ",所以要用4:
這個應該也該寫出來了(叭?
要判斷一下是不是list為空
用"w"寫入,中文的話也要注意ensure_ascii=False
記得因為book被重新賦值,系統會判定其為區域變數
所以要另外global一次
在這次實作中,我們使用全域變數 "book" 來儲存資料,
這會讓所有使用者的資料是共用的
若是想要讓每個使用者能夠保存自己的資料,
可以使用 Dictionary:
Key 是使用者名稱
Value 是使用者的書單列表
這個問題就留給有興趣的弟妹玩
Inline Keyboard:
Inline Keyboard,按鈕的玩法:
def gen_markup():
markup = InlineKeyboardMarkup()
markup.row_width = 1
markup.add(InlineKeyboardButton('💕', callback_data="double"),
InlineKeyboardButton('💖', callback_data="star"),
InlineKeyboardButton('💘', callback_data="arrow"))
return markup
@bot.message_handler(commands=['inline'])
def message_handler(message):
bot.send_message(message.chat.id, "按鈕選擇", reply_markup=gen_markup())
@bot.callback_query_handler(func=lambda call:True)
def callback(call):
player_choice=call.data
if player_choice=="double":
bot.reply_to(call.message,"double")
elif player_choice=="star":
bot.reply_to(call.message,"star")
else:
bot.send_message(call.message.chat.id,"arrow")蛤?
啊如果我要弄兩個不同功能的按鈕怎麼辦?
call:call.data in ["double", "star","arrow"]
#把call:True改掉就好記得之前說的過濾作用嗎?
只要指定需要的過濾的訊息就好了
按完按鈕會覺得怪怪的?有按跟沒按好像一樣?
pop_message=f"你選的是{player_choice}"
bot.answer_callback_query(call.id,pop_message,show_alert=True)注重客戶UX的我們
肯定要來個方便的小東西來提醒他們對叭?
萬一有五星好評呢?XD
用按鈕實作一個猜拳bot:
用按鈕實作一個猜拳bot:
開發要求:
/game - 顯示出 Inline Keyboard,包含剪刀、石頭、布三個選項
使用者點選 Keyboard 後,Bot 要隨機選擇要出什麼
回傳使用者、Bot 分別出什麼,並且「平手」、「使用者贏」、「Bot 贏」三個情況要分別回傳不同訊息到聊天室中
別忘了要先import
這個一定要寫出來的
對叭?(懇切的眼神
gesture是為了方便取用才寫的list
要有兩個變數,分別表示bot跟player
再來要介紹的是ReplyKeyboardMarkup:
大家在跟bot father聊天的時候,
會發現有個加速溝通的神祕鍵盤
那個東西就被稱為回覆鍵盤
from telebot.types import KeyboardButton, ReplyKeyboardMarkup就這個東西:
可以這樣使用:
@bot.message_handler(commands=['start'])
def send_welcome(message):
keyboard = ReplyKeyboardMarkup(resize_keyboard=True,input_field_placeholder="請選擇一個選項",one_time_keyboard=True)
#按鈕的寬度會根據內容的長度自動調整,節省螢幕空間
#keyboard = ReplyKeyboardMarkup(resize_keyboard=True, row_width=2) 至多兩個按鈕一行
button1 = KeyboardButton("吱吱好中二")
button2 = KeyboardButton("吱吱是怪人")
keyboard.add(button1, button2)
bot.send_message(message.chat.id, "請選擇一個最合適的選項:", reply_markup=keyboard)
@bot.message_handler(func=lambda message: True)
def handle_message(message):
if message.text == "吱吱好中二":
bot.reply_to(message, "確實!")
elif message.text == "吱吱是怪人":
bot.reply_to(message, "雀食!")
else:
bot.reply_to(message, f"收到消息:{message.text}")
bot.infinity_polling()
最後再介紹一個酷東西:
location!!!
相信各位在探索telegram的路途上
會發現這東西居然有定位功能?!
對,我們來借用剛剛學到的鍵盤玩看看
location定位功能:傳送使用者位置
@bot.message_handler(commands=['location'])
def ask_for_location(message):
location_button = KeyboardButton(text="發送我的位置", request_location=True)
markup = ReplyKeyboardMarkup(row_width=1, resize_keyboard=True)
markup.add(location_button)
bot.send_message(message.chat.id, "請分享你的地理位置:", reply_markup=markup)
@bot.message_handler(content_types=['location'])
def handle_location(message):
latitude = message.location.latitude
longitude = message.location.longitude
bot.send_message(message.chat.id, f"你的地理位置是:\n緯度: {latitude}\n經度: {longitude}")
location定位功能:傳送指定位置
@bot.message_handler(commands=['send_location'])
def send_location(message):
latitude=25.07110660725248
longitude=121.52090323406448
bot.send_location(
chat_id=message.chat.id,
latitude=latitude,
longitude=longitude
)恭喜各位結束實作教程,有什麼問題都可以問看看
(關愛的眼神)
補充教學
大家在週二的網頁前端似乎也學了點東西
有沒有可能跟bot一起用呢?
哼哼,當然有,講師來補充一下遊戲鑲嵌
直接跟大家分享步驟
詳細的資料在簡報後面給各位研究一下
1.準備一個HTML/JS(遊戲)檔案
2.上傳到GitHub Pages,獲取遊戲網址
3.在BotFather裡輸入指令/newgame
並依指示傳送訊息
4.連接TG Bot程式
1.準備一個HTML/JS(遊戲)檔案
2.上傳到GitHub Pages,獲取遊戲網址
3.在BotFather裡輸入指令/newgame
並依指示傳送訊息
4.連接TG Bot程式
連接TG Bot程式
#你的GitHub Pages遊戲網址
GAME_URL = ""
#遊戲按鈕
@bot.message_handler(commands=['game'])
def send_game(message):
bot.send_game(message.chat.id, "game short name")
# 點擊遊戲按鈕回應
@bot.callback_query_handler(func=lambda call: True)
def game_callback(call):
if call.game_short_name == "game short name":
bot.answer_callback_query(callback_query_id=call.id, url=GAME_URL)
else:
bot.answer_callback_query(callback_query_id=call.id, text="遊戲未找到!")設定一下privacy
1.Enable Privacy mode:不會收到其他人訊息
->Bot 權限不大,要 mention、回覆這個 bot,Bot 才會收到
->預設
2.Disable Privacy mode:Bot 可以讀取輸入的所有訊息
TG的privacy有兩種模式:
1.找到 Bot Father,輸入 /mybots 選擇你要設定的 Bot
2.依序點選 Bot Settings -> Group Privacy -> Turn off
TG的privacy有兩種模式:
1.到bot資訊頁面
2.點擊加入群組
3.選擇你的小隊群組
4.開始轟炸你的群組
(如果發現你家bot怪怪的,請按下ctrl+C,拯救你們的群組
將你家bot加入群組:
有什麼bot
用來過濾非真人使用者的互動型 bot,如:
狼人殺:
文件轉換器:
遊戲