1. 程式人生 > 資料庫 >Azure IoT Edge入門(11)IoT Edge裝置上的函式計算Function,使用Function寫資料庫-Using Azure Function On Edge device save

Azure IoT Edge入門(11)IoT Edge裝置上的函式計算Function,使用Function寫資料庫-Using Azure Function On Edge device save

Python的使用

計算機簡介

計算機的組成

計算機由兩部分組成:硬體和軟體

  1. 硬體 硬體包含:鍵盤、滑鼠、顯示器、cpu等
  2. 軟體 軟體包含:系統軟體(windows、macOS、Linux)和應用軟體(office、QQ等)

計算機的使用方式

  1. 必須通過軟體來對計算機完成各種操作,但是注意的是,軟體中並不是所有的功能都會對使用者開放,使用者需要呼叫軟體提供的介面來操作計算機
  2. 使用者介面分為兩種:TUI(文字互動介面)和GUI(圖形化互動介面)

常用DOS命令

系統命令

  1. shutdown /s /t 1800 /s表示關機 /t表示設定時間
  2. shutdown /a 表示取消關機
  3. cls 表示清空螢幕
  4. time 顯示當前計算機時間
  5. ping www.baidu.com 檢查網路是否可通
  6. ipconfig 尋找ip地址

目錄與檔案相關

  1. cd 切換目錄,不能切換碟符,並且只能在當前碟符下進行切換目錄 切換碟符(例: D:)
  2. md test 表示新建目錄(只能建目錄)
  3. echo "明天放假">a.txt 表示新建檔案
  4. rd test 刪除目錄 如果包括目錄中的檔案也刪除,使用rd /s test
  5. del a.txt 刪除檔案
  6. del test 刪除目錄,如果是選擇目錄,將會連同檔案一塊兒刪除,跟rd /s test功能類似
  7. copy test/a.txt b.txt 在test下複製a.txt檔案到test下取名為b.txt
  8. move test/a.txt C:tests 移動檔案到C:tests下

環境變數

基本介紹

  1. 環境變數指的就是作業系統當中的一些變數
  2. 可以通過修改環境變數,來對計算機進行配置(主要是來配置一些路徑的)
  3. 環境變數分為兩個部分,上邊是使用者環境比那輛,下邊是系統環境變數,建議值修改使用者的環境變數,不喲啊修改系統的環境變數(個人採用的是隻在系統變數進行新增,不進行修改及刪除)

path環境變數

  1. path環境變數中儲存的是一個個的路徑
  2. 當我們在命令列中輸入一個命令(或訪問一個檔案時),系統會首先在當前目錄下尋找,如果找到了則直接執行或開啟,如果沒有找到,則會依次去path環境變數的路徑中去尋找,直到找到為止,如果path環境變數中的路徑都沒有找到則報錯,可以將一些經常需要訪問到的檔案新增到path環境變數中,這樣就可以在任意的位置訪問到這些檔案了
  3. 注意事項
    1. 如果環境變數中沒有path,可以手動新增
    2. path環境變數不區分帶小寫
    3. 修改完環境變數必須重新啟動命令列視窗
    4. 多個路徑之間使用分號隔開

文字與字符集

文字

文字分為兩種,一種叫做純文字,還有一種叫做富文字

  1. 純文字中只能儲存單一的文字內容,無法儲存內容無關的東西(字型、顏色、圖片)
  2. 富文字可以儲存文字以外的內容(word文件)
    在開發時,編寫程式使用的全都是純文字
    純文字在計算機底層也會轉換為二進位制儲存
  3. 將字元轉換為二進位制碼的過程,稱為編碼
  4. 將二進位制碼轉換為字元的過程,稱為解碼
  5. 編碼和解碼所採用的的規則,我們稱為字符集

字符集

常見的字符集

  1. ASCII 美國人編碼,使用7位來對沒過常用的字元進行編碼
  2. ISO-8859-1 歐洲編碼,使用8位
  3. GB2312和GBK 國標嗎,中國編碼
  4. Unicode 萬國碼,編寫程式一般使用Unicode編碼
    亂碼 編寫程式時,如果發現程式程式碼出現亂碼的情況,就需要檢查字符集是否正確

編譯語言和解釋型語言

計算機智慧識別二進位制編碼,所以任何的語言在交由計算機執行時,必須先轉換為機器碼,也就是像print('hello')必須要轉換為類似1010101這樣的機器碼
根據轉換時機的不同,語言分成兩大類

  1. 編譯型語言 C語言 特點:還行速度快,跨平臺性差
  2. 解釋型語言 python、js、java 特點:執行速度比較慢,跨平臺性比較好

初識Python

C/S架構跟B/S架構

  1. C/S結構,即Client/Server(客戶機/伺服器)結構,是大家熟知的軟體系統體系結構,通過將任務合理分配到Client端和Server端,降低了系統的通訊開銷,可以充分利用兩端硬體環境的優勢。早期的軟體系統多以此作為首選設計標準。
  2. B/S結構,即Browser/Server(瀏覽器/伺服器)結構,是隨著Internet技術的興起,對C/S結構的一種變化或者改進的結構。在這種結構下,使用者介面完全通過WWW瀏覽器實現,一部分事務邏輯在前端實現,但是主要事務邏輯在伺服器端實現,形成所謂3-tier結構。

Python介紹與安裝

  1. Python語言是一種解釋性、面向物件、動態資料型別的高階程式設計語言
  2. Python語言是資料分析師的首選資料分析語言,也是智慧硬體的首選語言
  3. 安裝:python3.7,傻瓜式安裝,需要選擇Add Python3.7 to PATH

pyCharm的常用快捷鍵

  1. Ctrl + Alt + L 程式碼格式化
  2. Shift + Enter 另起一行
  3. Ctrl + Shift + R 全域性替換
  4. Ctrl + Shift + F 全域性查詢
  5. Shift + F10 執行
  6. Shift + F9 除錯

python的基本語法

  1. 在python中嚴格區分大小寫
  2. python中的每一行就是一條語句,沒跳語句以換行結束
  3. python中每一行語句不要過長(規範中建議每行不要超過80個字元)
  4. 一條語句可以分多行編寫,語句後邊以\結尾
  5. python是縮排嚴格的語言,所以在python中不要隨便寫縮排
  6. 在python中使用#來表示註釋,#後的內容都屬於註釋,註釋的內容將會被直譯器所忽略,我們可以通過註釋來對程式進行解釋說明

Python的輸入與輸出

name = "吳鵬"
# 普通的輸出變數
print(name)
# 輸出變數不換行
# print(name, end='')

# 第二種格式化輸出變數

a = '吳鵬'
b = 20
print("a:{},b:{}".format(a, b))

# 輸入變數
data = input("請輸入你的名字:")  # 可以作為一個變數然後返回列印輸出
print(data)

變數、資料型別和運算子

變數

  1. 什麼是變數? 可能改變的資料叫做變數
  2. 變數規則
    1. 變數名必須是大小寫英文字母_數字或下劃線_的組合,不能用數字開頭,並且對大小寫敏感.
    2. 關鍵字不能用於命名變數(31個),如and、as、assert等
  3. 註釋
    1. # 表示註釋一行內容
    2. """ """ 表示註釋多行內容
  4. 什麼是識別符號? 在python中所有可以自主命名的內容都屬於識別符號,比如:變數名、函式名、類名
  5. python中遵循兩種命名規範
    1. 下劃線命名法
    2. 帕斯卡命名法(大駝峰命名法)

資料型別

  1. Python語言常用資料型別包括整型、浮點型、字串、布林型和空值
  2. 資料型別轉換可以把一些資料轉換成我們需要的型別
    1. int() 轉換成數字
    2. float() 轉換成小數
    3. str() 轉換成字串
    4. bool() 轉換成布林值
  3. 對浮點數進行運算時,可能會得到一個不精準的結果
  4. 一般使用三重引號來表示一個長字串,三重引號可以換行,並且會保留字串中的格式
  5. 使用type()方法可以對資料型別進行型別檢查

