python练习题(五)

1、定义代表三维笛卡尔坐标系上某个点的Point类(包括x、y、z三个属性),为该类定义一个方法,可接收b、c、d三个参数,用于计算当前点、b、c组成的面与b、c、d组成的面之间的夹角。

import math
class Point:
    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z
    # 求差
    def __sub__(self, no):
        return Point((self.x-no.x), (self.y-no.y), (self.z-no.z))
    # 点积
    def dot(self, no):
        return (self.x-no.x)+(self.y-no.y)+(self.z-no.z)
    # 叉乘
    def cross(self, no):
        return Point((self.y*no.z-self.z*no.y), (self.z*no.x-self.x*no.z),
                     (self.x*no.y-self.y*no.x))
    # 求绝对值
    def absolute(self):
        return (self.x**2+self.y**2+self.z**2)**0.5
if __name__ == '__main__':
    points = list()
    print("请依次输入4个点的x y z(中间用空格隔开):")
    for i in range(4):
        a = list(map(float, input().split()))
        points.append(a)
    a, b, c, d = Point(*points[0]), Point(*points[1]), Point(*points[2]), Point(*points[3])
    X = (b - a).cross(c - b)
    Y = (c - b).cross(d - c)
    angle = math.acos(X.dot(Y) / (X.absolute() * Y.absolute()))
    print("%.2f" % math.degrees(angle))

2、定义交通工具、汽车、火车、飞机这些类,注意它们的继承关系,为这些类提供构造器。

class Transport:
    def move(self, distance):
        print('我移动了%s千米' % distance)
class Car(Transport):
    def __init__(self, name):          #重写构造方法
        self.name = name
    def move(self, distance):           #重写方法move
        print('%s我在马路上开了%s千米' % (self.name, distance))
class Train(Transport):
    def __init__(self, speed):            #重写构造方法
        self.speed = speed
    def move(self, distance):           #重写move
        print('我以速度%s在铁轨上走了%s千米' % (self.speed, distance))
class Plain(Transport):            #继承了父类的构造方法
    def fly(self, distance):
        print('我在天空飞了%s千米' % distance)
if __name__ == '__main__':
    c = Car('BMW')
    c.move(30.2)
    t = Train(300)
    t.move(230.5)
    p = Plain()
    p.move(3440.8)    #子类实例调用父类方法
    p.fly(3440.8)

3、提示用户输入一个N,表示用户接下来要输入N各个字符串,程序尝试将用户输入的每一个字符串用空格分割成两个整数,并结算这两个整数整除的结果。要求:使用异常处理机制来处理用户输入的各种错误情况,并提示用户重新输入。

str_n = input('请输入整数N: ')
try:
    n = int(str_n)
    print(n)
    i = 0
    while True:
        try:
            a , b = input('请输入2个整数(空格隔开): ').split()
            print(int(a) // int(b))
            i += 1
            if i >= n: break
        except:
            print('务必输入空格隔开的2个整数!')
except:
    print('请输入整数N!')

4、提示用户输入一个整数,如果用户输入的整数是奇数,则输出有趣;如果用户输入的整数时偶数,且在2~5之间,则打印没意思;如果用户输入的整数是偶数,且在 6-20之间,则暑促和有趣;如果输入的整数是其他偶数,则打印没意思。要求:使用异常处理机制来处理用户输入的各种错误情况。

while True:
    str_n = input('请输入整数N: ')
    if str_n == 'exit':
        import sys
        sys.exit(0)
    try:
        n = int(str_n)
        if n % 2 != 0:
            print('有趣')
        elif 5 > n > 2:
            print('没意思')
        elif 20 > n > 6:
            print('有趣')
        else:
            print('没意思')
    except:
        print('务必输入整数')

5、提供一个字符串元组,程序要求元组中的每一个元素的长度都在5~20之间;否则,程序引发异常。

def fn(tp):
    for e in tp:
        if not isinstance(e, str):
            raise ValueError('所有元素必须是字符串')
        if not (20 >= len(e) >= 6):
            raise ValueError('字符串的长度必须在6~20之间')
    print(tp)


if __name__ == '__main__':
    fn(('fkjava', 'crazyit'))
    #    fn((20,))
    fn(('fkjavafkjavafkjavafkjava'))

6、提示用户输入x1,y1,x2,y2,x3,y3六个数值,分别代表三个点的坐标,程序判断这三个点是否在同一条直线上。要求:使用异常处理机制处理用户输入的各种错误情况,如果三个点不在同一条直线上,则程序出现异常。

while True:
    st = input("请输入3个点的x、y值(空格隔开): ")
    if st == 'exit':
        import sys
        sys.exit(0)
    try:
        x1_st, y1_st, x2_st, y2_st, x3_st, y3_st = st.split()
        x1, y1, x2, y2, x3, y3 = float(x1_st), float(y1_st), float(x2_st), float(y2_st), float(x3_st), float(y3_st)
        if x1 == 0 and x2 == 0 and x3 == 0:
            print('处于同一条直线')
        elif 0 in (x1, x2, x3):
            print('不处于同一条直线')
        elif y1 / x1 == y2 / x2 and y1 / x1 == y3 / x3:
            print('处于同一条直线')
        else:
            print('不处于同一条直线')
    except:
        print('必须输入6个空格隔开的数')

7、自定义一个序列,该序列按顺序包含52张扑克牌。分别是黑桃、红心、草花、方块的2~A。要求:提供序列的各种操作方法。

def check_key (key):
    if not isinstance(key, int): raise TypeError('索引值必须是整数')
    if key < 0: raise IndexError('索引值必须是非负整数')
    if key >= 52: raise IndexError('索引值不能超过%d' % 52)

class CardSeq:
    def __init__(self):
        self.flowers = ('♠', '♥', '♣', '♦')
        self.values = ('2', '3', '4', '5',
            '6', '7', '8', '9',
            '10', 'J', 'Q', 'K', 'A')
        self.__changed = {}
        self.__deleted = []
    def __len__(self):
        return 52
    def __getitem__(self, key):
        check_key(key)
        # 如果在self.__changed中找到已经修改后的数据,就返回该数据
        if key in self.__changed :
            return self.__changed[key]
        # 如果key在self.__deleted中,说明该元素已被删除
        if key in self.__deleted :
            return None
        # 否则根据计算规则返回序列元素
        flower = key // 13
        value = key % 13
        return self.flowers[flower] + self.values[value]
    def __setitem__(self, key, value):
        check_key(key)
        self.__changed[key] = value
    def __delitem__(self, key):
        check_key(key)
        # 如果__deleted列表中没有包含被删除key,添加被删除的key
        if key not in self.__deleted : self.__deleted.append(key)
        # 如果__changed中包含被删除key,删除它
        if key in self.__changed : del self.__changed[key]

if __name__ == '__main__':
    cq = CardSeq()
    print(len(cq))
    print(cq[2]) # '♠4'
    print(cq[1]) # '♠3'
    # 修改cq[1]元素
    cq[1] = '♣2'
    # 打印修改之后的cq[1]
    print(cq[1]) # '♣2'
    # 删除cq[1]
    del cq[1]
    print(cq[1]) # None
    # 再次对cq[1]赋值
    cq[1] = '♦5'
    print(cq[1]) # ♦5

8、自定义一个序列,该序列按顺序包含所有三位数(如100,101,102 ···)。要求:根据序列的各种操作方法。

start = 100
end = 999
nums = end - start + 1
def check_key (key):
    if not isinstance(key, int): raise TypeError('索引值必须是整数')
    if key < 0: raise IndexError('索引值必须是非负整数')
    if key >= nums: raise IndexError('索引值不能超过%d' % nums)
def check_value (value):
    if not isinstance(value, int): raise TypeError('序列值必须是整数')
    if not (end >= value >= start): raise IndexError('序列值必须在%d和%d之间' % (start, end))

class NumSeq:
    def __init__(self):
        self.__changed = {}
        self.__deleted = []
    def __len__(self):
        return nums
    def __getitem__(self, key):
        check_key(key)
        # 如果在self.__changed中找到已经修改后的数据
        if key in self.__changed :
            return self.__changed[key]
        # 如果key在self.__deleted中,说明该元素已被删除
        if key in self.__deleted :
            return None
        return start + key
    def __setitem__(self, key, value):
        check_key(key)
        check_value(value)
        self.__changed[key] = value
    def __delitem__(self, key):
        check_key(key)
        # 如果__deleted列表中没有包含被删除key,添加被删除的key
        if key not in self.__deleted : self.__deleted.append(key)
        # 如果__changed中包含被删除key,删除它
        if key in self.__changed : del self.__changed[key]

if __name__ == '__main__':
    nq = NumSeq()
    print(len(nq))
    print(nq[2]) # 101
    print(nq[1]) # 100
    # 修改nq[1]元素
    nq[1] = 123
    # 打印修改之后的nq[1]
    print(nq[1]) # 123
    # 删除nq[1]
    del nq[1]
    print(nq[1]) # None
    # 再次对nq[1]赋值
    nq[1] = 987
    print(nq[1]) # 987

9、自定义一个迭代器,该迭代器分别返回1,1+2,1+2+3···的累计和。

class Sums:
    def __init__(self, len):
        self.current_index = 1
        self.current_value = 0
        self.__len = len
    # 定义迭代器所需的__next__方法
    def __next__(self):
        if self.__len == 0:
            raise StopIteration
        # 完成数列计算:
        self.current_value += self.current_index
        self.current_index += 1
        # 数列长度减1
        self.__len -= 1
        return self.current_value
    # 定义__iter__方法,该方法返回迭代器
    def __iter__(self):
        return self
sums = Sums(10)
# 获取迭代器的下一个元素
print(next(sums))
for el in sums:
    print(el, end=' ')

10、自定义一个生成器,该生成器可按顺序返回52张扑克牌,分别是黑桃、红心、草花、方块的2~A。

def card_generator():
    nums = 52
    flowers = ('♠', '♥', '♣', '♦')
    values = ('2', '3', '4', '5',
        '6', '7', '8', '9',
        '10', 'J', 'Q', 'K', 'A')
    for i in range(nums):
        yield flowers[i // 13] + values[i % 13]

if __name__ == '__main__':
    cg = card_generator()
    print(next(cg)) # ♠2,生成器“冻结”在yield处
    print(next(cg)) # ♠3,生成器再次“冻结”在yield处
    for ele in cg:
        print(ele, end=' ')

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值