python學習課件


張鑫  18511446896

--------------------------------------------------------------------------------------
Day1
1、概述
2、環境搭建、工具安裝與配置
3、Python的運行原理
4、基本知識:縮進與行、跨行、注釋
5、字符集編碼問題
6、變量與數據類型
7、Python的內存管理機制(指針存儲、動態類型、可變與不可變、引用計數)
8、Python的內置數據類型
9、Python的運算符(算數、比較、賦值、邏輯、成員、三目)
10、字符串常用屬性與操作
---------------------------------------------------------------------------------------
Day2
11、輸入與輸出
12、控制語句之分支語句
13、控制語句之循環語句
14、元組
---------------------------------------------------------------------------------------
Day3
15、列表
16、字典
17、函數
18、類和對象
---------------------------------------------------------------------------------------
Day4
19、異常
20、模塊
21、常用標准庫
22、Python多線程
23、裝飾器(權重)
24、上下文協議、文件讀寫
25、數據庫操作
26、web相關
------------------------------------------1、概述--------------------------------------------
新的性能課程體系,前4天 Python語言基礎

原因:
	1. 性能測試工具選型——Locust 

	    --開源(Python)、支持二次開發、易於平台化
	    --基於協程,節省資源開銷,支持高並發
	    --HTML+JS界面,整潔、跨平台、易擴展

	    --使用Python語言編寫腳本

	2. 企業、社會對測試代碼能力的要求提升
		--更好地應對筆試、面試
		--突破職場瓶頸、拓寬發展空間

	3. Python的應用越來越廣泛
	    --自動化測試、大數據、人工智能
	    --語法相對簡單、易上手
	    --自帶標准庫、擴展庫非常多 Battery included	    
	    --可以方便地操作其他程序,引入其他語言寫成的庫

學習的側重點有哪些?
	測試用到的知識點
	Python基礎語法和知識點
	Python常用模塊、常用的第三方庫

學習方法:
	講過的內容,認真練習(抄寫、調試、自己寫)
	做好作業,按時提交
	多練習
	100天  每天100行  

原則:
	不追求難,只追求通用、實用
	測試中用不到的難點,可以后續工作中自己尋求新的突破

--------------------------------------2、環境搭建與配置-------------------------------------------
一、安裝Python-解釋器和虛擬機

	*目前常用的有Python2.X和Python3.X

	Python3.X相對之前版本是一次較大的升級,
	Python3.X在設計時沒有考慮向下兼容。
	python3 和 python2 有一些差異。
	兩個版本目前都在維護,可以選用。
	
	*選擇哪個版本進行學習?Python3
		
	從Python2切換到Python3,難度並不大:
		官方遷移指南提供了在Python 3中運行Python 2代碼的建議
		區別:http://www.runoob.com/python/python-2x-3x.html

	Windows:
		下載地址:https://www.python.org/downloads/windows/

	Linux(下載源碼進行安裝)
		下載地址:https://www.python.org/downloads/source/

	Mac OS X
		下載地址:https://www.python.org/downloads/mac-osx/

二、PATH環境變量配置
	環境變量作用
	設置方法

三、Python編輯器安裝
    1.cmd下執行python  交互式解釋器模式
    2.安裝python自帶的編輯器IDLE
    3.專業的編輯器 Pycharm 優點:
      人性化設計:代碼聯想與提示等

    PyCharm安裝與破解

    配置:
	    主題、字體、字號設置 

------------------------------------------3、Python的運行原理-------------------------------------------
編寫第一個程序
	創建Python項目,“Pure Python”  
	改名

	*Python虛擬環境

	項目下創建python文件
	創建項目的默認路徑
	文件:day1.py
	內容:最簡單

運行方法:
	1、Pycharm直接運行
	2、cmd命令行執行

***練習:
	自己創建一個項目,創建一個簡單的python文件,兩種方式(Pycharm、cmd命令行)執行

運行原理:
	Python、Java-先編譯、后解釋-虛擬機(圖)

	.pyc演示 day1.py  demo.py

手動編譯(了解):
	目的:執行效率更高,看不到原始代碼,暫時保密

	python -m py_compile filepath
	python -m compileall dirpath
------------------------------------------4、一些Python的基本知識-------------------------------------------

1、縮進

	大部分語言用{}標識代碼塊,嵌套很深時,大括號層數很多
	為了清晰,需要通過縮進來幫助查看

	Python
強制縮進
	習慣:每一層級,固定縮進4個字符(空格)

	要求:
		1、使用固定的編輯器
		2、采用4個空格進行縮進

	對於PyCharm,默認配置——一個Tab符相當於4個空格
	其他編輯器不可以用Tab符

錯誤舉例,使用notepad++編輯,

def mytest():
	if True:
		print('a')
	else:
		print('b')  #以上縮進都是使用制表符
        print('c')  #此行采用空格縮進

mytest()

以下使用pycharm編輯,自動縮進和tab都會被處理成四個一組的空格
def mytest2():
    if True:
        print('a')
    else:
        print('b')  自動縮進
        print('c')  兩個tab
        print('d')  8個空格


2、換行顯示
	字符串\
	表達式\
	定義的列表、元組,等

	python中不需要以分號作為語句結束,正常換行自動結束

3、定義多行字符串
	xml舉例-天氣webservice接口

4、注釋
	作用:(1)代碼功能說明
	      (2)保留代碼,但暫不執行


	單行注釋 
	多行注釋(區域注釋) 
	批量注釋
	特殊注釋
		#! /usr/bin/python
		    Linux下指定運行腳本文件時使用的解釋器,Windows不需要

5、單引號、雙引號

6、字符集編碼 
	計算機存儲、處理數據的方式
		
		ASCII:
			最早只有127個字母被編碼到計算機里,也就是大小寫英文字母、數字和一些符號
			1個字節
			A的編碼是65,a的編碼是97,小寫字母z的編碼是122	

		GBXXXX:
			處理中文
			2個字節--65535
				原本ASCII有的字符
				7000多個簡體漢字
				數學符號、羅馬希臘的字母、日文的假名
			GB2312---GBK(擴展)

		Unicode
			把所有語言都統一到一套編碼里
			unicode是一種編碼標准,
			具體的實現方法可能是utf-8,utf-16,gbk ……
			
			2字節表示一個字符 UTF-16
			4字節表示一個字符 UTF-32
			
			UTF-8
				可變長編碼
				UTF-8編碼把一個Unicode字符根據不同的數字大小編碼成1-6個字節
					常用的英文字母被編碼成1個字節,漢字通常是3個字節

------------------------------------------5、變量與數據類型-------------------------------------------
數據類型
    為了規定數據的存儲方式,包括分配內存和磁盤空間,限制存儲內容
 
    數據分為  變量   和   常量

  
變量

    變量:占用一部分內存空間,用來存放變量的值(或地址)。用一個標識符(identifier)來表示
          a
          number ID
          class_16_name1

          字母 數字 下划線 以字母或下划線開頭

          區分大小寫

          number
          Number

    變量的賦值
        =
        變量名=變量值
        變量名=其他變量名
        變量名=表達式
        變量名=函數(返回值)


		a = 1
		print(a)

		a = 1
		a = a + 1
		print(a)

		if a == 1:
		    print('ok')

		a = 1
		b = a
		print(b)

		a = 1
		b = 2
		c = a + b * 2
		print(b)

 C和Java的變量
 	
 	使用前先定義,定義時指定變量的數據類型
 	強制數據類型

 	int a;
 	....
    a = 2;
    a = 3;
    a = 'haha';    #會報錯

 Python的變量
    
    (1)不用預先定義,首次賦值時即實現定義
    (2)賦值可以使用任意類型的數據
    (3)一個變量的類型不固定
    (4)變量值有固定的類型

查看數據類型
	type(變量名)

    a = 1
	print(type(a))
	a = 1.2
	print(type(a))
	a = 'haha'
	print(type(a))

為什么會有這樣的區別呢?

    內存管理機制 Java、C
                 Python

    通過id(變量名)可以查看變量指向的內存地址


*函數簡介

		數值型
			int 整數  實際為長整型,動態長度,最小24字節
			float 浮點數  24字節 

			類型轉換
				自動類型轉換
					float>int
					+ - *運算時,若類型 不一致,會轉換成float型進行運算

				強制類型轉換
					int(X)轉換X到一個普通整數
					float(X)轉換X到浮點數字
					chr(X) 將一個整數轉換為可對應ASCII的字符
					ord(X) 將一個字符轉換為對應的ASCII碼數值   

		布爾型
			True、False--注意大小寫
	
		字符串
		'''
			  ABC
			  I'm OK
			  Mary said, "I'm OK"
        '''
			 轉義字符:
			 	作用:
			 		  1.去掉某些特殊字符的特殊含義,而使用其作為一個普通字符
			 		    字符串中的單、雙引號、反斜線


			 		   2.反斜線與一些字母連用,為了表示一些特殊含義
			 		   '''
			 					\n 換行
			 					\r 退回到行首,后續輸入會覆蓋前面的輸入
						    	\t 制表符

					    \\	代表一個反斜線字符
						'''

			  r的應用
				  字符串前加r,代表忽略內部的轉義字符

			  ***練習:分別輸出以下內容
				'''
					1. 用換行符和多行注釋分別輸出
						Bob said
						I'm OK.
					2. div[@id='goodItem']/a	
					3. Bob said "I'm OK".
					4.  "C:\Program Files\fnord\foo\bar\baz\frozz"
					5. ^test/\d{n,}/$
				'''
			str(x)將對象 x 轉換為字符串

		元組(Tuple)、列表、字典

	    空值  None

	    	None有自己的數據類型NoneType
	    	None表示一個空對象
			不是0、False、空字符串
	    	
	    	如果函數無return,則默認返回None
	
	** 了解:可變數據類型與不可變數據類型

			不可變類型:內存中的那塊內容的值不可以被改變。
				數字、字符串、布爾值、元組

			可變類型:內存中的那塊內容的值是可以改變的。
				列表(List)
				字典(Dictionary)
				其它對象
			(1)當企圖通過+=、append等修改該內存地址內容時,可變類型不會創建出新對象,只在原來地址上對值進行修改。
			(2)無論是可變還是不可變類型,對一個變量重新賦值都會創建出新對象;

				a = (1, 2, 3)
				print(id(a))

				a += (4,)
				print(id(a))


				a = [1, 2, 3]
				print(id(a))

				a += [4,]
				print(id(a))