字串

  1. 字串之間可以進行加法執行,如果兩個字串進行相加,則會自動將兩個字串拼接為一個
  2. 在建立字串時,可以在字串中指定佔位符,%s在字串中表示任意字元
  3. %f表示浮點數佔位符 一般用於數字
  4. %d表示整數佔位符 一般用於數字
  5. %.5s字串的長度限制5個字元
  6. 格式化字串
  7. 如果將字串和數字相乘,則直譯器會將字串重複指定的次數返回
a = "你是頭豬%s" % "顧成龍" + ",是的吧"
print(a)
# 如果傳入多個引數,那麼%後面加上括號,引數以逗號隔開
b = "你是%s,他是%s" % ("豬", "牛")
print(b)
# 表示保留3位字元
c = "需要幾個字母:%.3s" % "牛鼻的人啊"
print(c)
# 表示浮點數長度保留3位,四捨五入
d = "需要幾個字母:%.3f" % 123.45678
print(d)
# 表示長度控制在5位,如果是三位整數,會在前面補全為0
e = "需要幾個字母:%.5d" % 123.45678
print(e)
# 使用格式化引數
name = "顧成龍"
f = f"你是{name}嗎"
print(f)
# 使用format進行格式化輸出
g = "你是{}嗎?".format("豬")
print(g)

布林值

布林值實際上也屬於整型,True就相當於1,False就相當於0,是可以跟數字進行運算的

型別轉換

所謂的型別轉換,將一個型別的物件轉換為其他物件
型別轉換不是改變物件本身的型別,而是將物件的值轉換為新的物件
型別轉換的四個函式 int() float() str() bool()

  1. int()可以將其他的物件轉換為整型,該函式不會對原來的變數產生影響,是物件轉換為指定的型別並將其作為返回值返回,如果希望修改原來的變數,需要對變數進行重新賦值
    1. 將布林值轉換 True→1 False→0
    2. 浮點數轉換 直接取整,省略小數點後的內容
    3. 字串轉換 合法的整數字符串,直接轉換為對應的數字,如果不是一個合法的整數字符串,就會報錯
  2. float()和init()基本一致,不同的是它會將物件轉換為浮點數
  3. str()可以將物件轉換為字串
  4. bool()可以將物件轉換為布林值,任何物件都可以轉換為布林值

日期型別

首先引入datatime
import datetime

# 獲取當前時間
time = datetime.datetime.now()
print(time)

# 獲取一個指定日期
this_time = datetime.datetime(2019, 10, 1, 12, 3, 30)
print(this_time)
# 日期轉字串
d = time.strftime("%Y-%m-%d %H:%M:%S")
print(d)

# 字串轉日期
s = "2017-10-1 10:30:59"
m = time.strptime(s, "%Y-%m-%d %H:%M:%S")
print(m)

運算子

運算子的種類

  1. 算數運算子 + - * / // ** //表示a除以b向下圓整,丟棄小數部分 **表示a的b次方
  2. 關係運算符 == != > < >= <=
  3. 賦值運算子 = += -= *= /= %= **= //=
  4. 邏輯運算子 and or not

運算子的優先順序

在python運算中有優先順序
運算子的優先順序可以根據優先順序的表格來查詢
在表格中為止越靠下的運算子優先順序越高,優先順序越高的越優先計算,如果優先順序一樣則自左向右計算
一般在開發中遇到優先順序不清楚,基本使用小括號來改變運算順序(基本上小括號是通用)

特殊的資料型別(容器)

列表

# 可以存放任意的資料型別  
a=[1,2,3,"wupeng",[1,2,3]]  
獲取指定位置的值,如:print(a[3])
如果使用的索引超過了最大的範圍,會丟擲異常

# 列表的切片
做切片操作時,總會返回一個新的列表,不會影響原來的列表
print(a[0:3])  包括0,不包括3
print(a[-4:-1])  包括-4,不包括-1  倒數第四個開始-倒數第一個結束(不包括)  取值:2,3,"wupeng"

# 通用操作
可以將兩個列表拼接為一個列表
mylist=[1,2,3]+[4,5,6]
print(mylist)
也可以將列表重複幾次
mylist=[1,2,3]*3
print(mylist)

使用in和not in來檢查元素是否存在於列表中
len()  獲取類表中元素的個數
min()  獲取列表中的最小值
max()  獲取列表中的最大值
index()  可以獲取指定元素在列表中第一次的索引,第一個引數是元素,第二個引數表示查詢的起始位置,第三個引數表示查詢的結束位置
append()  表示在原有資料上追加  
insert(a,b)  向列表的指定位置插入一個元素,第一個引數表示插入的位置,第二個引數表示插入的引數
extend(list)  需要一個類表作為引數,會將該序列中的元素新增到當前列表中
clear()  清空序列
pop()  根據索引刪除並返回被刪除的元素
remove()  刪除指定的元素,如果相同值的元素有多個,只會刪除第一個
reverse()  用來反轉列表
sort()  用來對列表中的元素進行排序,預設是升序排列,如果需要降序排列,則需要傳遞一個reverse=True作為引數
 
# 指定位置新增元素
a.insert(2,4)  在列表的下標為2的位置後面新增4

# 通過索引修改元素
a=[1,2,3,4,5]
a[0]=2
print(a)

# 通過切片來修改列表,在給切片進行賦值時,只能使用序列
mylist[0:2]=[1,2,3]  打印出來的結果會將索引為0,1的數值換掉

# 函式(range)
range()是一個函式,可以用來生成一個自然數的序列
該函式需要三個引數
1. 起始位置
2. 結束位置
3. 步長(可以省略,預設是1(常用也是預設值))

序列

序列是python中最基本的一種資料結構
序列用於儲存一組有序的資料,所有的資料在序列當中都有一個唯一的位置(索引),並且序列彙總的資料會按照新增的順序來分配索引
系列的分類

  1. 可變序列(序列中的元素可以改變) 列表
  2. 不可變序列
    1. 字串
    2. 元祖(如果必須修改,那麼將資料去除存放於列表中,在轉換為元祖)

元祖和字典

  1. 元祖
    1. 元素資料結構與列表類似,其中元素可以有不同的型別,但是元祖中的元素時不可變的,即一旦初始化之後,就不能夠在做修改(報錯:元祖物件不支援賦值),所以在操作元祖時,就把元祖當成跟一個不可變的列表就可以
    2. 一般我們希望資料不改變時,就是用元祖,其餘情況都是用列表,當元祖不是空元祖時,括號可以省略,如果元祖不是空元祖,它裡面至少有一個
# 元祖的解包
my_tuple=(1,2,3,4,5)
a,b,c,d,f=my_tuple
a,b=b,a
print(a,b)

# 在對一個元祖進行解包時,變數的數量必須和元祖中的元素數量一致,也可以在變數前邊新增一個*,這樣變數將會獲取元素中所有剩餘的資源(剩餘的資源會產生在新增*的變數,並且以列表存在)
my_tuple=(1,2,3,4,5)
a,b,c,*d=my_tuple
a,b=b,a
print(a,b,c,d) # d的值為[4,5]
  1. 字典
    1. 字典是一種大小可變的鍵值對集,其中的鍵和值都是Python物件,字典用在需要高速查詢的地方
    2. 字典屬於一種新的資料結構,作用和列表類似,都是用來儲存物件的容器
    3. 列表儲存資料的效能很好,但是查詢資料的效能很差,在查詢元素時,字典的效率是非常快的
    4. 在字典中可以儲存多個物件,每個物件都會有一個唯一的名字,我們稱為鍵,通過key可以快速查詢value,這個物件稱為值
    5. 每個字典中都可以有多個鍵值對,而每個鍵值對我們稱其為一項(item)
    6. 字典的值可以是任意的不可變物件,字典的鍵是不能重複的,如果出現重複的後邊會替換到前邊的
a={"username":"吳鵬","age":18}
print(a["username"])    # 能夠得到值:吳鵬
# 使用dict()函式來建立字典
# 每一個引數都是一個鍵值對,引數名就是鍵,引數名就是值(這種方式建立的字典,key都是字串)
d=dict(name="wupeng",age=18)
print(d)

# 也可以將一個包含有雙值子序列的序列轉換為字典,雙值序列,序列中只有兩個值,子序列,如果序列中的元素也是序列,那麼我們成這個元素為子序列
d = dict([(4, 2), (1, 3)])
print(d)  # {4:2,1:3}

# len()  可以獲取字典中鍵值對的個數
# in  檢查字典中是否包含指定鍵
# not in  檢查字典中是否不包含指定的鍵
# get()  通過get獲取鍵值對的值
d=dict(username="吳鵬",age=18)
print(d.get("username"))

# 修改字典
d=dict(username="吳鵬",age=18)
d['username']="吳磊"
print(d.get('username'))

# 字典新增鍵值對
# 使用setdefault()想字典中新增key-value,如果key已經存在於字典中,則返回key的值,不會對字典做任何操作,如果key已經存在於字典中,則返回key的值,不會對字典做任何操作
d=dict(username="吳鵬",age=18)
d.setdefault('username1','吳娟')
print(d)

# 將其他字典新增到當前字典update方法
d=dict(username="吳鵬",age=18)
d2={'class':123,'huiyi':333}
d.update(d2)
print(d)

集合

# 集合是一種無序集,是一組鍵的集合,不儲存值
# 在集合中,重複的鍵是補被允許的,集合可以用於去除重複值
# 集合也可以進行數學集合運算
# 應用:把一個列表變成集合,就自動去重了
a={1,2,3,4,5,6}
b={4,5,6,7,8,9}
print(a-b)  表示集合的差集:1,2,3
print(a|b)  表示集合的並集:1,2,3,4,5,6,7,8,9
print(a&b)  表示集合交集:4,5,6
print(a^b)  表示集合的對稱差:1,2,3,7,8,9

選擇結構

if-else語句

if 判斷條件:

  執行語句

if-elif-else語句

if 判斷條件:

  執行語句

elif 判斷條件:

  執行語句

else:

  執行語句

巢狀if

如果需要在某一個條件裡面做二次判斷,那麼可以使用if巢狀,也就是if結構裡面在包含一個或多個if結構
if 條件1:

  if 條件2:

  else:

else:

迴圈結構

for迴圈

# for迴圈是可以依次得到序列迴圈中的每個元素,並依次處理
"""
    for 迴圈指定次數:for i in range(初始值,結束值,步長)
"""
for i in range(0,10,2):
    print("列印十次")

# 對列、元祖、集合遍歷
# 列
list = [1, 2, 3, 4, 5, 6]
# 元祖
list1 = (1, 2, 3, 4, 5)
# 字典
list2 = {"username": "吳鵬", "age": 18}
# 集合
list3 = {1, 2, 3, 4, "wupeng"}
# 遍歷列表
for i in list:
    print(i)
# 遍歷元祖
for m in list1:
    print(m)
# 遍歷字典
for n,k in list2.items():
    print(n,k)
# 遍歷集合
for p in list3:
    print(p)

for迴圈案例

# 求100以內的和
# 求1-100的和
sum = 0
for i in range(0, 101):
    sum += i
print(sum)

# 求列表中的最大值
# 求列表中的最大值,思路:先設定下標為0是最大的,迴圈遍歷列表的數,如果下標0<下標1,那麼最大值=下標1
a = [1, 2, 234, 456, 678]
maxx = a[0]
for i in range(0, len(a) - 1):
    if a[0] < a[i + 1]:
        maxx = a[i + 1]
print(maxx)

while迴圈

while迴圈和for迴圈不同的是,它的停止條件是個人自己設定的
while 判斷條件:
  執行語句
判斷條件和if語句是相同的,那麼什麼時候用while呢,在你確定滿足條件而不確定需要的迴圈次數時,那麼while是最好的選擇

while的巢狀迴圈

# 迴圈操作20年每年的每個月遞增20元,統計每年每月的金額數
i = 0
sum = 0
while i <= 20:
    print("這是第", i, "年")
    j=1
    while j<=12:
        sum+=20
        print("第",i,"年,","第",j,"月,","需要交納",sum,"元")
        j+=1
    i+=1
print(sum)

continue和break

  1. continue是結束當前迴圈,進行下一次迴圈
  2. break是結束整個迴圈
  3. 巢狀迴圈的break對應內外迴圈,內迴圈內的break結束內迴圈,外迴圈內的break結束外迴圈

無限迴圈

如果迴圈中的迴圈條件永遠為真,且沒有break關鍵字進行終端,那麼就形成一個無線迴圈,無線迴圈也被成為死迴圈.一般情況會通過一個條件結束死迴圈

迴圈相關練習

# 計算所有的奇數之和(使用while)
num = 0
sum = 0
while num <= 100:
    if num % 2 != 0:
        print(num)
        sum += num
    num += 1
print("所有奇數和:{}".format(sum))

# 計算所有的奇數之和(使用for... in ...)
sum = 0
# 與while的區別:num不需要定義變數為0
for num in range(101):
    if num % 2 != 0:
        print(num)
        sum += num
    num += 1
print("所有的奇數之和:{}".format(sum))

# 使用for動態列印矩形
# 外層迴圈控制行,內層迴圈控制列
num = input("請輸入邊數:")
num = int(num)
for i in range(num - 1):
    for j in range(num):
        print("*", end="")
    print("")

# 動態列印正三角
num = input("請輸入三角的邊數:")

num = int(num)
for i in range(num):
    for j in range(i + 1):
        print("*", end="")
    print("")

# 乘法表
# 1*1=1
# 1*2=2 2*2=4
# 1*3=3 2*3=6 3*3=9

num = int(input("請輸入乘法表邊數(行跟列)"))
for i in range(num + 1):
    for j in range(i + 1):
        print("{}*{}={}".format(j + 1, i + 1, (j + 1) * (i + 1)), end="  ")
    print("")

# 電腦隨機一個0 - 100的數, 將使用者輸入的跟電腦隨機的數字對比, 滿分是100分, 猜錯口扣10分, 分數為0, 停止程式.
import random

score = 100
# randint(0,100) 包含0跟100
a = random.randint(0, 100)
count = 0
while True:
    num = int(input("請輸入第{}個:".format(count + 1)))
    if num > a:
        print("猜大了")
    elif num < a:
        print("猜小了")
    else:
        print("猜對了")
    count += 1
    if count == score / 10:
        break
print("分已經全沒,重啟程式")

"""
猜數字遊戲, 電腦隨機產生一個0 - 100的整數, 使用者在控制檯輸入一個整數, 將使用者輸入的和電腦產生的進行對比:
如果使用者猜大了, 就提示猜大了, 猜小了, 就提示猜小了, 猜對了就恭喜答對了
滿分是100分,猜錯一次就減10分,
當分數為0的時候,停止程式。
"""
import random

content = random.randint(0, 100)
count = 0
score = 100
while True:
    if score == 0:
        print("您的分數已經歸為0,再見")
        break
    num = int(input("請輸入第{}個數:".format(count + 1)))
    if num > content:
        print("您猜大了")
        score -= 10
        print("當前分數為:{}".format(score))
    elif num < content:
        print("您猜小了")
        score -= 10
        print("當前分數為:{}".format(score))
    else:
        print("恭喜你,猜對了,當前分數為:{}".format(score))
        break
    count += 1
    
