KarrLab/wc_lang

View on GitHub
examples/jupyter_examples/Math expressions.ipynb

Summary

Maintainability
Test Coverage
{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Dynamic Expressions"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Define wc_lang math expressions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import warnings\n",
    "warnings.simplefilter(\"ignore\")\n",
    "import wc_lang\n",
    "from wc_lang import (Model, SpeciesType, Species, Compartment, Parameter, Function, FunctionExpression, Observable,\n",
    "                     StopCondition, ExpressionMethods)\n",
    "\n",
    "def make_test_reference_objects():\n",
    "    model = Model()\n",
    "    comp = model.compartments.create(id='comp')\n",
    "    objects = {\n",
    "        Observable: {},\n",
    "        Parameter: {},\n",
    "        Function: {},\n",
    "        Species: {},\n",
    "    }\n",
    "    for id in ['a', 'b', 'duped_id']:\n",
    "        objects[Parameter][id] = model.parameters.create(id=id)\n",
    "    for id in ['ccc', 'ddd', 'duped_id']:\n",
    "        objects[Observable][id] = model.observables.create(id=id)\n",
    "    for id in ['f', 'g', 'duped_id']:\n",
    "        objects[Function][id] = model.functions.create(id=id)\n",
    "    species_types = []\n",
    "    for i in range(4):\n",
    "        species_type = model.species_types.create(id='spec_type_{}'.format(i))\n",
    "        species = Species(species_type=species_type, compartment=comp)\n",
    "        objects[Species][species.get_id()] = species\n",
    "    return model, objects\n",
    "\n",
    "model, objects = make_test_reference_objects()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Function"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "id: fun_1\n"
     ]
    }
   ],
   "source": [
    "# Function can reference Observables, Parameters, and other Functions, and it can use some Python functions\n",
    "fun_1 = ExpressionMethods.make_obj(model, Function, 'fun_1', 'ccc + max(a, ddd)', objects)\n",
    "# make_obj has this signature:\n",
    "# def make_obj(model, model_type, id, expression, objects)\n",
    "print('id:', fun_1.id)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "type of expression: FunctionExpression\n",
      "valid_functions: (<built-in function ceil>, <built-in function floor>, <built-in function exp>, <built-in function pow>, <built-in function log>, <built-in function log10>, <built-in function min>, <built-in function max>)\n"
     ]
    }
   ],
   "source": [
    "# each math expression has a corresponding Expression object\n",
    "print('type of expression:', type(fun_1.expression).__name__)\n",
    "# math expressions that can use Python functions have a list of valid functions in Meta\n",
    "print('valid_functions:', FunctionExpression.Meta.valid_functions)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "expression: ccc + max(a, ddd)\n",
      "observables: ['ccc', 'ddd']\n",
      "parameters: ['a']\n",
      "functions: []\n"
     ]
    }
   ],
   "source": [
    "# references to the objects used are stored in a related attribute\n",
    "print('expression:', fun_1.expression.expression)\n",
    "for attr in ['observables', 'parameters', 'functions']:\n",
    "    print(\"{}: {}\".format(attr, [obj.get_id() for obj in getattr(fun_1.expression, attr)]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "analyzed_expr tokens: ['ccc', '+', 'max', '(', 'a', ',', 'ddd', ')']\n",
      "\n",
      "analyzed_expr wc_tokens:\n",
      "   WcLangToken(tok_code=<TokCodes.wc_lang_obj_id: 1>, token_string='ccc', model_type=<class 'wc_lang.core.Observable'>, model_id='ccc', model=<wc_lang.core.Observable object at 0x7fc04c0cc748>)\n",
      "  WcLangToken(tok_code=<TokCodes.op: 4>, token_string='+', model_type=None, model_id=None, model=None)\n",
      "  WcLangToken(tok_code=<TokCodes.math_fun_id: 2>, token_string='max', model_type=None, model_id=None, model=None)\n",
      "  WcLangToken(tok_code=<TokCodes.op: 4>, token_string='(', model_type=None, model_id=None, model=None)\n",
      "  WcLangToken(tok_code=<TokCodes.wc_lang_obj_id: 1>, token_string='a', model_type=<class 'wc_lang.core.Parameter'>, model_id='a', model=<wc_lang.core.Parameter object at 0x7fc04c100828>)\n",
      "  WcLangToken(tok_code=<TokCodes.op: 4>, token_string=',', model_type=None, model_id=None, model=None)\n",
      "  WcLangToken(tok_code=<TokCodes.wc_lang_obj_id: 1>, token_string='ddd', model_type=<class 'wc_lang.core.Observable'>, model_id='ddd', model=<wc_lang.core.Observable object at 0x7fc04c0cc9b0>)\n",
      "  WcLangToken(tok_code=<TokCodes.op: 4>, token_string=')', model_type=None, model_id=None, model=None)\n"
     ]
    }
   ],
   "source": [
    "# FunctionExpression contains an 'analyzed_expr', which is a tokenized, validated expression\n",
    "# it contains the Python tokens from the expression ...\n",
    "print('analyzed_expr tokens:', [t.string for t in fun_1.expression.analyzed_expr.tokens])\n",
    "\n",
    "# wc_tokens, which contain the interpretation of each Python token ...\n",
    "print('\\nanalyzed_expr wc_tokens:\\n',\n",
    "      '\\n'.join(['  '+str(wc_token) for wc_token in fun_1.expression.analyzed_expr.wc_tokens]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Stop condition"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<wc_lang.core.StopCondition: sc 1>\n"
     ]
    }
   ],
   "source": [
    "# StopCondition is like Function, but it must return a boolean\n",
    "sc_1 = ExpressionMethods.make_obj(model, StopCondition, 'sc 1', '1 < a + ddd', objects)\n",
    "print(sc_1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "'expression':\n",
      "  Evaluating 'a + ddd', a StopConditionExpression expression, should return a bool but it returns a float\n"
     ]
    }
   ],
   "source": [
    "# expressions are validated by executing a test Python evaluation\n",
    "# if a StopCondition doesn't return a boolean its validation fails\n",
    "print(ExpressionMethods.make_obj(model, StopCondition, 'sc 1', 'a + ddd', objects))\n",
    "# the test evaluation assumes that all referenced objects have values of 1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Observable"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<wc_lang.core.Observable: ccc>\n"
     ]
    }
   ],
   "source": [
    "# Observables can reference Species and other Observables\n",
    "ccc = ExpressionMethods.make_obj(model, Observable, 'ccc', 'ccc + ddd - 2 * spec_type_0[comp]', objects)\n",
    "print(ccc)\n",
    "\n",
    "# cycles aren't allowed, but they cannot be detected until all expression have been made"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}