主頁 > 後端開發 > 【從0開始入門python】一個半月的三萬字學習筆記匯總!!!

【從0開始入門python】一個半月的三萬字學習筆記匯總!!!

2021-09-02 08:14:56 後端開發

  • python學習

    • DAY01-DAY04基礎操作
    • DAY05-DAY09基本模塊

    常用pip源

    (1)阿里云

    http://mirrors.aliyun.com/pypi/simple/
    

    (2)豆瓣

    http://pypi.douban.com/simple/
    

    (3)清華大學

    https://pypi.tuna.tsinghua.edu.cn/simple/
    

    (4)中國科學技術大學

    http://pypi.mirrors.ustc.edu.cn/simple/
    

    (5)華中科技大學

     http://pypi.hustunique.com/
    

第一講

基礎知識

# ctrl+/ 添加注釋
# ctrl+alt+l 三鍵實作格式規范
# 或者在pycharm編譯器中點擊“code->Reformat Code
# 英文輸入符號
# \+特定字符 產生一個新的含義,就是轉義字符(# \\ \t)
print(666)
print('我愛編程')
# sep=','指定,為分隔變數的符號
print('唐三', '小舞', '張三', sep=',')
print('唐三', '小舞', sep='\n')
# end='\n'指定換行結尾
print('唐三', '小舞', end='*')
print('唐三', '小舞', end='\n')
# 變數
# 1.有一定意義
# 2.由數字,字母,下劃線組成,數字不能開頭
name = '張三'#等號是賦值
print(name)
# input()表示輸入,在括號里面加入''可加入提示
input('請輸入您的密碼')

第二講

資料型別

# 整型 int
# 浮點型 float
# 字符型 str
# '''中間可以放幾段話'''
name = '''
啦啦啦
啦啦啦
啦啦啦
'''
print(name)
# type函式
name = '漩渦鳴人'
print(type(name))
# 運算注意優先級以及從左向右計算
# 字符不能和整數型別相加,但可以變換
name = '張三'
age = 48
print(name + str(age))
# 同理整型和浮點型別也可以相互轉換,但有非數字的字符不能轉換為整數,也不能是浮點型別結構

第三講

運算子

