目录
Day 15-18
一、安装VSCode、Python
- Python 3.6
- 安装完成后,在VSCode的扩展中安装Python、Python Extended、Python Extended Pack、Git Graph。
- 在工作区新建一个工作区,再新建一个文件夹(New Folder),创建一个文件(f1.py)。
- Ctrl + Shift + P 查找settings.json;
在settings.json文件中加入一行,使vscode自动补全。
“python.autoComplete.addBrackets”:true,
二、Python
- f1.py
输出Hello World!
print('Hello World!')
1、运算符和注释
- f2.py
"""
Python算术运算符
+ 加
- 减
* 乘
/ 除
% 取模 - 返回除法的余数
** 幂 - 返回除法的余数
// 取整除 - 向下取接近商的整数
"""
print(10/3) # 除法
print(2**3) # 幂次方
print('ab'+'cd') # 字符串相加
print('ab'*4) # 字符串和数字相乘
# Python比较运算符
# == != > < >= <=
print(100>33) # 比较运算符,布尔类型首字母大写
# Python逻辑运算符
# and or not 为python中的与、或、非
print(2 < 4 and 2 == 4)
print(2 > 4 or 2 < 4)
print(not 6.2 <= 6)
print(3 < 4 < 5)
'''
Python赋值运算符
= 简单的赋值运算符
可以连续赋值,配对赋值
+= -= *= /= %= **= //= 算数运算符+赋值运算符
:= 海象运算符:可在表达式内部为变量赋值
'''
i=j=5
k,t=6,7
print(i,j,k)
# 在这个示例中,赋值表达式可以避免调用 len() 两次:
if (n := len(a)) > 10:
print(f"List is too long ({n} elements, expected <= 10)")
'''
Python成员运算符
in 如果在指定的序列中找到值返回 True,否则返回 False。
not in 如果在指定的序列中没有找到值返回 True,否则返回 False。
'''
'''
Python位运算符
按位运算符是把数字看作二进制来进行计算的。
& 按位与
| 按位或
^ 按位异或
~ 按位取反
<< 左移动运算符:由"<<"右边的数指定移动的位数,高位丢弃,低位补0。
>> 右移动运算符
'''
'''
Python身份运算符
身份运算符用于比较两个对象的存储单元,即实际上比较的是地址
is 判断两个标识符是不是引用自一个对象
is not 判断两个标识符是不是引用自不同对象
'''
Python 单行注释用 # ,多行(块)注释用三个单引号 ‘’’ 或者三个双引号 “”" 将注释括起来;
VSCode快速注释
行注释:鼠标所在行 Ctrl + /
块注释:选中区域 Alt + Shift + A
- Python中运算符的优先级
运算符 | 描述 |
---|---|
** | 指数 (最高优先级) |
~ + - | 按位翻转, 一元加号和减号 (最后两个的方法名为 +@ 和 -@) |
* / % // | 乘,除,求余数和取整除 |
+ - | 加法减法 |
>> << | 右移,左移运算符 |
& | 位 ‘AND’ |
^ 丨 | 位运算符 |
<= < > >= | 比较运算符 |
== != | 等于运算符 |
= %= /= //= -= += *= **= | 赋值运算符 |
is is not | 身份运算符 |
in not in | 成员运算符 |
not and or | 逻辑运算符 |
2、变量
- f3.py
i=100
print(id(i)) # id函数查看变量i的地址
i=i+1
print(id(i)) # 变量i的地址改变了
j=100
print(id(j))
# 在python中,栈不存放数据,只保存变量地址,而地址指向的是对象。
def abc():
print('hello')
i=abc
j=abc
print(id(i))
print(id(j)) # 两次结果相同
def bcd():
print('hello')
i=bcd
print(id(i)) # 结果与上面的不同,两个函数内容相同,地址不同
shell中所有变量只能保存字符串
变量保存的是地址,而地址指向的内容可以是任何类型
-128~127为常用数据,垃圾回收器不删除
Python中变量保存的也是地址,地址指向的是“对象”
python中都是对象:变量值、函数定义、类定义以及传统对象等
python语言在运算任何语句之前首先要进行寻址,寻址行为耗时
3、条件语句
if i>10:
print('i > 10')
elif i>5:
print('i > 5')
else:
print('i <= 5')
依靠缩进分离代码结构
4、循环语句
- 1-100累加
s,j=0,1
while i<100:
s+=i
i+=1
print(s)
- while循环计算前十个斐波那切数列
n=0
f1,f2=1,1
while n <10:
print(f1,f2,sep=' ',end=' ')
f1+=f2
f2+=f1
n+=2
- while循环计算所有小于60的斐波那切数
f1,f2=1,1
while f1 <60:
print(f1,end=' ')
f1,f2=f2,f1+f2
- for循环
# 1-100求和
for i in range(101):
s+=i
print(s)
# 打印水仙花数
for i in range(101,1000):
a=i//100
b=(i//10)%10
c=i%10
if i == a**3+b**3+c**3:
print(i,end=' ')
#
for name in ['张三','李四','王五','赵六']:
print(name,end=',')
# 用三元表达式打印水仙花数
for abc in range(100,1000):
a,b,c=abc//100,abc//10%10,abc%10
print(abc) if abc==a**3+b**3+c**3 else ''
range()函数用法:
range(10) 0~9
range(1,10) 1~9
range(0,10,2) 0、2、4、8
5、字符串
s='a\tb'
print(s) # 打印结果为a b
# 用 \ 使单个转义符失效
s='a\\ab'
print(s) # 打印结果为 a\ab
s=r'\n"'
print(s)
'''
r使字符串中的转义失效,除了左右两个单引号,打印结果为\n"
如果内容有单引号,就用双引号括起来
如果内容有双引号,就用单引号括起来
如果内容既有单引号,也有双引号,就用三个单/双引号括起来
'''
s=r"""`"\n```"""
h='hello'
print(h[1]) # e 字符串切片
print(h[0:2]) # he
print(h[2:]) # llo
print(h[:4]) # hell
print(h[0:6:2]) # hlo
print(h[1,-1]) # ell
print(h[-2:]) # lo
# input()函数接收语句实现人机交互,得到的为字符串
s=input('请输入一个整数')
print(s)
# 二进制数转换为十进制数-从左向右
b=input('请输入一个二进制数:')
le=len(b)
s=0
for i in range(le):
c,n=b[i],le-i-1
s+=(2**n)*int(c)
print(s)
# 二进制数转换为十进制数-从右向左
b=input('请输入一个二进制数:')
le=len(b)
s=0
for i in range(le):
c=b[-i-1]
s+=(2**i)*int(c)
print(s)
- enumerate()函数:得到的是[下标,字母]构成的两列数据
# 二进制数转换为十进制数
b=input('请输入一个二进制数:')
le=len(b)
for i,c in enumerate(b):
s+=(2**(b-i))*c
print(s)
- append()往数组中增加元素,pop()将数组中的元素删除
# 计算网络地址
ip = '192.168.33.4'
mask = '255.255.254.0'
nets=[]
for a,b in zip(ip.split('.'),mask.split('.')):
nets.append(str(int(a)&int(b)))
print('.'.join(nets))
# 人机交互(给ip地址和子网掩码)实现计算广播地址
ip = input('请输入ip地址:')
mask = input('请输入子网掩码:')
nets = []
noMask = []
boradcast = []
for a,b in zip(ip.split('.'),mask.split('.')):
nets.append(str(int(a)&int(b)))
noMask.append(str(int(b) & 0b00000000))
print('.'.join(nets))
print('.'.join(noMask))
for a,b in zip(nets,noMask):
boradcast.append(str(int(a)|int(b)))
print('.'.join(boradcast))
理论:
任何数字和全0相与结果全0,和全1相与结果保持不变;
任何数字和全0相或结果保持不变,和全1相或结果全0。
ip地址和子网掩码相与,结果为网络地址;
【网络地址和(子网掩码的反)相或】结果为广播地址。
6、列表
Python中没有数组,列表是栈中存放头结点的地址,头结点中有指向0号元素的地址和指向下一个节点的地址,以此类推。
Python中的4大容器:列表list、元组tuple、集合set、字典dict
ar=['hello','world','ok',100]
ar1=ar[1:3]
print(ar1)
ip='192.168.33.4'
ar2=split('.')
print(ar2)
ar3=['ab','cd','ef','hi','jk']
print(':'.join(ar3)) # ab:cd:ed:hi:jk
# 用ar3中的元素组装出 ab:ef:jk
print(':'.join(ar3[::2]))
# 列表可嵌套
ar4=[1,2,3]
ar5=['a','b','c']
ar6=['hello',ar4,5,ar5,'world']
print(ar6[0])
print(ar6[1][2])
# enumerate函数,返回下标和对应元素
names=['张三','李四','王五']
for i,name in enumerate(names):
print('我是第'+str(i+1)+'名学生,我叫'+name)
#zip函数
names,fruits=['张三','李四','王五'],['苹果','菠萝','樱桃']
for name,fruit in zip(names,fruits):
print(name+'喜欢吃'+fruit)
# list()函数:实际上是数列的构造器
lst=list('abc')
print(lst) #['a','b','c']
# append()函数意为追加,所以参数是待追加的元素
lst.append('d')
print(lst) #['a','b','c','d']
# insert()函数的参数是(下标,待插入元素)
lst.insert(1,'e')
print(lst) #['a','e','b','c','d']
# remove()函数的参数是删除的对象,不是下标
# 删除的是从左向右找到的第一个元素
lst.remove('d')
print(lst) #['a','e',,'b','c']
# pop()函数的参数是下标,不加参数则默认删除最后一个元素,pop()函数还会返回被删除的元素
print(lis.pop(1))
print(lst) #['a','b','c']
- 打印1-5的平方
lst=[1,2,3,4,5]
ret=[]
for u in lst:
ret.append(u**2)
print(ret)
# 用列表表达式实现
lst=[1,2,3,4,5]
ret=[u**2 for u in lst]
print(ret)
- 打印0-10中偶数的平方
# 一般方法
lst=[]
for i in range(0,11):
lst.append(i)
print(lst)
ret1=[]
for u in lst:
if u%2==0:
ret1.append(u**2)
print(ret1)
# 用列表表达式实现
ret2=[u**2 for u in range(11) if u%2==0]
print(ret2)
- 笛卡尔积(双重循环),列表表达式实现
ret=[i*j for j in range(5) for i in range(10) if i%2==1]
print(ret)
# 等价于
ret=[]
for j in range(5):
for i in range(10):
if i%2==1:
ret.append(i*j)
print(ret)
# 字符串格式化
i,j=3,5
print('%d*%d=%d'%(i,j,i*j))
# 乘法口诀
multi=['%d*%d=%d'%(i,j,i*j) for j in range(1,10) for i in range(1,j+1)]
print(multi)
7、元组
- 元组中的内容一旦创建出来就不能修改
- 只需要将数列的[]换成tuple()就可以做元组的操作
# tuple()即为构造函数,可以将list转换为tuple。
a=list('hello')
t=tuple('world')
print(a)
print(t)
# 元组也可以用切片,类型不变
print(t[2:4])
元组的优点是速度快,缺点是不可改
函数返回的多值就是元组
- 可以给多变量赋值,但左右必须数量上相等
def abc():
return 10,20
ret=abc()
print(ret)
a,b=ret
print(a,b)
i,j=[100,200]
print(i,j)
8、集合
- 集合中的元素无序、不重复;集合不允许通过下标访问
# 生成0-99之间的十个不重复随机数
import random
s=set() # set()为集合的构造函数,也可以用 {} 直接构造
print(s)
while True:
if len(s)==10:
break
s.add(random.randint(0,100)) # 添加方法为add(),参数是待添加元素
# 添加重复数字不会报错,
print(s)
# pop()可以随机弹出元素,无参
# remove()删除指定元素,参数为指定要删除的元素,如果待删除元素不存在会报错
9、字典
- dict(),键值对,java中的map图。
# 构造
dt={'张三':'苹果','李四':'梨子'}
# 增加
dt['王五']='樱桃'
# 修改:key也就是键(下标)是不会重复的,因为所有的键存放在一个set集合中,而集合不支持重复数据
dt['张三']='菠萝'
# 打印方法1
for k,v in dt.items():
print('%s<----->%s'%(k,v))
# 打印方法2
for key in dt.keys():
print('%s<----->%s'%(key,dt[key]))
- 现在有一段文字:‘ahtjfqwejyjgfdwetyrjfAGRHARHSAFEN’,请统计出每个字母出现的次数,要求打印格式:…出现…次
a = 'ahtjfqwejyjgfdwetyrjfAGRHARHSAFEN'
dt = dict()
for c in a:
dt[c]=dt[c]+1 if c in dt.keys() else 1
for k,v in dt.items():
print('%s出现%s次'%(k,v))
- 现有一段文字:abc def ab ac abc ddef cd cd ef ab
请统计每个单词出现的次数
s='abc def ab ac abc ab def cd cd ef ab'
dt=dict()
for a in s.split(' '):
dt[a]=dt[a]+1 if a in dt.keys() else 1
[print('%s出现%s次'%(k,v)) for k,v in dt.items()]
- 容器不可以作为key
10、execl
- terminal终端中安装openpyxl
pip install openpyxl
- 先创建一个execl文件用于测试
from openpyxl.reader.excel import load_workbook
wb = load_workbook(r'绝对路径\test.xlsx')
ws = wb.worksheets[0]
row1=[item.value for item in list(ws.rows)[0]]
print('第一行值',row1)
col1=[item.value for item in list(ws.columns)[0] if item.value is not None]
print('第1列值',col1)
cell_2_2=ws.cell(row=2,column=2).value
print('第2行第2列值',cell_2_2)
max_row=ws.max_row
print('最大行',max_row)
11、简单加密
- 字母和ascii相互转换
# 字母转ascii
ord('a')
# ascii转字母
chr(97)
- 范例1
st='hello world'
ret=''
# 加密
for s in st:
ret=ret+chr(ord(s)+10)
print(ret)
# 解密
ret1=''
for s in ret:
ret1=ret1+chr(ord(s)-10)
print(ret1)
- 优化
st='hello world'
ln=len(st)
ret=''
# 加密
for i,s in enumerate(st):
ret=ret+chr(ord(s)+ln-i)
print(ret)
# 解密
ret1=''
for i,s in enumerate(ret):
ret1=ret1+chr(ord(s)-(ln-i))
print(ret1)
12、排序
- 冒泡排序
import random
lst=[random.randint(0,100) for i in range(10)]
print(lst)
ln=len(lst)
for i in range(0,ln-1):
for j in range(0,ln-i-1):
if lst[j]>lst[j+1]:
lst[j],lst[j+1]=lst[j+1],lst[j]
print(lst)
- 选择排序
import random
lst=[random.randint(0,100) for i in range(10)]
print(lst)
ret=list()
for j in range(len(lst)):
idx=lst.index(min(lst))
ret.append(lst.pop(idx))
print(ret)
- 插入排序
def insert_sort(list):
count = len(list)
for i in range(1, count):
key = list[i]
j = i - 1
while j >= 0:
if list[j] > key:
list[j + 1] = list[j]
list[j] = key
j -= 1
return list
13、函数
- 格式
def 函数名(参数):
···
return 参数
- 范例
dt={'张三':33,'李四':28,'王五':19}
dt1={'赵晓梅':35,'李华':44,'周军':27}
def getMax(dct):
mx,nm=None,''
for k,v in dct.items():
if mx is None:
mx,nm=v,k
elif v>mx:
mx,nm=v,k
return '%s的年龄最大:%d'%(nm,mx)
print(getMax(dt))
- 只有将容器传入函数内部进行修改,外部才会一起改变
- 如果仅仅传递常规数据进入函数,函数修改后外部是不会改变的
- 形参用逗号间隔,标签赋值方式可以实现错位赋值
def cal(a,b):
print(a,b)
cal(b=20,a=10)
- 默认参数
def cal(a,b=100):
print(a,b)
cal(10)
cal(10,50)
- 可变长参数:单个*
def cal(a,b=100,*c)
print(a,b)
print('c',end=':')
print(c)
cal(1,2,3,4,5,6,7,8,9)
def cal1(a,b,*c)
s=0
s=a+b
for i in c:
s+=i
print(s)
cal1(1,2,3,4,5,6,7,8,9)
- 可变长参数:两个*,表示字典
- 返回值:可以返回多个值
def cal(a,b,*c)
s=0
s=a+b
for i in c:
s+=i
return 100,s
ret=cal(1,2,3,4,5,6,7,8,9)
print('ret',end=':')
print(ret)
# 也可以这样
a,b=cal(1,2,3,4,5,6,7,8,9)
print(a,b)
- 编写一个函数randLowChr生成一个随机的小写字母
编写一个函数randHighChr生成一个随机的大写字母
再利用上面的两个函数编写一个函数randChr随机生成一个大写/小写字母
import random
def randLowChr():
return chr(random.randint(97,122))
def randHighChr():
return chr(random.randint(65,90))
def randChr():
return randLowChr() if random.randint(0,1)==0 else randHighChr()
print(randChr())
- 在一定随机范围内生成ip地址
def randIp(ip,dlt):
dt=random.randint(0,dlt)
return ipAdd(ip,dt)
def ipAdd(ip,dlt=1):
ret=[]
for u in ip.split('.')[::-1]:
r=int(u)+dlt
y=r%256
dlt=r//256
ret.insert(0,str(y))
return '.'join(ret)
- 根据子网掩码和已有的ip地址,随机生成一个ip地址
def randIp(ip,mask):
dlt=0
m=[]
for a,b in zip(ip.split('.'),mask[0].split('.')):
m.append(str(int(a)|int(b)))
print(m)
i=0
for j in m[::-1]:
dlt=(256**i)*(255-int(j))+dlt
i=i+1
dt=random.randint(0,dlt)
return ipAdd(ip,dt)
- 函数递归
# 累加求和
def getSum(s,i):
if i==0:
return s
else
return getSum(s+i,i+1)
# 返回第N个斐波那契数和创建函数实例的次数
def Fibr(a,b,n,times):
times+=1
if n==1:
return a,times
return Fibr(b,a+b,n-1,times)
# 通过传引用实现上面的函数
def fibr(n,times):
times[0]+=1
if n==1 or n==2:
return 1
else:
return fibr(n-1,times)+fibr(n-2,times)
- 高阶函数
def a(b):
print('This is a')
b()
def c():
print('This is c')
def d(e):
print('This is d')
return e
a(c)
- 函数表达式、内置函数
# 匿名函数 lambda
ret=lambda i,j:i**2+j**2
print(ret(1,2))
lst=[i for i in range(10)]
ret=map(lambda i:i**2,lst)
# 生成两个随机数列表并用map求和
# map() 会根据提供的函数对指定序列做映射
import random
lst1=[random.randint(1,100) for i in range(10)]
lst2=[random.randint(1,100) for i in range(10)]
ret=map(lambda x,y:x+y,lst1,lst2)
print(list(ret))
# reduce(function, iterable[, initializer])
# reduce() 函数会对参数序列中元素进行累积
# 自 Python3 之后,这个函数从全局命名空间中移除,放在了 functools
import random
from functools import reduce
lst=[random.randint(0,100) for i in range(10)]
ret=reduce(lambda x, y: x+y, lst))
# 生成斐波那切数列
import random
from functools import reduce
n=10
ret=reduce(lambda x,_:x+[x[-1]+x[-2]],range(n-2),[1,1])
print(ret)
# 偏函数 - 固化参数
from functools import partial
basefrom2 = partial(int,base=2)
x= basefrom2('10010')
print(x)
14、迭代
- 迭代器
lst = [1,2,3,4,5]
i=iter(lst)
print(i.__next__())
print(next(i))
# 迭代器对象可以使用常规for语句进行遍历
for it in i:
print(it)
- 生成器
def abc():
for i in range(10):
yield i
# 此时abc()可迭代
for x in abc():
print(x)
# 构建函数getX2(lst),lst为整数数列
#函数迭代出整数数列的平方
def getX2(lst):
for i in lst:
yield i**2
1、yield和return的区别在于yield只是暂时离开函数,而return是永久离开,并宣告函数死亡
2、使用yield的函数变成了可迭代元素,可以被in驱动或被iter监控
15、类和对象
- 自定义图纸,把这个图纸称为类;而用这个图纸实例化的内容称为对象。
- 刻画自定义图纸的时候一般需要描述未来的实例拥有哪些特征(属性)以及未来的实例能做什么(行为)
class Human:
name=''
age=0
def introduce(self):
print(self.name,self.age)
h1=Human()
h1.name,h1.age='张三',19
h1.introduce()
- 用类的结构实现一个单向链表
class MyNode:
data,point=None,None
def setData(self,d):
self.data=d
def setPoint(self,p):
self.point=p
class chain:
head=None
def getLast(self):
cur=self.head
if cur is None:
return None
while cur.point is not None:
cur=cur.point
return cur
def append(self,nd):
if self.getLast() is None:
head=nd
else:
self.getLast().setPoint(nd)
三、作业
1、根据ip地址得到广播地址
ip = input('请输入ip地址:')
mask = input('请输入子网掩码:')
nets = []
noMask = []
boradcast = []
for a,b in zip(ip.split('.'),mask.split('.')):
nets.append(str(int(a)&int(b)))
noMask.append(str(int(b) & 0b00000000))
print('.'.join(nets))
print('.'.join(noMask))
for a,b in zip(nets,noMask):
boradcast.append(str(int(a)|int(b)))
print('.'.join(boradcast))
2、实现扫雷两个地图初始化
import random
# 十个不重复的随机数
s=set()
while len(s)<=30:
s.add(random.randint(1,100))
print(s)
print('')
# 构建地雷地图
map1=[[] for i in range(10)]
for i in range(len(map1)):
for j in range(10):
if int(i*10+j+1) in s:
map1[i].append(1)
else:
map1[i].append(0)
# 打印地雷地图
for i in range(len(map1)):
for j in range(len(map1[i])):
print(map1[i][j],end=' ')
print('')
print('')
'''
构建提示地图
1、初始化为0
2、修改提示数字
3、修改地雷数字为*
'''
# 1
map2=[[] for i in range(10)]
for i in range(10):
for j in range(10):
map2[i].append(0)
# 2
for t in s:
ps=[t-11,t-10,t-9,t-1,t+1,t+9,t+10,t+11]
ti=(t-1)//10
tj=(t-1)%10
for p in ps:
if p<0 or p>100:
continue
if tj==0 and (p==t-11 or p==t-1 or p==t+9):
continue
if tj==9 and (p==t-9 or p==t+1 or p==t+11):
continue
pi=(p-1)//10
pj=(p-1)%10
if pi<0 or pj<0 or pi>9 or pj>9:
continue
else:
map2[pi][pj]=1+map2[pi][pj]
# 3
for t in s:
ti=(t-1)//10
tj=(t-1)%10
map2[ti][tj]='*'
# 打印提示地图
for i in range(len(map2)):
for j in range(len(map2[i])):
print(map2[i][j],end=' ')
print('')
print('')
# 人机交互方式选择位置
print('输入坐标,不合法位置退出')
while True:
x=int(input('请输入横坐标')) # 1-10
y=int(input('请输入纵坐标')) # 1-10
if x<0 or x>10 or y<0 or y>10:
break
t=(x-1)*10+y
ti=(t-1)//10
tj=(t-1)%10
if t in s:
print('这是一颗雷')
else:
print('这个位置周围有'+str(map2[ti][tj])+'颗雷')
3、函数编程
# 十进制转二进制 - 辗转相除法 - 参数是十进制数字
def d2b(n):
b = [] # 存储余数
while True: # 一直循环,商为0时利用break退出循环
s = n // 2 # 商
y = n % 2 # 余数
b.append(y) # 每一个余数存储到b中
if s == 0:
break # 余数为0时结束循环
n = s
b.reverse() # 使b中的元素反向排列
b=[str(i) for i in b]
return ''.join(b)
# 二进制转十进制 - 参数为二进制字符串,不带0b前缀
def b2d(b):
le=len(b)
s=0
for i in range(le):
c,n=b[i],le-i-1
s+=(2**n)*int(c)
return s
# 根据ip和掩码计算网络号
def getNetId(ip,mask):
nets = []
for a,b in zip(ip.split('.'),mask.split('.')):
nets.append(str(int(a)&int(b)))
return '.'.join(nets)
# 根据ip和掩码计算广播号
def getBroadId(ip,mask):
nets = []
rMask = []
boradcast = []
for a,b in zip(ip.split('.'),mask.split('.')):
nets.append(str(int(a)&int(b)))
rMask.append(str(255 - int(b)))
for a,b in zip(nets,rMask):
boradcast.append(str(int(a)|int(b)))
return '.'.join(boradcast)
# 将掩码反转,正掩码转反掩码或者反掩码转正掩码
def reverseMask(mask):
rMask = []
for a in mask.split('.'):
rMask.append(str(255 - int(a)))
return '.'.join(rMask)
# 将ip地址加上增量
def ipAdd(ip,dlt=1):
ret=[]
for u in ip.split('.')[::-1]:
r=int(u)+dlt
y=r%256
dlt=r//256
ret.insert(0,str(y))
return '.'.join(ret)
# 将掩码转变为长度格式
def mask2len(mask):
ln=0
for i in mask.split('.'):
for j in d2b(int(i)): # 这里用到了上面的十进制转二进制
if int(j)==1:
ln=ln+1
return ln
# 将长度转变为掩码格式 - IPv4
def len2mask(ln):
mask=''
if ln<0 or ln>32:
return '非法输入'
for i in range(1,32):
if i<ln:
mask=mask+'1'
else:
mask=mask+'0'
if i%8==0:
mask=mask+'.'
return mask
# 指定ip和增量获得随机范围内的ip地址
# 或者指定ip和掩码获得范围内的随机ip地址
import random
def randIp(ip,dlt,*mask):
if len(mask)==1:
dlt=0
m=[]
for a,b in zip(ip.split('.'),mask[0].split('.')):
m.append(str(int(a)|int(b)))
print(m)
i=0
for j in m[::-1]:
dlt=(256**i)*(255-int(j))+dlt
i=i+1
print(i,dlt)
dt=random.randint(0,dlt)
return ipAdd(ip,dt)
# 指定起始地址以及步长,数量
# 返回指定数量的ip地址列表
def getIpList(ip,dlt,num):
lst=[]
for i in range(1,num):
lst.append(ipAdd(ip,dlt*i))
return lst
# 参数ip,网络号,掩码,判断ip是否在网络号和掩码指定的子网中
# 返回True或False
def ipInRange(ip,net,mask):
net1=[]
for a,b in zip(ip.split('.'),mask.split('.')):
net1.append(str(int(a)&int(b)))
if '.'.join(net1)==net:
return True
else:
return False
4、链表类
class MyNode:
data,point=None,None
def setData(self,d):
self.data=d
return self
def setPoint(self,p):
self.point=p
return self
class myChain:
head=None
def getLast(self):
cur=self.head
if cur is None:
return None
while cur.point is not None:
cur=cur.point
return cur
def appendC(self,nd):
if self.getLast() is None:
self.head=nd
else:
self.getLast().setPoint(nd)
def exeistNd(self,dt):
cur=self.head
if cur is None:
return False
while cur is not None:
if cur.data==dt:
return True
cur=cur.point
return False
class MyString:
myStr=None
# 追加字符串
def append(self,s):
if self.myStr is None:
self.myStr=myChain()
n1=MyNode()
n1.setData(s)
self.myStr.appendC(n1)
# 返回完整字符
def result(self):
str1=''
cur=self.myStr.head
if cur is None:
return 'myStr is none'
while cur is not None:
str1=str1+cur.data
cur=cur.point
return str1
# 删除一个片段 - 我的方法是破坏链表结构,重新创建链表
def remove(self,s):
str1=self.result()
if s in str1:
str1=str1.replace(s,'')
self.myStr.head=MyNode().setData(str1)
return True
return False
str1=MyString()
str1.append('123')
print(str1.result())
str1.append('456')
print(str1.result())
str1.append('789')
print(str1.result())
if str1.remove('567'):
print('remove 789 successful:',str1.result())