diff --git a/works/OLDERHARD/M2.1/M2.1.txt b/works/OLDERHARD/M2.1/M2.1.txt new file mode 100644 index 0000000..b78eec2 --- /dev/null +++ b/works/OLDERHARD/M2.1/M2.1.txt @@ -0,0 +1,31 @@ +HTTP 协议的基本组成部分包括: + +HTTP 方法:定义了对特定资源执行的操作。常见的 HTTP 方法包括 GET、POST、PUT、DELETE 等。 + +URL(Uniform Resource Locator):用于标识要访问的资源的地址。 + +HTTP 头部:包含了请求或响应的元数据信息,如内容类型、内容长度、授权信息等。 + +HTTP 主体:可选的,用于传输数据,如 POST 请求中的表单数据。 + +状态码:在响应中指示请求的处理状态,如 200 OK、404 Not Found 等。 + + +HTTP 请求中传参的方式包括: + +查询字符串参数:通过在 URL 的末尾附加参数来传递数据,格式为 '?key1=value1&key2=value2'。 + + 请求头部:在 HTTP 头部中添加自定义的字段来传递参数,例如 'Content-Type: application/json'。 + +3请求主体:主要用于 POST、PUT 请求,将数据作为主体传输,可以是表单数据、JSON 数据等。 + +URL 路径参数:在 URL 中通过路径的方式传递参数,例如 '/users/123' 中的 '123' 就是路径参数。 + +这些都是常见的 HTTP 请求传参方式,选择哪种方式取决于实际需求和约定。HTTP 请求的灵活性和可扩展性使得开发者可以根据需要选择最合适的方式来传递参数。 + + + +Flask 是一个轻量级的 Web 框架,用于构建 Web 应用程序。它提供了路由、请求处理、模板渲染、数据库连接等功能,使开发 Web 应用变得更加简单和灵活。 + +本次作业的流程: +Flask 接收请求,调用本地的 Python 脚本,执行查询逻辑,响应给浏览器。 diff --git a/works/OLDERHARD/M2.1/app.py b/works/OLDERHARD/M2.1/app.py new file mode 100644 index 0000000..51bdb9c --- /dev/null +++ b/works/OLDERHARD/M2.1/app.py @@ -0,0 +1,75 @@ +from flask import Flask,request,jsonify,Response +from fake_useragent import UserAgent +import requests +import json +url="https://codeforces.com/api/user.info" +headers={ + 'user-Agent':UserAgent().random +} +def solve(name): + params = { + "handles": name + } + try: + response=requests.get(url=url,params=params,headers=headers) + status_code =response.status_code + if status_code==200: # 此项 handle 可以查询到 + Json=json.loads(response.text) + user=Json['result'][0] + if 'rating' in user: + return { + 'success':True, + 'result':{ + 'handle':user['handle'], + 'rating':int(user['rating']), + 'rank':user['rank'] + } + } + else: + return { + 'success':True, + 'result':{ + 'handle':user['handle'] + } + } + elif status_code==400: # 此项 handle 无法找到 + return { + 'success':False, + 'type':1, + 'message':'no such handle' + } + else: # 在查询此项时遭遇异常 HTTP 响应 + return { + 'success':False, + 'type':2, + 'message':'HTTP response with code {}'.format(status_code) + } + except requests.exceptions.ConnectionError or requests.exceptions.RequestException as e: # 在查询此项时未收到有效 HTTP 响应 + return { + 'success':False, + 'type':3, + 'message':'Request timeout' + } + except : # 在查询此项时程序发生运行时异常 + return { + 'success':False, + 'type':4, + 'message':'Internal Server Error' + } + + +app=Flask(__name__) # 定义一个Flask的实例 + +@app.route('/') # 装饰器,将 URL 路径映射到下面的处理函数 +def query(): + handles= request.args.get('handles').split(',') + results=[] + for handle in handles: + result= solve(handle) + results.append(result) + return Response(json.dumps(results),mimetype='application/json') # 返回 JSON 格式的查询结果 + + +if __name__=='__main__': + app.run(host='127.0.0.1',debug=True,port=2333) # Flask监听 IP地址和端口号 + diff --git a/works/OLDERHARD/M2.2/M2.2.txt b/works/OLDERHARD/M2.2/M2.2.txt new file mode 100644 index 0000000..da1ba09 --- /dev/null +++ b/works/OLDERHARD/M2.2/M2.2.txt @@ -0,0 +1,38 @@ +后端路由: +后端路由是由服务器处理的。当客户端(通常是浏览器)发出请求时,服务器根据请求的 URL 来找到相应的映射函数,然后执行该函数并将结果返回给客户端。 + +后端路由的流程: +浏览器发出请求。 +服务器监听到请求并解析 URL 路径,这里是Flask。 +根据服务器的路由配置,返回相应信息(可以是 HTML 文件、JSON 数据或图片)。 +浏览器根据数据包的 Content-Type 来解析数据。 + + +当浏览器访问网页时,服务器会返回一个包含 HTTP 状态码的信息头,用以响应浏览器的请求。这些状态码表示服务器对请求的处理结果。以下是常见的 HTTP 状态码: + +1xx(信息性状态码):表示接收的请求正在处理。 +100 Continue:服务器已接收到请求的头部,客户端可以继续发送请求的主体部分。 +101 Switching Protocols:服务器要求客户端切换协议。 + +2xx(成功状态码):表示请求正常处理完毕。 +200 OK:请求成功,一般用于 GET 和 POST 请求。 +201 Created:已创建,成功请求并创建了新的资源。 +204 No Content:无内容,服务器成功处理,但未返回内容。 + +3xx(重定向状态码):需要后续操作才能完成请求。 +300 Multiple Choices:请求的资源有多个选择,服务器可以根据请求的条件返回不同的资源。例如,浏览器请求一个目录时,服务器可以返回多个文件供用户选择。 +301 Moved Permanently:请求的 URL 已永久移动到新位置,用于网站重定向。 +302 Found:临时移动,资源只是临时被移动。 + +4xx(客户端错误状态码):表示请求包含语法错误或无法完成。 +400 Bad Request:客户端请求的语法错误,服务器无法理解。 +401 Unauthorized:表示客户端未经授权,需要提供有效的身份验证凭据。通常用于需要登录的资源。 +403 Forbidden:表示客户端没有访问权限,服务器拒绝请求。这可能是因为客户端没有登录、没有足够的权限或者其他原因。 +404 Not Found:服务器无法找到请求的资源,常见于访问不存在的页面。 + +5xx(服务器错误状态码):服务器在处理请求的过程中发生了错误。 +500 Internal Server Error:服务器内部错误,无法完成请求。 +501 Not Implemented:服务器不支持请求的功能,无法完成请求。这通常是因为服务器没有实现请求的方法(例如,某个 HTTP 方法)。 +502 Bad Gateway:表示服务器作为网关或代理,从上游服务器接收到无效的响应。通常用于反向代理服务器。 +503 Service Unavailable:服务器暂时无法处理客户端的请求。 +504 Gateway Timeout:表示服务器作为网关或代理,无法在规定的时间内从上游服务器接收到响应。这通常是因为上游服务器处理请求的时间过长。 diff --git a/works/OLDERHARD/M2.2/app.py b/works/OLDERHARD/M2.2/app.py new file mode 100644 index 0000000..581a2c6 --- /dev/null +++ b/works/OLDERHARD/M2.2/app.py @@ -0,0 +1,132 @@ +from flask import Flask,request,jsonify,Response,make_response +from fake_useragent import UserAgent +import requests +import json +from datetime import timedelta,datetime +import pytz + + +def solve1(name): + url="https://codeforces.com/api/user.info" + headers={ + 'User-Agent':UserAgent().random + } + params={ + "handles": name + } + try: + response=requests.get(url=url,params=params,headers=headers) + status_code=response.status_code + if status_code==200: # 此项 handle 可以查询到 + Json=json.loads(response.text) + user=Json['result'][0] + if 'rating' in user: + return { + 'success':True, + 'result':{ + 'handle':user['handle'], + 'rating':int(user['rating']), + 'rank':user['rank'] + } + } + else: + return { + 'success':True, + 'result':{ + 'handle':user['handle'] + } + + } + elif status_code==400: # 此项 handle 无法找到 + return { + 'success':True, + 'type':1, + 'message':'no such handle' + } + else: # 在查询此项时遭遇异常 HTTP 响应 + return { + 'success':False, + 'type':2, + 'message':'HTTP response with code {}'.format(status_code), + 'datails':{ + 'status':status_code + } + } + except requests.exceptions.ConnectionError or requests.exceptions.RequestException as e: # 在查询此项时未收到有效 HTTP 响应 + return { + 'success':False, + 'type':3, + 'message':'Request timeout' + } + except: # 在查询此项时程序发生运行时异常 + return { + 'success':False, + 'type':4, + 'message':'Internal Server Error' + } + + +def solve2(name): + url=f"https://codeforces.com/api/user.rating?handle={name}" + headers={ + 'User-Agent':UserAgent().random + } + + try: + response=requests.get(url=url,params=name,headers=headers) + status_code=response.status_code + ans=[] + if status_code==200: + Json=json.loads(response.text) + user=Json['result'] + for date in user: + ratingUpdateTime=date['ratingUpdateTimeSeconds'] + time=datetime.fromtimestamp(ratingUpdateTime, pytz.timezone('Asia/Shanghai')) + ratingUpdateAt=time.isoformat() + result={ + 'handle':date['handle'], + 'contestId':date['contestId'], + 'contestName':date['contestName'], + 'rank':int(date['rank']), + 'ratingUpdateAt':ratingUpdateAt, + 'oldRating':int(date['oldRating']), + 'newRating':int(date['newRating']) + } + ans.append(result) + return ans + elif status_code==400: + return { + 'message':'no such handle' + } + else: + return { + 'message':'HTTP response with code {}'.format(status_code) + } + except requests.exceptions.ConnectionError or requests.exceptions.RequestException as e: + return { + 'message': 'Request timeout', + } + except: + return { + 'message': 'Internal Server Error' + } + +app= Flask(__name__) +@app.route('/batchGetUserInfo') +def get1(): + handles=request.args.get('handles').split(',') + results=[] + for handle in handles: + result =solve1(handle) + results.append(result) + return Response(json.dumps(results),mimetype='application/json') + +@app.route('/getUserRatings') +def get2(): #单用户查询接口 + handle = request.args.get('handle') + result = [] + result = solve2(handle) + return Response(json.dumps(result), mimetype='application/json') + +if __name__ == '__main__': + app.run(host='127.0.0.1', port=2333, debug=True) diff --git a/works/OLDERHARD/M2.3/M2.3.txt b/works/OLDERHARD/M2.3/M2.3.txt new file mode 100644 index 0000000..4083da4 --- /dev/null +++ b/works/OLDERHARD/M2.3/M2.3.txt @@ -0,0 +1,16 @@ +缓存是一种存储机制,旨在提供高速访问已保存的数据或计算结果。它通过将数据存储在临时存储位置,当再次需要这些数据时,可以迅速从缓存中检索,而不是重新进行原始数据的昂贵或时间耗费的获取和计算过程。 + +在设计缓存系统时,需要考虑不同缓存策略的优缺点和适用场景,以优化缓存系统的性能和效率。以下是一些常见的缓存策略: + +Cache-Aside(旁路缓存): +应用程序首先检查缓存中是否有请求的数据,如果有则返回缓存的数据,否则从数据库查询数据并更新缓存,然后返回数据。 +Read-Through(读取穿透): +缓存对数据库进行读取/查询操作,然后更新自己并将请求数据返回给最终用户。 +Refresh-Ahead(预刷新): +在数据过期之前刷新缓存数据,适用于热数据。 +Write-Through(写穿透): +缓存作为主数据存储,首先在缓存中更新数据,然后才在数据库中更新数据。 +Write-Back(写回): +类似于 write-through,但数据库写调用是异步的。 + +当然,本次作业中,这些都没用到,就用了两个字典存储了已访问且未超时的数据一个用来存储访问 /batchGetUserInfo 路由的信息,另一个存储访问 /getUserRatings 路由的信息,提高检索速度 diff --git a/works/OLDERHARD/M2.3/app.py b/works/OLDERHARD/M2.3/app.py new file mode 100644 index 0000000..23d689e --- /dev/null +++ b/works/OLDERHARD/M2.3/app.py @@ -0,0 +1,148 @@ +from flask import Flask,request,jsonify,Response +from fake_useragent import UserAgent +import requests +import json +from datetime import timedelta,datetime +import pytz + +map_user={} +map_rating={} + +def solve1(name): + if name in map_user and map_user[name]['time']>datetime.now(): + return map_user[name]['date'] + + url='https://codeforces.com/api/user.info' + headers={ + 'User-Agent':UserAgent().random + } + params={ + 'handles':name + } + try: + response=requests.get(url=url,params=params,headers=headers) + status_code=response.status_code + if status_code==200: + Json=json.loads(response.text) + user=Json['result'][0] + if 'rating' in user: + date={ + 'success':True, + 'result':{ + 'handle':user['handle'], + 'rating':int(user['rating']), + 'rank':user['rank'] + } + } + else: + date={ + 'success':True, + 'result':{ + 'handle':user['handle'] + } + } + elif status_code==400: + date={ + 'success':True, + 'type':1, + 'message':'no such handle', + } + else: + date={ + 'success':False, + 'type':2, + 'message':'HTTP response with code {}'.format(status_code), + 'datails':{ + 'status':status_code + } + } + map_user[name]={ + 'date':date, + 'time':datetime.now()+timedelta(seconds=15) + } + return date + except requests.exceptions.ConnectionError or requests.exceptions.RequestException as e: + return { + 'success':False, + 'type':3, + 'message':'Request timeout' + } + except: + return { + 'success':False, + 'type':4, + 'message':'Internal Server Error' + } + +def solve2(name): + if name in map_rating and map_rating[name]['time']>datetime.now(): + return map_rating[name]['date'] + + url=f"https://codeforces.com/api/user.rating?handle={name}" + headers={ + 'User-Agent': UserAgent().random + } + params={ + 'handles': name + } + try: + response=requests.get(url=url,params=params,headers=headers) + status_code=response.status_code + if status_code==200: + Json=json.loads(response.text) + user=Json['result'] + ans=[] + for date in user: + ratingUpdateTime=date['ratingUpdateTimeSeconds'] + time=datetime.fromtimestamp(ratingUpdateTime,pytz.timezone('Asia/Shanghai')) + ratingUpdateAt=time.isoformat() + result={ + 'handle':date['handle'], + 'contestId':date['contestId'], + 'contestName':date['contestName'], + 'rank':int(date['rank']), + 'ratingUpdateAt':ratingUpdateAt, + 'oldRating':int(date['oldRating']), + 'newRating':int(date['newRating']) + } + ans.append(result) + elif status_code==400: + ans={ + 'message':'no such handle' + } + else: + ans={ + 'message':'HTTP response with code {}'.format(status_code) + } + map_rating[name]={ + 'date':ans, + 'time':datetime.now()+timedelta(seconds=15) + } + return ans + except requests.exceptions.ConnectionError or requests.exceptions.RequestException as e: + return { + 'message':'Request timeout' + } + except: + return { + 'message':'Internal Server Error' + } + + +app=Flask(__name__) +@app.route('/batchGetUserInfo') +def get1(): + handles=request.args.get('handles').split(',') + results=[] + for handle in handles: + result=solve1(handle) + results.append(result) + return Response(json.dumps(results),mimetype='application/json') +@app.route('/getUserRatings') +def get2(): + handle=request.args.get('handle') + result=[] + result=solve2(handle) + return Response(json.dumps(result),mimetype='application/json') +if __name__=='__main__': + app.run(host='127.0.0.1',port=2333,debug=True) diff --git a/works/OLDERHARD/M2.4/M2.4.txt b/works/OLDERHARD/M2.4/M2.4.txt new file mode 100644 index 0000000..ad3a275 --- /dev/null +++ b/works/OLDERHARD/M2.4/M2.4.txt @@ -0,0 +1,10 @@ +POST请求的几种Content-Type +1. application/x-www-form-urlencoded +“application/x-www-form-urlencoded”是POST请求方法中一种常见的Content-Type类型。对于浏览器的原生
表单,如果不设置“enctype”属性,其就会以“application/x-www-form-urlencoded”对消息主体进行编码。 +2. multipart/form-data +“multipart/form-data”是POST请求方法中另一种常见的Content-Type类型。当我们使用表单上传文件时,必须让表单的enctype属性等于“multipart/form-data”。 +3. application/json +由于JSON规范的流行,“application/json”类型也成为了常见的Content-Type类型之一。实际上,现在越来越多的人使用这种类型发送POST请求,用来告诉服务端消息主体是序列化后的JSON字符串。现在除了低版本IE之外,各大浏览器都对JSON有着良好的支持,服务端语言也都有处理JSON格式内容的相关函数。与通常的键值对相比,JSON格式支持更复杂的结构化数据。 + +关于本次作业,要根据不同的Content-Type类型,按照不同的方式解析请求体的内容,这块还有很多技巧,可以规范地得到想要解析的内容。 +在清除缓存的时候,要按照blue的要求,删除相应的信息和返回相应的响应和状态码。 diff --git a/works/OLDERHARD/M2.4/app.py b/works/OLDERHARD/M2.4/app.py new file mode 100644 index 0000000..11379bc --- /dev/null +++ b/works/OLDERHARD/M2.4/app.py @@ -0,0 +1,226 @@ +from flask import Flask,request,jsonify,Response +from fake_useragent import UserAgent +import requests +import json +from datetime import timedelta,datetime +import pytz + +map_user={} +map_rating={} + + +def solve1(name): + if name in map_user and map_user[name]['time']>datetime.now(): + return map_user[name]['date'] + + url='https://codeforces.com/api/user.info' + headers={ + 'User-Agent':UserAgent().random + } + params={ + 'handles':name + } + try: + response=requests.get(url=url,params=params,headers=headers) + status_code=response.status_code + if status_code==200: + Json=json.loads(response.text) + user=Json['result'][0] + if 'rating' in user: + date={ + 'success':True, + 'result':{ + 'handle':user['handle'], + 'rating':int(user['rating']), + 'rank':user['rank'] + } + } + else: + date={ + 'success':True, + 'result':{ + 'handle':user['handle'] + } + } + elif status_code==400: + date={ + 'success':True, + 'type':1, + 'message':'no such handle', + } + else: + date={ + 'success':False, + 'type':2, + 'message':'HTTP response with code {}'.format(status_code), + 'datails':{ + 'status':status_code + } + } + map_user[name]={ + 'date':date, + 'time':datetime.now()+timedelta(seconds=15) + } + return date + except requests.exceptions.ConnectionError or requests.exceptions.RequestException as e: + return { + 'success':False, + 'type':3, + 'message':'Request timeout' + } + except: + return { + 'success':False, + 'type':4, + 'message':'Internal Server Error' + } + +def solve2(name): + if name in map_rating and map_rating[name]['time']>datetime.now(): + return map_rating[name]['date'] + + url=f"https://codeforces.com/api/user.rating?handle={name}" + headers={ + 'User-Agent': UserAgent().random + } + params={ + 'handles': name + } + try: + response=requests.get(url=url,params=params,headers=headers) + status_code=response.status_code + if status_code==200: + Json=json.loads(response.text) + user=Json['result'] + ans=[] + for date in user: + ratingUpdateTime=date['ratingUpdateTimeSeconds'] + time=datetime.fromtimestamp(ratingUpdateTime,pytz.timezone('Asia/Shanghai')) + ratingUpdateAt=time.isoformat() + result={ + 'handle':date['handle'], + 'contestId':date['contestId'], + 'contestName':date['contestName'], + 'rank':int(date['rank']), + 'ratingUpdateAt':ratingUpdateAt, + 'oldRating':int(date['oldRating']), + 'newRating':int(date['newRating']) + } + ans.append(result) + elif status_code==400: + ans={ + 'message':'no such handle' + } + else: + ans={ + 'message':'HTTP response with code {}'.format(status_code) + } + map_rating[name]={ + 'date':ans, + 'time':datetime.now()+timedelta(seconds=15) + } + return ans + except requests.exceptions.ConnectionError or requests.exceptions.RequestException as e: + return { + 'message':'Request timeout' + } + except: + return { + 'message':'Internal Server Error' + } + +def solve3(response): + ans={ + 'message':'invalid request' + } + status_code=200 + try: + for key in response.keys(): + if key!='cacheType' and key!='handles': #参数不符合请求体的数据结构定义 + status_code=400 + return ans,status_code + if not 'cacheType' in response: + status_code=400 + return ans,status_code + if response['cacheType']!='userInfo' and response['cacheType']!='userRatings': + status_code=400 + return ans,status_code + if response['cacheType']=='userInfo': + if 'handles' in response: + for handle in response['handles']: + if handle in map_user: + del map_user[handle] + else: + map_user.clear() + if response['cacheType']=='userRatings': + if 'handles' in response: + for handle in response['handles']: + if handle in map_rating: + del map_rating[handle] + + else: + map_rating.clear() + ans['message']='ok' + except requests.exceptions.RequestException as e: + status_code=400 + except Exception as e: + status_code=500 + ans['message']='invalid Server Error' + return ans,status_code + + +app=Flask(__name__) + +@app.route('/batchGetUserInfo') +def get1(): + handles=request.args.get('handles').split(',') + results=[] + for handle in handles: + result=solve1(handle) + results.append(result) + return Response(json.dumps(results),mimetype='application/json') + +@app.route('/getUserRatings') +def get2(): + handle=request.args.get('handle') + result=[] + result=solve2(handle) + return Response(json.dumps(result),mimetype='application/json') + +@app.route('/clearCache',methods=['POST']) +def clear_cache(): + if request.content_type=='application/json': + response=request.json + ans=solve3(response) + return jsonify(ans[0]),ans[1] + elif request.content_type=='application/x-www-form-urlencoded': + response=request.form + if 'handles' in response: # 4种情况,handles,handles[],handles[0],无 + list=response.getlist('handles') + response=json.loads(json.dumps(response)) + response['handles']=list + elif 'hanles[]' in response: + list=response.getlist('handles[]') + response=json.loads(json.dumps(response)) + del response['handles[]'] + response['handles']=list + elif 'hanles[0]' in response: + cnt=0 + res={} + list=[] + for key,value in response.items(): + if key=='handles['+str(cnt)+']': + list.append(value) + cnt +=1 + else: + res[key]=value + if len(list)!=0: + res['handles']=list + response=json.loads(json.dumps(res)) + else: + response=json.loads(json.dumps(response)) + ans=solve3(response) + return jsonify(ans[0]),ans[1] + +if __name__=='__main__': + app.run(host='127.0.0.1',port=2333,debug=True) diff --git a/works/OLDERHARD/M2.4/main.py b/works/OLDERHARD/M2.4/main.py new file mode 100644 index 0000000..ac9237d --- /dev/null +++ b/works/OLDERHARD/M2.4/main.py @@ -0,0 +1,15 @@ +import json +import requests + +url = "http://127.0.0.1:2333/clearCache" +headers = { + 'Content-Type': 'application/json' +} +form_data = { + "cacheType": "userInfo", + "handles": ['jiangly','zxw'], + "name":['OLDERHARD'] +} + +response = requests.post(url, json=form_data, headers=headers) +print(response.text) diff --git a/works/OLDERHARD/M3.1/M3.1.txt b/works/OLDERHARD/M3.1/M3.1.txt new file mode 100644 index 0000000..fbf59ec --- /dev/null +++ b/works/OLDERHARD/M3.1/M3.1.txt @@ -0,0 +1,23 @@ +TXT 文本存储: +TXT 文件是最简单的存储格式之一,几乎兼容任何平台。虽然不利于检索,但如果对检索和数据结构要求不高,可以采用 TXT 格式。 +with open('demo.txt', 'a', encoding='utf-8') as file: + file.write(data) + +JSON 文件存储: +JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,适用于结构化数据。Python 中可以使用 json 库进行读写操作。 +import json +with open('demo.json', 'w', encoding='utf-8') as f: + f.write(json.dumps(data, indent=2, ensure_ascii=False)) + +CSV 文件存储: +CSV(Comma-Separated Values)以纯文本形式存储表格数据,逗号分隔。适用于保存大量数据。 +import csv +with open('demo.csv', 'w', encoding='utf-8') as csvf: + writer = csv.writer(csvf) + writer.writerow(['id', 'name', 'gender']) + + +持久化存储通常指将数据保存到磁盘或其他持久性介质中,以便在应用程序关闭后仍然可以访问。这对于保存用户配置、文件、数据库记录等非易失性数据非常有用。 +内存缓存是将数据存储在应用程序的内存中,以便在运行时更快地访问。这对于频繁读取的数据、临时计算结果和缓存数据非常有用。 +持久化存储和内存缓存可以结合使用,以优化性能和数据可靠性。 +可以从数据库中读取数据并将其缓存在内存中,以避免频繁的数据库查询。如果数据发生更改,你可以更新数据库并清除缓存,以便下次重新加载最新数据。 diff --git a/works/OLDERHARD/M3.1/app.py b/works/OLDERHARD/M3.1/app.py new file mode 100644 index 0000000..0c7c666 --- /dev/null +++ b/works/OLDERHARD/M3.1/app.py @@ -0,0 +1,183 @@ +from flask import Flask,request,jsonify,Response +from fake_useragent import UserAgent +import requests +import json +from datetime import timedelta,datetime +import pytz + + +def solve1(name): + + url='https://codeforces.com/api/user.info' + headers={ + 'User-Agent':UserAgent().random + } + params={ + 'handles':name + } + try: + response=requests.get(url=url,params=params,headers=headers) + status_code=response.status_code + if status_code==200: + Json=json.loads(response.text) + user=Json['result'][0] + if 'rating' in user: + ans={ + 'success':True, + 'result':{ + 'handle':user['handle'], + 'rating':int(user['rating']), + 'rank':user['rank'] + } + } + else: + ans={ + 'success':True, + 'result':{ + 'handle':user['handle'] + } + } + return ans + elif status_code==400: + ans={ + 'success':True, + 'type':1, + 'message':'no such handle' + } + return ans + else: + ans={ + 'success':False, + 'type':2, + 'message':'HTTP response with code {}'.format(status_code), + 'details':{ + 'status':status_code + } + } + return ans + except requests.exceptions.ConnectionError or requests.exceptions.RequestException as e: + ans={ + 'success':False, + 'type':3, + 'message':'Request timeout' + } + return ans + except: + ans={ + 'success':False, + 'type':4, + 'message':'Internal Servel Error' + } + return ans + +def find1(name): + try: + with open('user_info','r') as f: # 如果存在,尝试打开 + cache_date=json.load(f) + deadline=datetime.fromtimestamp(cache_date['deadline']) + if cache_date['name']==name and deadline>datetime.now(): + return cache_date['date'] + except: + pass + date=solve1(name) + deadline=datetime.now()+timedelta(seconds=30) + cache_date={ + 'deadline':deadline.isoformat(), + 'date':date, + 'name':name + } + with open('user_info','w') as f: + json.dump(cache_date,f) + return date + +def solve2(name): + + url=f"https://codeforces.com/api/user.rating?handle={name}" + headers={ + 'User_Agent':UserAgent().random + } + params={ + 'handles':name + } + try: + response=requests.get(url=url,params=params,headers=headers) + status_code=response.status_code + if status_code==200: + Json=json.loads(response.text) + user=Json['result'] + ans=[] + for date in user: + ratingUpdateTime=date['ratingUpdateTimeSeconds'] + time=datetime.fromtimestamp(ratingUpdateTime,pytz.timezone('Asia/Shanghai')) + ratingUpdateAt=time.isoformat() + result={ + 'handle': date['handle'], + 'contestId': date['contestId'], + 'contestName': date['contestName'], + 'rank': int(date['rank']), + 'ratingUpdateAt': ratingUpdateAt, + 'oldRating': int(date['oldRating']), + 'newRating': int(date['newRating']) + } + ans.append(result) + return ans + elif status_code==400: + ans={ + 'message':'no such handle' + } + return ans + else: + ans={ + 'message':'HTTP response with code {}'.format(status_code) + } + return ans + except requests.exceptions.ConnectionError or requests.exceptions.RequestException as e: + ans={ + 'message':'Request timeout' + } + return ans + except: + ans={ + 'message':'Internal Server Error' + } + return ans + +def find2(name): + try: + with open('user_rating','r') as f: #如果存在,尝试打开 + cache_date=json.load(f) + deadline=datetime.fromtimestamp(cache_date['deadline']) + if cache_date['name']==name and deadline > datetime.now(): + return cache_date['date'] + except: + pass + date=solve2(name) + deadline=datetime.now()+timedelta(seconds=30) + cache_date={ + 'deadline':deadline.isoformat(), + 'date':date, + 'name':name + } + with open('user_rating','w') as f: + json.dump(cache_date,f) + return date + +app=Flask(__name__) + +@app.route('/batchGetUserInfo') +def get1(): + handles=request.args.get('handles').split(',') + results=[] + for handle in handles: + result=find1(handle) + results.append(result) + return Response(json.dumps(results),mimetype='application/json') + +@app.route('/getUserRatings') +def get2(): + handle=request.args.get('handle') + result=find2(handle) + return Response(json.dumps(result),mimetype='application/json') + +if __name__=='__main__': + app.run(host='127.0.0.1',port=2333,debug=True) diff --git a/works/OLDERHARD/M3.2/M3.2.txt b/works/OLDERHARD/M3.2/M3.2.txt new file mode 100644 index 0000000..ec09531 --- /dev/null +++ b/works/OLDERHARD/M3.2/M3.2.txt @@ -0,0 +1,24 @@ +关系型数据库(RDB): +关系型数据库是一种以关系(即表格)为基础的数据库。它使用关系代数等数学概念和方法来处理数据。 +数据以行和列的形式存储在表中,每个表都由一组行和列组成。 +用户通过查询来检索数据库中的数据,查询是一个用于限定数据库中某些区域的执行代码。 + +SQLite 数据类型: +SQLite 是一种轻量级的嵌入式数据库,常用于移动应用和小型项目。 +它支持以下数据类型: +NULL:空值。 +INTEGER:带符号的整数,根据值的大小存储在 1、2、3、4、6 或 8 字节中。 +REAL:浮点数,存储为 8 字节的 IEEE 浮点数字。 +TEXT:文本字符串,使用数据库编码(UTF-8、UTF-16BE 或 UTF-16LE)存储。 +BLOB:二进制对象。 + +主键和外键: +主键:用于唯一标识表中每一行数据的字段或字段组合。主键的值在表中必须是唯一的。 +外键:用于建立表与表之间的关系。外键引用另一个表的主键,可能存在多个相同的外键值。 + +SQL 语句: +查询数据:使用 SELECT 语句来检索数据。您可以使用 WHERE 子句指定条件,使用 ORDER BY 子句排序结果,使用 JOIN 操作连接多个表。 +更新数据:使用 UPDATE 语句修改表中已经存在的数据。语法:UPDATE 表名 SET 列名1 = 新值1, 列名2 = 新值2, ... WHERE 条件表达式; +删除数据:使用 DELETE 语句删除表中不再使用的数据。语法:DELETE FROM 表名 WHERE 条件表达式; + +本次作业,把运行逻辑弄清楚了,对sqlite3和SQL语句使用的不熟练。 diff --git a/works/OLDERHARD/M3.2/app.py b/works/OLDERHARD/M3.2/app.py new file mode 100644 index 0000000..e7d0e55 --- /dev/null +++ b/works/OLDERHARD/M3.2/app.py @@ -0,0 +1,252 @@ +from flask import Flask,request,jsonify,Response +from fake_useragent import UserAgent +import requests +import json +from datetime import timedelta,datetime +import pytz +import sqlite3 + + +def sqlite_user_info(handle,rating,rank): + with sqlite3.connect('cf.db') as conn: + cursor=conn.cursor() + cursor.execute("PRAGMA foreign_keys = ON") #将外键约束打开 + now = datetime.now(pytz.timezone('Asia/Shanghai')).isoformat() + cursor.execute(''' + INSERT OR REPLACE INTO + user_info(handle,rating,rank,updated_at) + VALUES(?,?,?,?)''',(handle,rating,rank,now)) + conn.commit() #提交事务 + +def sqlite_user_rating(handle,contestId,contestName,rank,oldRating,newRating,ratingUpdatedAt): + with sqlite3.connect('cf.db') as conn: + cursor = conn.cursor() + cursor.execute("PRAGMA foreign_keys = ON") #将外键约束打开 + now = datetime.now(pytz.timezone('Asia/Shanghai')).isoformat() + cursor.execute(''' + SELECT handle FROM user_info WHERE handle = ? + ''',(handle,)) + date=cursor.fetchone() #获取查询结果的第一行数据 + if date is None: + solve1(handle) + cursor.execute(''' + INSERT OR REPLACE INTO + user_ratings(handle,contest_id,contest_name,rank,old_rating,new_rating,rating_updated_at,updated_at) + VALUES(?,?,?,?,?,?,?,?)''',(handle,contestId,contestName,rank,oldRating,newRating,ratingUpdatedAt,now)) + conn.commit() #提交事务 +def solve1(name): + with sqlite3.connect('cf.db') as conn: + cursor = conn.cursor() + sub=(datetime.now(pytz.timezone('Asia/Shanghai'))-timedelta(seconds=30)).isoformat() + cursor.execute(''' + SELECT rating,rank + FROM user_info + WHERE handle = ? AND updated_at > ?''',(name,sub)) + res=cursor.fetchone() #获取查询结果的第一行数据 + if res: + rating,rank=res + if rating and rank: + result={ + 'handle':name, + 'rating':rating, + 'rank':rank + } + else: + result={ + 'handle':name + } + ans={ + 'success':True, + 'result':result + } + return ans + url='https://codeforces.com/api/user.info' + headers={ + 'User-Agent':UserAgent().random + } + params={ + 'handles':name + } + try: + response=requests.get(url=url,params=params,headers=headers) + status_code=response.status_code + if status_code==200: + Json=json.loads(response.text) + user=Json['result'][0] + if 'rating' in user: + ans={ + 'success':True, + 'result':{ + 'handle':user['handle'], + 'rating':int(user['rating']), + 'rank':user['rank'] + } + } + sqlite_user_info(user['handle'],user['rating'],user['rank']) + conn.close() + else: + ans={ + 'success':True, + 'result':{ + 'handle':user['handle'] + } + } + return ans + elif status_code==400: + ans={ + 'success':True, + 'type':1, + 'message':'no such handle' + } + return ans + else: + ans={ + 'success':False, + 'type':2, + 'message':'HTTP response with code {}'.format(status_code), + 'details':{ + 'status':status_code + } + } + return ans + except requests.exceptions.ConnectionError or requests.exceptions.RequestException as e: + ans={ + 'success':False, + 'type':3, + 'message':'Request timeout' + } + return ans + except: + ans={ + 'success':False, + 'type':4, + 'message':'Internal Servel Error' + } + return ans + +def solve2(name): + with sqlite3.connect('cf.db') as conn: + cursor = conn.cursor() + sub = (datetime.now(pytz.timezone('Asia/Shanghai')) - timedelta(seconds=30)).isoformat() + cursor.execute(''' + SELECT contest_id,contest_name,rank,old_rating,new_rating,rating_updated_at + FROM user_ratings + WHERE handle =? AND updated_at > ? + ''',(name,sub)) + res=cursor.fetchall() #获取查询结果的所有行数据 + if res: + ans=[] + for date in res: + contest_id,contest_name,rank,oldrating,newrating,ratingUpdatedAt= date + result={ + 'handle':name, + 'contestId':contest_id, + 'contestName':contest_name, + 'rank':rank, + 'ratingUpdatedAt':ratingUpdatedAt, + 'oldrating':oldrating, + 'newrating':newrating + } + ans.append(result) + return ans + + url=f"https://codeforces.com/api/user.rating?handle={name}" + headers={ + 'User_Agent':UserAgent().random + } + params={ + 'handles':name + } + try: + response=requests.get(url=url,params=params,headers=headers) + status_code=response.status_code + if status_code==200: + Json=json.loads(response.text) + user=Json['result'] + ans=[] + for date in user: + ratingUpdateTime=date['ratingUpdateTimeSeconds'] + time=datetime.fromtimestamp(ratingUpdateTime,pytz.timezone('Asia/Shanghai')) + ratingUpdatedAt=time.isoformat() + result={ + 'handle': date['handle'], + 'contestId': date['contestId'], + 'contestName': date['contestName'], + 'rank': int(date['rank']), + 'ratingUpdatedAt': ratingUpdatedAt, + 'oldRating': int(date['oldRating']), + 'newRating': int(date['newRating']) + } + ans.append(result) + sqlite_user_rating(date['handle'],date['contestId'],date['contestName'],int(date['rank']),int(date['oldRating']),int(date['newRating']),ratingUpdatedAt) + conn.close() + return ans + elif status_code==400: + ans={ + 'message':'no such handle' + } + return ans + else: + ans={ + 'message':'HTTP response with code {}'.format(status_code) + } + return ans + except requests.exceptions.ConnectionError or requests.exceptions.RequestException as e: + ans={ + 'message':'Request timeout' + } + return ans + except: + ans={ + 'message':'Internal Server Error' + } + return ans + +def creat(): + with sqlite3.connect('cf,db') as conn: + cursor=conn.cursor() + cursor.execute(''' + CREATE TABLE IF NOT EXISTS user_info( + handle VARCHAR PRIMARY KEY NOT NULL, + rating INT, + rank VARCHAR, + updated_at DATETIME NOT NULL + ) + ''') + cursor.execute(''' + CREATE TABLE IF NOT EXISTS user_ratings( + user_rating_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, + handle VARCHAR NOT NULL, + contest_id INT NOT NULL, + contest_name VARCHAR NOT NULL, + rank INT NOT NULL, + old_rating INT NOT NULL, + new_rating INT NOT NULL, + rating_updated_at DATETIME NOT NULL, + updated_at DATETIME NOT NULL, + FOREIGN KEY (handle) REFERENCES user_info (handle), + UNIQUE(handle,contest_id) ON CONFLICT REPLACE + ) + ''') + conn.commit() + +app=Flask(__name__) + +@app.route('/batchGetUserInfo') +def get1(): + handles=request.args.get('handles').split(',') + results=[] + for handle in handles: + result=solve1(handle) + results.append(result) + return Response(json.dumps(results),mimetype='application/json') + +@app.route('/getUserRatings') +def get2(): + handle=request.args.get('handle') + result=solve2(handle) + return Response(json.dumps(result),mimetype='application/json') + +if __name__=='__main__': + creat() + app.run(host='127.0.0.1',port=2333,debug=True) diff --git a/works/OLDERHARD/README.md b/works/OLDERHARD/README.md new file mode 100644 index 0000000..644a7b1 --- /dev/null +++ b/works/OLDERHARD/README.md @@ -0,0 +1 @@ +My name is olderhard, and I'm not a two-dimensional.