# + - * / % 加減乘除求余
number = input('請輸入數字')
number = int(number) # 輸入的是字符型別,用int轉換為整數型別進行運算
result = number % 2
print(result)
# //表示整除運算
bounty = 5000
print(bounty/280) # 結果是17.86
print(bounty//280) # 結果是17
# += *= /= -= 運算子
# 關系運算子回傳值型別是布爾型別
# ord()函式可以查看字符對應的整數數值
print(ord('a'))
# 邏輯運算子 and or not
# and 有假就為假   or 有真就為真  not 真就假假就真

第四講

條件陳述句

  1. if陳述句的使用
  2. if…else陳述句的使用
  3. 多重if陳述句的使用
  4. if嵌套
# if 要判斷的條件:        (標準結構)
#     條件成立時要做的事情
# else:
#     條件成立時要做的事情
money = input('請輸入您的錢數')
money = int(money) # 注意轉換
things1 = '盲盒'
if money>35:
   print('拿下{}'.format(things1))
# 用{}進行占位,用.format()函式填充占位
else:
   print('買不起')
# elif陳述句
# if 條件1:
#     事情1
# elif 條件2:
#     事情2
# else:
#     事情3
choice1 = input('請輸入你要選的品牌')
choice2 = input('請輸入你要選的衣服型別')
money = input('請輸入你手中有多少錢')
money = int(money)
if choice1 == '安踏' and choice2 == '短袖' and money > 60 :
    print('您購買了{}品牌的{}'.format(choice1,choice2), '您還有{}元錢'.format(money-60) , sep = '\n')
elif choice1 == '李寧' and choice2 == '短袖' and money > 60 :
    print('您購買了{}品牌的{}'.format(choice1,choice2), '您還有{}元錢'.format(money-60) , sep = '\n')
elif choice1 == '耐克' and choice2 == '短袖' and money > 60:
    print('您購買了{}品牌的{}'.format(choice1, choice2), '您還有{}元錢'.format(money - 60), sep='\n')
else:
    print('您要的我們沒有或者您的錢不足以支付請重試')
    # if下陳述句可繼續嵌套if

第五講

回圈陳述句

  1. while的使用
  2. for的使用
  3. break和continue的使用
  4. while或者for與else結合使用

回圈的核心在于減少重復代碼,條件要盡量通用化

# while 回圈條件:(當回圈條件不成立時結束)
# 	回圈執行的代碼
i = input('請輸入數字')
i = int(i)
while i <= 5:
    i += 1
    print(i)
# 需求:限制登陸次數
i = 3
while i >= 1:
    username = input('請輸入用戶名')
    password = input('請輸入密碼')
    if username == 'admin' and password == '123456' :
        print('登錄成功')
        break # 作用在于登錄成功后退出回圈
    else:
        print('登錄失敗')
        i -= 1
        print('還有{}次機會' .format(i))
        continue # 繼續回圈
# for 變數 in 序列:
#		回圈體
# 變數:自定義變數名,要求和單獨定義時候一樣
# 序列:容器型資料型別的資料,比如字串,布爾,串列,元組,集合
# 回圈體:需要重復執行的代碼
for x in range(1,11):
    print('今天你直播下單{}次'.format(x))
    # range()函式作用是產生一個序列,從0開始
    # range(1,11)則表示從1開始11結束但是不包括11
    # range(1,6,2)表示135的序列,即2為步長(可以是負數)
# 需求:限制登陸次數
for i in range(3):
    username = input('請輸入用戶名')
    password = input('請輸入密碼')
    if username == 'admin' and password == '123456' :
        print('登錄成功')
        break # 作用在于登錄成功后退出回圈
    else:
        print('登錄失敗')
        print('還有{}次機會' .format(2-i))
        continue # 繼續回圈
# continue 跳過本次回圈,后面陳述句不執行,繼續執行下一次回圈
# 需求:列印1-12數字,除了8不列印
# 方法一
for i in range(1,13):
    if i == 8:
        continue
    else:
        print(i)
# 方法二
i = 1
while i <12:
    i += 1
    if i == 8 :
        continue
    print(i)
# else可以和while,for進行配合
# 案例一
i = 13
while i <12:
    print('驗證失敗')
else:
    print('驗證成功')
# 案例二
for i in range(8):
    print(i , end=' ')
else:
    print('\n')
    print('結束')

第六講

資料型別串列(串列類似陣列,字典類似結構體)

  1. 串列的使用
  2. 字典的使用
  3. 字串的使用
# 以前介紹的int bool str float都只能存放一個值,需要串列存放一堆值
# 變數名字 = [元素,元素,元素]
heros = ['張三', '張四', '張五', '張六', '張七', '張八']
print(type(heros))

輸出結果是<class ‘list’>,即構成了一種新的資料型別串列

# 那怎么找到串列中的某一個元素呢?這就要用到串列索引
# 計算機編號從0開始,相關方式類比陣列
heros = ['張三', '張四', '張五', '張六', '張七', '張八']
print(heros[1])

即可獲取張四,同理可以獲取其他元素,若要同時獲取多個元素,則要使用串列切片的辦法

# 1:3表示索引的一個左閉右開區間,只包含左邊不包含右邊
heros = ['張三', '張四', '張五', '張六', '張七', '張八']
print(heros[0:6])
# [3:]若省去終止位置,則表示從標明的初始位置一直索引到終止位置
heros = ['張三', '張四', '張五', '張六', '張七', '張八']
print(heros[0:])

這樣就可以把上述元素全部輸出出來了(倆個方法結果一樣)

輸出結果為 [‘張三’, ‘張四’, ‘張五’, ‘張六’, ‘張七’, ‘張八’]

但是顯然不可能所有的取法步長都為一也不可能都是順序取元素

# 完整格式  print(串列名(初始位置:終止位置:步長)) 默認步長為+1
heros = ['張三', '張四', '張五', '張六', '張七', '張八']
print(heros[0::2])

這樣就可以輸出從第一個元素開始的所有奇數項元素

我們在長資料超大資料時,往往不方便一次看出到底有多少個元素

# len()函式可以獲取串列的長度
print(len(heros))

我們往往需要增加洗掉修改查找串列元素,實作串列元素動態管理

(增刪改查)

# append可以實作串列元素增加
heros.append('張九')
# insert函式可以定向添加元素
# insert方法只是插入元素,原來在此位置以及之后的元素全體后移
heros.insert(3, '張六plus')# pop或者remove可以實作串列元素洗掉
# 串列.pop[索引]表示洗掉特定位置索引位置的元素
heros.pop() # 若索引為空表示洗掉最后一個元素
heros.remove('張三') # 移除張三這個元素

改
heros[0] = '張三plus' # 實作修改定向位置的元素# index函式可以實作查找某一元素具體位置,并通過變數存盤,在案例實作的時候有奇效
number1 = heros.index('張三')
print(number1)
# 可以利用 in 來判斷元素在不在串列內
# 格式  查找的元素 in 串列名  回傳值是布爾型別,可以用int轉換后用變數儲存下來
heros = ['張三', '張四', '張五', '張六', '張七', '張八']
number3 = int('張2' in heros)
print(number3)
# index 和 in 可以相互補充相互協調,index回傳具體位置,in判斷在不在,還可以配合后面的count來判斷在不在

有些時候一個串列會有很多重復的元素,我們需要函式來幫我們進行計數

# 串列名.count(要查詢的元素)   回傳值為元素個數
heros = ['張三', '張四', '張五', '張六', '張七', '張八']
heros.append('張三')
heros.append('張三')
heros.append('張三')
heros.append('張三')
number2 = heros.count('張三')
print(number2)

字典

# 基礎格式 變數名字 = {key1:value1,key2:value2}
hero = {'姓名': '孫悟空','性別': '男', '定位':'戰士' }
print(hero)
print(type(hero))

得到的結果是<class ‘dict’>即構成了一種新的資料型別串列

字典還可以和串列搭配使用

hero = {'姓名': '孫悟空', '性別': '男', '定位': '戰士', '最佳搭檔': ['八戒', '沙僧', '唐僧']}
print(hero)
print(type(hero))
# 那如何獲取里面中的東西呢
print(hero['性別'])
# 如何判斷字典里面是否有我們查找的鍵呢
# print(字典名.get(查找的鍵,如果找不到回傳的東西))
hero = {'姓名': '孫悟空', '性別': '男', '定位': '戰士', '最佳搭檔': ['八戒', '沙僧', '唐僧']}
print(hero.get('定位', '未知'))
# 我們用get的時候,如果鍵存在則回傳鍵的值,如果鍵不存在則回傳設定的回傳值,如果我們沒有設定回傳值,則回傳NONE

字典同樣支持增刪改查操作,實作動態管理

hero = {'姓名': '孫悟空', '性別': '男', '定位': '戰士', '最佳搭檔': ['八戒', '沙僧', '唐僧']}
hero['血量'] = 4399 # 對于一個原來沒有的鍵進行操作會添加
hero['性別'] = '未知' # 對于一個原來有的鍵進行操作會修改
print(hero)
# 字典名.pop[鍵名]表示洗掉特定鍵
heros.pop('定位') 
# 可以利用 in 來判斷元素在不在字典內
# 格式  查找的鍵 in 字典  回傳值是布爾型別,可以用int轉換后用變數儲存下來
hero = {'姓名': '孫悟空', '性別': '男', '定位': '戰士', '最佳搭檔': ['八戒', '沙僧', '唐僧']}
number4 = int('姓名' in hero)
print(number4)
# value函式可以輸出字典的所有值
hero = {'姓名': '孫悟空', '性別': '男', '定位': '戰士', '最佳搭檔': ['八戒', '沙僧', '唐僧']}
print(hero.values())
# 結果為:                                                    dict_values(['孫悟空', '男', '戰士', ['八戒', '沙僧', '唐僧']])
# value的作用不光只是顯示,還可以配合in進行邏輯判斷
hero = {'姓名': '孫悟空', '性別': '男', '定位': '戰士', '最佳搭檔': ['八戒', '沙僧', '唐僧']}
print(int('孫尚香' in hero.values())) # 回傳值為布爾型別

字串的使用

# 單引號,雙引號,三引號三種宣告方式,三引號的優點在于可以原樣輸出,空格空行都會被保留
hero1 = 'hello'
hero2 = "hi"
hero3 =     '''
            hello
            hi
            '''
print(hero1, hero2, hero3)

字串和串列一樣,也有切片和索引的訪問形式

把字串當成字符的串列

message = '王者榮耀'
print(message[0])
print(message[:2]) # 從初始位置到2這個位置
# 案例 在任意一個輸入字串中,查找是否有英雄這個子串
string = input('請輸入一個字串')
lenstr = int(len(string))
for x in range(0, lenstr):
    if string.find('英雄') >= 0:
 # find函式可以查找,如果找到顯示第一個字符的位置,如果沒找到會回傳-1
        print('有英雄這個子串')
        break
    else:
        if x == lenstr - 1 :
            print('沒有英雄這個子串')
        else:
            continue
print(string.startswith('王者'))
print(string.endswith('王者'))
# startswitch函式可以判斷是否以某某字符或字串開頭,回傳值為布爾型別
# endswitch函式可以判斷是否以某某字符或字串結尾,回傳值為布爾型別

簡化字串技巧

字串中有很多空格或者轉義字符我們可以用一個函式全部去除

# strip函式
s = '       hello\\\\\mm\n\n\n\n'
print(s.strip())

輸出結果是 hello\\mm

第七講

函式

  1. 函式的作用與定義
  2. 函式的引數
  3. 函式的回傳值
# 函式格式(定義)
def sum(num): 
# def關鍵字表示定義一個函式 sum是函式名 num是形參可以有多個
    result = 0
    for x in range(1, num+1):
        result += x
        print(result)
# 要注意縮進,以及分號的使用
# 函式呼叫
# 呼叫格式: 函式名(引數)這里引數是實參
def sum(num):
    result = 0
    for x in range(1, num+1):
        result += x
        print(result)
number = 1
sum(number)

案例

定義一個函式來實作用戶的登錄

def login():
    username = input('輸入用戶名')
    password = input('輸入密碼')
    if username == 'admin' and password == '123456':
        print('登錄成功')
    else:
        print('登錄失敗')
login()

函式的引數

# 有參傳參,無參空著,順序一致
def milk_tea(n,kind='波霸奶茶'): # n表示奶茶數量,kind表示奶茶種類
    # 默認引數一定要在普通引數后,默認引數可以不傳參使用默認值
    # 可以有很多默認引數但一定要在所有普通引數結束后再寫默認引數
    for i in range(n):
        print('正在制作第{}杯奶茶'.format(i+1))
        print('放入{}的原材料'.format(kind))
        print('調制奶茶')
        print('倒入奶茶')
        print('封口')
milk_tea(5)
milk_tea(1, '珍珠奶茶')
milk_tea(4, '椰果奶茶')
milk_tea(5, '黑糖珍珠奶綠')

關鍵字引數

def milk_tea(n, kind='波霸奶茶',price=15): # n表示奶茶數量,kind表示奶茶種類
    print('顧客您需要的{},每杯{}元,應收{}元'.format(kind,price,n*price))
    for i in range(n):
        print('正在制作第{}杯奶茶'.format(i+1))
        print('放入{}的原材料'.format(kind))
        print('調制奶茶')
        print('倒入奶茶')
        print('封口')
milk_tea(1)
milk_tea(2, '原味奶茶')
milk_tea(n=4, kind='原味奶茶',price=18) # 關鍵字引數可以自定義傳輸

回傳值

# 計算從1到num的和
def ger_sum(num):
    sum = 0
    for i in range(num):
        sum += i+1
    return sum
num1 = input('請輸入要計算到的數字')
num1 = int(num1)
result = ger_sum(num1)
print('result = {}'.format(result))

第八講

面向物件基礎

一類人或一類車等的定義方法用串列太過復雜,所以抽象出類這一概念

面向程序編程(把大象放進冰箱需要幾步)

  • 把冰箱門打開
  • 把大象裝進去
  • 把冰箱門關上

面向物件編程(大象,冰箱的種類,具象化目標具象化實作)

類的定義

# class 類名:
#     屬性
#     方法

要求

  1. 類的首字母必須大寫

  2. 類名后面必須有冒號

  3. 類體有縮進

class Phone:
    pass
# 在python中 pass是空陳述句,是為了保持程式結構的完整性,pass不做任何事情,一般用于占位有陳述句,支撐結構
class Phone:
    brand = '華為'
    color = '黑色'
    type = 'Mate30 pro'
    price = 9999
# 定義行為和函式相似,只是必須帶上一個引數self
    def call(self):
        print('打電話')
    def send_message(self):
        print('可以發資訊')
class Saiya:
    name = '悟空'
    hair = '固定'
    has_tail = True
    appetite = '大'
    def fight(self):
        print('我們賽亞人就是喜歡戰爭')

類的使用

類的定義主要用途是把一個類的所有特征抽象出來,而用到具體物件時則需要講抽象的特征一一賦值一一對應

# 物件名 = 類名(引數),其中引數是可選引數,可有可無
phone1 = Phone()
phone2 = Phone()
phone3 = Phone()
print(phone1)
print(phone2)
print(phone3)
# 訪問方式  物件名.屬性名  or   物件名.方法名
print(phone1.price)

屬性添加的方式

  1. 通過外層的物件動態添加
  2. 使用建構式添加
# 通過外層的物件動態添加
phone1.price = 10000
print(phone1.price)
# __init__魔術構造方法也就是建構式,會在開始時自動呼叫
class Person:
    country = '中國'
    def __init__(self,name):
# self表示物件本身,self.name = name表示在當前物件中增加一個屬性并且賦值(在這里也就是Person)
        print('我是一個__init__方法')
        self.name =name
    def eat(self):
        print('我是一個吃貨')
p1 = Person(name = '龜龜')
p2 = Person(name = '兔兔')
print(p1)
print(p2)

類的方法的定義與呼叫

class Person:
    name = '悟空'
    def __init__(self,name):
        self.name =name
    def eat(self):
        print('我是一個吃貨')
    def sprot(self, time):
        if time < 6:
            print(self.name + '你怎么這么勤快,這么早就起床了')
        else:
            print(self.name + '怎么這么愛睡懶覺!')
        self.eat()
p1 = Person(name = '龜龜')
p2 = Person(name = '兔兔')
p1.sprot(time=3)
p2.sprot(time=7)

類的繼承

class Saiya:
    def __init__(self,name):
        self.name = name
    def eat(self):
        print(self.name + '我是一個吃貨')

    def sprot(self, time):
        if time < 6:
            print(self.name + '你怎么這么勤快,這么早就起床了')
        else:
            print(self.name + '怎么這么愛睡懶覺!')
        self.eat()
# 假設有另外一類人的定義,和上面Person幾乎一樣,為了減少代碼重復,引入繼承
class Saiya(Person):
    #這樣就可以表示Saiya類繼承了所有Person屬性和行為(可以任意呼叫Python),這樣我們就有更多的代碼空間進行Saiya不同于Person的特性,大大簡化了代碼

第九講

模塊(python的魔法棒)

  1. 模塊簡介
  2. 模塊匯入
  3. 包的匯入
  4. 模塊搜索路徑
  5. __name__的使用
  6. 常見系統模塊介紹
# 創建模塊的本質就是創建一個.py檔案,它可以被其他模塊匯入并使用
# 呼叫模塊的方法
# import 
# from ... import
# 模塊命名要用小寫字母,且不要和內置模塊重名
創建一個.py檔案(harry.py)
# harry.py
name = 'Harry Potter'
age = 10
def Fight(tool=None):
    if tool:
        print('在魔法學校駕駛' + tool + '練習飛行')
    else:
        print('走到魔法學校就會練習飛行了!')
class Course:
    def __init__(self,name,c_list=[]):
        self.name = name
        self.c_list = []
    def add_course(self,c_name):
        if c_name:
            self.c_list.append(c_name)
        else:
            print('選修課不能為空')
    def remove_course(self,c_name):
        if c_name:
            self.c_list.remove(c_name)
        else:
            print('選修課不能為空')
再創建一個magic.py檔案
# magic.py
def use_magic():
    print('我會施展厲害的魔法')

此時兩個模塊已經封裝完畢,我們只需要import 模塊名即可呼叫模塊里面的函式變數以及類,我們的使用方式主要是通過點運算子來完成的

# 在包檔案中進行呼叫(一般匯入陳述句都在開頭)
import harry
import magic
print(harry.name)
harry.Fight()
c = harry.Course('哈利')
c.add_course('黑魔法防御術')
magic.use_magic()
# 模塊重命名
import harry as hy # 這樣防止模塊名字太長起到重命名的作用
# 匯入方法2
from harry import name
from harry import Fight
from harry import Course
print(name)
Fight()
c = Course('哈利')
c.add_course('黑魔法防御術')
# 這種方法就不用使用harry.的方法,相當于提前宣告來源,簡化邏輯,也可以起到引入特定變數特定函式特點類的作用
# from harry import name
# from harry import Fight
# from harry import Course
也可以用以下表達代替用來簡化代碼
from harry import name, fight, Course
或者
from harry import *
# 這個表示把所有的都匯入

匯入模塊從本質上來說就是去執行一個.py檔案,開辟一個新記憶體,把匯入的東西放進記憶體中,這樣我們呼叫就可以直接從記憶體中獲取,當模塊數量越來越多時,我們就需要通過包的形式對模塊進行管理

包就是一個包含__init__.py的檔案夾

# 創建一個包(包的命名規則與模塊相同)
# 右鍵點擊new,然后創建python package

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-2wsqM5f0-1630476391786)(C:\Users\dell\Desktop\QQ截圖20210813172613.png)]

