python进阶--月考五

(一)使用socket和多线程,实现支持多人对话的聊天室

1.实现服务端server中Manager类,实现管理员进入和离开聊天室,接受成员消息并广播
2.实现客户端client中Chatter类,实现向管理员发送加入和退出的请求,发送和接受消息
3.Manager类需要使用多线程服务多个用户
4.Chatter类需要使用多线程进行发送接受消息
5.Manager类具有定向转发功能,比如Chatter可以在消息中通过@指定用户,这样Manager将只把消息转发给对应用户
6.Chatter离开时,自动将聊天室保存到本地记录client.log中,包括时间,发信人,发送信息
7.Manger同时需要将信息存入到本地的mysql中
8.正确连接本地mysql,表自定义
import socket
import threading,datetime,pymysql

conn = pymysql.connect(
    host='127.0.0.1',
    port=3306,
    user='root',
    password='12345678',
    db='test_m4'
)
cursor = conn.cursor()

#服务器端的类
class Manager():
    users = {}  # 建群
    def msg(self,client):
        while True:
            #发件人【0】@收件人【1】@消息【2】
            str1 = client.recv(1024).decode()
            if str1:
                print(str1)
                send_str = int(str1.split('@')[0])  #发件人
                recv_str = int(str1.split('@')[1])  #收件人
                msg_str = str1.split('@')[2]  #消息

                # 离开
                if msg_str == 'bye':
                    self.users.pop(send_str)  # 踢人
                    print(f'{send_str}客户端已退出')

                # 存聊天记录
                sql = f"insert msg(send_name,recv_name,message,s_time) VALUES('{send_str}','{recv_str}','{msg_str}','{datetime.datetime.now()}')"
                cursor.execute(sql)
                conn.commit()

                # 群聊
                if recv_str == 0:
                    for i in self.users.values():
                        i.send(f'{send_str}:{msg_str}'.encode())
                else:
                    #私聊  收件人
                    self.users.get(recv_str).send(f'{send_str}:{msg_str}'.encode())

    def create_server(self):
        server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        server.bind(('127.0.0.1', 7007))
        server.listen(128)

        while True:
            client, ip = server.accept()  #ip[0]ip地址  ip[1]端口号
            self.users[ip[1]] = client
            print(f'欢迎{ip[1]}加入聊天室')

            thread1 = threading.Thread(target=self.msg, args=(client,))
            thread1.start()

if __name__ == '__main__':
    m = Manager()
    m.create_server()

客户端

import datetime
import socket
import threading


class Chatter():

    messeage = []
    def msg_send(self,client):
        while True:
            str1 = input(':>')
            client.send(str1.encode())
            #55898@55898@hello
            if 'bye'in str1:
                with open('client.log','a') as f:
                    f.write(f'{self.messeage}')
                break

    def msg_recv(self,client):
        while True:
            str2 = client.recv(1024).decode()
            if str2:
                self.messeage.append(f'{datetime.datetime.now()}--{str2}')   #缓存到列表里
                print(str2)

    def create_client(self):
        client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        client.connect(('127.0.0.1', 7007))
        #发送的线程
        thread1 = threading.Thread(target=self.msg_send,args=(client,))
        thread1.start()
        #接收的线程
        thread2 = threading.Thread(target=self.msg_recv, args=(client,))
        thread2.start()

if __name__ == '__main__':
    c =  Chatter()  #创建对象,是为了调用类中的函数
    c.create_client()

(二)创建my_web.py,使用python装饰器以及socket实现简易的web静态服务器

1.编写一个TCP服务端程序,支持持续接受浏览器的访问
2.正确获取浏览器发送的HTTP请求报文数据
3.如果请求报文是index的话,返回本地的index.html(文件自定义),如果是资源未找到的话,返回404,如果是baidu的话,支持重定向到baidu的官网
4.读取固定页面数据,把页面数据组装成HTTP响应报文数据发给浏览器
5.HTTP响应报文数据发送完成以后,关闭服务于客户端的套接字
6.定义日志装饰器,记录每次请求的报文信息以及当前时间到web.log中
import datetime
import socket
from functools import wraps

def my_log(fn):  #fn = main
    @wraps(fn)
    def inner(*args,**kwargs):
        bw = fn(*args,**kwargs) #str1是main的返回值
        with open('web.log','a') as f:
            f.write(f'报文:{bw}---当前时间{datetime.datetime.now()}')
        return bw
    return inner

@my_log
def main():
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server.bind(('127.0.0.1', 9008))
    server.listen(5)

    client, ip = server.accept()
    bw = client.recv(1024).decode()  # 报文
    print(bw)
    path = bw.split(' ')[1]  #地址
    print(path)
    if path == '/index':
        try:
            with open('index.html', 'r') as f:
                str1 = f.read()
        except BaseException as e:
            str2 = f'HTTP/1.1 404 not found\nServer:amy\n\n404'
            client.send(str2.encode())
            print(e)
        else:
            str2 = f'HTTP/1.1 200 Ok\nServer:amy\n\n{str1}'
            client.send(str2.encode())
    elif path == '/baidu':
        with open('baidu.html', 'r') as f:
            str1 = f.read()
        str2 = f'HTTP/1.1 307\nServer:amy\n\n{str1}'  # 307重定向
        client.send(str2.encode())
    server.close() #关闭服务器
    return bw

if __name__ == '__main__':
    main()

(三)创建my_process.py,使用python多进程完成如下需求

具体要求:
1.定义一个进程,随机生成多个数字,存入到队列中
2.定义一个进程,获取生成的数字中,可以构成多少个三角形
3.定义一个进程,获取上面可以构成三角形的3个边的数据,分别计算对应的三角形周长
4.正确保证数据的执行的效果
import multiprocessing
import random


#生成随机3个数,放队列
def get_num(queue1):
    for i in range(3):
        num = random.randint(1,9)
        queue1.put(num)

def check_num(queue1,queue2):
    list1 = []  #[1,1,1]
    for i in range(3):
        list1.append(queue1.get())

    #等边
    if list1[0]== list1[1] == list1[2]:
        print(f'{list1}是等边三角形')
        queue2.put([list1])  #[[3,3,3]]

    #等腰
    elif list1[0]== list1[1] or list1[2]== list1[1] or list1[0]== list1[2]:
        #是不是能组成三角形(两边之和大于第三边)
        if list1[0]+list1[1] >list1[2] and  list1[0]+list1[2] >list1[1] and list1[2]+list1[1] >list1[0]:
            queue2.put([list1])
    else:
        #推导式(三个数字,能有多少种排列的情况) [[],[],[]]
        list2 = [[x,y,z] for x in list1 for y in list1 for z in list1 if x+y>z and x+z>y and y+z>x and x!=y and x!=z and y!=z]
        queue2.put(list2)

def sum1(queue2):
    list3 = queue2.get()  #[[1,1,1]]  [[2,2,1]]   [[],[],[]]
    print(f'构成{len(list3)}个三角形')
    for i in list3:  #i是小列表 ,每个小列表里有三个数字,表示三角形的三条边
        print(f'三角形{i},和是{sum(i)}')

if __name__ == '__main__':

    queue1 = multiprocessing.Queue()
    queue2 = multiprocessing.Queue()
    pro1 = multiprocessing.Process(target=get_num,args=(queue1,))
    pro1.start()
    pro1.join()
    pro2 = multiprocessing.Process(target=check_num, args=(queue1,queue2))
    pro2.start()
    pro2.join()
    pro3 = multiprocessing.Process(target=sum1, args=(queue2,))
    pro3.start()
    pro3.join()


(四)创建my_test.py,完成以下推导式

old_student_score_info={"Jack":{"chinese":87,"math":92,"english":78},
                        "Tom":{"chinese":92,"math":100,"english":89}}
# 1.从上述包含所有学生成绩信息的字典中,找出数学考满分的同学
dict1 = {k:v for k,v in old_student_score_info.items() if v.get('math') == 100}
print(dict1)
# 2.提取上述图片中每个同学的姓名以及总成绩作为字典,将所有同学的信息存入到列表中
dict1 = {k:sum(v.values()) for k,v in old_student_score_info.items() }
print(dict1)
# 3.生成器推导式生成1-10000直接所有偶数的平方
list43 = (i**2 for i in range(1,10001) if i %2 == 0)
print(list43)

# 4.使用推导式生成如下数据[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2)]
list4 =[(x,y) for x in range(2) for y in range(3)]
print(list4)
# 5.使用嵌套推导式生成九九乘法表
list5 = [f'{x}*{y}={x*y}' for x in range(1,10) for y in range(1,10) if x<=y]
print(list5)


  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值