"""
隨機加減乘除運算, 一共出10題, 電腦隨機產生2個0 - 100的整數, 進行隨機加減乘除法計算
然後使用者輸入計算結果, 判斷使用者輸入的是否正確, 回答正確就加十分, 錯誤就不加分, 10題全對就是100分
"""
import random

score = 0
test = 0
sum = 0
while True:
    if test == 10:
        break
    num1 = random.randint(0, 100)
    num2 = random.randint(0, 100)
    t = random.randint(0, 3)
    if t == 0:
        print("請回答第{}題:{}+{}=?".format((test + 1), num1, num2))
        sum = num1 + num2
    elif t == 1:
        print("請回答第{}題:{}-{}=?".format((test + 1), num1, num2))
        sum = num1 - num2
    elif t == 2:
        print("請回答第{}題:{}*{}=?".format((test + 1), num1, num2))
        sum = num1 * num2
    else:
        print("請回答第{}題:{}//{}=?".format((test + 1), num1, num2))
        sum = num1 // num2
    user = int(input("請輸入結果:"))
    if user == sum:
        score += 10
        print("回答正確加10分,當前分數為:{}".format(score))
    else:
        print("回答錯誤減10分,當前分數為:{}".format(score))
    print("當前總分為:{}".format(score))
    test += 1

# 建立一個10個長度整數列表, 列表中的10個元素, 使用隨機數賦值, 範圍0 - 100, 然後找出列表中的最大值
import random

list = []
for i in range(10):
    list.append(random.randint(0, 100))
    for j in range(len(list)):
        max = list[0]
        if max < list[j]:
            max = list[j]
    print(list[i], end=" ")
print("最大值為max:{}".format(max))

# 氣泡排序
num = [51, 12, 55, 29, 18, 18, 18, 18, 55, 295, 5, 29]
for i in range(len(num)):
    # 選出最大去掉一個
    for j in range(len(num) - 1 - i):
        if num[j] > num[j + 1]:
            t = num[j]
            num[j] = num[j + 1]
            num[j + 1] = t
print(num)

"""
從26個字母中,隨機選出4個不重複的字母並且把4個字母,新增到一個列表中
使用者在控制檯輸入4個字母,將使用者輸入的也新增到一個列表中
然後將電腦的和使用者的進行對比
"""
import random


# 從26個字母中,隨機選出4個不重複的字母
def getChar():
    c1 = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
          'w', 'x', 'y', 'z']
    c2 = []
    for i in range(4):
        index = random.randint(0, len(c1) - 1)
        c2.append(c1[index])
        del c1[index]
    print(c2)
    return c2


# 檢查使用者輸入是否正確的
def check(charList, user):
    # 第一個下標儲存猜對了幾個,
    # 第二個下標儲存位置對了幾個
    result = [0, 0]
    for i in range(len(charList)):
        if user[i] in charList:
            result[0] += 1
            if user[i] == charList[i]:
                result[1] += 1
    print("猜對了{}個,位置對了{}個。".format(result[0], result[1]))
    return result


print("猜字母遊戲開始了。")
charList = getChar()
while True:
    str = input("請輸入四個字母,退出輸入exit")
    if str == "exit":
        break
    user = []
    for s in range(4):
        user.append(str[s])
    print(user)
    res = check(charList, user)
    if res[1] == 4:
        print("恭喜,全部猜對了")
        break
print("遊戲結束")

函式和模組

初識函式

# 函式就是可以把我們要執行的程式碼放到一起,需要執行的時候直接呼叫就可以.
# 函式的命名規則
def name(x):
  s=x*x
  return s
  
def  是個關鍵字
name  是函式命名
x  輸入一個引數
return  返回一個值

引數傳遞

# 幾種引數設定方法:順序傳入、關鍵詞、預設引數、不定長引數
# 函式預設按照輸入引數列表的順序傳入
def sum(a, b, c):
    result = a + a * 2 + b * 3 + c * 4
    return result

print(sum(1, 2, 3))

# 關鍵詞傳入
# 指定了預設值以後,如果使用者傳遞了引數則預設值沒有任何作用,如果使用者沒有傳遞,則預設值就會生效
def sum(a, b, c):
    result = a + a * 2 + b * 3 + c * 4
    return result

print(sum(a=1, b=2, c=3))

# 預設引數傳入
def sum(a, b, c=3):
    result = a + a * 2 + b * 3 + c * 4
    return result

print(sum(a=1, b=2))

# 不定長引數(不常用)
def fun(a, b, *c):
    print(a)
    print(b)
    print(c)

fun(1, 2, 3, 4, 5, 6, 7, 8) #最終c的值為(3,4,5,6,7,8)元祖型別

# 可變引數不是必須寫到最後,但是注意,帶*的引數後的所有引數,必須以關鍵字引數的形式傳遞
def fun(a, *b, c):
    print(a)
    print(b)
    print(c)

fun(1, 2, 3, 4, 5, 6, 7, c=8)

# 引數的解包
# 傳遞實參時,也可以在序列型別的引數前新增型號,這樣他會自動將序列中的元素一次作為引數傳遞
# 這裡要求序列中元素的個數必須和形參的個數一致
def fun(a, b, c):
    print(a)
    print(b)
    print(c)

typle1 = (1, 2, 3)
fun(*typle1)

# 通過兩個*對一個字典進行解包
def fun(a, b, c):
    print(a)
    print(b)
    print(c)


typle1 = {'a': 100, 'b': 200, 'c': 300}
fun(**typle1)

作用域

作用域是指變數生效的區域
變數定義在函式內部,所以作用域就是函式內部,函式外部無法訪問
在python中一共有兩種作用域

  1. 全域性作用域
    1. 全域性作用域在程式執行時建立,在程式執行結束時銷燬
    2. 所以函式以外的區域都是全域性作用域
    3. 在全域性作用域定義的變數都屬於全域性變數,全域性變數可以在程式的任意位置被訪問
  2. 函式作用域
    1. 函式作用域在函式呼叫時建立,在呼叫結束時銷燬
    2. 函式每呼叫一次就會產生一個新的函式作用域
    3. 在函式作用域中定義的變數,都是局不變數,它只能在函式背部被訪問

變數的查詢
當我們使用變數時,會優先在當前作用域中尋找該變數,如果有則使用,如果沒有則繼續去上一級作用域中尋找,如果有就使用,如果依然沒有則繼續去上一級作用域中尋找,以此類推,知道找到全域性作用域,依然沒有找到則會丟擲異常.

# 在函式中為變數賦值時,預設都是為區域性變數賦值,如果希望在函式內部修改全域性變數,則需要使用global關鍵字來宣告變數,然後在進行修改
def fun():
    global a
    a = 10
    print(a)


fun()
print(a)  # 上面使用global a,已經將a變成全域性,然後a修改為10,所以這裡也就列印10

名稱空間

  1. 名稱空間指的是變數儲存的位置,每一個變數都需要儲存到指定的名稱空間當中
  2. 每一個作用域都會有一個它對應的名稱空間
  3. 全域性名稱空間,用來儲存全域性變數,函式名稱空間用來儲存函式中的變數
  4. 名稱空間實際上就是一個字典,是一個專門用來儲存變數的字典
  5. locals()用來獲取大年作用域的名稱空間
  6. 如果在全域性作用域中呼叫locals()則獲取全域性名稱空間,如果在函式作用域中呼叫locals()則獲取函式名稱空間,返回的是一個字典
  7. 向scope中新增一個key-value就相當於在全域性中建立一個變數
  8. 在函式內部呼叫locals()會獲取到函式的名稱空間
  9. 可以通過scope來操作函式的名稱空間,但是不建議這麼做
def un1():
    a = 1
    scope = locals()
    print(scope)