# 創建好以后將之前封裝好的harry.py和magic.py拖到包中檔案夾

包的匯入

# 拖入后我們可以看到原來的匯入格式被修改了
from package.harry import *
# 編譯器自動維護了package.的格式表明路徑
import sys
print(sys.path)
# 利用sys包我們可以查找我們當前腳本檔案的位置
# 在新創建的包檔案中創建magic1,magic2,text的.py檔案
magic1.py
def use_magic():
    print('我會施展最厲害的魔法')
print('我是一個新的magic模塊' + __name__)
text.py
from package.harry import *
from package.magic1 import use_magic
# __name__的用途在于,如果在它原本的模塊運行,輸出為__main__在別的模塊運行則輸出為路徑,可以利用這一性質,來實作一些陳述句只模塊內輸出而不模塊外輸出
magic.py
def use_magic():
    print('我會施展最厲害的魔法')
if __name__ == '__main__':
    print('我是一個新的magic模塊' + __name__)
這樣'我是一個新的magic模塊'這個陳述句就不會被誤輸出了!妙啊

系統內置模塊

  • # time模塊 
    # 可以獲取當前的時間戳
    import time
    t1 = time.time()
    print(time.ctime(t1))
    # 利用sleep函式進行每隔一秒回圈進行一次
    import time
    for i in range(5):
        print(i)
        time.sleep(1)
    # datetime
    # datetime中封裝了date,time,datetime,timedelta其中timedelta是值時間差
    from datetime import *
    print(datetime.now())
    dt = datetime.now()
    dt1 = dt + timedelta(days=-1) # 表示日期-1
    print(dt, dt1, sep='\n')
    
  • # random模塊
    import random
    print(random.random()) # 表示從0到1的隨機小書
    print(random.randint(1, 10))
    # 表示從1到10的隨機整數(包括1和10)
    print(random.randrange(1, 10))
    # 表示從1到10的隨機整數(不包括10)
    print(random.choice(range(10)))
    # random.choice(串列或資料集),表示從串列或資料集中隨機獲取一個元素,起到定范圍而又隨機的作用
    
  • # os模塊
    import os
    # 查看當前作業目錄
    result1 = os.getcwd()
    print(result1)
    # 在當前檔案夾中創建一個檔案夾
    # os.mkdir()只能創建一級目錄,而os.makedirs()可以創建多級目錄,
    os.mkdir('images')
    # 獲取當前環境變數
    print(os.environ)
    # 獲取絕對路徑
    result = os.path.abspath('harry.py')
    print(result)
    # os.listdir('package')查看檔案串列
    # os.remove('package/text.py')洗掉某個模塊
    注意以下操作只能針對同級或下級檔案,如harry.py中使用下面代碼則會報錯,一定要在與package同級的.py檔案中操作才有用
    result = os.listdir('package')
    print(result)
    os.remove('package/text.py')
    # 查看檔案大小
    path = './package/harry.py' # .表示當前目錄下
    result = os.path.getsize(path)
    print(result)
    # 查看是否為檔案
    result1 = os.path.isfile('path')
    print(result1)
    # 查看是否為檔案夾
    result1 = os.path.isdir('path')
    print(result1)
    

第十講

python的檔案操作(自動化記錄)

  1. 檔案寫入
  2. 檔案讀取
  3. csv檔案的寫入
  4. csv檔案的讀取
# open()函式的使用,open函式的作用是打開一個檔案并且有回傳值(布爾型別)
# 檔案要素:存放位置,檔案名字
# 相對位置 ./main.py同一目錄下的檔案表示
# 絕對路徑 D://user/hello/main.py
stream = open(file='./666') # 變數stream起到了傳輸管道的作用
print(stream)

輸出結果為<_io.TextIOWrapper name=’./666’ mode=‘r’ encoding=‘cp936’>

mode = 'r’讀操作,'w’寫操作,'a’追加,'t’文本格式,'b’位元組方式讀取且這些字母可以組合使用

encoding表示編碼集即翻譯方式

# mode,encoding可以修改
stream = open(file='./666', mode='w')
print(stream)
stream = open(file='./666', mode='w', encoding='utf-8')
print(stream)

檔案寫入以及關閉

stream = open(file='./666', mode='w', encoding='utf-8')
print(stream)
record = '4月18日 17:00 FPX PK RNG'
stream.write(record) # 檔案寫入
stream.close() # 檔案關閉 一定要關閉涉及資料安全
# 如果打開的檔案不存在,則會新建一個檔案
stream = open(file='./text1.txt', mode='w', encoding='utf-8')
print(stream)
# 將mode改成a即可實作不斷追加,但追加并不會幫我們換行,所以當我們需要換行的時候需要在加入的文本前用換行符號
stream = open(file='./text1.txt', mode='a', encoding='utf-8')
print(stream)
record = '\n4月18日 17:00 FPX PK RNG'
stream.write(record) # 檔案寫入
stream.close()

那如果資料量很大怎么辦呢

record = ['4月1日 17:00 IG PK RA',
          '4月2日 17:00 LGD PK SN',
          '4月3日 17:00 FPX PK RA',
          '4月4日 17:00 SN PK WE',
          '4月5日 17:00 JDG PK FPX',
          '4月6日 17:00 SN PK TEX'
          ]
stream = open('records.txt',mode='w',encoding='utf-8')
for record1 in record: # 通過回圈來進行寫入并在后面添加換行符號
    stream.write(record1 + '\n')
stream.close()
stream = open('records.txt',mode='a',encoding='utf-8')
# 再次寫入的時候格式要變成a,并且重新打開
stream.write('123456')
stream.close()
# 寫入后一定要關閉檔案

那檔案的讀取改如何操作

stream = open('records.txt', mode='r', encoding='utf-8')
# 讀取中格式為r
content = stream.read()
# 用一個變數保存我們閱讀的值
print(content)
stream.close()
# 讀格式和寫格式有所不同,當寫格式檔案不存在的時候會創建一個檔案,而讀取一個不存在的檔案則會報錯

檔案的例外處理(處理報錯情況)

  • # 格式
    try:
        可能會有例外的代碼
    except:
        發生例外的時候要執行的代碼
    finally:
        無論是否有例外都要執行的代碼
    
  • # 方法1
    content = None
    try:
        stream = open('records.txt', mode='r', encoding='utf-8')
        content = stream.read()
    except:
        print('檔案找不到')
    finally:
        print(content)
     # 這段代碼邏輯就是,設定變數為空,如果檔案可以找到并打開,將改空代碼重新賦值并且輸出,如果檔案無法找到并打開,則會輸出except的提示陳述句,并且輸出空,這樣就可以避免了報錯導致程式例外終止
    
  • # with關鍵字的使用
    with 運算式 as 變數:
        陳述句
    
  • with open('records.txt',mode='r',encoding='utf-8') as  stream:    content = stream.read()    print(content)
    

csv檔案的操作

csv檔案是以逗號隔開的

import csvrecord = [['4月1日 17:00 IG PK RA'],          ['4月2日 17:00 LGD PK SN'],          ['4月3日 17:00 FPX PK RA'],          ['4月4日 17:00 SN PK WE'],          ['4月5日 17:00 JDG PK FPX'],          ['4月6日 17:00 SN PK TEX']]with open('electronic_sport.csv', 'w', encoding='utf_8') as stream:    writer = csv.writer(stream)    writer.writerow(['date', 'time','adversary'])    for recod in record:    writer.writerow(recod)    # 也可以直接用writer.writerows來實作多行同時寫入

檔案寫入不同作業系統的展示結果不同,windows常會附加空行

如有需要改變可以open(‘electronic_sport.csv’, ‘w’, encoding=‘utf_8’,newline = ‘’ )

csv檔案的讀取

with open('electronic_sport.csv', mode='r', encoding='utf-8') as stream:    reader = csv.reader(stream)    for row in reader:        print(row)

第十一講

Pillow圖片處理

PIL是python中一個強大而方便的影像處理庫,Pillow是PIL的一個分支,我們在安裝的時候盡量安裝pillow,PIL和pillow不能共存,記得先卸載PIL哦!

如果遇到問題解決網址

Pycharm無法用pip安裝PIL以及安裝Pillow之后依然報錯“No module named ‘Pillow’”的詭異問題_清水河C羅——Leonardo-Liu-CSDN博客

  1. Image模塊的使用
  2. 其他模塊的使用
    • ImageDraw
    • ImageFont
    • ImageFilter
# open()
# new()
# convert()
# 呼叫與展示
import PIL
from PIL import Image
image = Image.open(fp='證件照.jpg')
image.show()
# 注意圖片要手動關閉,不然會占用程式行程

圖片屬性

print(image.size) # 大小回傳一個二維坐標
print(image.mode) # 回傳影像渲染模式RGB等
print(image.format) # 回傳格式
# 如果不是本地檔案則無法讀取格式

convert函式

# convert函式可以改變影像渲染格式,1是一種渲染方式
image1 = image.convert('1')
image1.show()
mode描述
11位像素,黑白,每位元組存盤一個像素
L8位像素,黑白
P8位像素,使用調色板映射到任何其他模式
RBG3×8位像素,真彩
RBGA4×8位像素,帶透明蒙版真彩
CMYK4×8位像素,分色
YCbCr3×8位像素,彩色視頻格式
LAB3×8位像素,Lab顏色空間
HSV3×8位像素,色相,飽和度,值顏色空間
I32位有符號整數像素
F32位浮點像素

RGB是指色彩顏色的組合,R代表紅,G代表綠,B代表藍,就是紅綠藍的組合每個顏色值都可以在0到255取值,即用0到255量化各顏色的比例

構造新影像

image = Image.new('RGB', (220, 150), (150, 150, 255))
# new函式可以生成一個新影像,第一個是影像渲染方式,第二個是影像大小,第三個是你選中的影像渲染方式的引數,我們這里是RGB,所以填的數字即為紅綠藍的引數
image.show()

ImageFilter的方法

filter描述
BLUR模糊
CONTOUR輪廓
DETAIL詳情
EDGE_ENHANCE邊緣增強
EDGE_ENHANCE_MORE邊緣增強更多
EMBOSS電磁波
FIND_ENGES尋找邊緣
SHARPEN夏普
SMOOTH光滑
SMOOTH_MORE更光滑

本節案例為案例2

第十二講

python之郵件操作

  1. 郵件相關協議介紹

    1. SMTP協議,即簡單郵件傳輸協議,它是一組由源地址到目的地址傳送郵件的規則,由它控制信件的中轉方式(中轉協議)
    2. POP3協議,即郵局協議第三版本,POP3允許用戶從服務器上把郵件存盤到本地主機上,同時洗掉保存在郵件服務器上的郵件(讀取協議)
    3. IMAP協議,因特網報文存取協議(讀取協議)
    4. 多途徑Internet郵件擴展協議,它解決了SMTP協議只能傳輸ASCII文本的限制,把聲音影像表格二進制資料這些作為郵件中[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-Lm7dARYe-1630476391787)(C:\Users\dell\Desktop\QQ截圖20210815142825.png)]附件進行處理
  2. python中的郵件模塊

    1. yagmail模塊 發郵件模塊
    2. keyring模塊 訪問系統密鑰環服務
    3. schedule模塊 定時任務執行器
    4. inbox模塊 IMAP包進行IMAP操作
  3. 使用python發送郵件

  4. 使用python發送帶附件的郵件

  5. 使用python接受郵件

