使用蒙特-卡罗方法计算圆周率近似值
蒙特-卡罗方法是一种通过概率来得到问题近似解的方法。假设又一块边长为2的正方形木板,上面画一个单位圆,然后随意往木板上扔飞镖,落点坐标(x,y)必然在木板上(更多的是落在单位圆内),如果扔的次数足够多,那么落在单位圆内的次数除以总次数再乘以4,这个次数会无限接近圆周率的值。
from random import random
times = int(input('请输入掷飞镖次数:'))
hits = 0
for i in range(times):x = random()y = random()if x*x+y*y<=1 :hits += 1
print(4.0*hits/times)
求素数
1.使用列表实现筛选法
maxNumber = int(input('请输入一个大于2的自然数:'))
lst = list(range(2,maxNumber))
# 最大整数的平方根
m = int(maxNumber**0.5)
for index,value in enumerate(lst):# 如果当前数字已大于最大整数的平方根,结束判断if value > m:break# 对该位置之后的元素进行过滤lst[index+1:] = filter(lambda x: x%value != 0,lst[index+1:])
print(lst)
2.使用集合实现筛选法
maxNumber = int(input('请输入一个大于2的自然数:'))
numbers = set(range(2,maxNumber))
# 最大整数的平方根,以及小于该数字的所有素数
m = int(maxNumber**0.5)+1
primesLessThanM = [p for p in range(2,m)if 0 not in [p%d for d in range(2,int(p**0.5)+1)]]
# 遍历最大整数平方根之内的自然数
for p in primesLessThanM:for i in range(2,maxNumber//p+1):# 在集合中删除数字所有的倍数numbers.discard(i*p)
print(numbers)
小明爬楼梯
假设一段楼梯共15个台阶,小明一步最多能上3个台阶。递推法,递归法。
def climbStairs1(n):# 递推法a = 1b = 2c = 4for i in range(n-3):c,b,a = a+b+c,c,breturn c
def climbStairs2(n):# 递归法first3 = {1:1,2:2,3:4}if n in first3.keys():return first3[n]else:return climbStairs2(n-1) + \climbStairs2(n-2) + \climbStairs2(n-3)
print(climbStairs1(15))
print(climbStairs2(15))
蒙蒂霍尔
假设你正参加一个有奖游戏节目,并且有3道门可选:其中一个后面是汽车,另外两个后面是山羊。你选择一个门,比如说1号门,主持人当然知道每个门后面是什么并且打开了一个门,比如说3号门,后面是一只山羊。这时,主持人会问你“你想改选2号门吗?”,然后根据你的选择确定最终要打开的门,并确定你获得山羊(输)或者汽车(赢)。
from random import randrangedef init():# 返回一个字典,键为3个门号,值为门后的物品result = {i: 'goat' for i in range(3)}r = randrange(3)result[r] = 'car'return resultdef startGame():# 获取本次游戏中每个门的情况doors = init()# 获取玩家选择的门号while True:try:firstDoorNum = int(input('Choose a door to open:'))assert 0 <=firstDoorNum <= 2breakexcept:print('Door number must be between {} and {}'.format(0,2))# 主持人查看另外两个门后的物品情况for door in doors.keys()-{firstDoorNum}:# 打开其中一个后面为山羊的门if doors[door] == 'goat':print('"goat" behind the door', door)# 获取第三个门号,让玩家纠结thirdDoor = (doors.keys()-{door,firstDoorNum}).pop()change = input('Switch to {}?(y/n)'.format(thirdDoor))finalDoorNum = thirdDoor if change == 'y' else firstDoorNumif doors[finalDoorNum] == 'goat':return 'I win!'else:return 'You win.'
while True:print('='*30)print(startGame())r = input('Do you want to try once more?(y/n)')if r == 'n':break
猜数游戏
程序运行时,系统生成一个随机数,然后提示用户进行猜测,并根据用户输入进行必要的提示(猜对了、太大了、太小了),如果猜对则提前结束程序,如果次数用完仍没有猜对,提前游戏结束并给出正确答案。
from random import randint
def guessNumber(maxValue=10,maxTimes=3):# 随机生成一个整数value = randint(1,maxValue)for i in range(maxTimes):prompt = 'Start to GUESS:(1-10)' if i==0 else 'Guess again:'# 使用异常处理结构,防止输入不是数字的情况try:x = int(input(prompt))except:print('Must input an integer between 1 and ',maxValue)else:if x == value:# 猜对了print('Congratulations!')breakelif x > value:print('Too big')else:print('Too little')else:# 次数用完还没猜对,游戏结束,提示正确答案print('Game ouer.FAIL.')print('The value is ',value)
guessNumber()
抓狐狸游戏
假设一共有一排5个洞口,小狐狸最开始的时候在其中一个洞口,然后玩家随机打开一个洞口,如果里面有狐狸就抓到了。如果洞口里没有狐狸就第二天再来抓,但是第二天狐狸会在玩家来抓之前跳到隔壁洞口里。
from random import choice,randrange
def catchMe(n=5,maxStep=10):'''模拟抓小狐狸,一共n个洞口,允许抓maxStep次如果失败,小狐狸就会跳到隔壁洞口'''# n个洞口,有狐狸为1,没有狐狸为0positions = [0] * n# 狐狸的随机位置oldPos = randrange(0,n)positions[oldPos] = 1# 抓maxStep次while maxStep >= 0:maxStep -= 1# 这个循环保证用户输入的是有效洞口编号while True:try:x = input('今天打算打开哪个洞口(0-{0}):'.format(n-1))# 如果输入的不是数字,就会跳转到except部分x = int(x)# 如果输入的洞口有效,结束这个循环,否则就继续输入assert 0 <= x < n,'要按套路来啊,再给你一次机会。'breakexcept:# 如果输入的不是数字,就执行这里的代码print('要按套路来啊,再给你一次机会。')if positions[x] == 1:print('成功,我抓到小狐狸啦。')breakelse:print('今天又没抓到。')# 如果这次没抓到,狐狸就跳到隔壁洞口if oldPos == n-1:newPos = oldPos - 1elif oldPos == 0:newPos = oldPos + 1else:newPos = oldPos + choice((-1,1))positions[oldPos],positions[newPos] = 0,1oldPos = newPoselse:print('放弃吧,你这样乱试是没有希望的。')
# 启动游戏,开始抓狐狸吧
catchMe()
汉诺塔问题
据说古代有一个梵塔,塔内有三个底座A、B、C,A座上有64个盘子,盘子大小不等,大的在下,小的在上。有一个和尚想把这64个盘子从A座移到C座,但每次只能允许移动一个盘子。在移动盘子的过程中可以利用B座,但任何时候3个座上的盘子都必须始终保持大盘在下、小盘在上额顺序。如果只有一个盘子,则不需要利用B座,直接将盘子从A移动到C即可。
def hannoi(num,src,dst,temp=None):if num < 1:returnglobal times # 声明用来记录移动次数的变量为全局变量# 递归调用函数本身,先把除最后一个盘子之外的所有盘子移动到临时柱子上hannoi(num-1,src,temp,dst)# 移动最后一个盘子print('The {0} Times move:{1}-->{2}'.format(times,src,dst))towers[dst].append(towers[src].pop())for tower in 'ABC': # 输出3根柱子上的盘子print(tower,':',towers[tower])times += 1# 把除最后一个盘子之外的其他盘子从临时柱子上移动到目标柱子上hannoi(num-1,temp,dst,src)
times = 1 # 用来记录移动次数的变量
n = 3 # 盘子的数量
towers = {'A':list(range(n,0,-1)),'B':[],'C':[]}
# A 表示最初放置盘子的柱子,C是目标柱子,B是临时柱子
hannoi(n,'A','C','B')
凯撒加密
输入一个字符串,然后输入一个整数作为凯撒加密算法的密钥,然后输出该字符串加密后的结果。
import string
def kaisa():s = input('请输入一个字符串:')k = int(input('请输入一个整数密钥:'))lower = string.ascii_lowercaseupper = string.ascii_uppercasebefore = string.ascii_lettersafter = lower[k:] + lower[:k] + upper[k:] + upper[:k]table = str.maketrans(before,after)out = s.translate(table)print(out)
kaisa()
自定义类模拟三维向量及运算
定义一个三维向量类,并定义相应的特殊方法实现两个该类对象之间的加、减运算(要求支持运算符+、-),实现该类对象与标量的乘、除运算(要求支持运算符*、/),以及向量长度的计算(要求使用属性实现)。
class Vector3:# 构造方法,初始化,定义向量坐标def __init__(self,x,y,z):self.__x = xself.__y = yself.__z = z# 与一个向量相加,对应分量相加,返回新向量def __add__(self, anotherPoint):x = self.__x + anotherPoint.__xy = self.__y + anotherPoint.__yz = self.__z + anotherPoint.__zreturn Vector3(x,y,z)# 减去另一个向量,对应分量相减,返回新向量def __sub__(self, anotherPoint):x = self.__x - anotherPoint.__xy = self.__y - anotherPoint.__yz = self.__z - anotherPoint.__zreturn Vector3(x, y, z)# 向量与一个数字相乘,各分量乘以同一个数字,返回新向量def __mul__(self, n):x, y, z = self.__x*n, self.__y*n, self.__z*nreturn Vector3(x,y,z)# 向量除以一个数字,各分量除以同一个数字,返回新向量def __truediv__(self, n):x, y, z = self.__x/n, self.__y/n, self.__z/nreturn Vector3(x, y, z)# 查看向量长度,所有分量平方和的平方根@propertydef length(self):return (self.__x**2 + self.__y**2 + self.__z**2)def __str__(self):return 'Vector3({},{},{})'.format(self.__x,self.__y,self.__z)v1 = Vector3(3, 4, 5)
v2 = Vector3(5, 6, 7)
print(v1+v2)
print(v1-v2)
print(v1*3)
print(v2/2)
print(v1.length)
文本文件操作
编写一个程序demo.py,要求运行该程序后,生成demo_new.py文件,其中内容与demo.py一样,只是在每一行的后面加上行号以#开始,并且所有行的#符号垂直对齐。
filename = 'demo.py'
with open(filename, 'r') as fp:lines = fp.readlines()
maxLength = len(max(lines, key=len))lines = [line.rstrip().ljust(maxLength)+'#'+str(index)+'\n'for index, line in enumerate(lines)]
with open(filename[:-3]+'_new.py', 'w') as fp:fp.writelines(lines)
磁盘垃圾文件清理器
要求程序运行时,通过命令行参数指定要清理的文件夹,然后删除该文件夹及其子文件夹中所有扩展名为tmp、log、obj、txt以及大小为0的文件。
from os.path import isdir,join,splitext
from os import remove,listdir,chmod,statfiletypes = ('.tmp','.log','.obj','.txt')def test2(directory):if not isdir(directory):returnfor filename in listdir(directory):temp = join(directory,filename)if isdir(temp):test2(temp)elif splitext(temp)[1] in filetypes or stst(temp).st_size == 0:chmod (temp,0o777)remove(temp)print(temp,'deleted...')
test2(r'D:\test')