un1()

遞迴

遞迴簡單理解就是自己去引用自己,遞迴式函式,在函式中自己呼叫自己.
遞迴是解決問題的一種方式,和迴圈很像,整體思想是將一個大問題分解為一個個的小問題,直到問題無法分解時,在去解決問題

  1. 基線條件 問題可以被分解為最小問題,當滿足基線條件時,遞迴就不再執行了
  2. 遞迴條件 將問題繼續分解的條件
def fun(n):
    # 基線條件
    if n == 1:
        return 1
    # 遞迴條件
    return n * fun(n - 1)

print(fun(3))

遞迴練習

# 計算n**i
# 10**5=10*10**4
# ...
# 10**1=10
def power(n, i):
    if i == 1:
        return n
    return n * power(n, (i - 1))

print(power(10, 5))

高階函式

接收函式作為引數,或者將函式作為返回值的函式是高階函式

def fun1(i):
    if i > 5:
        return True
    else:
        return False

def fun2(i):
    if i % 2 == 0:
        return True
    else:
        return False

l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

def method(func, lst):
    new_list = []
    for n in lst:
        if func(n):
            new_list.append(n)
    return new_list

print(method(fun1, l))

匿名函式

# filter()可以從序列中過濾出符合條件的元素,儲存到一個新的序列中

引數:

1. 函式,根據該函式來過濾序列(可迭代的結構)
2. 需要過濾的序列(可迭代的結構)

返回值:過濾後的新序列(可迭代的結構)
def fun(i):
    return i % 3 == 0

l = [12, 3, 4, 5, 6, 7, 8, 9]
r = filter(fun, l)
print(list(r))

# fun是作為引數傳遞進filter()函式中,而fun實際上只有一個作用,就是作為filter()引數,filter呼叫完畢以後,fn4就已經沒用
# 匿名函式lambda函式表示式
# lambda函式表示式專門用來建立一些簡單的函式,是函式建立的有一種方式
# 語法:lambda 引數列表:返回值
l = [12, 3, 4, 5, 6, 7, 8, 9]
r = filter(lambda i: i % 3 == 0, l)
print(list(r))

# map()函式可以對可迭代物件中的所有元素做指定的操作,然後將其新增到一個新的物件中返回
l = [12, 3, 4, 5, 6, 7, 8, 9]
r = map(lambda i: i * 2, l)
print(tuple(r))

排序函式(sort)

# sort()  該方法用來對列表中的元素進行排序,預設是直接比較列表中的元素大小,在sort可以接收一個關鍵字引數key,key需要一個函式作為引數,每次都會以列表中的一個元素作為引數來呼叫函式,並且使用函式的返回值來比較元素的大小
l = ["a", "bbb", "cc", "dddd"]
l.sort(key=len)
print(l)

# sorted() 這個函式和sort()的用法基本一致,但是sorted()可以對任意的序列進行排序,並且使用sorted()排序不會影響原來的物件,而是返回一個新物件

閉包

# 將函式作為返回值返回,也是一種高階函式,這種高階函式我們也稱為閉包,通過閉包可以建立一些只有當前函式能訪問的變數,可以將一些私有的資料藏到閉包中
def fun():
    def fun1():
        print("你是豬")

    return fun1

fun()()

內建函式

數學相關

  1. abs(a) 求絕對值
  2. max(list) 求list最大值
  3. min(list) 求list最小值
  4. sum(list) 求list元素的和
  5. sorted(list) 返回排序後的list
  6. len(list) list長度
  7. divmod(a,b) 獲取商和餘數,返回的是元祖,(商,餘數)
  8. pow(a,b) 獲取乘方數,與a**b類似
  9. round(a,b) 獲取指定位數的小數 表示保留b位小數
  10. range(a,b) 生成一個a-b的值,左閉右開

型別轉換

  1. int(str) 轉換為int型別
  2. float(int/str) 將int型別或字元型別轉換為浮點型
  3. str(int) 轉換為字元型
  4. bool(int) 轉換為布林型別
  5. list(iterable) 轉換為list
  6. dict(iterable) 轉換為字典
  7. enumerate(iterable) 返回一個列舉物件
  8. tuple(iterable) 轉換為元祖

認識模組

  1. 模組是Python中的最高級別組織單元,將程式程式碼和資料封裝起來以便重用,模組的作用,一個py檔案就是一個模組
    1. 程式碼重用
    2. 實現共享服務和資料
  2. 匯入從本質上講,就是在一個檔案中載入另一個檔案,並且能夠讀取那個檔案的內容,一個模組內的內容通過這樣的方法其屬效能夠被外界使用,在一個模組中引入外部模組
    1. import 模組名 模組名,就是python檔案的名字,注意不要py
    2. import 模組名 as 模組別名
  3. 可以引入同一個模組多次,但是模組的例項只會建立一個
  4. import可以在程式的任意位置呼叫,但是一般情況下,import語句都會統一寫在程式的開頭
  5. 在每一個模組內部都有一個__name__屬性,通過這個屬性可以獲取到模組的名字
  6. 也可以只引入模組中的部分內容(語法 from 模組名 import 變數,變數...)
  7. 也可以為引入的變數使用別名(語法 from 模組名 import 變數 as 別名)

檔案讀寫

# 檔案讀取
# 讀取txt中的資料
file = open('th.txt', 'r')
result = file.read()
print(result)
file.close()

# 讀取txt中的第一行資料(需要獲取第二行在讀取一次)
file = open('th.txt', 'r')
result1 = file.readline()
print(result1)
file.close()

# 迴圈讀取txt中的所有行資料
file = open('th.txt', 'r')
result1 = file.readlines()
for i in result1:
    print(i)
file.close()

# 檔案寫入
# 如果檔案存在,就重新寫入;如果檔案不存在則新建一個檔案並寫入
file = open('th.txt', 'w')
file.write("你不是很聰明")
print(file)
file.close()

# 檔案追加寫入
# 如果檔案存在,就重新寫入;如果檔案不存在則新建一個檔案並寫入
file = open('th.txt', 'a')    # a表示append 追加寫入
file.write("你不是很聰明")
print(file)
file.close()

# 檔案讀取二進位制檔案
# 如果檔案存在,就重新寫入;如果檔案不存在則新建一個檔案並寫入
file = open('th.txt', 'rb')  # a表示append 追加寫入
result = file.read()
print(result)

# 將讀取檔案封裝成方法(使用with...as的作用就是開啟後,最終自動關閉)
def read_txt(fileName):
    filepath = "C:/Users/17327/PycharmProjects/yunhe/data/" + fileName
    arr = []
    with open(filepath, "r", encoding="utf-8") as file:
        datas = file.readlines()
        for data in datas:
            arr.append(tuple(data.strip().split(",")))
    return arr
    
# seek()可以修改當前讀取的位置,需要兩個引數
1. 第一個是要切換到的位置
2. 計算位置方式,可選值
   1. 0  從頭計算,預設值
   2. 1  從當前位置計算
   3. 2  從最後位置開始計算

# tell()方法用來檢視當前讀取的位置

# 讀取檔案的其他方法
# 引入os
os.listdir()  獲取指定目錄的目錄結構,需要一個路徑作為引數,會獲取到該路徑下的目錄結構,預設路徑為.,當前目錄,該方法會返回一個列表,目錄中的每一個檔案的名字都是列表中的一個元素
os.getcwd()  獲取當前所在的目錄
os.chdir("c:/")  切換到當前所在目錄
os.mkdir("aaa")  在當前目錄下建立一個名字為aa的目錄
os.rmdir("abc")  刪除目錄
os.remove("aa.txt")  刪除檔案
os.rename("舊名字","新名字")  可以對一個檔案進行重新命名,也可以用來移動一個檔案

面向物件

一個類中的基本組成

class Dog(object):
    tpyes = "阿拉斯加"  # 類變數

    # 初始化方法
    def __init__(self, name, age, sex):
        # 例項化變數(屬性)
        self.name = name
        self.age = age
        self.sex = sex

    # 定義普通方法
    def eat(self):
        print("狗仔吃飯")

    def run(self):
        print("狗仔跑步")

例項化物件、self和初始化方法

class Dog(object):
    types = "寵物"  # 類變數

    # 初始化方法,也就是在物件建立的時候就會呼叫這個方法
    def __init__(self, name, age, sex):    # self表示當前物件
        # 例項化變數(屬性)
        self.name = name
        self.age = age
        self.sex = sex    # self.__sex=sex 表示私有化(要想獲取,需要在類內部定義一個方法呼叫self.__sex)

    # 定義普通方法
    def eat(self, speed):
        print(self.name + "狗仔吃飯" + "特別快" + speed)

    def run(self):
        print("狗仔跑步")


# 例項化物件
dog = Dog('阿拉斯加', '18', '雄')
dog.name = '薩摩耶'
print(dog.name)
dog.eat("3m/s")

類的繼承和多型

# 建立一個父類
class Animal(object):
    def __init__(self,color):
        self.color=color

    def eat(self):
        print("動物在吃")

    def run(self):
        print("動物在跑")
        
# 建立一個子類繼承
from animal import Animal
import all


class Cat(Animal):
    pass


class Dog(Animal):
    def __init__(self, name, age, color):
        super().__init__(color)  # 呼叫父類的color,dog同樣繼承
        self.name = name
        self.age = age

    def eat(self):
        print("狗仔吃飯")

    def run(self):
        print("狗仔跑步")


an1 = Animal("綠色")
cat = Cat("黃色")
cat.eat()
dog = Dog("阿拉斯加", 19, "黃色")
dog.eat()
print(dog.color)
all.feed(an1)  # 模擬多型實現動物在吃
all.feed(cat)  # 模擬多型實現貓在吃,如果沒有eat方法,呼叫父類方法
all.feed(dog)  # 模擬多型實現狗在吃

方法的重寫及super()

  1. 如果在子類中如果有和父類同名的方法,則通過子類例項去呼叫方法時,會呼叫子類的方法而不是父類的方法,這個特點我們稱之為方法的重寫(也可以叫做覆蓋)
  2. 當我們呼叫一個物件的方法時,會優先去當前物件中尋找是否具有該方法,如果有則直接呼叫,如果沒有則去當前物件的父類中尋找,如果父類中有則直接呼叫父類中的方法,如果沒有則去父類的父類中尋找
  3. 父類中的所有方法都會被子類繼承,包括特殊方法.同樣也可以重寫特殊方法
  4. 希望可以呼叫父類的__init_來初始化父類中定義的屬性,super()可以用來獲取當前類的父類,並且通過super()返回物件呼叫父類方法時,不需要傳遞self
class Animal:
    def __init__(self, name, age, nom):
        self.name = name
        self.age = age
        self.nom = nom

    def run(self):
        print("你確實會跑")


class Dog(Animal):
    def __init__(self, name, age, nom, sex):
        super().__init__(name, age, nom)
        self.sex = sex

    def run(self):
        print(self.name, self.age, self.nom, self.sex)


d = Dog("wupeng", 12, 23, 45)
d.run()

多重繼承

  1. 在python中支援多重繼承,也就是我們可以為一個類同時指定多個父類,可以在類名的()後面新增多個類,來實現多重繼承
  2. 多重繼承,會使子類同時擁有多個父類,並且會獲取到所有父類中的方法
  3. 在開發中沒有特殊的情況,應該儘量避免使用多重繼承,因為多重繼承會讓我們的程式碼過於複雜
  4. 如果多個父類中有同名的方法,則會先在第一個父類中尋找,然後找第二個,然後找第三個,前邊父類的方法會覆蓋後邊父類的方法

屬性和方法

  1. 類屬性,直接在類中定義的屬性是類屬性,類屬性可以通過類或類的例項訪問到,但是類屬性只能通過類物件來修改,無法通過例項物件修改
  2. 例項屬性,通過例項物件新增的屬性屬於例項屬性,例項屬性只能通過例項物件來訪問和修改,類物件無法訪問修改
  3. 例項方法,在類中定義,以self為第一個引數的方法都是例項方法,例項方法在呼叫時,python會將呼叫物件作為self傳入,例項方法可以通過例項和類去呼叫,當通過例項呼叫時,會自動將當前呼叫物件作為self傳入,當通過類呼叫時,不會自動傳遞self,此時我們必須手動傳遞self a.test()等同於A.test(a)
  4. 類方法,在類內部使用@classmethod來修飾的方法屬於類方法,類方法的第一個引數是cls,也會被自動傳遞,cls就是當前的類物件,類方法和例項方法的區別,例項方法的第一個引數是self,而類方法的第一個引數是cls類方法可以通過類去呼叫,也可以通過例項呼叫,沒有區別 A.test()
  5. 靜態方法,在類中使用@staticmethod來修飾的方法屬於靜態方法,靜態方法不需要指定任何的預設引數,靜態方法可以通過類和例項去呼叫,基本上是一個和當前類無關的方法,它只是一個儲存到當前類中的函式,一般都是一些工具方法,和當前類無關,並且有個特點,不需要傳遞self或者cls

股票提醒系統實戰

# 需要安裝Tushare,Tushare是一個免費、開源的ptyhon財經資料介面包,主要實現對股票等金融資料從資料採集、清洗加工到資料儲存的過程,能夠為金融分析人員提供快速、整潔和多樣的便於分析的資料.  pip install tushare
程式碼實現:
import time
import tushare
import datetime


class GetShare(object):
    def __init__(self, code):
        self.dateNow = tushare.get_realtime_quotes(code)
        datetime.datetime.now()

    def getShare(self):
        # 股票名
        name = self.dateNow.loc[0][0]
        # 當前價格
        price = float(self.dateNow.loc[0][3])
        # 最高價
        high = self.dateNow.loc[0][4]
        # 最低價
        low = self.dateNow.loc[0][5]
        # 成交量
        volumn = self.dateNow.loc[0][8]
        # 成交額
        amount = self.dateNow.loc[0][9]
        # 開盤價
        openToday = self.dateNow.loc[0][1]
        # 收盤價
        pre_close = self.dateNow.loc[0][2]
        # # 時間
        # timee = self.dateNow.loc[0][30]

        return print("股票名:", name, "\t", "當前價格:", price, "\t", "最高價:", high, "\t", "最低價:", low, "\t", "成交量:", volumn,
                     "\t", "成交額:",
                     amount, "\t", "開盤價:", openToday, "\t", "收盤價:", pre_close, "\t", "當前時間:",
                     datetime.datetime.now(), "\t")


ge = GetShare("300026")
ge1 = GetShare("600577")
ge2 = GetShare("300152")
list1 = [ge, ge1, ge2]
while True:
    for i in list1:
        i.getShare()
        print("")
    ge.getShare()
    print(
        "\n---------------------------------------------------------------------------------------------"
        "---------------------------------------------------------------------------------------------")
    time.sleep(10)

異常處理

認識異常

  1. 異常處理就是在寫Python時,經常看到的報錯資訊
  2. 異常是一個時間,該事件會在程式執行過程中發生,一般情況下,在Python中無法處理程式時就會發生異常,當Python無法處理程式時就會發生異常,當Python指令碼發生異常時,我們需要捕獲並處理異常
  3. 在執行過程中,不可避免的會出現一些錯誤,這些錯誤在程式彙總,我們稱其為異常,程式執行過程中,一旦出現異常將會導致程式立即終止,異常以後的程式碼全部都不會執行