------------------------------------------6、運算符-------------------------------------------
算術運算符
	+ 
	- 
	* 
	/ 結果的類型為float
	
	9/2   4.5

	** 冪
	2**3

	%  取余

	// floor除
		不管操作數為何種數值類型,總是會舍去小數部分,返回數字序列中 比真正的商小的 最接近的 整數數值,
		數值類型取決於操作數的類型。  

	練習:
			 請寫出以下程序的運行結果
				a = 21
				b = 10

				print(a / b)  #2.1
				print(a % b)  #1

				a = 11
				b = 3  

				print(a//b)  3
				print(a//float(b)) 3.0

				a = -11.0
				b = 3
				print(a//b) -4.0

比較(關系)運算符

	返回值為布爾值
	不僅可以比較數值,還可以比較其他類型,字符串、布爾值

	== 等於 - 比較對象的值是否相等

	!= 不等於

	>

	<

	>= 

	<=

	is 兩個引用(變量)所指的對象是否相同


	a is b
	id(a) == id(b)


	        *數值、字符串、布爾值

	            定義多個變量,若它們值相等,則這些變量是指向同一對象

	        a = 'True'
	        b = 'True'

	        id(a) == id(b)
	        a is b 


	        *元組、列表、字典
	            定義多個變量,若通過直接賦值方式使它們值相等,指向的不是同一對象;
	            			  若通過傳遞的方式賦值,可以使它們指向同一對象。	            			  
	            			  (對於列表、字典)此時如果對一個變量的值進行了修改,則其他變量的值也會發生變化。



	*作業:

		請寫出以下程序的運行結果

				a = 1
				b = 1
				print(id(a) == id(b))   #True     
				print(a is b)           #True      

				a = 2
				print(id(a) == id(b))   #False        
				print(a is b)           #False    

				c = "very good morning"
				d = "very good morning"
				print(id(c) == id(d))   #True      

				c = True
				d = True
				print(c is d)           #True              

				e = [1, 2, 3]
				f = [1, 2, 3] 
				print(id(e) == id(f))    #False     
				print(e == f)            #True                          
				print(e is f)            #False            

				g = [4, 5, 6]         
				id1 = id(g)
				g.append(7)
				id2 = id(g)
				print(id1 == id2)       #True             

賦值運算符
	=	
	+=
	-=
	*=
	/=
	%=
	**=
	//=
	
	連續賦值
		a=b=c=1
		a,b,c=1,2,3
	
	值互換
		a,b=b,a

邏輯運算符

	and 與 兩真結果真, 一真一假結果為假,兩假結果假
	or  或 兩真結果真, 一真一假結果為真,兩假結果假
	not 非

	結果: True False

	表達式:任意表達式
	無論結果是否布爾型

	在作為邏輯運算符的操作數時,
	'0、空字符串、空列表、空元組、空字典、None'被作為False處理,其他作為True處理。

	注意:短路邏輯

		and 多個表達式都成立(為True),結果才成立;只要有一個不成立,結果就不成立,后面的不再計算

		or  多個表達式中只要有一個成立(為True),結果就成立,后面的不再計算

		1 and 2 and 3 and 4

		1 or 2 or 3 or 4

	***練習:寫出下面程序的執行結果

	(1)	
		def a():
		    print('A')
		    return 0

		def b():
		    print('B')

		def c():
		    print('C')
		    return []

		def d():
		    print('D')
		    return False

		if a() or b() or c() or d():   
		    print('ok')

    (2)
		def a():
		    print('A')
		    return 0

		def b():
		    print('B')

		def c():
		    print('C')
		    return []

		def d():
		    print('D')
		    return False

		if a() and b() and c() and d():   
		    print('ok')

成員運算符

	in  	如果在指定的序列中找到一個變量的值,則返回true,否則返回false
	                    序列:有序的隊列 字符串 元組 列表
	not in  如果在指定序列中找不到變量的值,則返回true,否則返回false
	應用:查看字符串中是否含有某個值
		print('e' in 'hello')
		print('ll' in 'world')

身份運算符

	也屬於比較的一種,結果是布爾值(見前述內容)
	is
	is not	

三目運算符


	為真時的結果 if 判定條件 else 為假時的結果  
		  1 if 5>3 else 0


 ++ 和 --	
	 Python不支持

------------------------------------------7、字符串常用屬性與操作-------------------------------------------
字符串的定義、賦值

	單引號、雙引號、混用:可以在一定程度上避免使用轉義字符
	長字符串--當字符串跨行

格式化輸出

	"您賬戶xxxx於xx月xx日入賬工資,人民幣xxxxx.xx,xxxxxxxxxxxxxxxxxxx"之類的短信,

	xxx的內容都是根據變量變化的

	通過%?格式化輸出:

		在Python中,采用的格式化方式和C語言是一致的,用%實現
			在字符串內部,%?代表此處的內容需要被變量填充
				數據類型不同
					%s	字符串
						如果字符串中有% 改用%%
					%d	整數
					%f	浮點數
						格式化整數和浮點數還可以指定整數與小數的位數 '%.2f'

					%x	十六進制整數
				如果你不太確定應該用什么,%s永遠起作用,它會把任何數據類型轉換為字符串
			在字符串外部,有幾個%?占位符,后面就跟幾個變量或者值,順序要對應好。如果只有一個%?,括號可以省略



    通過字符串的format()函數格式化輸出:
   
		format
			str.format(text) 
			str中包含占位符,text中是要填充的內容
				使用'{name}'形式的占位符
				使用'{}'占位符
				使用'{0}','{1}'形式的占位符
	
			***作業:

				1.練習:格式化輸出以下字符串:
				'親愛的小岳岳你好!你9月的話費是32.00元,余額是18.00元'
				其中姓名、月份、話費、余額為可變的值。
				用%?占位符和format()兩種方法實現。
          
            ***作業:

				1.輸出一個get請求地址,形如:
				http://192.168.2.111/huice/event/api/add?title=python大會&time=2018-01-06
                其中可變的內容為:
                	協議類型:形如http
                	主機名:形如192.168.2.111
                	地址:形如huice/event/api/add
                	參數:形如title=python大會&time=2018-01-06
				


常用屬性和操作

	長度
		內置方法len(string)


	序列

		在Python中,最基本的數據結構是序列 -- 有序的隊列

		序列中的每個元素被分配一個序號——即元素的位置,也稱為索引

		第一個索引是 0,第二個則是 1,以此類推

        若長度為n,則最后一個元素的索引為n-1

		序列中的最后一個元素標記為 -1,倒數第二個元素為 -2

		常用的內建序列:
			列表、元組、字符串
		
		“字符串其實就是一個字符元素組成的序列”
	
	索引和分片(切片)

		索引:string[index]

			超出索引:IndexError: string index out of range
			
			*遍歷字符串中的每個字符
				0到   len-1

			*翻轉輸出每個字符
			    -1 到 -len

		分片(截取)
			格式:string[頭下標:尾下標:步長]

				步長默認為1

				頭下標為空:從第一個字符開始截取
				尾下標為空:截取到最后
				[:]字符串“拷貝”
				越界不會報錯,取到結尾

		字符串翻轉
			[::-1]

***********10.27***********

		作業講解(9:30-9:45)


		字符串連接(9:45-10:00)
			+
			1.可以通過加號進行拼接,但非字符串型需要先強制轉成字符串型,使用str()函數轉換

			2.每連接一次,就要重新開辟空間,然后把字符串連接起來,再放入新的空間
			  大量字符串拼接時,效率低
		
		join
			'sep'.join(seq)
			上面的語法即:以sep作為分隔符,將序列seq所有的元素合並成一個新的字符串

		*加號連接效率低是在連續進行多個字符串連接的時候出現的,如果連接的個數較少,加號連接效率反而比join連接效率高

		對於多個元素組成的序列,只有當它們之間使用的分隔符都一樣時,才可以用join()


		*對象的函數 -> 類和對象介紹(10:00-10:05)
						
			函數 len(), id(), type()

			a = 'Hello{name}'
			a.format(name='tls')

			'&'.join()

			=> 類和對象


	字符串替換
	
		str.replace(old, new[, max])  返回新字符串
		參數:old -- 將被替換的子字符串。
     		new -- 新字符串,用於替換old子字符串。未找到就不替換
     		max -- 可選字符串, 替換不超過 max 次

	字符串查找
		find
			str.find(target, [start,end) )
			在字符串中查找指定字符串首次出現的index,找不到時返回-1
		index
			str.index(target, [start,end) )
			在字符串里查找子串第一次出現的位置,找不到子串會拋出異常

	**字符串分割
		str.split(sep, [,max])
			將一個字符串分裂成多個字符串組成的列表
				不帶參數時以空格進行分割
				帶參數sep時,以該參數值為分隔符進行分割
				未查詢到分隔符時,列表只包含原始字符串
				

	字符串大小寫
		轉換:
			str.upper() --轉大寫
			str.lower() --轉小寫
			str.capitalize() --首字母大寫,其余字母小寫
		判斷:
			str.istitle() --是否是每個單詞首字母都大寫的
			str.isupper() --字母是否全是大寫
			str.islower() --字母是否全是小寫 

	字符串去空格	
		str.strip()  --去掉字符串的左右空格
		str.listrip() --去掉字符串的左邊空格
		str.rstrip() --去掉字符串的右邊空格

	其他
		str.isalnum() --是否全是字母或數字,並至少有一個字符
		str.isalpha() --是否全是字母,並至少有一個字符
		str.isdigit() --是否全是數字,並至少有一個字符
		str.isspace() --是否全是空白字符,並至少有一個字符
		str.count(target,[min,max))   --統計某個字符在字符串中出現的次數
		str.startswith(target)  --判斷字符串是否以某個字符串開始
		str.endswith(target)  --判斷字符串是否以某個字符串結尾

------------------------------------------8、輸出與輸入(10:20-10:35)-------------------------------------------
輸出	
	print()
		Python3.x時代,print是一個函數
			輸出內容
				1. 字符串和數值類型
				2. 變量--無論什么類型,數值,布爾,列表,字典...都可以直接輸出

	輸出單個數據:

		print(1)
		print('')
		print(a)
		print(type())
		print([])
		print(())
		print({})

	輸出多個數據
		print(A, B, C)

		   *默認以空格分隔;即默認分隔符為' ' 。
		    如果要以其他字符分隔,需加sep='xxx'參數
	
	*默認輸出結束自動換行,即默認結束符為'\n',
	 如果不需要換行並需要其他結束符,需加end='xxx'參數

	*默認輸出到控制台
	 如果需要輸出到文件,需加file=參數
	 st = open('1.txt', 'w')
	 print(1, 2, 3, file=st)


輸入
	input
		變量名 = input(提示信息)
		將所有輸入作為字符串看待

	例: 接收一個數字,把這個數字加1再輸出出來

------------------------------------------9、控制語句-------------------------------------------
分支語句(AB 10:50 - 11:30)
	有多種情況需要處理,根據不同的情況,代碼執行不同的分支

		例子:接收用戶輸入的一個數,判斷能否被3整除
		如果用戶輸入不是純數字,怎么處理?
		如果能被3整除,輸出什么?
	    如果不能被3整除,輸出什么?
	    有沒有其他情況?

	第一種:
		if 條件表達式:
	 		條件表達式為真時,執行此代碼塊

	 	if判斷條件還可以簡寫,比如:
			if x:
				print('True')
			只要x是非零數值、非空字符串、非空list等,就判斷為True,否則為False(None,0,空列表、元組、字典,'',False)

	第二種:
		if 條件表達式:
			條件表達式為真時,執行此代碼塊
		else:
			條件表達式為假時,執行此代碼塊
	第三種:
		if 條件表達式A:
			條件表達式為真時,執行此代碼塊
		elif 條件表達式B:
			條件表達式B為真時,執行此代碼塊
	第四種:
		if 條件表達式A:
			條件表達式為真時,執行此代碼塊
		elif 條件表達式B:
			條件表達式B為真時,執行此代碼塊
		elif 條件表達式C:
			條件表達式C為真時,執行此代碼塊
		else:
			以上表達式都為假時,執行此代碼塊

	注意:1.如果在某個判斷上是True,把該判斷對應的語句執行后,就忽略掉剩下的elif和else
		  2.Python中沒有switch語句,所以多個條件時,可以用elif來實現
		  最容易出現的條件靠前寫。

	復雜 if 條件  
	    可包含 and、or、not,用()標識計算優先級

    if 嵌套

		if xxx:
			xxxxxxxxxxxxxxxxxxxxx
			if xxx:
				xxx
			else:
				xxx
		else:
			xxxxxxxxxxxxxxxxxxxxx


	舉例:
		1.接收用戶輸入的一個字符串,判斷是否為純數字	
		2.接收用戶輸入的一個數,判斷能否被3整除

		**整體縮進和取消縮進

	練習:
		1.接受用戶輸入的一個字符串,如果是正整數, 就判斷是否能同時被3和7整除
		2.根據輸入的月份來輸出,這個月有幾天(默認2月有28天,不考慮閏年),
		要求輸出格式:xx月有xx天!

    作業:
		1.接收用戶輸入一個年份,判斷是否是閏年(判斷閏年的方法是該年能被4整除並且不能被100整除,或者是可以被400整除)
		2.某電信公司的市內通話費計算標准如下:三分鍾內0.2元,
		  三分鍾后每增加一分鍾增加0.1元,不足一分鍾的按一分
		  鍾計算。要求編寫程序,給定一個通話時間(單位:秒)
		  計算出應收費金額。
		3.接收用戶輸入一組整數,輸入負數時結束輸入,輸出這組數字的和:格式--您輸入的數字之和是:10
		4.某市的出租車計費標准為:3公里以內10元,3公里以后每0.5公里加收1元;每等待5分鍾加收1元;
		超過15公里的加收原價的50%為空駛費。要求編寫程序,對於任意給定的里程數(單位:公里)和等待時間(單位:秒)
		計算出應付車費

循環語句(前兩種 11:30-12:00)
		循環的必要性:
		1、保證程序不退出,一直能響應和處理
			例:根據月份判斷天數,一直判斷下去

	    2、代替人做重復性工作
	    	最簡單例子:打印1-100以內所有的數
	                判斷
	                處理

	while 循環

		只要條件滿足,就不斷循環
		
		while 條件表達式:
			條件表達式為真時,執行此代碼塊

		舉例:根據輸入的月份來輸出,這個月有幾天(默認2月有28天,不考慮閏年)。不退出,重復執行
		
		練習:(1)重復接受用戶輸入的一個字符串,如果是正整數, 就判斷是否能同時被3和7整除。

		使用while循環容易產生死循環

		while True:
		    如果不通過break結束,就是死循環

		while 表達式:
			當在循環體里沒有語句讓表達式趨近於不成立,也是死循環

		舉例:模擬倒計時

		
	for 循環   

		第一種:for...in 序列(str、list、tuple)

            *適用於:序列內容不太多,或容易列出時

			for ele in [1,3,7,2,4]:
				print(ele)

			for c in 'Hello Huice':
				print(c)

			for c in '大家好':
				print(c)
            

			總結:for ele in seq 的理解

			舉例:1、對於列表[1,5,2,4,9],打印其中每個數的平方
			      2、對於字符串'Huice',打印出每個字符的ASCII碼值(十進制)
		
			練習: 
			      輸入一行字符,分別統計出其中英文字母、空格、數字和其它字符的個數

			*循環后對數據的處理
				判斷
				容器、計數器、計算器、其他

		第二種:for...in range(start, end, step)
		                  range 范圍

		    *適用於:1、連續整數范圍
		             2、列表、元組內容較多,不易列出————通過索引遍歷
		             3、其他涉及序列索引時

				for num in range(1, 101)
				for num in range(1, 101, 2)
				for num in range(100, 0, -1)  倒序

				for idx in range(0, len(seq)):
					...seq[idx]...
	            
	            從0開始且步長為1時可以省略初始值0,只寫尾下標:
					for idx in range(len(seq)):
						...seq[idx]...

			例:分別使用while循環和for循環,打印 1-100中所有的數

				**總結———— for 循環和 while 循環的區別:

					while 循環,while表達式中不包含數據變化 和 結束條件
	                數據變化要在循環體里寫;
	                結束條件通過數據變化形成(直到while表達式值變為False),或通過一定條件下的break完成。

					for 循環自帶數據變化和結束條件,不用在循環體中寫;
					依次循環遍歷范圍內的每個值,遍歷完自動結束。

					for 后面的變量不用預先定義,while 表達式里的變量需要預先定義

			練習:
				1.分別使用while與for循環輸出1-100之間的所有偶數
				2.用python輸出一個簡單的旋轉風車,模擬等待圖標
		
		第三種:for...in enumerate(seq)	(至最后 13:30-14:30)
			
			enumerate()函數

			適用於:同時用到序列中的 元素 和 元素下標
			
			舉例:以下列表中是按照銷量高低排序的手機品牌名稱
				['OPPO', 'vivo', 'Apple', 'Huawei', 'HONOR', 'MI', 'MEIZU']
               
               格式化輸出為下面的形式:
				第X名:xxxx
				第X名:xxxx
				... ...
				第X名:xxxx

			練習:給一個字符串,找出其中數字分別是第幾個字符
				seq = '2Apples&3Pears&5bananas'
				for i, j in enumerate(seq):
				    if j.isdigit():
				        print("第%d個字符是數字,為'%s'" % (i+1, j))


	break 和 continue
				        
    	break  - 終止循環語句,退出循環
        continue - 跳出本次循環,直接進入下次循環

        舉例:根據輸入的月份來輸出,這個月有幾天(默認2月有28天,不考慮閏年)。不退出,重復執行

	

	循環中的 else

		Python特有

		代表在循環正常結束后,執行else中的代碼塊
		循環沒有執行完,比如break或者return,else中的代碼塊不執行

	占位語句 pass

        用於循環體、if代碼塊、函數體等
		暫時或永久,表示什么都不做,只是為了保證程序結構的完整性

	嵌套循環、分支/循環互相嵌套

		例:
		    打印一個9*9 的方陣,由星號組成

		    * * *     第1行
		    * * *     第2行
		    * * *     第9行

		練習:
			1. 接收用戶輸入的一個字符串:h, w 代表矩形的長和寬,打印一個空心的矩形
		   	2. 輸出九九乘法口訣

		例:
	        接收用戶輸入的數字,計算該數字的階乘


	    練習:
	    	輸入n, 計算1到n的階乘之和

		例:找1000以內最大平方數

		例:給定一個字符串 target = 'hello huice',從中找出第一個不重復的字符,輸出它是第幾位
		
		練習:去除上一題中的重復字符,得到一個新的字符串
		
		作業:
		    1.一個5位數,判斷它是不是回文數。即12321是回文數,個位與萬位相同,十位與千位相同
			2.打印出100-999中所有的"水仙花數",所謂"水仙花數"是指一
			  個三位數,其各位數字立方和等於該數本身。例如:
			  153是一個"水仙花數",因為153=1的三次方+5的三次方+3的三次方
			3.輸出100之內的素數總個數,所謂"素數"是指除了1和它本身以外,不能被任何整數整除的數,例如17
			4.一個數如果恰好等於它的因子之和,這個數就稱為“完數”。例如6=1+2+3.編程找出1000以內的所有完數

	*Pycharm斷點調試
------------------------------------------10、元組-------------------------------------------
字符串——數據結構:序列
另一種序列結構:元組

定義元組

	方式一:
		a = (1,2,3)    --圓括號 逗號
	方式二:
		a = 1,2,3

		特別地:
			a = 1,
			a = (1,)

訪問元組對象	

	通過索引、分片

		a = (1,6,4,8,3,5,6)
		索引
		print(a[0])
		print(a[-1])
		分片
		print(a[2:6:1]
		print(a[::-1]

	元組中的元素值不允許修改!

		a = (1,6,4,8,3,5,6)
		a[0] = 2 錯誤!!! 

		元組屬於不可變數據類型,要想改變某個值只能重新賦值,重新開辟內存空間創建新對象

		(列表可以通過元素賦值修改某個元素,內存地址不變)

		很多系統函數返回值為元組。

刪除元組
	
	del(元組名)
		刪除整個元組

元組運算符

	+ 連接: tup3 = tup1 + tup2;
	*N 復制並連接: 重復N次 tup3 = tup1 * 3

內置函數作用於元組

	len(tuple):計算元組元素個數。
	max(tuple):返回元組中元素最大值。
	min(tuple):返回元組中元素最小值。

將其他序列轉為元組:
	tuple(seq):將其他類型序列轉換為元組。

元組操作

	index : T.index(target)
	獲取元素在元組中的索引值,對於重復的元素,默認獲取從左起第一個元素的索引值
			找不到時報ValueError
	count : T.count(target)返回元組中某元素的個數

元組中的數據類型
	
	任意,不必一致


元組嵌套 和 多維元組

	多維元組
		((1, 2, 3), (4, 5, 6))
		如何取到每個元素?

	元組嵌套

		可以嵌套任何數據類型

		*元組雖然是不可變數據類型,但是當元組中嵌套可變元素時,該可變元素是可以修改的,元組本身不變

		([1, 2, 3], (4, 5, 6))


作業:員工工資表,查詢結果集如下:((1, 'zhangsan', 3000), (2, 'lisi', 2500), (3, 'tiantian', 20000))
	  1.計算員工的平均工資	  
	  2.輸出工資最高的員工姓名

------------------------------------------11、列表-------------------------------------------
列表--可變數據類型

	列表屬於可變數據類型,可以增加元素,可以通過賦值的方式改變元素的值,且內存地址不變
	
列表中可保存的數據類型

	可以保存任何數據類型--數據項不需要具有相同的類型

列表的創建
	[]

訪問數據項
	
	索引
	分片

更新數據項

	索引賦值
		
		list[idx] = value
		注意: 不能超過索引范圍

	追加元素

		單個元素追加 list.append(ele)

		追加一個列表中的所有元素 +=

		不太常用的方式:list[x:x] = list2

			固定寫法,第x項后插入一個列表的所有元素

				注:與分片賦值區分開

	分片賦值

			變化: x:
				   x:y

	批量刪除 和 清空列表
		list[x:y] = []
		list[:] = []

	刪除數據項
		del(list[index])
		del(list[x:y])
		del(list) 不加索引直接刪除引用,回收對象

	列表方法

		有返回值和無返回值
			list.count()  有返回值
			list.append() 原地操作,改變了對象本身



		list.append(obj)  			用於在列表末尾追加新的元素或對象  直接操作對象,無返回值
		list.insert(index, obj)		將元素或對象插入到列表指定項

		list.extend  在列表末尾一次性追加另一個序列中的多個值,相當於+=
				
		list.count   用於統計某個元素在列表中出現的次數
		list.index   用於從列表中找出某個值第一個匹配項的索引位置
		
		list.pop     該方法從列表中彈出一個元素,默認是最后一個。並且返回彈出的元素;參數為下標,指定要彈出的元素
		list.remove  	從列表中移除某個值的第一個匹配項。與pop不同的是,該方法並不返回移除的元素, 並且參數
		                為要移除的元素
		
		list.reverse 	該方法對序列反向存放。注意該方法改變了列表但是沒有返回值
						reversed函數:並不返回一個列表,而是返回一個迭代器對象,使用list把迭代器對象轉換成列表

		list.sort  用於在原位置對列表進行排序。 在原位置意味着列表會被修改
			  			注意:sort()方法的返回值並不是序列本身,而是None

			修改排序規則
		
				reverse參數

					reverse 默認為False--按照ASCII碼的升序排列,reverse=True降序

				key參數

					key = 函數名

					key = len
					key = mysort 					

						函數為接收單參數的函數,能逐個接收 list 中的每個元素,經過運算后返回一個值
					該值就作為排序的依據

					key = lambda x: xxx

		
			保存原序列順序而進行排序

				1.拷貝后再排序
				
				2.內建函數:sorted()
					sorted(seq, reverse=True/False, key=fun)
						第一個參數是一個序列(或無序的隊列如字典)
						key指定一個接收單參數的函數,這個函數接收序列中的每個元素,經過運算后返回一個值
				該值就作為排序的依據。默認為None
						
						reverse是一個布爾值。如果設置為True,列表元素將被倒序排列
					返回值是一個對序列中元素進行排序后的列表(list)
					

		練習:一行代碼輸出[[1, 'zhangsan', 3000], [2, 'lisi', 2500], [3, 'tiantian', 20000]] 工資最高人的姓名
		    		

		練習:

			1.檢查get請求的參數中是否包含sign,如果包含將參數值替換為空格,重新拼接為參數字符串
		title=華為春季新品發布會&sign=2&limit=100&status=0&address=國家會議中心&time=2018-03-28	

		作業:
			1.用python實現冒泡排序
			# [50,20,30,10]
			#
			# 升序:誰大誰交換到后面
			# 降序:誰大誰交換到前面
			#
			# 以升序為例
			# 第1趟:
			# [20,50,30,10]
			# [20,30,50,10]
			# [20,30,10,50]
			# 第2趟:
			# [20,30,10,50]
			# [20,10,30,50]
			# 第3趟:
			# [10,20,30,50]
			
			2.用python實現選擇排序
			# 定義:選擇法排序指每次選擇所要排序的數組中的最大值(由小到大排序則選擇最小值)的數組元素,
			# 將這個數組元素的值與最前面沒有進行排序的數組元素的值互換
			# 以升序為例:
			#
			# 原始:
			# lst = [50, 30, 10, 20]

			# 比較:
			# 第一趟:[10, 30, 50, 20]
			# 第二趟:[10, 20, 50, 30]
			# 第三趟:[10, 20, 30, 50]


			3.接收用戶輸入的數字,輸入負數時結束輸入。存入一個列表
			  然后找出用戶所輸入的所有數字中最大的數,最小的數,再將所有數字從小到大排序輸出
  			
	迭代整個列表:
		for x in list: 
			print(x)
		for x in range(len(list)):
			print(x)

		
		(了解)[x for x in list] --迭代后自動裝填成新列表


			練習:
				1.
				a=[1, 2, 3, 4, 5, 6]
				一行代碼實現對a中的偶數位置的元素進行加3后,組成的新列表

				print([i + 3 for i in range(1, len(a), 2)])



	運算
		a = a + b 生成了一個新的列表存這兩個列表的和
		a += b    效果與extend()一樣,向原列表追加一些新元素,在原有列表上增加
		
		* [1,2,3] * 3

	列表嵌套:
		多維列表: [ [1, 2, 3], [4, 5, 6] ]

		zip函數
			它接受一系列可迭代的對象作為參數,將對象中對應的元素打包成一個個tuple(元組),然后返回由這些tuples組成的zip對象。
			若傳入參數的長度不等,則返回list的長度和參數中長度最短的對象相同

		練習:用zip函數組合出
			((1, 'zhangsan', 3000), (2, 'lisi', 2500), (3, 'tiantian', 20000))	

	類型轉換
		其他對象轉列表
			list(str)
			str.split(seperator)
			eval(str)

		列表轉字符串
			str(list)
			''.join(list)

		列表轉元組
			tuple(list)


	*Set介紹
		集合類型--無序不重復元素集
			創建
				set(序列對象) 或 {A,B,C} (Python3)
				不支持索引和分片
				可以循環
			
			操作
				添加一項 s.add('x') 
				刪除一項 s.remove('H')  
					remove()用於刪除一個set中的元素,這個值在set中必須存在,如果不存在的話,會引發KeyError錯誤。
					discard()用於刪除一個set中的元素,這個值不必一定存在,不存在的情況下刪除也不會觸發錯誤。
				彈出首個 s.pop()  
				清空	 s.clear()  清空后為空set 
			因為也被當做序列對象,所以可以轉元組或者轉列表

	列表去重:
		方式一:循環原始列表,創建新列表
		方式二:利用Set		
		*方式三:利用字典
		練習:把[1,2,3,1,2,3] 中的重復元素剔除。至少寫出兩種方式

	練習:1.列表合並(用你能想到所有方法實現)
		[1, 2, 3, 5, 6]    [0, 2, 5, 7]
		結果:[0, 1, 2, 3, 5, 6, 7]	

		2. 去掉列表[2, 5, 3, 9, 7, 3, 6, 9, 2]中的重復元素,剩余元素要與原列表中出現順序一致。
			# def my_sort(x):
			#     return list0.index(x)
			#
			# print(list(set(list0))
			# print(sorted(list(set(list0)), key=my_sort)


	作業:
		1.大腳超市賒賬人員名單如下:
		['劉能', '王老七', '謝廣坤', '趙玉田', '楊曉燕', '劉大腦袋', '王長貴', '謝飛機', '趙四', '王大拿']
		大腳想移除掉里面的姓氏重復的人(不考慮復姓),但是對於每種姓氏大腳想保留最后出現的那個人。希望你來幫助她

		['楊曉燕','劉大腦袋','謝飛機', '趙四','王大拿']

		*2.調用慧測會議管理接口,需要填寫一個參數sign-數字簽名
  			  sign的算法如下:
  			  	用戶輸入的參數中,去除username參數,將其余的參數按參數名的ASCII碼降序排列,
  			  	在得到的參數字符串之前拼接上user=username值
  			  	組合成一個新的字符串,加密后作為sign
  			  要求:用戶入參如下:
  			  		address=beijing&limit=200&title=Huice_Test&time=2018-01-30&username=tianlaoshi
  			  	    結果:user=tianlaoshititle=Huice_Test&time=2018-01-30&limit=200&address=beijing

------------------------------------------12、字典-------------------------------------------

	字典是可變類型,
	字典中的數據是無序的
	一個字典條目的語法是 鍵:值 key value
	任何不可變數據類型都可以作為條目的鍵

		創建
			{ } 、dict(key1=value1,key2=value2...)
				鍵
					必須獨一無二(如果鍵重復存入,會被覆蓋),值不必
					只能是不可變類型(常用字符串和數字)
				值
					可以是任意數據類型


			dic1 = {'name':'zhangsan', 'age': 18, 'address': 'beijing', 'xxx': 'hahaha'}

			{'zhangsan':80, 'lisi':90}
		
		訪問數據項
			通過key
				dic[key]
				如果key不存在,報KeyError
					***沒有索引!不能分片!


			取值:
				print(dic1['age'])
				print(dic1.get('xxx'))

			賦值:
				dic1['age'] =  19
				dic1['xxx'] = 'hahaha'

				dic={}
				dic['sdfafs'] = 'afsafd'

		
		更新數據項
			dic[key] = value
			如果key不存在,就是新增數據項
			
			練習:
				1、把字符串”k1:1|k2:2|k3:3”處理成 python 字典的形式:{'k1': 1, 'k2': 2, 'k3': 3}


		刪除數據項
			del dic[key]  刪除鍵是'key'的條目
			del dict      刪除字典

		字典方法
			判斷key存在
				*in 、not in

			*dict.keys() 返回一個包含字典所有KEY的列表(Python3中為dict_keys類型對象)

			*dict.values() 返回一個包含字典所有value的列表(Python3中為dict_keys類型對象)

			*dict.items() 返回一個包含所有(鍵,值)元組的列表(Python3中為dict_keys類型對象)

			dic.pop(key)
				刪除鍵key的項並返回key對應的 value值
				如果key不存在,報錯

			dict.clear() 刪除字典中的所有項或元素

			*dict.fromkeys(seq, val=None) 創建並返回一個新字典,以seq中的元素做該字典的鍵,val做該字典中所有鍵對應的初始值(默認為None)

			*dict.get(key) 返回字典中key對應的值,若key不存在字典中,則返回None

			adict.update(bdict) 將字典bdict的鍵值對添加到字典adict中
				key存在,就更新value。key不存在就新增數據項
				字典合並	

		運算
			字典不支持拼接和重復操作符(+,*)
			
			字典的比較操作
				長度等、鍵等、值等
				
		迭代
			遍歷字典的key
				for key in adict.keys():
					print(key)

			遍歷字典的value
				for value in adict.values(): 
					print(value)

			遍歷字典的項
				for item in adict.items():
					print(item)

			遍歷字典的key-value
				for key, value in adict.items(): 
					print('key=%s, value=%s' % (key, value))

		練習:
			把字典{'k3': 3, 'k2': 2, 'k1': 1}處理成字符串的形式: k1:1|k2:2|k3:3”

		排序

			字典是無序的,排序后生成的是列表,或列表內嵌套元組


			sorted(dic,value,reverse)

    			dic為可以迭代的對象,value 為排序的對象(這里指鍵或鍵值)
    			reverse:注明升序還是降序,True--降序,False--升序(默認)
    			鍵排序
    			    --sorted(dict.keys())
    			  
    			值排序
    			    --sorted(dict.values())
    			
    			項排序,按照鍵或按照值
    			    --sorted(dict.items(), key=lambda item:item[0])
    			    --sorted(dict.items(), key=lambda item:item[1])

    			    scores = {'zhangsan': 98, 'lisi': 85, 'wangwu': 90}

    			    (1) 對所有名字排序,按ASCII升序排列
    			    sorted(scores.keys())
    			    
    			    (2) 對所有成績排序,按照高低分排列
    			    sorted(scores.values(), reverse=True)
    			    
    			    (3) 對所有人和成績排序,按照名字的ASCII碼降序排列
    			     [('zhangsan', 98), ('lisi',  85), ('wangwu',90)]
    			    sorted(scores.items(), key=lambda x:x[0], reverse=True)
   			    
    			    (4) 對所有人和成績排序,按照名字的長度升序排列
    			    sorted(scores.items(), key=lambda x:len(x[0]))

    			    (5) 對所有人和成績排序,按照高低分排列
    			    sorted(scores.items(), key = lambda x:x[1], reverse=True)



		類型轉換
			其他類型轉字典:
				字符串:eval(str)
				
				列表:
					二維列表轉換
						lst = [('name', 'zhangsan'), ('age', 18)]
						print(dict(lst))						
						
						手動構造
							lst1=['name', 'age']
							lst2=['tianlaoshi', 18]
							dic = {}
							for i in range(0,len(lst1)):
							    dic[lst1[i]] = lst2[i]
							print(dic)

						利用zip

							zip()  --內建函數
								
								它接受一系列可迭代的對象作為參數,將對象中對應的元素打包成一個個tuple(元組)
								*與dict() 連用,完成list組合成字典
							
							lst1=['name', 'age']
							lst2=['tianlaoshi', 18]
							print(dict(zip(lst1,lst2)))

			字典轉列表:
				list(dic) == dict.keys()
				dict.keys() dict.values()
			字典轉元組:
				tuple(dic) -- 只包含key值
			字典轉字符串:
				str(dic)

		練習:
			編寫一組數據,記錄組內每個人的語文成績
					data = {
					     'ZhaoLiYing': 60,
					     'FengShaoFeng': 75,
					     'TianLaoShi': 99,
					     'TangYan': 88,
					     'LuoJin': 35,
					     'LiuLaoShi': 100
					}
				a.算出平均分
				b.再找出學霸

			編寫一組數據,記錄組內每個人的語文成績、數學成績、英語成績	
				data = {
				     'ZhaoLiYing': [60, 68, 45], 
				     'FengShaoFeng': [10, 28, 5],
				     'TianLaoShi': [44, 86, 73],
				     'TangYan': [99, 95, 95],
				     'LuoJin': [98, 65, 100],
				     'LiuLaoShi': [77, 97, 65]
 				}
				a.找到平均分不足60分的人
				b.找出各科的最高分
				c.算出各科的平均分,再找出各科的學霸
		作業:
			1.編寫一組數據,記錄組內每個人的語文成績、數學成績、英語成績	
				data = {
			        '穎寶':{'語文':60, '數學':68, '英語':45},
			        '馮威':{'語文':10, '數學':28, '英語':5},
			        '糖糖':{'語文':44, '數學':86, '英語':73},
			        '咕嚕':{'語文':99, '數學':95, '英語':95},
			        '田老師':{'語文':98, '數學':65, '英語':100},
			        '劉老師':{'語文':77, '數學':97, '英語':65},
			   	}
				a.找到平均分不足60分的人,
				b.找出各科的最高分,平均分
				c.找出各科的學霸

			2.統計一篇英文文章每個單詞的出現頻率,並返回出現頻率最高的前5個單詞及其出現次數(字典形式)
A small sample of texts from Project Gutenberg appears in the NLTK corpus collection. However, you may be interested in analyzing other texts from Project Gutenberg. You can browse the catalog of 25,000 free online books at http://www.gutenberg.org/catalog/, and obtain a URL to an ASCII text file. Although 90% of the texts in Project Gutenberg are in English, it includes material in over 50 other languages, including Catalan, Chinese, Dutch, Finnish, French, German, Italian
			
			3.給定一個字符串,例如abcabcd,請你求得到該字符串中所有的長度大於等於2的子串,
並統計每個字串出現的次數

------------------------------------13、函數-------------------------------------
作用:1.代碼復用,常用功能封裝成函數;2. 模塊化開發
特點:定義處暫不執行函數體中的內容,調用時才執行

內置函數
    id(), type(), len(), max(list), 

	1、絕對值:abs(-1)
	2、最大最小值:max([1,2,3])、min([1,2,3]),對序列進行操作
	3、序列長度:len('abc')、len([1,2,3])、len((1,2,3))
	4、乘方:pow(2,3,4)	// (2**3) % 4
	5、浮點數:round(3.1415926, 2)	//3.14 四舍五入
	6、類型轉換函數:int()、str()、list()....

匿名函數-lambda

	def func(x,y):
		return x+y
	func = lambda x,y:x+y

創建函數

	def 函數名(參數列表):
		函數體語句

		函數的命名規則:

			一個單詞--直接小寫
			多個單詞--每個單詞小寫,以下划線分隔
				 enroll
				 submit_info
				 verify_password

		文檔化說明
			函數首行加 ''  或 ''' '''
			函數名.__doc__ 可以查看函數文檔   系統內建參數

			測試用例中,用於輸出用例描述

		callable(函數名) --判斷函數是否可以被調用
			debug的時候經常報錯,xx is not callable 
			--說明你應該在報錯的地方給一個函數,結果你給的xxx不能當函數用
			1.文件中定義的某個變量名與系統函數名重復,
		
		pass--占位
				
函數的參數 arguments

	實參和形參

	傳參時,可以指定參數名

		def my_function1(name, address, age):
	    print('姓名:%s, 地址:%s, 年齡:%s' %(name, address, age))

		1 不指定參數名
			my_function1('zhangsan', 'beijing', 10)
		
		2 出錯的情況:參數數量大,順序記不住,不想按順序寫
			my_function1('lisi', 10, '男')
		
		3 指定參數名,即使順序不一致也沒關系
			my_function1(age=10, address='shanghai', name='王五')



	參數默認值

		*定義函數時 可指定參數的默認值

			沒有默認值時:
				def my_function2(name, age):
					print('姓名:%s, 年齡:%s' % (name, age))

			調用時,傳參數量與定義時不一致:

				my_function2('tianlaoshi')  #會報錯,給出的參數數量與要求不一致

			定義時沒有指定參數默認值,則只能嚴格按照定義時的數量傳參

				my_function2('tianlaoshi', 46)

			定義函數時,可以給一些數值相對固定的參數以默認值,賦值給形參

				def my_function2(name, age=18):
    				print('姓名:%s, 年齡:%s' % (name, age)

    			調用時若不給相應形參傳值,則自動取用默認值;
    			若傳值,則覆蓋默認值

    			my_function2('張老師')
				my_function2('田老師', 46)

		*有默認值時的參數順序

			*錯誤舉例:
				def enroll(gender, age=6, city='Beijing', name):  #SyntaxError: non-default argument follows default argument

					print('name:', name)
					print('gender:', gender)
					print('age:', age)
					print('city:', city)
					print('-------------')

				enroll('男', 'tiantian')

			**結論:帶默認值的參數往后放,后面不能再有必填參數
				def enroll(gender, name, age=6, city='Beijing'):

		*參數默認值的數據類型和初始化邏輯

			默認值最好是不可變數據類型 
			如果是可變數據類型,默認為空要用None,別用空對象。

			例:
			
				以下的代碼的輸出什么? 你將如何修改 extendList 的定義所帶來的隱患問題
					def extendList(val, list=[]):
					    list.append(val)
					    return list

					list1 = extendList(10)      
					list2 = extendList(123,[])
					list3 = extendList('a')

					print("list1 = %s" % list1)
					print("list2 = %s" % list2)
					print("list3 = %s" % list3)

				# 隱患和修改方法:
				# 函數定義時,如果參數有默認值,則在定義時就會開辟一塊內存空間來存儲該默認值
				# 調用函數時,如果未給有默認值的參數傳值,就會使用該內存空間的數據
				# 多次調用時,該空間就會被重復使用,如果某一次調用時改變了該空間的數據,其他次調用也會收到影響
				# 可變數據類型,內存空間地址可以被改變,所以盡可能不用可變數據類型
				# 如果一定要用,默認值不要用空對象,應該用None

					def extendList(val, list=None):
						if list == None:
							list = []
					    list.append(val)
					    return list

	可變參數
		傳入的參數個數是可變的

		*params
			在函數內部,參數numbers接收到的是一個tuple或list
			在函數調用時,可以一個一個的傳,也可以傳list或tuple --*params

		**params
			在函數內部,參數numbers接收到的是一個dict
			在函數調用時:
				可以一個一個的傳 key=value
				也可以傳dict --**params

	**參數定義的順序必須是:必選參數、帶默認值參數、可變參數

關於返回
	見到return 函數就結束
	不寫return無返回--None
	只寫return 返回None
	返回多個值--實際返回的是元組

練習:

		1. 寫函數,判斷用戶傳入的序列(字符串、列表、元組)長度是否大於5

		2. 寫函數,輸入一個列表(列表元素均為數值型),返回列表元素的平均值

		3. (選做)編寫一個生成get請求地址的函數,上游傳遞過來的參數有url=“”,domain=“”,data={},
	  請根據以上參數返回一個get請求的完整鏈接,其中data和url有可能不傳

	  http://127.0.0.1/access/log?a=1&b=2
              domain       url     data {'a':1,'b':2}

	  
			def gen_get_address(domain, url=None, data=None):
			    address = 'http://' + domain
			    if url:
			        address += '/' + url
			    if data:
			        params_list = []
			        for k, v in data.items():
			            param = k + '=' + v
			            params_list.append(param)
			        params = '&'.join(params_list)
			        address += '?' + params
			    return address


			print(gen_get_address(domain='127.0.0.1', 
								  url = 'huice/huice', 
								  data={'usr': 'tiantian', 'passwd': 'bugaosuni'}))

	 		http://127.0.0.1/huice/huice?passwd=bugaosuni&usr=tiantian


遞歸
	如果一個函數在內部調用自身,這個函數叫做遞歸函數
	遞歸調用的次數過多,會導致棧溢出
	練習:
		1.求一個數n的階乘

函數式編程--函數的參數是函數
	高階函數


		def f():
			pass
			
		def fun(x, y, f):
			pass

	
	map():函數接收兩個參數,一個是函數,一個是序列
		  將傳入的函數依次作用到序列的每個元素,並把結果作為map對象返回
		  應用:並行遍歷--序列合並


	filter():“篩選”函數
			接收一個布爾值返回值的函數和一個序列,
			把傳入的函數依次作用於每個元素,根據返回值是True還是False決定保留還是丟棄該元素

練習:
		1.利用map()函數,把用戶輸入的不規范的英文名字,變為首字母大寫,其他小寫的規范名字。
		輸入:['adam', 'LISA', 'barT'],輸出:['Adam', 'Lisa', 'Bart']
	
---------------------------14、類和對象-----------------------------------------------------------------------------

面向對象
面向過程

	生活中的例子

	蛋炒飯 怎么來做

	蒸米飯,煎雞蛋  一起炒 面向過程

	人 米飯 雞蛋 鍋 油 鹽 蔥花 西紅柿    一切皆對象


	Java  -  強制面向對象  類


	Python - 既支持面向對象,也支持面向過程


	*if __name__ == '__main__' 該如何理解?


		只有單獨運行本文件時,該if條件下的語句塊才會被執行

		__name__ 是內置變量,用於表示當前模塊的名字
		如果一個模塊被直接運行,其 __name__ 值為 __main__


類是對某一類具有共同特點的事物的抽象,是在概念上的一個定義
	比如:動物,人,學生。但是單獨說這三個概念的時候,不代表任何一個具體的個體

	    類   屬性  名字 身高 體重       變量
	             
	         行為  吃飯 學習            函數  方法 



		屬性             成員
						 類  

		行為             成員
			             類
    成員方法定義時都要有self參數,但調用時不需要傳值

類的具體實例叫做 【對象】 【類的實例】 【實例化一個類】
	學生是類,張三是一個具體的學生就是 學生類的實例(Instance),也叫學生對象

	學生   慧測的學生      類
	張三                   對象 實例


    #變量  屬性
    身高           成員變量 實例變量
    體重

    學校='huice'    類變量
    學費=500        



    
    #方法  行為、功能

    學習            成員方法 實例方法
    上學            類方法
   


類的定義:
	class 類名(父類):
		類實體	
		*類名:每個單詞的首字母大寫

	屬性的定義:

		成員變量

			構造函數(初始化函數) __init__(self)
				作用:python在創建類的實例的時候,會首先調用這個類的__init__()方法
					  初始化數據

				self:創建的實例自身(存儲當前對象的地址)
					  所有的成員方法第一個參數默認是self,但是調用的時候不需要為self傳值。
					  只要用類的實例調用成員方法,默認相當於已經給self傳值了。

			類的屬性:變量
				成員變量--屬於實例的變量
					每次實例化就創建,實例結束就銷毀
						*一般是在__init__方法中通過self完成 定義
						*類內部:通過self訪問,類外部:通過實例名訪問

		類變量

			屬於類自己的變量(保存在內存),每次被構造的時候,拷貝一個副本給對象
				*在類起始處統一定義
				*通過類名或實例來訪問 	
					通過實例的修改只對當前實例生效,通過類名的修改才能改變整個類所有對象的值


	類的操作:方法
		成員(實例)方法
			定義:必須帶有參數self
				內部:可以訪問成員變量、類變量(self或類名)、成員方法(self)、類方法(self或類名)
				      通過self調用
				外部:通過類實例調用
		類方法
			定義:必須帶有@classmethod、和cls參數
				內部:可以訪問類變量、類方法
				外部:通過類實例或類名調用

		靜態方法
			定義:必須帶有@staticmethod
			內部:如果靜態方法調用類方法或屬性時,只能直接類名.屬性名或類名.方法名
			外部:通過類實例或類名調用
------------------------------------------------------------
總結:類由屬性和方法組成
分類
定義
調用
------------------------------------------------------------
		訪問限制
			私有變量:__變量名
				python使用的是名字重整技術,改變了私有變量的值:_類名__變量名

		專屬變量
			__xx__

		私有方法:
			__xx()

			私有變量和方法,在類的內部訪問不受限制。

		特殊方法:
			__xx__() 代表一定的協議,相當於Java中的接口方法

				* __str__()與__repr__() 
					__str__()  --讓class作用於print()函數
					(了解即可)__repr__() --返回程序開發者看到的字符串

				* __len__() --讓class作用於len()函數

				__iter__() --讓class具有可迭代的屬性,返回值必須是對象自己
					next():每一次for循環都調用該方法

				__getitem__() --讓class作用於索引方式 

				__getattr__()
					當調用不存在的屬性時,會試圖調用此方法,來嘗試獲得屬性

		

封裝
	變量私有化 + 提供getter和setter方法


練習:
	1.設計一個汽車類Auto,
	  有速度屬性speed,啟動start、加速speedup(1次速度+10)和停止stop(1次速度-30)方法;

作業:	
	1.設計一個汽車類Auto,
	  屬性:品牌brand
	  		顏色color
	  		速度speed,初始為0

	  方法:啟動start,打印‘yyyy色的xxxx啟動了’,xxxx為品牌,yyyy為顏色
	  		加速speedup(加速數值支持通過參數傳入)
	  		減速slowdown(減速數值支持通過參數傳入)

	2.設計一個子類Bus表示公共汽車,Bus增加一個屬性passenger表示乘客數量。
	  另外在添加兩個方法gotOn和gotOff表示乘客的上車和下車;
	  通過main方法完成對Auto和Bus的使用

	3.利用列表實現數據結構--棧
	pop
	append
	    有極限大小
	    可以彈棧
	    可以壓棧
	    后進先出
	    棧滿時壓棧,提示已滿
	    棧空時彈棧,提示為空

		要求:
		0.不能直接訪問棧
		1.初始化函數,傳入棧的極限大小
		2.提供一個弾棧和一個壓棧的方法
		3.提供一個獲取棧極限大小的方法
		4.其他方法私有--判斷棧是否到達極限,棧是否為空


繼承和多態		
	繼承		
		方法覆蓋(重寫)
			1.當我們需要傳入一個對象時,我們可以不傳入具體的類型,而傳入一個抽象的概念---父類對象
			2.這樣,在程序實際運行時,可以動態綁定傳入的類型
		    3.因為都有共同的父類,所以一定有共同的方法。使用時,內部使用時,調用共有的方法就可以
			  isinstance(instance, class)方法
		多重繼承
				(class1, class2, class3)  --class1優先

作業:
		
		設計一個部門類Department,屬性為部門名稱(name)
		需求:
			1.直接通過Department調用get_all方法,返回公司員工總數
			2.通過部門實例,調用方法get_count方法,返回部門員工數
			3.通過部門實例,調用方法get_employees(),顯示該部門所有員工信息
			  格式為: 工號-xxx ,姓名-xxx ,手機號-xxx,工資-xxx
			提示:有人入職,員工數就要增加,部門存入員工對象
		設計一個員工類Employee,員工屬性有姓名(name)、手機號(phone)、工資(salary)、所屬部門。
		需求:
			1.新員工入職時,分配一個不重復的工號。從1開始排列,已離職員工工號作廢。
			2.員工本人可以調用get_salary方法查詢自己的工資
			3.員工本人可以調用get_info方法查詢自己的全部信息--字典形式
		測試:人力資源部(小紅)、技術部(田老師、劉老師)
			輸出 每個部門的人員和公司總人數,輸出兩個部門的人員信息

----------------------------------------15、異常------------------------------------------------------------------------------------

	在程序運行過程中,總會遇到各種各樣的錯誤

		有的錯誤是程序編寫有問題造成的
		還有一類錯誤是完全無法在程序運行過程中預測的

		舉例-各種類型的異常

	調試時我們關心
		什么類型的錯誤?  分類
		在哪兒出錯的?    記錄並顯示文件、行數、代碼
		為什么出錯?      錯誤的具體說明,顯示原因

	拋出的異常也是對象
		異常的分類
			系統定義的異常
				BaseException 所有異常的基類	
					Exception 常規錯誤的基類
						StandardError 所有的內建標准異常的基類
							ImportError  導入模塊錯誤
							ArithmeticError 所有數值計算錯誤的基類
								FloatingPointError 浮點計算錯誤
							AssertionError  斷言語句失敗
							AttributeError  對象沒有這個屬性
						Warning 警告的基類


	異常處理

		不做處理,出現異常程序直接斷掉

		需求:出現錯誤時,希望后面代碼還能執行

		捕獲 try except     finally

			格式:
				try:
				 	可能會發生錯誤的語句塊
				except:
				 	發生錯誤后跳轉到該語句塊執行

				finally:
					不管有沒有發生錯誤,都會跳轉到此處,語句都會被執行

					收尾、資源釋放工作,如關閉文件、流等

					有return時,先執行finally中的語句,然后再return


			執行順序:
				當我們認為某些代碼可能會出錯時,就可以用try來運行這段代碼
				如果執行出錯,則 try 語句塊中的后續代碼不會繼續執行,而是直接跳轉至錯誤處理代碼,即except語句塊
				執行完except后,如果有finally語句塊,則執行finally語句塊
				try except 語句塊可以相互嵌套

			except:
				
				0.后面可寫要捕獲的異常類型,不寫異常類型代表捕獲一切類型的錯誤
				1.如果不確定會發生什么類型的異常,可以抓所有,或抓父類
				2.后面可以寫多個異常類型,都會捕獲 (exception1, exception2)
				3.可以在except語句塊后面加一個else,當沒有錯誤發生時,會自動執行else語句
				4.可以用變量(如e)代表當前異常的實例 print可以顯示錯誤信息  , e  or as e
 				5.如果想要輸出詳細堆棧信息,使用import traceback traceback.print_exc()
 						程序不會終止運行

 			利用異常實現分支
 			例:
 			 	a = [1,'a','c',10,23] 只使用try...catch,統計出a列表中有幾個非整數

 			 	非整數 - int()時會拋出異常
 			 	counter = 0
 			 	for ele in a:
 			 		try:
 			 			int(ele)
 			 		except:
 			 			counter+=1
 			 	print(counter)


 			練習:
 				1.從開發的代碼庫中得到一組數據,表示每個文件的代碼變更情況
 				  {'login.py': 'a 8 d 2 u 3 ', 'order.py': 'a 15 d 0 u 34', 'info.py': 'a 1 d 20 u 5 '}
 				  其中 a表示新增行數,d表示刪除行數,u表示修改行數。login.py的變更行數為13
 				  要求:統計出每個文件的變更行數
 				

 				2.優化練習
 					接受用戶輸入的一個字符串,如果是正整數就判斷是否能同時被3和7整除

		拋出

			自動拋出:

				如果錯誤沒有被捕獲,它就會一直往上拋,最后被Python解釋器捕獲,打印一個錯誤信息,然后程序退出
			
			手動拋異常:

				def sum(a,b):
					if a==0 or b==0:
						raise BaseException('不能為0')
					else:
						return a+b

			raise 異常類名 (錯誤信息)

		總結:函數對異常的的兩種處理:
				上拋——交由調用它的函數或一直上拋給解釋器處理
				捕獲


			*選擇捕獲還是拋出?

				如果有能力處理異常,不是導致系統崩潰的,程序必須斷掉的,非拋出不可的異常,
			應對異常進行捕獲處理,給用戶友好的合理的可控的返回值。

			*綜合使用:捕獲,補充信息,再上拋——異常的二次處理
				
				需求:1.替換系統自動拋出的提示信息,但要求拋出異常時程序停止運行。


			def div(a, b):
				try:
					return a/b
				except:
					raise BaseException('除數不能為0')
			div(2,0)

				需求:2.不是把異常信息打印到控制台,而是可以用來記錄系統日志,需要捕獲
						except中可以寫記錄日志的代碼,記錄完再拋出

			對比:兩種不同的處理方式

				def div(a, b):
					try:
						return a/b
					except BaseException('除數不能為0') as e:
						print(e)
						return 0


		自定義異常

			系統定義的異常不可能覆蓋全部情況,
			可自己定義,可繼承系統異常

				創建類,繼承相應系統異常即可


	練習:
		1.編寫一個計算減法的方法,當第一個數小於第二個數時,拋出“被減數不能小於減數”的異常
		2.編寫一個計算加法的方法,接收鍵盤輸入的兩個數字,進行加法運算,當輸入的有非數字時,通過異常處理機制使程序正常運行(返回0)
		3.創建一個用戶注冊服務,其中有一個register方法。當用戶名小於6位時,拋出自定義異常
		  系統異常NameError的子類異常UserNameError

----------------------------------16、模塊-------------------------------------------------------------------------------------

	在Python中,一個文件就稱之為一個模塊(Module)
		可以作為module的文件類型有: ".py"、".pyo"、".pyc"、".pyd"、".so"、".dll"

	導入--使用其他模塊中的代碼

		如何導入?
		
			最基本的:import xxx

			


			
			導入xxx模塊后,我們就有了變量xxx指向該模塊,利用這個變量,就可以訪問xxx模塊的所有功能



		導入的作用?

			導入的模塊是用於定義的--定義類、變量、函數

			首次導入會運行模塊中的代碼

			*如果有導入時不希望執行的代碼,可以放在if __name__ == '__main__'條件語句下

			*再次導入不會運行。除非使用reload(模塊名)函數

		導入的幾種情況

			*導入文件

				import student   #python文件不用寫.py

				使用文件中的類、方法
					student.Student()
					student.Student().成員變量和成員方法
					student.Student.類變量和類方法
					student.sum()

			*導入類、導入方法

				即:從文件中導入類、方法

				from student import Student
				from student import sum
				from student import Student, sum

				使用類、方法
					Student()
					Student().成員變量和成員方法
					Student.類變量和類方法
					sum()

				*重名的情況
				from student import Student, sum
				from huice import sum

			*涉及包時的導入

				*什么是包?
					將多個.py文件組織起來,以便在外部統一調用
					
					包含__init__.py文件的文件夾

						__init__.py: 包的初始化文件。當包或包下的內容(子包、文件、文件中的類/方法/變量被加載時,
						會執行該文件中的代碼

					不包含__init__.py的,是普通文件夾,其中的內容不能被導入

					包可以嵌套多層

					完整的模塊名 = 包名.子包名.模塊名

				*從包中的文件中導入類、方法
					from day111.day1111.student import Student,ordinary_method

					from 完整模塊名 import 類名,方法名

				*從包中導入文件
					from day111.day1111 import student

					from 完整包名 import 模塊名 

				*從包中導入子包
					from day111 import day1111
					from selenium import webdriver

					意義:如果包中的__init__.py中導入了其他文件中的類、方法,則可以直接使用"包名."的方式
					使用這些類


		解釋器如何找到的模塊?

			1.首先在當前目錄查找 

			2.當前腳本指定的sys.path   --python搜索模塊的路徑集合
				可以在python 環境下使用sys.path.append(path)添加相關的路徑,但在退出python環境后自己添加的路徑就會自動消失
			
			3.環境變量 --PYTHONPATH
			4.安裝設置相關的默認路徑
				built-in --內建模塊
				'''C:\Python27\Lib --所有python類庫的總目錄'''
					標准庫模塊
						email、json、csv、httplib、io....
					site-packages --第三方包(包括自定義)

			5.在任一步驟,找到名稱符合的就停止,不再繼續尋找

			如果我們要引入自定義的模塊:
				0.在一個目錄中直接import名稱

				1.添加自己的搜索目錄,有三種方法:
					第一種是直接修改sys.path,添加要搜索的目錄:
						import sys
						sys.path.append('/Users/my_py_scripts')
						但在退出python環境后自己添加的路徑就會自動消失
					第二種方法是設置環境變量PYTHONPATH
					第三種方法是將包放到python安裝目錄的Lib下或sitepackage下(不推薦)

		關於from A import *的坑
			
			__all__ = ['module_13', 'module_12']

		使用別名
			import xxx as X
				應用:統一變量名
	
    				例:
						try:
	    					import json  python >= 2.65
						except ImportError:
	    					import simplejson as json  python <= 2.5
 

 		練習:新創建一個子包 sub
 			sub中有一個模塊:util.py 其中有一個工具類:Util,有一個靜態方法求兩數之和;一個類方法求兩數之積	
 			如果單獨運行該文件,顯示說明文字
 			在當前包下的demo.py文件中調用這些方法	


----------------------------------17、常用標准庫-------------------------------------------------------------------------------------

	os --對目錄或文件操作

		變量
			os.environ --以字典形式返回系統環境變量

		函數
			os.system(command) --執行命令行(運行外部程序),不能存儲結果
			os.startfile(path) --windows特有,模擬雙擊打開文件
							     mac/linux-- subprocess.Popen(path)
			**os.popen(command)  --執行命令行,並返回一個文件對象
			os.getpid()	    --返回當前進程ID

			操作目錄(文件夾):
				os.getcwd()	        --得到當前工作的目錄
				os.listdir()        --指定目錄下所有的文件和目錄名
				os.mkdir()          --創建目錄,已存在報錯
				os.makedirs()		--創建多級目錄 
				os.rmdir()		    --刪除指定目錄,只能是空目錄(不能有文件或子目錄)
				os.removdirs()		--刪除多級目錄,只能是空目錄
				os.chdir()          --改變目錄到指定目錄
				os.path.isfile()    --判斷指定對象是否為文件。是返回True,否則False
				os.path.isdir()     --判斷指定對象是否為目錄。是True,否則False
				os.path.exists()    --檢驗指定的對象(文件)是否存在
				os.path.split()     --返回路徑的目錄和文件名
				os.path.join(path, name)  --連接目錄和文件名
				os.path.dirname(path)     --返回path中的文件夾部分
				os.path.basename(path)    --返回文件名
				os.path.abspath(path)     --獲得絕對路徑
				

				練習:
					report文件夾中,是所有自動化測試報告的存放路徑。
						編寫new_report函數,傳入路徑。返回最新一份報告的文件名(完整路徑+文件名)
							 1.報告以時間戳命名
							*2.報告不以時間戳命名

			操作文件:
					os.path.getmtime(path)  --文件或文件夾的最后修改時間,從新紀元到訪問時的秒數
					os.path.getctime(path)  --輸出文件最近訪問時間
					os.path.getsize(path)   --文件或文件夾的大小,若是文件夾返回0
					os.remove(path)		    --移除文件	
					os.rename(old, new)	    --重命名文件或目錄	
					os.chown(path, uid, gid)	--改變文件或目錄所有者	   
					os.chmod(path, mode)	--改變文件訪問權限	
											os.chmod('/home/user/c/a.tar.gz', 0777)

	shutil --高級的 文件、文件夾、壓縮包 處理模塊
		
		shutil.copyfile(src, dst)  --拷貝文件,如果當前的dst已存在的話就會被覆蓋掉
		shutil.copy(src, dst)      --拷貝文件和權限
		shutil.copytree(src, dst)  --遞歸地拷貝文件
		shutil.rmtree(src) 		   --遞歸刪除一個目錄以及目錄內的所有內容

	time  --提供了各種操作時間值

		time.time()  獲取當前時間時間戳--秒
		time.ctime(seconds)	根據秒數取時間戳--美式時間格式
		time.asctime([tuple]) 根據時間元組,獲取時間戳--美式時間格式
		time.localtime(seconds)  將秒數轉換成一個時間值元祖
		time.mktime(tuple)	將一個時間值元組轉換成秒數
		time.sleep(seconds)	延遲執行給定的秒數
		*time.strftime(format[,tuple_time])
		    根據傳入的格式化字符串,將tuple時間格式化為指定的格式
			tuple_time可以不傳,不傳返回當前時間格式化后的結果
			  python中時間日期格式化符號:
				 %y     兩位數的年份表示(00-99)
				 %Y     四位數的年份表示(000-9999)
				 %m     月份(01-12)
				 %d     月內中的一天(0-31)
				 %H     24小時制小時數(0-23)
				 %I     12小時制小時數(01-12) 
				 %M     分鍾數(00=59)
				 %S     秒(00-59)

			應用:獲取當前時間字符串:time.strftime('%Y-%m-%d %H:%M:%S')

		time.strptime(string, format)
				 傳入的時間為字符串
				 按照傳入的format解析字符串時間為tuple格式的時間

	random  --生成隨機數

		random.uniform(a,b)  返回a和b范圍內的隨機實數 [a,b)
		random.randint(a,b)	返回整數a和b范圍內數字  [a,b]
		random.random()	返回隨機數,它在0和1范圍內(不包括1)
		random.randrange(start, stop[, step])	返回整數范圍的隨機數
		random.sample(seq, x)	從序列或set、dict中返回隨機x個元素(若為字典只返回key) - -列表形式
		random.shuffle(list)   給指定的列表進行原地隨機移位
		random.choice(seq) 從序列seq中隨機選擇一個元素

	練習:
		0.編寫一個方法,輸出當前時間三天前的時間點,格式:2017-05-01_13:59:06 
		1.編寫一個方法,根據傳入的美式時間字符串(13:28:06_12/21/2018),生成標准時間字符串(2018-12-21_13:28:06)

	作業:
		1.編寫一個方法,接受參數為一個列表:[2017, 01, 15] (不考慮1970.1.1之前的時間點)
		  隨機輸出2017.1.15日 00:00:00 之前的一個時間點,格式為:2017-01-01_13:59:06		  
		2.用python腳本,寫一個斗地主的發牌程序
		  3個人每人17張,三張底牌歸地主所有
		  要求:函數返回一個字典,{地主:[], 農民1:[], 農民2:[]}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM