实验4 函数与异常处理应用编程

Posted on 2022-05-05 22:07  灯下白头人  阅读(20)  评论(2编辑  收藏  举报

实验内容

1.实验任务1

 1 def task1():
 2     import builtins
 3     print(builtins.sum)
 4 
 5     sum = 42
 6     print(sum)
 7     
 8     def inc(n):
 9         sum = n+1
10         print(sum)
11         return sum
12     
13     sum = inc(7) + inc(7)
14     print(sum)

运行截图

Q:task1.py源码中,共有4处有python语句 print(sum) (line3, line6, line9, line13)。

这4处使用的标识符sum是代表一个变量名吗?如果不是,请分别指出这4行中变量sum的作用域。

A:不是。若不考虑task1的调用,假设全部文本直接执行,则出现的变量依次为built-in类型,global类型,local类型,Enclosing local类型。

* 为达到预期输出调用了builtins库。

2.实验任务2

 1 def task2_1():
 2     def func1(a, b, c, d, e, f):
 3         '''
 4     返回参数a,b,c,d,e,f构成的列表
 5     默认参数按位置传递; 也支持关键字传递
 6         '''
 7         return [a,b,c,d,e,f]
 8 
 9     def func2(a, b, c,*, d, e, f):
10         '''
11     返回参数a,b,c,d,e,f构成的列表
12     *后面的参数只能按关键字传递
13         '''
14         return [a,b,c,d,e,f]
15 
16     def func3(a, b, c, /, d, e, f):
17         '''
18     返回参数a,b,c,d,e,f构成的列表
19     /前面的参数只能按位置传递
20         '''
21         return [a,b,c,d,e,f]
22 
23     # func1调用:按位置传递、按参数传递都可以
24     print( func1(1,9,2,0,5,3) )
25     print( func1(a=1, b=9, c=2, d=0, e=5, f=3) )
26     print( func1(1,9,2, f=3, d=0, e=5))
27 
28     # func2调用:d,e,f必须按关键字传递
29     print( func2(11, 99, 22, d=0, e=55, f=33) )
30     print( func2(a=11, b=99, c=22, d=0, e=55, f=33) )
31     #print(func2(11,99,22,0,55,33))
32 
33     # func3调用:a,b,c必须按位置传递
34     print( func3(111, 999, 222, 0, 555, 333))
35     print( func3(111, 999, 222, d=0, e=555, f=333) )
36     #print(func3(a=111,b=999,c=222,0,555,333))
37 
38 def task2_2():
39     list1 = [1, 9, 8, 4]
40 
41     print( sorted(list1) )
42     print( sorted(list1, reverse=True) )
43     print( sorted(list1, True) )
44 
45 def task2_3():
46     def func(a, b, c, /, *, d, e, f):
47         return( [a,b,c,d,e,f] )
48     # 补足一行代码,调用func()并打印生成的列表,使得结果为[1,2,3,4,5,6]
49     # 待补足。。。
50     print(func(1,2,3,d=4,e=5,f=6))

运行截图

Q:python内置函数sorted()中,参数reverse的传递方式是否必须使用关键字传递?

A:由上述第三张截图知是reverse参数是仅支持关键字传递的。

*经测试可变参数也支持此格式。

3.实验任务3

 1 def task3():
 2     def solve(a, b, c):
 3         '''
 4         求解一元二次方程, 返回方程的两个根
 5         :para: a,b,c: int 方程系数
 6         :return: tuple
 7         '''
 8         delta = b*b - 4*a*c
 9         delta_sqrt = abs(delta)**0.5
10         p1 = -b/2/a;
11         p2 = delta_sqrt/2/a
12 
13         if delta>=0:
14             root1 = p1 + p2
15             root2 = p1 - p2
16         else:
17             root1 = complex(p1, p2)
18             root2 = complex(p1, -p2)
19 
20         return root1, root2
21 
22     print(solve.__doc__)
23     while True:
24         try:
25             a,b,c = eval(input('Enter eqution coefficient: '))
26             if a == 0:
27                 raise
28         except:
29             print('invalid input, or, a is zero')
30             break
31         else:
32             root1, root2 = solve(a, b, c)
33             print(f'root1 = {root1:.2f}, root2 = {root2:.2f}')
34             print()

运行截图

*函数的注释在编译时被保存在solve中的_doc_函数中,因此可直接调用读取。help()方法也可读取。

4.实验任务4

 1 def task4():
 2     def list_generator(start,end,step=1):
 3         try:
 4             if not(
 5                                 (type(start)==int or type(start)==float)
 6                         and (type(start)==int or type(start)==float)
 7                         and (type(start)==int or type(start)==float)
 8                    ):
 9                 raise ValueError
10         except ValueError:
11             print("Input must be numbers!")
12         else:
13             list0=[]
14             while (start<=end):
15                 list0.append(start)
16                 start+=step
17 
18             return list0
19 
20 
21     list1 = list_generator(-5, 5) ;print(list1)
22     list2 = list_generator(-5, 5, 2) ;print(list2)
23     list3 = list_generator(1, 5, 0.5); print(list3)

运行截图

*函数大致与range()相同,细节仍可打磨。

5.实验任务5

 1 def task5():
 2     def is_prime(n):
 3         try:
 4             if not(type(n)==int and n>1):
 5                 raise ValueError
 6         except ValueError:
 7             print("Input must be a natural number and greater than 1!")
 8         else:
 9             for i in range(2,n):
10                 if n%i==0:
11                     return False;break
12             else:
13                 return True
14 
15     primes=[]
16     for i in range(2,21):
17         if is_prime(i):
18             primes.append(i)
19     for i in range(4,21,2):
20         #tag=0
21         for j in range(len(primes)):
22             for k in range(j,len(primes)):
23                 if i==primes[j]+primes[k]:
24                     print(f"{i} = {primes[j]} + {primes[k]}")
25                     #tag=1
26             #if tag==1:
27                 #break

运行截图

*若要实现与所给截图一致的输出,将line145,150-152的内容解注释即可。然从数学上如此输出并无错误,故保留。

6.实验任务6

 1 def task6():
 2     def encoder(s):
 3         try:
 4             if type(s)!=str:
 5                 raise TypeError
 6         except TypeError:
 7             print("Input must be a string!")
 8         else:
 9             capital=tuple([chr(x) for x in range(ord('A'),ord('Z')+1)])
10             lowercase=tuple([chr(x) for x in range(ord('a'),ord('z')+1)])
11             S=list(s)
12             for i,j in enumerate(S):
13                 for k in range(len(capital)):     
14                     if j==capital[k]:
15                         S[i]=capital[(k+5)%26];break
16                     elif j==lowercase[k]:
17                         S[i]=lowercase[(k+5)%26];break
18             s="".join(S)
19             return s
20         
21     def decoder(s):
22         try:
23             if type(s)!=str:
24                 raise TypeError
25         except TypeError:
26             print("Input must be a string!")
27         else:
28             capital=tuple([chr(x) for x in range(ord('A'),ord('Z')+1)])
29             lowercase=tuple([chr(x) for x in range(ord('a'),ord('z')+1)])
30             S=list(s)
31             for i,j in enumerate(S):
32                 for k in range(len(capital)):     
33                     if j==capital[k]:
34                         S[i]=capital[(k-5)%26];break
35                     elif j==lowercase[k]:
36                         S[i]=lowercase[(k-5)%26];break
37             s="".join(S)
38             return s
39 
40     s=input("Input a English text:")
41     print(f"Encoded text: {encoder(s)}")
42     print(f"Decoded text: {decoder(encoder(s))}")

运行截图

*慎用range()方法!必须使用enumerate()方法方可保证遍历每个字符。因list(range(0,0))为空列表。

 亦可先用enumerate()读取所有字母的下表再遍历。

7.实验任务7

 1 def Collatz():
 2     def collatz(n):
 3         if n%2==0:
 4             n/=2
 5         else:
 6             n=3*n+1
 7         return int(n)
 8 
 9     try:
10         n=eval(input("Input an integer:"))
11         if not(type(n)==int and n>0):
12             raise ValueError
13     except (ValueError,NameError):
14         print("Error: must be a positive integer")
15     else:
16         nums=[]
17         while(n!=1):
18             nums.append(n)
19             n=collatz(n)
20         nums.append(1)
21         print(nums)

运行截图

*NameError必须被纳入except!当eval内表达式不符合数学结果是会被认为是变量,触发NameError。

实验总结

python体系因开源而凌乱无序,在使用方法时必须结合相应函数的实际输入输出决定。