20190604第二次月考

20190604第二次月考

文章目录

  • 20190604第二次月考
    • 第一题(10分)
    • 第二题(10分)
    • 第三题(5分)
    • 第四题(10分)
    • 第五题:(10分)
    • 第六题:(10分)
    • 第七题(10分)
    • 第八题
    • 第九题
    • 第十题(15份)
    • 进阶题:(20分)

第一题(10分)

  • 解释什么是装饰器,请写一个记录日志的装饰器。
# 装饰器:本质就是一个函数,主要是为其他函数添加附加功能
# 原则:不修改被修饰函数的源代码,不修改被修饰函数的调用方式。
import functools

def log(fn):
    """ 记录日志的装饰器"""
    @functools.wraps(fn)
    def _log(*args,**kwargs):
        print("{}函数开始执行。args = {}, kwargs = {}".format(fn.__name__,args,kwargs.items()))
        req = fn(*args,**kwargs)
        print("{}函数执行完成,返回结果为:{}".format(fn.__name__,req))
    return _log

@log
def add(x,y):
    return x+y

if __name__ == "__main__":
    add(4,5)
    add(x=4,y=5)
    add(4,y=5)

20190604第二次月考_第1张图片

第二题(10分)

  • 解释下re模块中的compile,match,search,fullmatch,findall,finditer,sub,split等方法的作用。
1. compile方法和作用
    * re.compile(pattern,flags=0)->regex #将正则表达式模式编译成正则表达式对象。
        * pattern #需要编译的正则表达式
        * flags #正则表达式使用的模式。re.S|re.M 开启多行模式和单行模式
            * 常用模式有:re.I,re.M,re.S,re.X   
    为了提高效率,正则表达式可以被编译,这些编译后的结果被保存,下次使用同样的pattern的时候,就不需要再次编译。  
    编译后的对象同样可以使用match(),search()方法进行匹配。
2. match方法和作用
    * re.match(pattern,string,flags=0)->match #匹配从字符串的开头匹配,返回match对象
    * regex.match(string[,pos[,endpos]])->match #regex对象match方法可以重设定开始位置和结束位置。返回match对象
        * pattern #正则表达式
        * string #需要匹配的字符串
        * flags #正则表达式使用的模式
            * 常用模式有:re.I,re.M,re.S,re.X   
        * pos  #匹配字符串的开始位置,默认从0索引位置开始匹配
        * endpos #匹配字符串的结束位置(不包含结束位置),默认值为len(string)
    * 注意:
    1. match会从字符串的开头开始查找,即使在re.M(多行模式)中。^符号也只表示字符串的开头,$符号也只表示字符串的结尾。即:多行模式re.M对match无效
    2. match只会从**字符串的开始位置**(开始位置可以是字符串的开头,也可以用pos指定)**正则表达式的第一个字符**开始匹配。
    3. regex.match中指定开始位置和结束位置后启用多行模式,对^和$符号无影响,依然是指原字符串的开头和结尾  
    4. re.match,re.search,re.fullmatch三个匹配方法中只有re.match忽略多行模式的影响。
3. search方法和作用
    * re.search(pattern,string,flags=0)->match #从头搜索到第一个匹配
    * regex.search(string[,pos[,endpos]])->match #从头搜索到第一个匹配
        * pattern #正则表达式
        * string #需要匹配的字符串
        * flags #模式
        * pos #匹配的起始位置
        * endpos #匹配的结束位置(不包含结束位置)
4. fullmatch方法和作用
    * re.fullmatch(pattern,string,flags=0)->match  #(整个字符串和正则表达式匹配)起始位置和结束位置的字符串和整个正则表达式匹配
    * regex.fullmatch(string[,pos[,endpos]])->match #(整个字符串和正则表达式匹配)起始位置和结束位置的字符串和整个正则表达式匹配
        * pattern #正则表达式
        * string #需要匹配的字符串
        * flags #模式
        * pos #匹配的起始位置
        * endpos #匹配的结束位置(不包含结束位置)
5. findall方法和作用
    * re.findall(pattern,string,flags=0)->list #对整个字符串从左至右匹配,返回所有匹配项的列表
    * regex.findall(string[,pos[,endpos]])->list  #对整个字符串从左至右匹配,返回所有匹配项的列表
        * pattern #正则表达式
        * string #需要匹配的字符
        * flags #模式
        * pos #匹配的起始位置
        * endpos #匹配的结束位置(不包含结束位置)
