目录
- 前言
- 1.进制转换
- 2.字符串加密的实现
- 3.猜拳游戏
- 4.多种方法计算π
- 尾语 💝
前言
嗨喽~大家好呀,这里是魔王呐 ❤ ~!
1.进制转换
功能:
获取十进制整数的二进制串,相当于内置函数bin。
算法分析:
-
对2辗转相除,直到商为0
-
每次所得余数逆序即可
流程图绘制
测试驱动,书写测试用例:
>>> convert(13)
'1101'
>>> convert(1)
'1'
>>> convert(0)
'0'
>>> convert(67)
'1000011'
>>> convert(15)
'1111'
代码实现:
def convert(n):
"""
添加上述测试用例
"""
s = ""
while n != 0:
r = n % 2
s = str(r) + s
n //= 2
return s
if __name__ == "__main__":
import doctest
doctest.testmod(verbose=True)
运行上述测试,可以看到0的二进制串没通过测试,
原因是s默认为空串,因而传入0时得到的将是空串。
我们可以在返回值时,使用三元运算符处理即可,return s if s != “” else “0”
。
扩展:十进制转任意进制
-
进制:变化的是数码和基数
-
基数我们可以通过参数传入来解决
-
数码我们可以通过定义码元串来完成,然后通过索引访问即可
代码实现:
def convert(num, base):
"""
>>> convert(13, 2)
'1101'
>>> convert(23, 16)
'17'
>>> convert(23, 8)
'27'
>>> convert(30, 16)
'1E'
"""
codes = "0123456789ABCDEF"
s = ""
while num != 0:
r = num % base
s = codes[r] + s
num //= base
return s if s != "" else "0"
if __name__ == "__main__":
import doctest
doctest.testmod(verbose=True)
2.字符串加密的实现
功能:
对英文串进行加密,规则英文字母循环右移n位,不失一般性,此处n设为3
算法分析:
-
chr,根据ASCII码获取字符;
-
ord,获取字母的ASCII码
循环右移,即越界翻转,z完后再到a,即(ord(ch) + 3 - 0x61) % 26 + 0x61
。
流程图绘制
测试先行:
>>> encrypt("abc")
'def'
>>> encrypt("xyz")
'abc'
>>> encrypt("Abc")
'Def'
>>> encrypt("a1b2c3")
'd1e2f3'
>>> encrypt("abc ABC")
'def DEF'
代码实现:
def encrypt(p):
"""
添加上述测试用例
"""
s = ""
for ch in p:
code = (ord(ch) - 0x61 + 3) % 26 + 0x61
s += chr(code)
return s
if __name__ == "__main__":
import doctest
doctest.testmod(verbose=True)
运行上述测试,前2个通过,后面3个失败。
原因分析:
大写字母处理不对,代码默认基础字母是‘a’。
只需要增加base变量,根据字母是大写还是小写来初始化,即base = 0x41 if ch.isupper() else 0x61
,将该行插入到第7行前,然后把后面行中出现的0x61修改为base即可。
再运行测试,前3个通过。
根据题意,对英文字母进行加密,非英文字母我们保持不变即可。
利用字符串对象提供的isalpha方法进行分支处理,
加密方法的完整代码如下:
def encrypt(p):
"""
添加上述测试用例
"""
s = ""
for ch in p:
if not ch.isalpha():
s += ch
continue
base = 0x41 if ch.isupper() else 0x61
code = (ord(ch) - 0x61 + 3) % 26 + 0x61
s += chr(code)
return s
注意:Python字符串的isalpha方法,支持unicode字符,因而中文也是字符,
这将导致上述代码无法正确处理中文。
我们可以通过自己定义is_letter函数来实现英文字母的判断。
3.猜拳游戏
功能:
玩家与计算机“剪刀石头布”,三局两胜(平局不算),最后输出获胜方。
计算机出拳,使用random库随机产生;玩家由键盘输入。
random库:
randrange函数
:和range函数的参数一样,在该范围产生一个随机数
choice函数
:抽取一个
choices函数
:有放回抽样
sample函数
:无放回抽样
seed函数
:默认系统时间作为种子。种子相同,则产生相同随机数列。
逻辑判断优化:
建立映射:0表示scissor,1表示stone,2表示cloth
观察可得,(x+1)%3 == y,表示y胜;否则,x!=y,表示x胜
代码实现
import random
def compare(computer, player):
choices = ["scissor", "stone", "paper"]
infos = ["it is a draw.", "computer win!", "player win!"]
wid = 0
if computer == (player + 1) % 3:
wid = 1
elif computer != player:
wid = 2
return wid, infos[wid] + f"{choices[computer]} VS {choices[player]}"
def run():
result = [0, 0, 0]
while True:
computer = random.choice([0, 1, 2])
player = int(input("please input your choice:"))
wid, info = compare(computer, player)
print(info)
result[wid] += 1
if max(result[1], result[2]) == 2: break
print(f"game over!{result[1]}:{result[2]}")
if __name__ == "__main__":
run()
程序运行情况如下:
please input your choice:0
computer win!stone VS scissor
please input your choice:0
computer win!stone VS scissor
game over!2:0
>>>
please input your choice:0
player win!paper VS scissor
please input your choice:1
player win!scissor VS stone
game over!0:2
>>>
please input your choice:0
it is a draw.scissor VS scissor
please input your choice:0
computer win!stone VS scissor
please input your choice:0
player win!paper VS scissor
please input your choice:0
player win!paper VS scissor
game over!1:2
4.多种方法计算π
功能:
数列方式求π:π/4 = 1 - 1/3 + 1/5 - 1/7 + 1/9......
通项分析:
-
分子为1,分母为奇数2n-1,正负交替
-
计算项数越多,精度越高
代码实现
def calc(n):
s, sign = 0, 1
for i in range(1, n+1):
item = sign / (2*i - 1)
s += item
sign *= -1 #正负交替
return 4 * s
if __name__ == "__main__":
s = calc(1000000)
print(f"{s}")
运行该程序,可以得到π值为:3.1415916535897743。
增加循环次数,可以提升精度,但运行时间会增加,请大家自行测试。
扩展练习:
已知数列,π2/6=1+1/4+1/9+1/16……,编程实现π的计算。
刘徽割圆术求π
割之弥细,所失弥少,计算正多边形的面积,就是圆的面积(单位圆的话,就是π的值)
正多边形就是n个相同大小的三角形,只需计算1个三角形的面积即可
三角形三边长容易获得,再利用海伦-秦九韶公式可以计算面积: p ( p − a ) ( p − b ) ∗ ( p − c ) \sqrt{p(p-a)(p-b)*(p-c)} p(p−a)(p−b)∗(p−c),其中p为周长的一半。
代码实现
import math
def calc_area(n):
angle = 2*math.pi / n
x1, y1 = 1, 0
x2, y2 = math.cos(angle), math.sin(angle)
a = math.sqrt((x1-x2)**2 + (y1-y2)**2) #求两点距离
p = (a+1+1) / 2 #周长的一半
s = math.sqrt(p * (p-a) * (p-1) * (p-1)) #海伦-秦九韶公式
return s
#学习中没有资料?可以加我VX:qian97378免费领
def run():
n = 20000
s = calc_area(n)
print(n * s)
if __name__ == "__main__":
run()
运行该程序,可得π \piπ的值:3.141592601914085。
扩展练习:
利用已知两边长及其夹角求面积公式,完成π \piπ的计算。
蒙特卡罗投针实验求π
概率可以用面积之比来表示
模拟投针实验:
-
单位圆和其外接正方形
-
随机投针
-
圆内针数与总针数的比例等于圆和方形的面积之比
代码实现
import random, math
def calc_area(n):
count = 0
for i in range(n):
x = random.random()
y = random.random()
d = math.sqrt(x*x + y*y) #到圆心的距离
if d < 1: #落入圆内,则计数加1
count += 1
return count * 4 / n
def run():
n = 1000000
s = calc_area(n)
print(s)
if __name__ == "__main__":
run()
运行程序,1百万次投针得到的π \piπ值为:3.140648,精度不算太高。
尾语 💝
要成功,先发疯,下定决心往前冲!
学习是需要长期坚持的,一步一个脚印地走向未来!
未来的你一定会感谢今天学习的你。
—— 心灵鸡汤
本文章到这里就结束啦~感兴趣的小伙伴可以复制代码去试试哦 😝