import yagmail
yagmail.register('zhai18172675553@163.com', 'EHIQNPTYCGJMAKQD')

發郵件

yag = yagmail.SMTP(user='zhai18172675553@163.com', host='smtp.163.com')
contents = ['Hello world', '這是一封郵件,通過python發送,哈哈哈哈']
# 第一個引數是發送物件,第二個是主題,第三個是內容
yag.send('zhai18172675553@163.com', '歡迎python', contents)

那怎么處理檔案呢,如字號字體格式等

發送富文本(HTML)郵件

yag = yagmail.SMTP(user='zhai18172675553@163.com', host='smtp.163.com')
contents = ['Hello world', '這是一封郵件,通過python發送,哈哈哈哈']
contents1 = ['<h3>Hello python</h3>', '<b>這是一封郵件,通過python發送</b>', 'hhhhhhhh']
yag.send('zhai18172675553@163.com', '歡迎python', contents1)

那怎么攜帶附件呢

yag = yagmail.SMTP(user='zhai18172675553@163.com', host='smtp.163.com')
contents = ['Hello world', '這是一封郵件,通過python發送,哈哈哈哈']
# 定義一個變數攜帶附件,然后再用正文串列攜帶就行
obj = yagmail.inline('text.txt')
contents1 = ['<h3>Hello python</h3>', '<b>這是一封郵件,通過python發送</b>', 'hhhhhhhh',obj]
yag.send('zhai18172675553@163.com', '歡迎python', contents1)

第十三講

爬蟲介紹

  1. 爬蟲簡介

    模擬瀏覽器,發送請求,獲取回應

    原則上只要是客戶端瀏覽器能做的事情,爬蟲都能做

    爬蟲也只能獲取客戶端瀏覽器所展示的資料

  2. 爬蟲分類

    通用爬蟲

    聚焦爬蟲

    ? 聚焦爬蟲是面向特定主題需求的一種網路爬蟲程式,它和通用爬蟲的區別在于只抓取特點我們需要的資訊

    根據目的可以分為

    1. 功能性爬蟲

    2. 資料增量爬蟲

    根據url地址和對應的頁面內容是否改變,資料增量爬蟲可分為

    1. 地址變內容也變的爬蟲

    2. 地址不變內容變的爬蟲

    url就是網址等

  3. 爬蟲作用

    資料采集

    軟體測驗

    網路安全

  4. 技術步驟

    1. 爬取資料,實際上就是根據一個網址向服務器發起網路請求,獲取服務器回傳的資料
    2. 決議資料,將服務器回傳的資料轉換為人容易理解的樣式
    3. 篩選資料,從大量的資料中篩選出需要的資料
    4. 存盤資料
from urllib.request import Request
from urllib.request import urlopen

# 爬取百度首頁
url1 = 'http://www.baidu.com'
# 用一個變數保存
request = Request(url=url1)
response = urlopen(request)
# print(response.read().decode('utf-8'))
# 獲取的資料是源代碼要用decode進行解碼操作
html_string = response.read().decode('utf-8')
with open('baidu.html', 'w', encoding='utf-8') as fp:
    fp.write(html_string)

第十四講

HTML基礎

HTTP協議

HTTP協議也就是超文本傳輸協議,它是基礎TCP協議的應用層傳輸協議,簡單來說就是客戶端和服務端進行資料傳輸的一種規則

并且HTTP是一種無狀態協議,HTTP協議本身不會對發送過的請求和相應的通信狀態進行持久化處理,主要是為了保持協議的簡單性,從而提高效率

HTTP默認埠號是80

HTTPS協議默認埠號是443區別在于進行了加密

請求

HTTP協議中每次請求都會攜帶下方的內容,比如有請求的方法,請求的路徑,協議的版本等我們稱作請求行

操作

進入百度首頁

右鍵檢查

選擇NETWORK也就是網路

重繪頁面

點擊www.baidu.com查看瀏覽器的資訊,我們爬蟲就是模擬瀏覽器去訪問

爬蟲中特別關注的請求頭

無論是瀏覽器還是爬蟲,在發出請求的時候都要遵守HTTP協議,遵守HTTP協議就要攜帶請求頭

我的百度首頁請求頭

Accept: 
支持的代碼型別
text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate, br
支持的編碼方式
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
支持的語言
Cache-Control: max-age=0
控制緩沖值
Connection: keep-alive
狀態
Cookie: BAIDUID=74AB3553F3D1843AA6627537EF425F8D:FG=1; BIDUPSID=74AB3553F3D1843AAF17FE022AC44843; PSTM=1611195247; __yjs_duid=1_51068de6ff007d2b17777ead3436db931621065947976; BD_UPN=12314753; BDUSS=djeGhzTUxpUVB5UmEwaDdpSGUzSG43a3JUVjhhWVJZMzF1VVFVSGFRLTdWMEZoSVFBQUFBJCQAAAAAAAAAAAEAAAB-HcmFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALvKGWG7yhlhQ2; BDUSS_BFESS=djeGhzTUxpUVB5UmEwaDdpSGUzSG43a3JUVjhhWVJZMzF1VVFVSGFRLTdWMEZoSVFBQUFBJCQAAAAAAAAAAAEAAAB-HcmFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALvKGWG7yhlhQ2; BDORZ=FFFB88E999055A3F8A630C64834BD6D0; H_PS_645EC=055bRlxSoHG2G295mw9NfthZiq%2FzdtjGSsR9%2F%2FYvHbTiuqO0bQbO%2BUU0APw73WKpdX0KXw; BD_HOME=1; H_PS_PSSID=34438_34370_31660_34376_34004_34072_34092_34094_26350_22158_34388_34360; BAIDUID_BFESS=74AB3553F3D1843AA6627537EF425F8D:FG=1; BA_HECTOR=848l200l0l05248krb1ghn6ia0q
Host: www.baidu.com
Referer: https://cn.bing.com/
跳轉界面出處
sec-ch-ua: "Chromium";v="92", " Not A;Brand";v="99", "Microsoft Edge";v="92"
sec-ch-ua-mobile: ?0
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: cross-site
Sec-Fetch-User: ?1
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) 
瀏覽器名稱
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36 Edg/92.0.902.73

回應

回應是HTTP訪問的一個回傳資料的程序

HTML

html是一種解釋性語言

標簽寫法

<!--單標簽-->
	<標簽名 屬性1='屬性值' 屬性2="屬性值" 屬性3=屬性值>
<!--對標簽-->
     <標簽名 屬性1='屬性值' 屬性2="屬性值" 屬性3=屬性值>內容</標簽名> 
        標簽不能創造!

HTML的全域架構標簽

<!doctype html>
<html>根標簽
    <head>頭部
        <meta charset="utf-8">告訴瀏覽器用utf-8編碼格式解釋檔案
        <title>Document</title>檔案標題
    </head>
    <body>
        
    </body>
</html>

常用標簽

  • h1——h6標題,一般一個頁面只設定一個h1標題

  • hr(單標簽)水平分割線

    • width可以使用絕對值,300,不帶單位也可以使用百分比
    • align對齊方式:left center right
  • p段落標簽,有段前間距和段后間距

  • br(單標簽)換行

  • nobr(雙標簽)不換行,所修飾的內容無論多長,不會自動換行,顯示不下會有滾動條

  • pre保持原來的樣式,無論空格還是換行都會正常顯示

  • b加粗

  • i斜體

  • u下劃線

  • sub/sup下標/上標,看圈在哪邊,在下就是下標

  • font字體

    • face字體顏色,到window目錄下font子目錄下查看
    • color字體顏色
    • size值取1-7,7最大
  • blockquote參考,會從正常的文本中分離,留有左右邊距

  • 物體參考

    • 空格 &nbsp
    • < &lt 等等
  • 串列

    • 有序串列(ol/li)
      • type 數字
      • start 開始標號,默認從1開始
    • 無序串列(ul/li)
      • type專案符號
        • disc默認 實心圓圈
        • square 實心方塊
        • ciecle 實心圓圈
  • 超鏈接

    超鏈接寫法

    <a href="http://www.baidu.com/">百度</a>
    

    href所請求的url,注意url必須寫協議

  • img標簽(單標簽)

    <img src='' title='' alt='' border='' width=''height=''>
    
  • 表格

    • table表
      • border表格線
      • cellspacing單元格的間距
      • cellpadding單元格到內容距離
      • align水平對齊left,center,right
      • height可以不用設定,自動撐開
    • tr行
      • align水平對齊left,center,right
      • valign垂直對齊top,middle,bottom
      • 注意:如果沒有給該表格設定高度,那么設定valign無效,在以后布局頁面的時候,一般不使用valign,只有一種情況使用到,就是圖片和文字平排排放的時候,需要設定圖片的valign為middle
    • td單元格
      • colspan跨列 向右合并
      • rowspan跨行 鄉下合并
    • th
      • 就是表格的表頭,內容會加粗,和td用法相同
    • caption表格標題,跟隨表格移動
<table border=1 width=100>
    <tr align='left'>
    	<td>A</td>
    	<td>A</td>
        <td>A</td>
    </tr>
    <tr align='left'>
        <td>B</td>
    	<td>B</td>
    	<td>B</td>
    </tr>
</table>
  • 表單(重要)
    • 用途:收集用戶資訊,提交給服務器
    • 基本使用
      • 不是所有的標簽都可以提交,能夠向服務器提交資訊的表單項,只有表單項才可以向服務器提交資訊
      • 表單項必須放到form標簽中才可以提交資訊
      • action提交地址,一般是服務器的頁面
      • methon提交方式
      • enctype用于檔案上傳
  • input框
    • 公有屬性
    • 單行文本框
    • 提交按鈕

在Python中只要看得懂標簽是干啥就行了

第十五講

BeautifulSoup決議HTML標簽

爬蟲實戰專案(英雄聯盟虎撲論壇)

import requests
url = 'https://bbs.hupu.com/lol'
headers = {
    'user-agant':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36 Edg/92.0.902.73'
}
response = requests.get(url=url, headers=headers)
print(response)

這一步輸出結構是一個狀態碼,如果和瀏覽器狀態碼相同,則訪問正常

# pip install reqeusts, lxml
import requests
from lxml import etree
import csv

url = 'https://bbs.hupu.com/lol-1'

headers = {
    'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0.3 Safari/605.1.15',
    'Host': 'bbs.hupu.com'
}

response = requests.get(url=url, headers=headers)
# print(response.text)

# with open('hupu.html', 'w', encoding='utf-8') as fp:
#     fp.write(response.text)

# 決議資料
# 資料決議的準備作業
root = etree.HTML(response.text)

names = root.xpath('//div[@class="bbs-sl-web-post"]/ul/li/div[@class="post-title"]/a/text()')
href = root.xpath('//div[@class="bbs-sl-web-post"]/ul/li/div[@class="post-title"]/a/@href')
author = root.xpath('//div[@class="bbs-sl-web-post"]/ul/li/div[@class="post-auth"]/a/text()')
time = root.xpath('//div[@class="bbs-sl-web-post"]/ul/li/div[@class="post-time"]/text()')

info = []
for i in range(len(names)):
    info.append([names[i], author[i], time[i], href[i]])

fieldnames = ['name', 'author', 'time', 'href']
f = open('hupudata.csv', 'a+', encoding='utf-8')
f_csv = csv.writer(f)
f_csv.writerows(info)
f.close()

第十五講

資料保存之csv和excel

import requests
from lxml import etree
import json


# 請求資料的程序
def request_data(url):
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36'
    }

    response = requests.get(url=url, headers=headers)
    with open('music.html', 'w', encoding='utf-8') as fp:
        fp.write(response.text)

    # 請求到的html字串回傳
    return response.text


# 決議函式
def parse_data(html_string):
    root = etree.HTML(html_string)
    ul_list = root.xpath('//div[@class="songList"]/ul')

    song_list = []
    for ul_node in ul_list:
        li_list = ul_node.xpath('./li')
        for li_node in li_list:
            song_list.append({'name': li_node.xpath('./a/text()')[0],
                              'href': li_node.xpath('./a/@href')[0]})

    return song_list


def save_data(items):
    fp = open('music.csv', 'a', encoding='utf-8')

    for item in items:
        json_string = json.dumps(item, ensure_ascii=False)
        fp.write(json_string + '\n')

    fp.close()


if __name__ == '__main__':
    html_string = request_data(url='https://www.1ting.com/song_n.html')

    song_list = parse_data(html_string)

    save_data(song_list)

第十六講

資料分析三劍客

在電腦左下角搜索輸入cmd進行命令提示符

輸入jupyter notebook進入網頁

進入網頁后點擊右方new進入編譯界面

單元格操作(都在選中狀態操作)

esc快速進入選中狀態

enter快速進入編輯狀態

  1. 增加單元格
    • 按b,在下面新增一個單元格
    • 按a,在上面新增一個單元格
  2. 洗掉單元格
    • 雙擊d,洗掉當前選擇的單元格
  3. 剪切單元格
    • 單擊x,剪切當前選中的單元格到剪切板內
  4. 粘貼單元格
    • 單擊v,粘貼內容
  5. 操作撤銷
    • 單擊z

單元格模式介紹

  1. code

    在選中狀態下按y鍵將快速進入code模式

  2. markdown

    在選中狀態下按m鍵將進入markdown模式

ctrl+enter 實作單元格運行 code模式下運行代碼,markdown模式下文本進入閱覽狀態

點擊jupyter旁邊的實作重命名

資料分析大劍客

  1. numpy

    矩陣,構造,運算,訪問,賦值

  2. pandas

    基與numpy,提供一維資料和二維表格資料的業務處理(去重等)

  3. matplotlib

    資料可視化包

資料挖掘

sklearn

第十七講

請一定要事先安裝好anaconda并且在控制中心輸入jupyter notebook進入編譯環境!

numpy的使用

主要用于資料處理的基礎方法

陣列和串列的區別

陣列要求資料型別保持一直,串列沒有強制要求

# 匯入模塊并且重命名  當然重命名為npy也可以
import numpy as np
# 查看版本
np.__version__
# 構造陣列
np.array([1,2,3,4,5])
# 二維陣列結構構造
np.array([[1,2,3],[3,4,5]])

其實我們還有更多便捷的方式去構造陣列去實作我們的需求

shift+tab鍵可以將說明檔案展開

# 可以用元組的方式來表達陣列的行列個數
# ones表示用1填充,zeros表示用1填充
np.ones(shape=(3,2,3))

那如果我們用其他數字填充改怎么辦呢

一直用英文開頭顯然不現實也不全面

# 指定陣列樣式并指定填充數字
np.full(shape=(2,4,3),fill_value=6)

但是我們的代碼不可能每次都是知道填充啥,我們需要引入亂數的概念

# 下面代碼表示生成從1到10的亂數填充進2行3列的二維陣列中
np.random.randint(1,10,size=(2,3))
# 下面代碼表示生從0-1的浮點數填充到5行5列的陣列中
np.random.random(size=(5,5))
# 下面代碼表示從0到10生成含有26個數的等引數列
np.linspace(0,10,26)
# 下面代碼表示從0到10,步長為1的陣列資料
np.arange(0,10,1)

Numpy陣列的訪問問題

# 訪問格式 array[index]
array = np.arange(0,10,1)
array[0]
# 這里我們可以看出陣列的訪問形式和串列的訪問形式是一樣的

但是陣列有著更加強大的功能和操作

# 串列陣列共有操作 切片
array[1:4]
# 陣列可以將串列作為索引也就是index
array[[0,1,2,3]]

這其中的妙用不僅僅是可以定向選擇輸出我們想要的資料,而且可以實作陣列重排列

這樣我們有一個基礎的元陣列我們就可以不斷衍生出新的陣列,減少重復代碼重復思考

array1 = array[[0,1,0,1,0,1,0,1,0,1,0,1]]
print(array1)

高級索引技巧

用布爾串列定向獲取資料

# 生成一個簡單點的陣列,我們想要的就在他對應的方位用true不想要的用false,同理我們也可以聯想到這樣的方法也可以構造新的陣列
array1 = np.array([1,2,3,4,5])
array1[[True,False,True,True,False]]

廣播運算

array1 = np.array([1,2,3,4,5])array1 > 3

輸出結果為

array([False, False, False,  True,  True])

我們還可以實作更加高級的設想

如果我們將廣播運算中的廣播放入索引當中呢

array = np.array([1,2,3,4,5,6,7,8,9,10,105])array1 = array[array>8]print(array1)

輸出結果為

[  9  10 105]

那么高維陣列我們該如何實作呢

array2 = np.random.randint(1,10,size=(3,3))# 輸出array2所有元素array2# 輸出array2中的第一行第一列array2[0][0]array[0,0]

Numpy陣列的運算

arr1 = np.array([1,2,3])arr2 = np.array([[1],[2],[3]])arr1+arr2

結果是

array([[2, 3, 4],       [3, 4, 5],       [4, 5, 6]])本質是1 2 3    1 1 11 2 3    2 2 21 2 3    3 3 3

兩大運算潛規則

  1. 缺失維度自動補充
  2. 缺失資料用已有的值填充

但是存在特殊情況

arr1 = np.array([1,2,3])arr2 = np.array([[1,2],[2,2]])# display()用來快捷輸出display(arr1,arr2)# 因為這時候arr2如果要擴展一列不知道如何擴展,我們如果再執行arr1+arr2就會報錯

報錯資訊

ValueError                                Traceback (most recent call last)<ipython-input-79-e489ba1ad4d1> in <module>----> 1 arr1+arr2ValueError: operands could not be broadcast together with shapes (3,) (2,2)

Numpy排序方法

data = np.random.permutation(10)data# 生成10個索引data.sort()data# 實作重排 從小到大

但這種排序方法原有的data結構會被破壞,我們一般采取別的方法,即既保留data結構又可以實作重排

data = np.random.permutation(10)datanp.sort(data)data

Numpy的拷貝方法

我們除了使用上述方法排序外,我們也可以拷貝原資料然后再更改拷貝資料,也能實作一樣的效果

data = np.random.permutation(10)datac_date = data.copy()c_datec_date.sort()c_datedata

Numpy的級聯方法

# 創建倆個陣列arr1 = np.random.randint(1,10,size=(3,2))arr2 = np.random.randint(11,20,size=(3,3))# 第一個括號是放入我們要進行操作的陣列,axis=0表示縱向級聯,axis=1表示橫向級聯,默認為0np.concatenate((arr1,arr2),axis=1)

級聯方法在業務處理上有關鍵作用

第十八講

pandas的使用

pandas本質上是在numpy基礎下進行的二次封裝

主要用來解決業務邏輯

pandas主要提供了倆種物件

  1. Series(一維串列)
  2. DataFrame(二維串列)
import pandas as pd
import numpy as np
from pandas import Series,DataFrame
Series([1,2,3])

輸出結果

0    1
1    2
2    3
dtype: int64

左邊有索引,但是顯示的是默認索引,這給我們提供一個思路,也就是我們可以對索引進行重命名,讓索引方式符合我們的日常使用習慣

Series([1,2,3],index=['tom','jack','lucy'])

輸出結果

tom     1
jack    2
lucy    3
dtype: int64

Series的索引機制非常符合我們用戶的習慣,像定向搜索等,所以Series更加適合去處理業務,提升可讀性

訪問型別

  1. 顯示訪問
s = Series([1,2,3],index=['tom','jack','lucy'])
s['tom']
s.loc['tom'] # 二者在訪問上沒有區別但推薦使用loc方法
  1. 隱式訪問
s = Series([1,2,3],index=['tom','jack','lucy'])
s[0]

由于pandas是基于numpy的

numpy的訪問方式在pandas中同樣適用,如串列和布爾串列

s.loc[['tom','lucy']]

輸出結果

tom     1
lucy    3
dtype: int64
s.loc[[True,False,True]]

輸出結果

tom     1lucy    3dtype: int64

廣播運算依然很有意義

s > 5
tom     Falsejack    Falselucy    Falsedtype: bool

DataFrame

引入了行標簽和列標簽

具有更加強大的現實意義

DataFrame(data=np.random.randint(0,10,size=(3,5)))

輸出結果

01234
020184
167753
225455

直接輸出了表格

哇哦!

我們在索引的時候還可以定制我們的行索引和列索引

甚至可以直接輸出我們的成績為表格狀態

注:index 行索引 columns 列索引

DataFrame(data=np.random.randint(60,100,size=(3,6)),index=['一模','二模','三模'],columns=['語文','數學','英語','物理','化學','生物'])

輸出結果

語文數學英語物理化學生物
一模939277996092
二模799579777177
三模916761687668

要不你也試試?

那如何訪問DataFrame中的物件呢

df = DataFrame(data=np.random.randint(60,100,size=(3,6)),index=['一模','二模','三模'],columns=['語文','數學','英語','物理','化學','生物'])df.loc['三模','生物']

我們的索引方法是先寫行索引再寫列索引

我們還可以通過一些簡單的操作訪問一個人一二三模的生物成績,或者一模的所有成績(串列形勢)

例如

df.loc[['三模','二模','一模'],'生物']

運算

  1. 索引對齊
  2. 廣播
# 廣播運算df+5df+df

那么就有一個問題

Series和DataFrame能進行運算嘛

答案當然是可以的

score = df.loc['一模']scoredf+score

輸出結果

語文數學英語物理化學生物
一模178180182196136144
二模149174177183131156
三模183184172175152143

可以觀察到進行了索引對齊的相加,所有數加上了一模所有學科的成績

但這種方法是豎著加的那我們想橫著加可以嘛

當然可以!

只不過會不對齊就會變成空值(NAN)

注:

axis=0表示縱向級聯,axis=1表示橫向級聯,默認為0

不清楚可以看numpy使用哦!

df.add(score,axis=1)
語文數學英語物理化學生物
一模178180182196136144
二模149174177183131156
三模183184172175152143
df.add(score,axis=0)
語文數學英語物理化學生物
一模NaNNaNNaNNaNNaNNaN
三模NaNNaNNaNNaNNaNNaN
二模NaNNaNNaNNaNNaNNaN
化學NaNNaNNaNNaNNaNNaN
數學NaNNaNNaNNaNNaNNaN
物理NaNNaNNaNNaNNaNNaN
生物NaNNaNNaNNaNNaNNaN
英語NaNNaNNaNNaNNaNNaN
語文NaNNaNNaNNaNNaNNaN

大家看行標簽應該就知道發生了什么

所以我們當進行相加的時候要注意索引是否一致

聚合運算

  1. 求和
  2. 求平均值
  3. 求方差

等等…

# 求和score.sum()# 平均值score.mean()# 方差score.var()# 標準差score.std()# 最大值score.max()# 最小值score.min()

我們試試讓我們的物件進行這些運算

df.sum()
語文    243數學    268英語    258物理    260化學    215生物    227dtype: int64

我們發現默認是列相加

如果我們要改成行方向,只要用老方法改axis=1就行了

df.sum(axis=1)
一模    508二模    462三模    501dtype: int64

這些就可以算出每次考試的總成績,大大簡化運算

還有倆種非常好用的聚合方式

  1. any
  2. all
df.isnull()
語文數學英語物理化學生物
一模FalseFalseFalseFalseFalseFalse
二模FalseFalseFalseFalseFalseFalse
三模FalseFalseFalseFalseFalseFalse

這個函式方法可以判斷我們的串列里面有沒有空值

但這樣全部顯示是否有點不太雅觀

# 全部為真才是真(score>10000).all()# 若至少一個值為真則為真(score>10000).any()

我們用any,all倆種方法配合判斷陳述句可以實作很多復雜功能

第十九講

Matplotlib實戰資料分析

一定要在jupyter notebook編譯環境中進行操作

主要內容

  1. 模板匯入
  2. 隨機曲線的生成
  3. 影像的操作
模板匯入

匯入我們資料分析三劍客,并且指令我們的圖在本頁面顯示

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

%matplotlib inline
隨機曲線的生成(折線圖)
# 生成亂數值
x = np.random.randint(3,9,size=10)
# 指定畫布相當于進行兩行倆列的分割
plt.subplot(221)
plt.plot(x)

此時我們可以看到生成了一個隨機的折線圖

我們同樣可以畫一個正弦函式曲線

x = np.linspace(0,2*np.pi,10)
y = np.sin(x)
plt.subplot(221)
plt.plot(x,y)

這時候一張sinx函式的圖就畫好了

影像的操作

我們資料分析的時候當然不止一個圖

怎么實作呢

plt.subplot(221)
plt.plot(x,y)

plt.subplot(222)

plt.subplot(223)

plt.subplot(224)

輸出這些代碼我們便得到了四張圖(畫布)

我們還可以設定橫軸標簽和一個縱軸標簽

有一個問題就是matplotlib無法顯示中文我們需要對他進行設定

plt.rcParams['font.sans-serif'] = 'SimHei'

然后標簽就可以設定成中文了

plt.subplot(111)
plt.xlabel('中國')
plt.ylabel('國民收入',fontsize=20)

fontsize可以修改我們的字體大小,默認字體大小是10

條形圖的繪制
# 生成一個4個資料的一維陣列
data = np.random.randint(5,10,size=4)
data
# 指定行索引列高,由.bar生成條形圖
plt.bar(x=['A','B','C','D'],height=data)
餅狀圖的繪制
# 設定畫布比例確保是一個正常的圓
plt.figure(figsize=(5,5))
# 傳入資料
plt.pie(x=data)
# 如果直接展示會有一大堆回傳值,我們用show函式就可以清晰簡單的得到那個園
plt.show()

但是只有一個餅顯然資訊不便表達,我們需要給他添加一些資訊

plt.figure(figsize=(5,5))# 我們設定他的各個區域標簽,然后autopct顯示比例plt.pie(x=data, labels=list('ABCD'),autopct='%.2f%%')plt.show()

畫圖方法還有很多,本文只是介紹一些基礎知識!

案例

import ImageFilter
import PIL
from PIL import Image
from PIL import ImageDraw, ImageFont, ImageFont
import random


def get_color():
    # get_color方法是通過亂數產生紅綠藍三個顏色的值構成RGB的調和色
    red = random.randint(0, 255)
    green = random.randint(0, 255)
    blue = random.randint(0, 255)
    return (red, green, blue)


def get_code(lenght):
    # get_code方法是通過隨機選擇,獲取傳入數字那么多的亂數字字母構成驗證發
    s = '1234567890qwertyuiopasdfghjklzxcvbnm'
    code = ''
    for i in range(lenght):
        code += random.choice(s)
    return code


def draw_code():
    # 此函式方法用來繪制驗證碼
    # 指定畫布的長度和寬度
    width = 120
    height = 40
    image_size = (width, height)
    # 定義畫布
    image = Image.new('RGB', image_size, get_color())
    # 定義畫筆
    draw = ImageDraw.Draw(image)
    # 指定字體和字體大小   tahoma.ttf是內置的一種字體,定義大小也可以不定義因為有默認的初始值
    myfont = ImageFont.truetype(font='tahoma.ttf', size=30)
    # 逐個繪制驗證碼字符
    code = get_code(4) # 先呼叫獲取字符的函式來獲取字符方便繪制
    for i in range(4):
        # 每繪制一個字母,x坐標改變y坐標不變也可以變化
        distance_x = random.randint(30 * i, 30 * i + 5)  # [0,10]
        distance_y = random.randint(0, 5)
        # draw.text(位置,內容,字體,填充顏色)
        draw.text((distance_x, distance_y), code[i], font=myfont, fill=get_color())
    # 干擾線和干擾點的數量也就是range后面的數字看自己需求不一定是10或20
    # 繪制干擾線
    for i in range(10):
        # 指定起始位置和終止位置
        begin = (random.randint(0, width), random.randint(0, height))
        end = (random.randint(0, width), random.randint(0, height))
        # 使用畫筆來繪制干擾線,并通過fill繪制顏色
        draw.line((begin, end), fill=get_color())
    # 繪制干擾點
    for i in range(20):
        draw.point((random.randint(0, width), random.randint(0, height)), fill=get_color())
    # 濾鏡邊界加強
    image = image.filter(ImageFilter.EDGE_ENHANCE_MORE)
    image.show()


draw_code()

i

mport yagmail
import schedule
import time

# 定義作業任務,可以在作業任務中發送郵件或者做其他的事情

def task1():
    print("I'm working...")

# 群發郵件

def task2():
    yag = yagmail.SMTP(user='zhai1172675553@163.com', host='smtp.163.com')
    obj = yagmail.inline('證件照.jpg')
    contents = ['<h3>Hello Python!</h3>', '<b>這是一封郵件,通過Python發送', obj]
    # 收件人,郵件主題,正文內容
    yag.send(['zhai18172675553@163.com','1376500051@qq.com'], 'LOVE', contents)

# 發送周報郵件

def task3():
    yag = yagmail.SMTP(user='zhai18172675553@163.com', host='smtp.163.com')
    contents = ['<h3>Hello 領導們!</h3>', '<b>這是我的會議記錄,請查收!</b>']
    # 收件人,郵件主題,正文內容
    yag.send('1376500051@qq.com', 'xxx的周報', contents)

# 其他的任務



# schedule.every(10).minutes.do(task1)   #部署每10分鐘執行一次task1函式的任務

# schedule.every(10).hours.do(task1)   #部署每10小時執行一次task1函式的任務

schedule.every().day.at("10:30").do(task2)   #部署每天的10點辦執行一次task2函式的任務
schedule.every().sunday.do(task3)   #部署每個周日執行一次task3函式的任務

while True:
    # 遍歷所有schedule的陳述句
    schedule.run_pending()
    # 每倆秒在回圈一次,防止回圈頻率太高占用過大記憶體
    time.sleep(2)

= 40
image_size = (width, height)
# 定義畫布
image = Image.new(‘RGB’, image_size, get_color())
# 定義畫筆
draw = ImageDraw.Draw(image)
# 指定字體和字體大小 tahoma.ttf是內置的一種字體,定義大小也可以不定義因為有默認的初始值
myfont = ImageFont.truetype(font=‘tahoma.ttf’, size=30)
# 逐個繪制驗證碼字符
code = get_code(4) # 先呼叫獲取字符的函式來獲取字符方便繪制
for i in range(4):
# 每繪制一個字母,x坐標改變y坐標不變也可以變化
distance_x = random.randint(30 * i, 30 * i + 5) # [0,10]
distance_y = random.randint(0, 5)
# draw.text(位置,內容,字體,填充顏色)
draw.text((distance_x, distance_y), code[i], font=myfont, fill=get_color())
# 干擾線和干擾點的數量也就是range后面的數字看自己需求不一定是10或20
# 繪制干擾線
for i in range(10):
# 指定起始位置和終止位置
begin = (random.randint(0, width), random.randint(0, height))
end = (random.randint(0, width), random.randint(0, height))
# 使用畫筆來繪制干擾線,并通過fill繪制顏色
draw.line((begin, end), fill=get_color())
# 繪制干擾點
for i in range(20):
draw.point((random.randint(0, width), random.randint(0, height)), fill=get_color())
# 濾鏡邊界加強
image = image.filter(ImageFilter.EDGE_ENHANCE_MORE)
image.show()

draw_code()


i

```python
mport yagmail
import schedule
import time

# 定義作業任務,可以在作業任務中發送郵件或者做其他的事情

def task1():
    print("I'm working...")

# 群發郵件

def task2():
    yag = yagmail.SMTP(user='zhai1172675553@163.com', host='smtp.163.com')
    obj = yagmail.inline('證件照.jpg')
    contents = ['<h3>Hello Python!</h3>', '<b>這是一封郵件,通過Python發送', obj]
    # 收件人,郵件主題,正文內容
    yag.send(['zhai18172675553@163.com','1376500051@qq.com'], 'LOVE', contents)

# 發送周報郵件

def task3():
    yag = yagmail.SMTP(user='zhai18172675553@163.com', host='smtp.163.com')
    contents = ['<h3>Hello 領導們!</h3>', '<b>這是我的會議記錄,請查收!</b>']
    # 收件人,郵件主題,正文內容
    yag.send('1376500051@qq.com', 'xxx的周報', contents)

# 其他的任務



# schedule.every(10).minutes.do(task1)   #部署每10分鐘執行一次task1函式的任務

# schedule.every(10).hours.do(task1)   #部署每10小時執行一次task1函式的任務

schedule.every().day.at("10:30").do(task2)   #部署每天的10點辦執行一次task2函式的任務
schedule.every().sunday.do(task3)   #部署每個周日執行一次task3函式的任務

while True:
    # 遍歷所有schedule的陳述句
    schedule.run_pending()
    # 每倆秒在回圈一次,防止回圈頻率太高占用過大記憶體
    time.sleep(2)

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/296887.html

標籤:python

上一篇:Django下使用celery 異步發送短信驗證碼

下一篇:就因為Python自動化,那個天天摸魚的同事,他居然升職了!

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more