6. finditer方法和作用
    * re.finditer(pattern,string,flags=0)->iterable #对整个字符串从左至右匹配,返回所有匹配选项,返回迭代器
    * regex.finditer(string[,pos[,endpos]])->iterable ##对整个字符串从左至右匹配,返回所有匹配选项,返回迭代器
        * pattern #正则表达式
        * string #需要匹配的字符
        * flags #模式
        * pos #匹配的起始位置
        * endpos #匹配的结束位置(不包含结束位置)
        * **注意:每次迭代返回的是match对象**   
7. sub方法和作用
    * re.sub(pattern,replacement,string,count=0,flags=0)->new_string #将匹配到的字符替换成指定字符
    * regex.sub(replacement,string,count=0)->new_string #将匹配到的字符替换成指定字符
        * pattern #正则表达式
        * replacement #替换字符串
        * string #字符串(原始字符串)
        * count #替换的次数,默认值为0 表示全部替换
        * flags #模式
        * 返回值new_string #替换后生成的新字符串
    * re.subn(pattern,replacement,string,count=0,flags=0)->(new_string,number_of_subs_made) #将匹配到的字符替换成指定字符
    * regex.subn(replacement,string,count=0)->(new_string,number_of_subs_made) #将匹配到的字符替换成指定字符
        * pattern #正则表达式
        * replacement #替换字符串
        * string #字符串(原始字符串)
        * count #替换的次数,默认值为0 表示全部替换
        * flags #模式
        * 返回值是个元组(new_string,number_of_subs_made)
            * new_string #替换后生成的新字符
            * number_of_subs_made #替换的次数   
8. split方法和作用
    * re.split(pattern,string,maxsplit=0,flags=0)->list
    * regex.split(string,maxsplit=0)->list
        * pattern #正则表达式
        * string #需要切割的字符串
        * maxsplit=0 #最大切割次数,默认值为0,表示全部切割
        * flags #模式

第三题(5分)

  • 解释什么是面向对象的三大要素及其意义。
## 面向对象三要素
1. **封装** 
    * 组装:将数据和操作组装到一起。 
    * 隐藏数据:对外只暴露一些接口,通过接口访问对象。
        * 比如:驾驶员使用汽车,不需要了解汽车的构造细 节,只需要知道使用什么部件怎么驾驶就行,踩了油门就能跑,可以不了解其中的机动原理。
2. **继承**
    * 多复用,继承来的就不用自己写了 
    * 多继承少修改,OCP(Open-closed Principle),使用继承来改变,来体现个性
3. **多态**
    * 面向对象编程灵活的地方,动态绑定

第四题(10分)

  • 随机生成一个长度为20的列表,
  • 列表内元素为1-1000内的纯数字,对其进行排序,要求排序结果为高位数字大小进 行比较,且剔除列表中为3的倍数的元素,
    如生成列表为[183, 224, 86, 402, 334, 635, 278, 521, 360, 805, 739, 627, 871, 752, 600, 143, 213, 427, 156, 4]
    处理后结果为[871, 86, 805, 752, 739, 635, 521, 427, 4, 334, 278, 224, 143]。
import random
lst = [random.randint(1,1000) for i in range(20)]
print("排序前:",lst)
print("排序后:",sorted(filter(lambda x: x%3,lst),key=lambda x: int(str(x)[0]),reverse=True))

20190604_002

第五题:(10分)

  • 编写一个程序,能在当前目录以及当前目录的所有子目录下查找文件名包含指定字符串的文件,并打印出相对路径。
from pathlib import Path

def findPath(findstr):
    return (i for i in Path(".").rglob("*") if i.is_file() and i.name.find(findstr)!=-1)

for i in findPath(".ipynb"):
    print(i)

20190604第二次月考_第2张图片

