Вычисление математических выражений в строке в python

У меня есть куча уравнений, загруженных из файла JSON, и я хотел бы оценить эти выражения. Эти выражения имеют некоторые константы, и значения констант (K1, K2, ...) также сохраняются в файле json. Значения, соответствующие переменным (var1, var2 ...), присутствующим в выражениях, определены в словаре vars. Я хочу вставить значения констант и переменных в выражения и вычислить числовые значения.

import json
vars = {"var1": 1, "var2": 2, "var3": 3, "var4": 4, "var5": 5, "var6": 5}
with open("tst.json", 'r') as f:
     r = json.load(f)
     print(r)

json-контент:

{
  "EQ1": {
    "parameters": {
      "EQ1_coeff1": {
        "value": 1.0e-06
      },
      "P2": {
        "value": 3.0
      },
      "P3": {
        "value": 3.0
      }
    },
    "expression": "(EQ1_coeff1 * ((1 dimensionless)/(1 dimensionless)) / (1 dimensionless))*(var1^P3/(var1^P3 + P2^P3) )"
  },
  "EQ2": {
    "parameters": {
      "EQ2_coeff2": {
        "value": 5253
      },
      "K2": {
        "value": 3
      },
      "K5": {
        "value": 1
      },
      "K3": {
        "value": 525
      },
      "K4": {
        "value": 3
      },
      "K6": {
        "value": 2
      },
      "K7": {
        "value": 0.01
      }
    },
    "expression": "(EQ2_coeff2 *((var2*var3)/(K1*K2))* ((1 dimensionless - ((var3*var4)/(var2))/K6) / ((1 dimensionless + var1/K1)*(1 dimensionless + var2)+ 1 dimensionless)))*(1 dimensionless/(1 dimensionless + var5/K7))"
  }
}

Я хотел бы попросить совета о том, как можно вычислить эти выражения (хранящиеся в expression).

Примечание:

1 dimensionless не что иное, как 1.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
110
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я просто обновлю globals() на dict, а затем использую eval, как показано ниже:

import json
vars = {"var1": 1, "var2": 2, "var3": 3, "var4": 4, "var5": 5, "var6": 5}
r = {
  "EQ1": {
    "parameters": {
      "EQ1_coeff1": {
        "value": 1.0e-06
      },
      "P2": {
        "value": 3.0
      },
      "P3": {
        "value": 3.0
      }
    },
    "expression": "(EQ1_coeff1 * ((1 dimensionless)/(1 dimensionless)) / (1 dimensionless))*(var1^P3/(var1^P3 + P2^P3) )"
  },
  "EQ2": {
    "parameters": {
      "EQ2_coeff2": {
        "value": 5253
      },
      "K2": {
        "value": 3
      },
      "K5": {
        "value": 1
      },
      "K3": {
        "value": 525
      },
      "K4": {
        "value": 3
      },
      "K6": {
        "value": 2
      },
      "K7": {
        "value": 0.01
      }
    },
    "expression": "(EQ2_coeff2 *((var2*var3)/(K1*K2))* ((1 dimensionless - ((var3*var4)/(var2))/K6) / ((1 dimensionless + var1/K1)*(1 dimensionless + var2)+ 1 dimensionless)))*(1 dimensionless/(1 dimensionless + var5/K7))"
  }
}

globals().update( **{k:v['value'] for k,v in r["EQ1"]["parameters"].items()})
globals().update( **{k:v['value'] for k,v in r["EQ2"]["parameters"].items()})
globals().update(**vars)

eval(r['EQ1']['expression'].replace("dimensionless", "").replace("^", "**"))

Это дает: 3.571428571428571e-08

Для EQ2 у вас не определена переменная K1. Это скорее хак, но я не знаю более элегантного способа. Также имейте в виду, что eval — не очень безопасная функция.

большое спасибо, помогает! Не могли бы вы сообщить мне, в какой форме оценки выражений Also keep in mind eval is a not very safe function это небезопасно.

Natasha 22.12.2020 14:29

М рад помочь :). eval может вызвать проблемы, если вы получите строку из ненадежного источника. Некоторая вредоносная строка при выполнении может нанести серьезный ущерб.

quest 22.12.2020 14:37

Спасибо за разъяснения. Кроме того, не могли бы вы немного объяснить, как работает global. Большое спасибо!

Natasha 22.12.2020 15:25

globals() возвращает словарь, в котором указаны все переменные, доступные в глобальной области видимости. Этот ответ очень поучителен stackoverflow.com/a/12694065/4551984

quest 22.12.2020 15:34

Другие вопросы по теме