a=[1,2,3,0,1,54,3,"a",2,1]
for i in a:
    try:
        if 3/i==1:
            print("有東西")
        else:
            print("東西沒用")
    except:
        print("此處出現異常")

try-except-else-finally

常見的錯誤和異常

  1. NameError 這是比較常見的一個錯誤,就是沒有定義變數就拿來用
  2. SyntaxError 語法錯誤,少了冒號,沒有空格等
  3. IO error 在做檔案操作的時候常遇到的錯誤,例如檔案操作的餓時候檔案不存在
  4. ZeroDivisionError 在做資料處理和計算的時候會遇到這種錯誤,就是除數是0
  5. IndentationError 這是新手常遇到的一種錯誤,就是縮排問題
# try-except-else的用法
a = [1, 2, 3, 0, 1, 54, 3, "a", 2, 1]
for i in a:
    try:
        if 3 / i == 1:
            print("有東西")
        else:
            print("東西沒用")
    except:
        print("此處出現異常")
    else:
        print("異常沒有丟擲,是正確的")  # 在沒有走except丟擲異常而是走try的時候,會執行else的內容
        
# try-except-else-finally的用法
a = [1, 2, 3, 0, 1, 54, 3, "a", 2, 1]
for i in a:
    try:
        if 3 / i == 1:
            print("有東西")
        else:
            print("東西沒用")
    except:
        print("此處出現異常")
    else:
        print("異常沒有丟擲,是正確的")  # 在沒有走except丟擲異常而是走try的時候,會執行else的內容
    finally:
        print("最終結束內容")  # 有異常也輸出,沒有異常也輸出

自定義異常

a="123456"

if len(a)<8:
    ex=Exception("不能小於8位")
    raise ex
else:
    print("可以進行操作")

網路程式設計

網路通訊概述

  1. 網際網路→路由器(分支)→主機(分支)
  2. 協議類似於一種規定
  3. 不同種類之間的計算式是通過大家任何都遵守的協議來進行資料傳遞,這個計算機都遵守的網路通訊協議就叫做TCP/IP協議

  1. 埠好比一個房子的進出口,如果一個程序需要收發網路資料,那麼就需要這樣的埠,在linux中,埠可以有65536個之多,作業系統為了統一管理,所以進行了編號,這就是埠號
  2. 埠是通過埠號來標記的,埠號只有證書,範圍是從0-65535
  3. 知名埠
    1. 80 分配給HTTP服務
    2. 21 分配給FTP服務
  4. 動態埠
    1. 動態埠的範圍是從1024-65535,它不固定分配某種服務,而是動態分配,動態分配是指當一個系統程序或應用程式程序需要網路通訊時,它向主機申請一個埠,主機從可用的埠號中分配一個供它使用.當這個程序關閉時,同時也就釋放了所佔用的埠號
    2. 埠號的作用 一臺擁有IP地址的主機可以提供許多服務,這些服務完全可以通過1個IP地址來實現,那麼為了區分不同的網路服務,所以需要使用IP地址+埠號來區分服務,需要注意的是,埠號並不是一一對應的,比如你的電腦作為客戶機訪問一臺www服務時,www伺服器使用80埠與你的電腦通訊,但你的電腦則可能使用3457這樣的埠

IP地址

  1. ip地址 用來在網路中標記一臺電腦的一串數字,比如192.168.1.1,在本地區域網是唯一的
  2. 每個IP地址包括兩部分:網路地址和主機地址
  3. ip地址分為五類
    1. A類保留給政府機構 由1位元組的網路地址和3位元組主機地址組成,網路地址的最高位必須是0(1.0.0.1)
    2. B類分配給中等規模的公司 由2個位元組的網路地址和2個位元組的主機地址組成,網路地址的最高位必須是10(128.1.0.1)
    3. C類分配給任何需要的人 c類網路可達2097152個,每個網路能容納254個主機
    4. D類用於組播 第一個位元組以1110開始
    5. E類用於實驗 第一個位元組以1111開始
  4. 私有IP
    1. 在這麼多網路IP中,國際規定有一部分IP地址是用於我們的區域網使用,也就是屬於私網IP,不在公網中使用範圍是10.0.0.0-10.255.255.255 172.16.0.0-172.31.255.255
    2. IP地址127.0.0.1~127.255.255.255用於迴路測試,可以測試本機中配置的web伺服器

TCP

  1. TCP/IP協議是一個協議族,裡面包括很多協議,UDP只是其中的一個,之所以命名為TCP/IP協議,因為TCP、IP協議是兩個很重要的協議
  2. TCP/IP協議包括應用層、傳輸層、網路層、網路訪問層
  3. TCP的三次握手,四次揮手
  4. 三次握手,建立TCP連線時,需要客戶端和伺服器共傳送3個包。
    1. 第一次:客戶端傳送初始序號x和syn=1請求標誌
    2. 第二次:伺服器傳送請求標誌syn,傳送確認標誌ACK,傳送自己的序號seq=y,傳送客戶端的確認序號ack=x+1
    3. 第三次:客戶端傳送ACK確認號,傳送自己的序號seq=x+1,傳送對方的確認號ack=y+1
  5. 四次揮手
    1. 第一次揮手:客戶端發出釋放FIN=1,自己序列號seq=u,進入FIN-WAIT-1狀態
    2. 第二次揮手:伺服器收到客戶端的後,發出ACK=1確認標誌和客戶端的確認號ack=u+1,自己的序列號seq=v,進入CLOSE-WAIT狀態
    3. 第三次揮手:客戶端收到伺服器確認結果後,進入FIN-WAIT-2狀態。此時伺服器傳送釋放FIN=1訊號,確認標誌ACK=1,確認序號ack=u+1,自己序號seq=w,伺服器進入LAST-ACK(最後確認態)
    4. 第四次揮手:客戶端收到回覆後,傳送確認ACK=1,ack=w+1,自己的seq=u+1,客戶端進入TIME-WAIT(時間等待)。客戶端經過2個最長報文段壽命後,客戶端CLOSE;伺服器收到確認後,立刻進入CLOSE狀態。

UDP

  1. 是一個非連線的協議,傳輸資料之前源端和終端不建立連線,當它傳送時,簡單的抓取來自應用程式的額資料,儘可能快的扔到網路上,在傳送端,UDP傳送資料的速度僅僅是受應用程式生成資料的速度、計算機的能力和傳輸頻寬的限制,在接收端,UDP把每個訊息段放在佇列總,應用程式每次從佇列中讀一個訊息段.
  2. 由於傳輸資料布簡歷連線,因此也不需要維護連線狀態,包括收發狀態,因此一臺服務機可同時向多個客戶機傳輸相同的訊息
  3. UDP資訊包的標題很短,只有8個位元組,相對於TCP的20個位元組資訊包的額外開銷很小
  4. 吞吐量不受擁擠控制演算法的調解,只受應用軟體生成資料的速率,傳輸頻寬、源端和終端主機效能的限制
  5. UDP使用盡最大努力交付,既不保證可靠交付,因此主機不需要維持複雜的連結狀態表
  6. 我們經常使用ping命令來測試兩臺主機之間TCP/IP通訊是否正常,其實Ping命令的原理就是向對方主機發送UDP資料包,然後對方主機確認收到資料包,如果資料包是否到達的訊息及時反饋回來,那麼網路就是通的.  
  7. ping命令時用來探測主機到主機之間是否可通訊,如果不能ping到某臺主機,表明不能和這臺主機建立連線.

電子郵件

電子郵件概述

常見的電子郵件協議有SMTP、POP3、IMAP4,隸屬於TCP/IP協議,預設狀態下,分別通過TCP協議埠25、110和143連線

  1. SMTP SMTP已經是事實上的E-Mail傳輸的標準,使用TCP的25埠
  2. POP協議 用於電子郵件的接受,使用TCP的110埠

