【Python实验设计】BMI计算 / 整数除法 / 蒙特卡洛近似圆周率 / 枚举法验证6174猜想 / 约瑟夫环 / 转盘抽奖 / 能力值 / 凯撒加密

目录

一、【计算BMI指数】

二、【输入整数相除】

三、【蒙特·卡罗方法计算圆周率近似值】

四、【使用枚举法验证6174猜想】

五、【模拟报数游戏(约瑟夫环问题)】

六、【模拟轮盘抽奖游戏】

七、【能力值累计】

八、【凯撒加密算法原理与实现】


一、【计算BMI指数】

输入:身高tall与体重kilo

输出:身体的BMI指数和BMI等级“过轻、正常、过重、肥胖、严重肥胖”

       流程图: 

# 2.1-肥胖指数BMI计算
# 输入小明身高1.75m,体重80.5kg.请根据BMI公式(体重除以身高的平方)帮小明计算他的BMI指数,计算规则为:
# 18.5<     过轻
# 18.5-25   正常
# 25-28     过重
# 28-32     肥胖
# >32       严重肥胖

def My_BMI(tall, kilo):
    BMI = kilo / pow(tall, 2)
    if 0 <= BMI < 18.5:
        print('BMI为{0:.2f}:过轻'.format(BMI))
    elif 18.5 <= BMI < 25:
        print('BMI为{0:.2f}:正常'.format(BMI))
    elif 25 <= BMI < 28:
        print('BMI为{0:.2f}:过重'.format(BMI))
    elif 28 <= BMI < 32:
        print('BMI为{0:.2f}:肥胖'.format(BMI))
    elif 32 <= BMI < 50:
        print('BMI为{0:.2f}:严重肥胖'.format(BMI))
    else:
        print('输入错误'.format(BMI))


x = float(input("请输入身高:"))
y = float(input("请输入体重:"))
My_BMI(x, y)

      运行结果: 

       如上图所示,输入小明的身高1.75,体重80.5,经过我的BMI算法得到BMI指数为26.29,判断为过重。实验结果与预期相符合,算法正确。

二、【输入整数相除】

       输入两个整数,打印他们相除后的结果,若输入的不是整数或除数为0,进行异常处理。定义函数,利用Python内置isinstance(x, int)函数判断输入的是否为整数,如果除数和被除数都是整数,则正常相除,如果不是则判断是除数还是被除数不是整数,进行异常处理输出判断。

      流程图:

# 输入两个整数,打印他们相除后的结果,若输入的不是整数或除数为0,进行异常处理

def My_Divi(x, y):
    if isinstance(x, int) and isinstance(y, int) and y != 0:    # 如果被除数x和除数y都是整数
        num = x / y
        print(num)
    elif not isinstance(x, int):
        print("被除数{0}不是整数".format(x))
    elif not isinstance(y, int):
        print("除数{0}不是整数".format(y))
    elif y == 0:
        print("除数为0啦")
    else:
        print("错误")


num1 = eval(input("请输入被除数:"))
num2 = eval(input("请输入除数:"))
My_Divi(num1, num2)

      运行结果: 

       输入被除数32与除数4得到8,输出正常,接下来尝试输出不是整数。

       上图,输入被除数23.5,不是整数,则抛出异常。

       上图,输入除数3.5,不是整数,则抛出异常。

       上图,输入除数0,抛出异常。经过测试,实验结果与预期相符合,算法正确。

三、【蒙特·卡罗方法计算圆周率近似值】

       蒙特卡罗法方法近似圆周率,按照我的理解设计思路:就是计算机模拟在正方形内撒一把豆子,计算落在圆内的豆子数量,按照圆豆子/正方形豆子比例,即可近似出圆周率π,计算公式推导:

       流程图:

# 使用蒙特.卡洛法计算圆周率近似值
import random
from tqdm import tqdm    # 进度条


def MY_Pi(N):    # 一共在正方形扔N次数
    count = 0    # 统计落在圆内的次数
    for i in tqdm(range(N)):    # 一共抛N次
        x = random.uniform(-1, 1)    # 随机浮点数
        y = random.uniform(-1, 1)
        if pow(x, 2) + pow(y, 2) <= 1:    # 在圆内
            count += 1    # 落在圆内,计数器加1
    pi = 4 * count/N
    print("运用蒙特卡洛法,执行{0}次,近似pi={1}".format(N, pi))


