一、实验目的
1、掌握Python异常处理机制。
2、掌握程序的控制结构及其实现方法。
3、掌握函数的定义和使用方法。
二、实验内容
1、考虑异常情况,编写程序从键盘获得一个全数字(可以含小数点或复数标记)输入,如果用户输入不符合,则要求用户再次输入,直至满足条件。打印输出这个输入。
2、一个不含0的数,如果它能被它的每一位除尽,则它是一个自除数。例如128是一个自除数,因为128能被1、2、8整除。编写函数self_div(num)判断num是否为自除数,使用该函数输出不大于N的所有自除数。注意含有0的自然数不是自除数。输入为一行,一个正整数n(n>=1)。输出为一行,是不大于n的所有自除数,每个数后面有一个空格。
样例输入:
22
样例输出:
1 2 3 4 5 6 7 8 9 11 12 15 22。
3、设计一个用二分法计算一个大于或等于0的实数n的平方根的函数sqrt_binary(n,m),实数n和计算精度控制由用户在同一行内输入,用逗号进行分隔,输出结果保留8位小数。当(abs(x * x - n) )小于或等于设定的精度时,近似认为 x * x == n。注意,初始区间取[0,n+0.25]。输入时,在同行内输入一个实数 n(大于或等于0)和一个代表精度的数字,逗号间隔。输出时,第一行输出用自己设计的函数计算得到的平方根,第二行输出用math库开平方函数计算得到的平方根。
样例输入:
5.0,1e-7
样例输出:
2.23606796
2.23606798
三、程序清单
Question1:
V1
def ab():
while 1:
try:
number = eval(input("请输入一个数字(整数,浮点数,复数):"))
print(number)
break
except ValueError:
print("请重新输入:")
except TypeError:
print("请重新输入:")
except NameError:
print("请重新输入:")
except IOError:
print("请重新输入:")
except SyntaxError:
print("请重新输入")
ab()
V2:对一些部分进行改进,如函数名变得更加容易理解,增加了对算数式的判断(我觉得算数式如5*5不算全数字,在第一个程序中用了错误类型的判断,第二个我想不用,直接用except来一次性判断,避免出现我未写出来的错误类型)
def get_number
while True:
td = 0
number = input("请输入一个数字(整数,浮点数,复数):")
for i in number:
if i in ['+','-','*','/']:
td = 1
if td:
print("输入无效,请重新输入")
continue
try:
number = eval(number)
print(number)
return number
except :
print("输入无效,请重新输入")
get_number()
Question2:
V1
def self_div(num):
iq = []
for i in range(1,num+1):
Is = []
a = i
while a:
Is.append(a%10)
a =a//10
for j in Is:
if (j == 0)or(i%j != 0):
break
else:
iq.append(i)
for k in iq:
print(k,end=" ")
number = eval(input("请输入一个正整数:"))
self_div(number)
V2(并没有太大的改进,只是让函数内部更加完整,使用户调用函数可以直接在调用函数时进行输入)
def self_div():
num = eval(input("请输入一个正整数:"))
iq = []
for i in range(1,num+1):
Is = []
a = i
while a:
Is.append(a%10)
a =a//10
for j in Is:
if (j == 0)or(i%j != 0):
break
else:
iq.append(i)
for k in iq:
print(k,end=" ")
self_div()
Question3
V1
from math import sqrt
number, num = eval(input("输入一个正整数和一个精度(用逗号分隔开):"))
a = number + 0.25
c = 0
b = (c + a ) / 2
while 1:
if abs(b*b-number) > num:
if b*b-number > 0:
a = b
else:
c = b
b = (a+c) / 2
else:
break
print("函数计算所得平方根为{:.8f}\nmath库开平方函数结果{:.8f}".format(b, sqrt(number)))
V2(对变量进行重新的命名,再也不想用a,b,c了,写一个代码改错的时候太难看逻辑关系了,用right,mid,left)更容易理解,以及改成了函数,把break改成了return使代码更具有可读性)
from math import sqrt
def sqrtsqrt_binary(n,m):
right = n + 0.25
left = 0
mid = (right + left ) / 2
while 1:
if abs(mid**2-n) > m:
if mid**2-n > 0:
right = mid
else:
left = mid
mid = (right+left) / 2
else:
break
return mid
number, num = eval(input("输入一个正整数和一个精度(用逗号分隔开):"))
print("函数计算所得平方根为{:.8f}\nmath库开平方函数结果{:.8f}".format(sqrtsqrt_binary(number,num), sqrt(number)))
四、调试及测试结果
Question1:
V1
请输入一个数字(整数,浮点数,复数):89/
请重新输入
请输入一个数字(整数,浮点数,复数):23*
请重新输入
请输入一个数字(整数,浮点数,复数):/*//
请重新输入
请输入一个数字(整数,浮点数,复数):88
88
进程已结束,退出代码0
V2
请输入一个数字(整数,浮点数,复数):8/7
输入无效,请重新输入
请输入一个数字(整数,浮点数,复数):8*8
输入无效,请重新输入
请输入一个数字(整数,浮点数,复数):wss
输入无效,请重新输入
请输入一个数字(整数,浮点数,复数):斯诺克
输入无效,请重新输入
请输入一个数字(整数,浮点数,复数):89
89
进程已结束,退出代码0
Question2:
V1
请输入一个正整数:22
1 2 3 4 5 6 7 8 9 11 12 15 22
进程已结束,退出代码0
Question3
V1
输入一个正整数和一个精度(用逗号分隔开):5.0,1e-7
函数计算所得平方根为2.23606796
math库开平方函数结果2.23606798
进程已结束,退出代码0
V2
输入一个正整数和一个精度(用逗号分隔开):5.0,1e-7
函数计算所得平方根为2.23606796
math库开平方函数结果2.23606798
进程已结束,退出代码0
五、实验总结与心得
Question 1:
问题分析:输出全数字
IPO:用户进行一次输入,判断是否为全数字,不是则让用户重新输入,直至遇到全数字然后输出
Question 2:
问题分析:判断从1到N的数中的自除数,并进行一行输出
IPO:用户输入一个数,遍历从1到N的数,对每一个数进行判断是否为自除数,然后进行输出
Question 3:
问题分析:利用二分法进行数字的开根号
IPO:用户输入一个正整数,使用二分法进行开根,最后输出二分法得出的结果和math函数中用sqrt函数开根的进行对比
总结和心得:
二分法:
1.先求区间[0,n]之间的中点值mid=(0+n)/2
2.判断mid的平方与n之间差值的绝对值是否符合精确度误差
3.符合就返回得到的值,不符合的话,如果mid**2>n,说明n的平方根小于mid,让mid等于区间较大的数,继续求中点值。如果mid**2<n,说明n的平方根大于mid,让mid等于区间较小的数,继续求中点值。
本次实验使我多错误类型的种类有了更多的使用以及认识,复数输入时,虚部应用j而不是i。对列表的基本使用和如何在列表中加入元素,学会了二分法的算法思想,并进行了运用和掌握,在第二个程序中,让我对变量的命名有了更多的认识,以后要减少对变量命名时使用a,b,c,如果这样命名对程序的修改以及改进会产生极大的不便,会对逻辑判断不清,混乱。对定义函数有了进一步的熟练运用,以及在函数中如果使用无限循环while中可以将break改成return这样能使代码更加容易理解