输入的两个数字或者一个小数或者一个字符串,转换成分数输出
def gcd(x, y):
"""求最大公约数"""
while y % x != 0:
x, y = y % x, x
return x
# 通过继承Exception自定义异常类型
# 继承Exception类或者它的子类
class FractionExcept(Exception):
"""自定义异常类型通常不需要写代码,
主要就是定义一种新的自定义的类型来标记特殊的异常状况,
代码直接用父类Exception的代码"""
pass
class Fraction:
"""分数"""
@classmethod
def from_value(cls, value: float, base=10000):
return cls(int(value * base), b)
@classmethod
def from_string(cls, string: str):
num, den = [int(item.strip()) for item in string.split('/')]
return cls(num, den)
def __init__(self, num, den):
# 如果分母为0,直接引发异常让程序崩溃
if self.den == 0:
# 通过raise关键字,后面跟上异常对象来引发异常
# 如果没有做异常处理,那么程序就会崩溃
raise FractionExcept('分母不能为0')
self.num = num
self.den = den
self.simplify
self.normalize
def __str__(self):
if self.num == 0:
return f'{self.num}'
return f'{self.num}/{self.den}'
def __add__(self, other):
"""加法"""
num = self.num * other.den + self.den * other.num
den = self.den * other.den
return Fraction(num, den)
def __sub__(self, other):
"""减法"""
num = self.num * other.den - self.den * other.num
den = self.den * other.den
return Fraction(num, den)
def __mul__(self, other):
"""乘法"""
num = self.num * other.num
den = self.den * other.den
return Fraction(num, den)
def __truediv__(self, other):
"""除法"""
num = self.num * other.den
den = self.den * other.num
return Fraction(num, den)
# 计算属性:通过对象现有的数学系运算得到的一个值
# 本来是个方法,可以通过添加@property装饰器,将它处理成属性
@property
def value(self):
return self.num / self.den
def simplify(self):
if self.num != 0:
factor = gcd(abs(self.num), abs(self.den))
self.num, self.den = self.num // factor, self.den // factor
return self
def normalize(self):
if self.den < 0:
self.num = -self.num
self.den = -self.den
return self
f1 = Fraction(-6, -9)
print('f1:', f1) # 2/3
f2 = Fraction(3, -4)
print('f2:', f2) # -3/4
f3 = f1 * f2
print('f3:', f3) # -1/2
f4 = Fraction(11, 19)
print('f4:', f1 + f2 - f3) # 5/12
print('f5:', (f1 + f2) * f3 / f4) # 19/264
f1 *= f2
print(f1) # -1/2
f1 /= f2
print(f1)
f5 = (f1 + f2) * f3 / f4
print(f5)
print(f5.value) # 0.07196969696969698
print(Fraction.from_string('6 / 9')) # 2/3
print(Fraction.from_value(0.07196, base=100000)) # 1799/25000
异常处理
Python中的异常处理
代码本身即便没有问题,但在运行时可能因为外部资源的问题,导致代码无法运行,程序出现异常状况,如果异常状况没有得到处理,那么程序就会崩溃,具体的表现就是代码直接停止运行。
如果不希望程序崩溃,就要对代码进行异常处理
在Python中,可以使用try
语法将可能出现状况的代码保护起来执行,在出现状况的时候,使用except
进行异常状况的捕获并给出相应的处理
import sys
import time
while True:
try:
with open('readme.txt') as file:
print(file.read())
break
# 如果程序运行没有发生状况,except都不会执行
except FileNotFoundError:
# except FileNotFoundError as arr:通过err对象就可以获取关于异常的各种信息
print('错误提示:文件不存在,5秒后重新尝试读取文件')
time.sleep(5)
except IOError:
print('错误提示:读取文件失败,请确认设备是否就绪')
sys.exit(1)
except Exception:
# 实际项目中,这里要通过日志记录问题,可能还会通过网络将异常信息反馈给开发者
print('错误提示:程序发生了一点小问题,请拨打400-800-8855寻求帮助')
sys.exit(1)
#此处通常用来释放外部资源,因为这里的代码在任何情况下都一定会被执行
# 我们把这里称为总是执行代码
finally:
print('这个地方最适合释放外部资源') # file.close()
作业:输入纯数字列表,求平均值、中位数、方差、标准差
import math
class NumListExcept(Exception):
pass
class NumList:
"""自定义列表"""
def __init__(self, list_mine: list):
"""初始化方法
:param list_mine: 列表
"""
for n in list_mine:
if type(n) not in (int, float):
raise NumListExcept('该列表不是纯数字字符串')
super().__init__()
self.list_mine = list_mine
def __str__(self):
return f'{self.list_mine}'
def averager(self):
"""求平均值"""
avg = sum(self.list_mine) / len(self.list_mine)
return avg
def median(self):
"""求中位数"""
if len(self.list_mine) % 2:
return f'{self.list_mine[len(self.list_mine) // 2]}'
return f'{self.list_mine[len(self.list_mine) // 2 - 1]},{self.list_mine[len(self.list_mine) // 2]}'
def variance(self, sum1=0):
"""求方差"""
var = [(self.average() - i) ** 2 for i in self.list_mine]
for n in var:
sum1 += n
return sum1 / len(self.list_mine)
@property # 计算属性
def sta_dev(self):
"""求标准差"""
return math.sqrt(self.variance())
n1 = NumList([10, 20, 30, 40])
print(n1)
print(n1.average())
print(n1.median())
print(n1.variance())
print(n1.sta_dev)