第六题:(10分)

  • 已知字符串: info = 'test, url("http://www.baidu.com")&,dddddd "=" ininnnin'
  • 要求通过使用正则表达式完成下面2个小功能:
    1.1 关闭[img]标签
    1.2 将url()中的["]转为[']
  • 最后结果字符串:
    "test, url('http://www.baidu.com')&,dddddd "=" ininnnin"
import  re
def amend(string:str):
    rep = re.compile("(]*>)")
    rep2 = re.compile("""(url\()"([^)]*)"(\))""")
    string = rep.sub(r"\1",string)
    string = rep2.sub(r"\1'\2'\3",string)
    return string
info = """test, url("http://www.baidu.com")&,dddddd "=" ininnnin'
"""
print(amend(info))

20190604_004

第七题(10分)

  • 文件a.txt内容:每一行内容分别为商品名字,价钱,个数。
apple 10 3 
tesla 100000 1 
mac 3000 2 
lenovo 30000 3 
chicken 10 3
  • 通过代码,将其构建成这种数据类型:
    [{'name':'apple','price':10,'amount':3}, {'name':'tesla','price':1000000,'amount':1}......]
  • 并计算出总价钱。
from pathlib import Path

class Goods(dict):
    def __init__(self,name,price,amount):
        self["name"] = name
        self["price"] = float(price)
        self["amount"] = int(amount)

    def sumprice(self):
        return self["price"]*self["amount"]

if __name__ == "__main__":
    merch = []
    sumprice = 0
    with open("a.txt") as a:
        for i in a:
            good = Goods(*i.split())
            merch.append(good)
            sumprice += good.sumprice()
    print(merch)
    print("总金额为:{}".format(sumprice))

20190604_005

第八题

  • 编写程序, 编写一个学生类, 要求有一个计数器的属性, 统计总共实例化了多少个学生.
class Students:
    """学生类,能记录所有实例化的学生个数"""
    __length = 0

    def __init__(self,name:str,age:int):
        self.name = name
        self.age = age
        self.__class__.__length += 1

    @classmethod
    def length(cls):
        return cls.__length

if __name__=="__main__":
    studlist = []
    for i in range(5):
        studlist.append(Students("小明",18))
    print("实例化的学生个数为:{}个".format(Students.length()))

第九题

需求:

  1. 房子有户型,总面积和家具名称列表 新房子没有任何的家具
  2. 家具有名字和占地面积,其中 床:占4平米 书柜: 占2平米 餐桌:占1.5平米 椅子4把:每把占地0.5平米
  3. 将以上三件家具添加到房子中 4.打印房子时,要求输出:户 型,总面积,剩余面积,家具名称列表

用面向对象的操作来实现上述需求。

class Furniture:
    """家具类"""
    def __init__(self,name,area):
        self.name = name
        self.area = area

    def __repr__(self):
        return "".format(self.name,self.area)

class House:
    """房子类"""
    def __init__(self,housetype,allarea):
        self.housetype = housetype #户型
        self.allarea = allarea    #总面积
        self.residual_area = allarea #剩余面积
        self.frun = []  #家具列表

    #添加家具方法
    def add_furniture(self,furn:Furniture):
        if self.residual_area>=furn.area:
            self.frun.append(furn)
            self.residual_area -= furn.area
        else:
            print("房子剩面积不够:剩余面为:{},添加的家具面积为:{}".format(self.residual_area,furn.area))
        return self

    def __repr__(self):
        return "户型:{},总面积:{}平米,剩余面积:{}平米,家具列表:{}".format(self.housetype,self.allarea,self.residual_area,self.frun)

if __name__=="__main__":
    house = House("大户型",108)
    house.add_furniture(Furniture("床",4))
    house.add_furniture(Furniture("书柜",1.5))
    house.add_furniture(Furniture("餐桌",1.5))
    for i in range(4):
        house.add_furniture(Furniture("椅子",0.5))
    print(house)

20190604_006

第十题(15份)

应用面向对象模拟一个简单的图书馆管理系统,里面的每本书都含有标题,作者,编号和借阅人等信息。每个借阅人 最多同时借三本书。图书馆提供添加、删除、查找、借阅和归还图书的方法。

class Book:
    """书本信息"""
    def __init__(self,id,name,auto,borrow=None):
        self.id = id    #编号
        self.name = name #标题
        self.auto = auto #作者
        self.borrow = borrow #借阅人

    def __repr__(self):
        return "<编号:{},标题:{},作者:{},借阅人:{}>".format(self.id,self.name,self.auto,self.borrow)

class Reader:
    """读者,借阅人"""
    def __init__(self,name,age):
        self.name = name
        self.age = age

class Library:
    """读书馆"""
    def __init__(self):
        self.books = {} #所有书籍
        self.readers = {} #借阅人信息

    #添加图书
    def addbook(self,book:Book):
        self.books[book.id] = book

    #删除图书
    def removebook(self,id):
        del self.books[id]
        print("删除图书成功")

    #遍历图书
    def __iter__(self):
        return iter(self.books.items())

    #查找图书
    def findbook(self,id):
        return self.books.get(id,None)

    #获取图书馆借阅人借阅次数
    def getreaderlen(self,borrow):
        reader = self.readers.get(borrow, None)
        if reader is None:
            self.readers[borrow] = []
        return self.readers[borrow]

    #借阅图书
    def borrow_book(self,borrow,id):
        if borrow is None:
            print("借阅人不能为None")
            return
        book:Book  = self.findbook(id)

        if book is None:
            print("{}编号的图书不存在".format(id))
            return
        elif book.borrow is not None:
            print("{}编号的图书已经被借走".format(id))
            return

        bbook = self.getreaderlen(borrow)
        print(bbook)
        if len(bbook)>=3:
            print("借阅失败!")
            print("{}借阅次数已达上限(最多三本),已经借阅{}".format(borrow,bbook))
            return
        book.borrow = borrow #图书记录借阅人
        bbook.append(book) #图书馆记录借阅人已经借阅书籍
        print("借阅成功{}".format(book))

     # 归还图书
    def retbook(self,reader,id):
        book = self.findbook(id)
        if reader in self.readers and book is not None:
            book.borrow = None
            bbook:list = self.getreaderlen(reader)
            bbook.remove(book)
            print("归还成功")

if __name__ == "__main__":
    library = Library()
    library.addbook(Book(1,"《西游记》","吴承恩"))
    library.addbook(Book(2,"《怎么吃棒棒糖》","xdd"))
    library.addbook(Book(3,"《python》","xdd"))
    library.addbook(Book(4, "《java》", "xdd"))
    library.addbook(Book(5, "《javascript》", "xdd"))
    zs = Reader("张三",18)
    ls = Reader("李四",19)
    #查找图书演示
    print(library.findbook(1))
    #删除图书演示
    library.removebook(1)
    for i in library:
        print(i)

    #借用图书
    library.borrow_book(zs,2)
    library.borrow_book(ls, 2)

    #借阅图书
    library.borrow_book(zs, 3)
    library.borrow_book(zs, 4)
    library.borrow_book(zs, 5) #借阅失败

    #归还图书
    library.retbook(zs,3)
    library.borrow_book(zs,5)

    #查找图书
    print(library.findbook(3))

20190604第二次月考_第3张图片

进阶题:(20分)

  • 要求: 某次战役中,为便于信息交互,我军侦察部门将此次战役的关键高地坐标设定为(x=0,y=0)并规定,每向东 增加100米,x加1,每向北增加100米,y加1。
  • 同时,我军情报部门也破译了敌军向坦克发送的指挥信号,其中有三种信号(L,R,M)用于控制坦克的运动,L 和 R 分别表示使令坦克向左、向右转向,M 表示令坦克直线开进100米,其它信号如T用于时间同步,P用于反转信号,即 出现p,后面的信号向左变为向右,向右变为向左,反之亦然。
  • 一日,我军侦察兵发现了敌军的一辆坦克,侦察兵立即将坦克所在坐标(P, Q)及坦克前进方向(W:西,E:东, N:北,S:南)发送给指挥部,同时启动信号接收器,将坦克接收到的信号实时同步发往指挥部,指挥部根据这些 信息得以实时掌控了该坦克的位置,并使用榴弹炮精准地击毁了该坦克。
  • 假设,侦察兵发送给指挥部的信息如下:坦克坐标:(11,39)坦克运行方向:W,坦克接收到的信号为: MTMPRPMTMLMRPRMTPLMMTLMRRMP,请通过编程计算出坦克所在的位置.
class Tank:
    def __init__(self,x,y,direction):
        self.x = x
        self.y = y
        self.direction = direction
        self.P = True

    #矫正命令
    def getPdirection(self,direction):
        if self.P:
            return direction
        if direction=="L":
            return "R"
        elif direction=="R":
            return "L"

    #坦克移动方法
    def move(self,num=1):
        if self.direction=="W":
            self.x -= num
        elif self.direction == "E":
            self.x += num
        elif self.direction == "N":
            self.y += num
        elif self.direction == "S":
            self.y -= num

    def unP(self):
        self.p = False if self.P else True

    # 坦克调整方向方法
    def direction_of_adjustment(self, direction):
        direction = self.getPdirection(direction)
        if direction == "L":
            if self.direction == "W":
                self.direction = "S"
            elif self.direction == "S":
                self.direction = "E"
            elif self.direction == "E":
                self.direction = "N"
            elif self.direction == "N":
                self.direction = "W"
        elif direction == "R":
            if self.direction == "W":
                self.direction = "N"
            elif self.direction == "N":
                self.direction = "E"
            elif self.direction == "E":
                self.direction = "S"
            elif self.direction == "S":
                self.direction = "W"

    def go(self,command:str):
        for i in command:
            if i in ["L", "R"]:
                tank.direction_of_adjustment(i)
            elif i == "P":
                tank.unP()
            elif i == "M":
                tank.move()


    def __repr__(self):
        return "方向:{},坐标:(x = {},y = {})".format(self.direction,self.x,self.y)


tank = Tank(11,39,"W")
mm = "MTMPRPMTMLMRPRMTPLMMTLMRRMP"
tank.go(mm)
print(tank)

20190604_008

你可能感兴趣的:(python基本知识)