傳送郵件的準備

  1. 郵件傳送方(傳送方地址,傳送方客戶端授權密碼,SMTP伺服器地址 smtp.163.com)
  2. 郵件內容
  3. 郵件接收方
  4. 安裝pyemail

郵件的實現

import smtplib
from email.mime.text import MIMEText

msg_from = "[email protected]"
pwd = "123453A"  # 授權密碼
to = "[email protected]"

subject = "這是我要傳送的郵件"
content = "你家著火了"
# 構造郵件
msg = MIMEText(content)  # msg郵件物件
msg["Subject"] = subject
msg["From"] = msg_from
msg["To"] = to

# 傳送郵件
ss = smtplib.SMTP_SSL("smtp.163.com", 465)
ss.login(msg_from, pwd)
ss.sendmail(msg_from, to, msg.as_string())

多執行緒

程序

程序就是一段程式的執行過程,它是一個具有一定獨立功能的程式關於某個資料集合的一次運動活動,它是作業系統動態執行的基本單元
程序有3種狀態

  1. 就緒態 獲取出cpu外的所有資源,之喲啊處理器分配資源就可以馬上執行
  2. 執行態 獲得了處理器分配的資源,程式開始執行
  3. 阻塞態 當程式條件不夠時候,需要等待條件滿足時候才能執行,如等待i/o操作時候,此刻的狀態就叫阻塞態

程序的實現原理
先建立程序在進行提交,然後就緒,就緒如果等待i/o時,阻塞,條件滿足後執行,最終在退出。

執行緒和多執行緒

  1. 執行緒 通常在一個程序中可以包含若干個執行緒,當一個程序中至少有一個執行緒,不然沒有存在的意義.執行緒可以利用程序所擁有的資源,我們把程序作為分配資源的基本單位,而把執行緒作為獨立執行和獨立排程的基本單位
  2. 多執行緒 多執行緒是為了同步完成多項任務,不是為了提高執行效率,而是為了提高資源使用效率來提高系統的效率.執行緒是在同一時間需要完成多項任務的時候實現的(車廂與火車的鮮明對比)
  3. 簡而言之,一個程式至少有一個程序,一個程序至少有一個執行緒.

Python的標準庫提供了兩個模組:_thread和threading,_thread是低階模組,threading是高階模組,對_thread進行了封裝,絕大多數情況下,我們只需要使用threading這個高階模組,啟動一個執行緒就是把一個函式傳入並建立Thread例項,然後呼叫start()開始執行

執行緒的運用(主執行緒和子執行緒)

# 主執行緒和子執行緒
import threading
import time


def run(name):
    print(name, "執行緒開始執行了")
    time.sleep(5)


# target指向一個目標
# 程式執行時,程式本身就是一個執行緒,叫主執行緒,手動建立的執行緒叫子執行緒
# 主執行緒的執行中不會等子執行緒執行完畢就會直接執行後面的程式碼
# 建立子執行緒
t1 = threading.Thread(target=run, args=("t1",))
t2 = threading.Thread(target=run, args=("t2",))
t1.start()
t2.start()

t1.join()  # 等待子執行緒執行完畢之後在執行主執行緒內容(會等待5s中之後執行print)
t2.join()
print("完畢了")

# 執行緒鎖(作用是為了防止執行緒在執行過程中出現跳出執行發生錯亂)
import threading
import time

lock = threading.Lock()  # 建立了執行緒鎖
num = 100


# 這邊方法傳值,那麼threading.Thread()需要傳入args=(引數,)
def run():
    lock.acquire()  # 設定鎖
    global num
    num = num - 1
    print("執行緒", num, "執行了,目前的值為:", num)
    lock.release()  # 釋放鎖


for i in range(100):
    td = threading.Thread(target=run)
    td.start()

訪問mysql資料庫

python安裝mysql模組包 pip install pymysql

資料庫建立連線

import pymysql

# 開啟資料庫連線, 主機地址 埠號3306 使用者名稱root 密碼 資料庫名
db = pymysql.Connect(host='localhost', port=3306, user='root', passwd='bb961202', db='animal', charset='utf8')
# 建立一個遊標物件,用來操作資料庫
cursor = db.cursor()
print(db)

python建立資料表

import pymysql

# 開啟資料庫連線, 主機地址 埠號3306 使用者名稱root 密碼 資料庫名
db = pymysql.Connect(host='localhost', port=3306, user='root', passwd='bb961202', db='animal', charset='utf8')
# 建立一個遊標物件,用來操作資料庫
cursor = db.cursor()
# 新建表
sql = 'create table persions(name varchar(20),age int(10))'
cursor.execute(sql)
print(db)

python取消sql語句高亮背景

  1. 開啟Settings,搜尋Language Injections 勾選掉SQL select/delete/insert/update/create
  2. 開啟Settings,Editor下找到Inspections 找到SQL勾選掉 no data source configured

python新增資料

# 需要注意的是在做python新增的時候需要commit,並且字符集資料庫要跟pymysql.Connect()中的charset='utf8'一致
import pymysql

# 開啟資料庫連線, 主機地址 埠號3306 使用者名稱root 密碼 資料庫名
db = pymysql.Connect(host='localhost', port=3306, user='root', passwd='bb961202', db='animal', charset='utf8')
# 建立一個遊標物件,用來操作資料庫
cursor = db.cursor()
# 新建表
# sql = "create table persions7(name varchar(20),age int(10))"
sql = 'insert into dog(name,age)values("球球",12)'
cursor.execute(sql)
db.commit()
print(db)

python查詢資料

import pymysql

# 開啟資料庫連線, 主機地址 埠號3306 使用者名稱root 密碼 資料庫名
db = pymysql.Connect(host='localhost', port=3306, user='root', passwd='bb961202', db='animal', charset='utf8')
# 建立一個遊標物件,用來操作資料庫
cursor = db.cursor()
# 新建表
# sql = "create table persions7(name varchar(20),age int(10))"
sql = 'select * from dog'
cursor.execute(sql)
# data = cursor.fetchone()  # 獲取單個物件(也就是單條資料)
# print(data)
data1 = cursor.fetchall()  # 獲取多個物件(也就是多條資料)
list = []
for i in data1:
    list.append(i)
print(list)  # 或者一個列表內包含元祖的資料

python修改資料和刪除

import pymysql

# 開啟資料庫連線, 主機地址 埠號3306 使用者名稱root 密碼 資料庫名
db = pymysql.Connect(host='localhost', port=3306, user='root', passwd='bb961202', db='animal', charset='utf8')
# 建立一個遊標物件,用來操作資料庫
cursor = db.cursor()
# 新建表
# sql = "create table persions7(name varchar(20),age int(10))"
sql = 'update dog set name="憨慫" where name="憨比"'
sq2='delete from dog where name="憨比1"'
cursor.execute(sql)
cursor.execute(sq2)
db.commit()  # 做修改時,需要提交
db.close()  # 執行任意增刪改查最好關閉資料庫

事務和異常處理

import pymysql

# 開啟資料庫連線, 主機地址 埠號3306 使用者名稱root 密碼 資料庫名
db = pymysql.Connect(host='localhost', port=3306, user='root', passwd='bb961202', db='animal', charset='utf8')
# 建立一個遊標物件,用來操作資料庫
cursor = db.cursor()
# 新建表
# sql = "create table persions7(name varchar(20),age int(10))"
sql = 'update dog set name="憨慫" where name="憨比"'
sq2 = 'delete from dog where name="憨比1"'
try:
    cursor.execute(sql)
    cursor.execute(sq2)
    db.commit()  # 做修改時,需要提交事務,事務中的操作就是要麼都提交,要麼都不提交
except:
    db.rollback()  # 回滾所有操作都不提交
    print()
db.close()  # 執行任意增刪改查最好關閉資料庫

後續補充...