Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 55 additions & 1 deletion hw1/app.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
from typing import Any, Awaitable, Callable
from http import HTTPStatus
from urllib.parse import parse_qs
from funcs import NotOK, fibonacci, factorial, mean
import json


async def application(
Expand All @@ -12,7 +16,57 @@ async def application(
receive: Корутина для получения сообщений от клиента
send: Корутина для отправки сообщений клиенту
"""
# TODO: Ваша реализация здесь
if 'path' not in scope:
await NotOK(send, HTTPStatus.NOT_FOUND, 'Not found')
return

if scope['path'].startswith('/fibonacci/'):
try:
n = int(scope['path'][11:])
except ValueError:
await NotOK(send, HTTPStatus.UNPROCESSABLE_ENTITY, 'Unprocessable Entity')
return
if n < 0:
await NotOK(send, HTTPStatus.BAD_REQUEST, 'Bad request')
return
await fibonacci(n, send)
return

elif scope['path'].startswith('/factorial'):
params = parse_qs(scope.get('query_string', b'').decode())
try:
n_str = params['n'][0]
except (KeyError, IndexError):
await NotOK(send, HTTPStatus.UNPROCESSABLE_ENTITY, 'Unprocessable Entity')
return
try:
n = int(n_str)
except ValueError:
await NotOK(send, HTTPStatus.UNPROCESSABLE_ENTITY, 'Unprocessable Entity')
return
if n < 0:
await NotOK(send, HTTPStatus.BAD_REQUEST, 'Bad request')
return
await factorial(n, send)
return

elif scope['path'].startswith('/mean'):
message = await receive()
body = message.get('body').decode()
data = json.loads(body)
if not isinstance(data, list):
await NotOK(send, HTTPStatus.UNPROCESSABLE_ENTITY, 'Unprocessable Entity')
return
if not data:
await NotOK(send, HTTPStatus.BAD_REQUEST, 'Bad request')
return
nums = list(map(float, data))
await mean(nums, send)
return

else:
await NotOK(send, HTTPStatus.NOT_FOUND, 'Not found')


if __name__ == "__main__":
import uvicorn
Expand Down
48 changes: 48 additions & 0 deletions hw1/funcs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
from typing import Any, Awaitable, Callable
from http import HTTPStatus
import json

async def NotOK(send: Callable[[dict[str, Any]], Awaitable[None]], status: HTTPStatus, message: str):
await send({
'type': 'http.response.start',
'status': status,
'headers': [[b'content-type', b'text/plain']]
})
await send({'type': 'http.response.body', 'body': message.encode()})

def app(func):
async def wrapper(arg, send):
await send({
'type': 'http.response.start',
'status': HTTPStatus.OK,
'headers': [
[b'content-type', b'text/plain'],
],
})
await send({
'type': 'http.response.body',
'body': json.dumps({'result': func(arg)}).encode(),
})
return wrapper

@app
def fibonacci(n: int) -> int:
def helper(n: int) -> int:
if n < 0:
raise ValueError("n must be non-negative")
return n if n <= 1 else helper(n - 1) + helper(n - 2)
return helper(n)

@app
def factorial(n: int) -> int:
def helper(n: int) -> int:
if n < 0:
raise ValueError("n must be non-negative")
return 1 if n == 0 else n * helper(n - 1)
return helper(n)

@app
def mean(numbers: list[int]) -> float:
if not numbers:
raise ValueError("empty list")
return sum(numbers) / len(numbers)