k = int(input("请输入执行次数:"))
MY_Pi(k)

       运行结果:

       输入执行10000次蒙特卡洛算法后,近似圆周率为3.138

       输入执行100000次蒙特卡洛算法后,近似圆周率为3.14148,由运行结果可知,当抛豆子的次数越多的时候,越逼近圆周率π,经过测试,实验结果与预期相符合,算法正确。

四、【使用枚举法验证6174猜想】

       任意一个四位数(四位数有大有小,不能完全相同相同),把它重新排列成从大到小的四位数,再排列成从小到大的四位数,然后用大的减去小的,所得的结果,再进行相同的排列、相减,最多7次,最后必将得到6174这个结果

       枚举法顾名思义,就是要循环遍历不全相同的四位数,验证每个四位数的6174算法,之后我定义了6174验证算法,该函数就是在8步之内,将四位数按大到小排序,减去按按小到大排序,判断相减是否得到6174,如果没有得到就将相减的数作为新数再重复排序相减。如果超出8步且没有得到6174即视为猜想错误,立刻结束程序。如果枚举所有四位数都得到6174即验证猜想正确。

       流程图:

# 使用枚举法验证6174猜想:6174猜想 ,1955年,卡普耶卡(D.R.Kaprekar)研究了对四位数的一种变换:
# 任给出四位数k0,用它的四个数字由大到小重新排列成一个四位数m,再减去它的反序数rev(m),得出数k1=m-rev(m),
# 然后,继续对k1重复上述变换,得数k2.如此进行下去,卡普耶卡发现,无论k0是多大的四位数, 只要四个数字不全相同,最多进行7次上述变换,就会出现四位数6174
def My_sort(n):    # 把数字从大到小排序
    s = str(n)         # s是n的字符串
    s_bu = '0' * (4 - len(s)) + s   # 把不足四位的数补零
    s_sort = ''.join(sorted(s_bu, reverse=True))   # 返回排序后的数字
    return s_sort


def My_6174(n):
    step = 1
    old_n = n
    print('验证:', old_n)
    while step <= 8:  # 一直循环
        n = int(n)  # 把n改成整数
        m = int(My_sort(n))  # 把n从大到小排序
        m_re = int(str(m)[::-1])  # 把m变成字符串后反序再变成整数
        k = m - m_re  # 新的差
        print("{0} - {1} = {2}".format(m, m_re, k))
        if k == 6174:  # 如果是6174则跳出循环
            break
        else:
            n = k  # 把差值作为新的数字
        step += 1  # 步数加一
    if k == 6174 and step <= 8:
        print('{0}进行了{1}次算法得到了6174'.format(old_n, step))
        return True
    else:
        print('验证6174失败')
        return False


Flag = True
i = 999

while Flag and i < 9999:    # 如果正确就会一直验证
    i += 1
    if len(set(str(i))) == 1:    # 如果所有数字都相同,则跳过
        continue
    else:    # 否则就进行验证
        Flag = My_6174(i)

if Flag == True:
    print('在四位数中验证6174没有失败!!猜想正确!')
elif Flag == False:
    print('在四位数中验证6174有失败!!猜想错误!')

       运行结果: 

       点击运行后,程序自动枚举不全相同的四位数,进行6174算法验证,从1000至9998遍历猜想,并且输出算法几次得到6174。

       验证到9998时,程序结束,且输出在四位数中验证6174没有失败,全部成功,猜想正确,实验结果与预期相符合,算法正确。

五、【模拟报数游戏(约瑟夫环问题)】

       通过前期自己绘图,模拟这个报数游戏,8个小朋友报数3后退出,最后剩7号小朋友。

       如下图所示,博主模拟了一个报数游戏过程,8个小朋友做成一个圈,每个小朋友身上都有一个编号,每个小孩报数报到3就退出圈(不参与接下来的报数),经过四轮报数淘汰,剩下7号小朋友。

       那接下来就需要通过编写代码,实现模拟实现报数游戏。我的思路是通过列表模拟约瑟夫环,定义一个指针,每次指针累加(报数)到报数的倍数时,就弹出列表这个数字,把列表长度作为每一轮。

       输入:多少个小朋友参加报数游戏、报到多少退出圈子。

       输出:最后留下的是多少号小朋友。

       流程图: 

# 模拟报数游戏(约瑟夫环问题)
# 有n个人围成一圈,从1开始按顺序编号,从第一个人开始从1到k(假设k=3)报数,
# 报到k的人退出圈子;然后圈子缩小,从下一个人继续游戏,问最后留下的是原来的第几号。

