1
0
Fork 0
mirror of https://github.com/EDeev/school_menu.git synced 2026-10-08 04:59:35 +03:00

Разбор граммовки и калорийности без eval

Значения ячеек Excel-меню с сайта школы вычислялись через eval — любой текст в файле
выполнился бы как код. Теперь arithmetic() разбирает только числа и + - * /.
This commit is contained in:
Деев Егор Викторович 2026-10-02 23:40:56 +00:00
parent ac866d7df1
commit ad20d4adea

View file

@ -1,7 +1,24 @@
import ast
import operator
import requests as req import requests as req
import datetime as dt import datetime as dt
import openpyxl, os, re import openpyxl, os, re
_OPS = {ast.Add: operator.add, ast.Sub: operator.sub, ast.Mult: operator.mul, ast.Div: operator.truediv}
def arithmetic(text):
"""Значение ячейки вида «150» или «150+30»: только числа и + - * /, без eval."""
def calc(node):
if isinstance(node, ast.Constant) and isinstance(node.value, (int, float)):
return node.value
if isinstance(node, ast.BinOp) and type(node.op) in _OPS:
return _OPS[type(node.op)](calc(node.left), calc(node.right))
if isinstance(node, ast.UnaryOp) and isinstance(node.op, ast.USub):
return -calc(node.operand)
raise ValueError(f"недопустимое значение в ячейке: {text!r}")
return calc(ast.parse(text, mode="eval").body)
def eating(day): def eating(day):
if day == 0: if day == 0:
@ -38,8 +55,8 @@ def eating(day):
if employees_sheet[f"D{j[1] + i}"].value is None: if employees_sheet[f"D{j[1] + i}"].value is None:
continue continue
gramm = str(int(eval(str(employees_sheet[f"E{j[1] + i}"].value).strip()))) gramm = str(int(arithmetic(str(employees_sheet[f"E{j[1] + i}"].value).strip())))
kkal = str(eval("".join(str(employees_sheet[f"J{j[1] + i}"].value).split()).replace(",", ".", 1))) kkal = str(arithmetic("".join(str(employees_sheet[f"J{j[1] + i}"].value).split()).replace(",", ".", 1)))
food[j[0]].append([employees_sheet[f"D{j[1] + i}"].value, [gramm, kkal]]) food[j[0]].append([employees_sheet[f"D{j[1] + i}"].value, [gramm, kkal]])