def My_baoshu(n, k):
    t = [1]    # 生成原始列表--圈圈
    for i in range(1, n):
        t.append(i + 1)
    count = 0    # 定义计数指针
    while len(t) != 1:
        t_new = t[:]
        print(list(t_new))
        for j in range(0, len(t_new)):    # 循环新列表
            count += 1
            if count % k == 0:    # 当报到k时弹出
                t.remove(t_new[j])    # 在原来的列表里除去点到的数
    print('留下的是原来的{0}号'.format(list(t)))


n = int(input("请输入多少个人参与:"))
k = int(input("请输入报到多少退出圈子:"))
My_baoshu(n, k)

       运行结果: 

       由图可知,输入8个小朋友参与报数,围成一个圈圈,报到3后退出这个圈,第一轮剩余【1,2,4,5,7】第二轮剩余【2,4,7,8】第三轮剩余【4,7】,最后只剩下【7】号小朋友,这与我们最开始模拟的圈图一致,实验结果与预期相符合,算法正确。

六、【模拟轮盘抽奖游戏】

       模拟转盘抽奖游戏,输入抽奖人数,自定义抽奖中奖一等奖、二等奖、三等奖,概率分别为10%、20%、70%

       流程图:

# 模拟转盘抽奖游戏
# 一等奖、二等奖、三等奖
# 一等奖【0--0.1】
# 二等奖【0.1--0.3】
# 三等奖【0.3--1】

import random
from tqdm import tqdm


def My_gift(n):
    count = [0, 0, 0]
    for i in tqdm(range(n)):
        k = random.uniform(0, 1)
        if 0 <= k < 0.1:
            count[0] += 1
        elif 0.1 <= k < 0.3:
            count[1] += 1
        elif 0.3 <= k < 1:
            count[2] += 1
        else:
            print("错误")
    print("一等奖个数{0}二等奖个数{1}三等奖个数{2}".format(count[0], count[1], count[2]))


x = int(input("请输入抽奖多少次:"))
My_gift(x)

       运行结果:

       输入模拟抽奖1000次,输出得到一等奖106人、二等奖198人、三等奖696人,实验结果与预期相符合,算法正确。 

七、【能力值累计】

       一年365天,如果好好学习时能力值比前一天提高1%,当放任时相比前一天下降1%,编程计算两种情况效果相差值,在这里我假设初始成绩为100分,每天努力提高1%,与每天放任下降1%后,进行对比,这里的主要思想就是迭代,每天都需要在前一天的基础上进行一个提高1%或者下降1%,通过Python编程就能实现这个过程。

   流程图:

# 7、一年365天,如果好好学习时能力值比前一天提高1%,当放任时相比前一天下降1%,编程计算两种情况效果相差值。

def My_Study(day):
    num_pro = 100
    num_des = 100
    for i in range(day):
        num_pro = num_pro * 1.01
        num_des = num_des * 0.99
    diff = (num_pro - num_des) / num_pro * 100
    print("{0}天后,好好学习成绩:{1:.2f};放任后成绩{2:.2f};好好学习成绩与放任成绩相比:{3:.2f}%".format(day, num_pro, num_des, diff))


x = int(input('请输入多少天:'))
My_Study(x)

      运行结果:

       输入365天,原先100分的基础,每天提升1%,最后成绩3778.34分,但是每天放任1%,最后只有2.55分,相比差了99.93%,实验结果与预期相符合,算法正确。

八、【凯撒加密算法原理与实现】

       凯撒密码最早由古罗马军事统帅盖乌斯·尤利乌斯·凯撒在军队中用来传递加密信息,故称凯撒密码。此为一种位移加密手段,只对26个(大小写)字母进行位移加密,规则相当简单,容易被破解。凯撒密码的替换方法是通过排列明文和密文字母表,密文字母表示通过将明文字母表向左或向右移动一个固定数目的位置。

      流程图:

import string


def My_kaisa(s, k):
    low = string.ascii_lowercase    # 小写字母
    up = string.ascii_uppercase     # 大写字母
    before = string.ascii_letters   # 变换前的字母表
    after = low[k:] + low[:k] + up[k:] + up[:k]
    table = ''.maketrans(before, after)
    new_s = s.translate(table)
    print("凯撒加密后前的字符串:{0}-->凯撒加密后的字符串{1}".format(s, new_s))


m = input("请输入代加密字符:")
n = int(input("请输入凯撒加密移动数:"))
My_kaisa(m, n)

       如图所示,输入【Hello My Name is Akaxi】经过凯撒加密(移动三个字母单位)后,输出【Khoor Pb Qdph lv Dndal】,实验结果与预期相符合,算法正确。

2023.10.23

渝北仙桃数据谷

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Akaxi-1

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值