Repository: stan-dev/cmdstanpy
Pull request #159 (2019-11-01 11:22:24)

Bugfix/json zero array
#### Submission Checklist

- [x] Run unit tests
- [x] Declare copyright holder and open-source license: see below

#### Summary
Changed logic for writing `Dict` objects to JSON files:
 - allow zero-length lists, arrays, matrices


#### Copyright and Licensing

Please list the copyright holder for the work you are submitting (this will be you or your assignee, such as a university or company):  Columbia University



By submitting this pull request, the copyright holder is agreeing to license the submitted work under the following licenses:
- Code: BSD 3-clause (https://opensource.org/licenses/BSD-3-Clause)




Patch:
diff --git a/cmdstanpy/utils.py b/cmdstanpy/utils.py
index 746f288..923a956 100644
--- a/cmdstanpy/utils.py
+++ b/cmdstanpy/utils.py
@@ -76,7 +76,7 @@ class MaybeDictToFilePath(object):
                 self._unlink[i] = True
             elif isinstance(o, str):
                 if not os.path.exists(o):
-                    raise ValueError("File doesn't exists {}".format(o))
+                    raise ValueError("File doesn't exist {}".format(o))
                 self._paths[i] = o
             elif o is None:
                 self._paths[i] = None
@@ -138,7 +138,6 @@ class TemporaryCopiedFile(object):
             self._path = path
             self._tmpdir = tmpdir
         else:
-            self._changed = False
             self._path = file_path
 
     def __enter__(self):
@@ -337,11 +336,6 @@ def jsondump(path: str, data: Dict) -> None:
         if isinstance(val, np.ndarray):
             val = val.tolist()
             data[key] = val
-        if isinstance(val, Sequence) and not val:
-            raise ValueError(
-                'variable: {}, error: '
-                'empty array not allowed with JSON interface'.format(val)
-            )
     with open(path, 'w') as fd:
         json.dump(data, fd)
 
diff --git a/cmdstanpy_tutorial.ipynb b/cmdstanpy_tutorial.ipynb
index a49116e..7e34a7c 100644
--- a/cmdstanpy_tutorial.ipynb
+++ b/cmdstanpy_tutorial.ipynb
@@ -90,7 +90,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
+   "execution_count": 1,
    "metadata": {},
    "outputs": [],
    "source": [
@@ -115,7 +115,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
+   "execution_count": 2,
    "metadata": {},
    "outputs": [],
    "source": [
@@ -132,9 +132,26 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "INFO:cmdstanpy:stan to c++ (/Users/mitzi/.cmdstanpy/cmdstan-2.20.0/examples/bernoulli/bernoulli.hpp)\n",
+      "INFO:cmdstanpy:compiling c++\n",
+      "INFO:cmdstanpy:compiled model file: /Users/mitzi/.cmdstanpy/cmdstan-2.20.0/examples/bernoulli/bernoulli\n"
+     ]
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "CmdStanModel(name=bernoulli,  stan_file=\"/Users/mitzi/.cmdstanpy/cmdstan-2.20.0/examples/bernoulli/bernoulli.stan\", exe_file=\"/Users/mitzi/.cmdstanpy/cmdstan-2.20.0/examples/bernoulli/bernoulli\")\n"
+     ]
+    }
+   ],
    "source": [
     "bernoulli_model = CmdStanModel(stan_file=bernoulli_path)\n",
     "bernoulli_model.compile()\n",
@@ -157,7 +174,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
+   "execution_count": 5,
    "metadata": {},
    "outputs": [],
    "source": [
@@ -173,7 +190,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
+   "execution_count": 6,
    "metadata": {},
    "outputs": [],
    "source": [
@@ -189,9 +206,24 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "INFO:cmdstanpy:start chain 1\n",
+      "INFO:cmdstanpy:start chain 2\n",
+      "INFO:cmdstanpy:finish chain 1\n",
+      "INFO:cmdstanpy:start chain 3\n",
+      "INFO:cmdstanpy:finish chain 2\n",
+      "INFO:cmdstanpy:start chain 4\n",
+      "INFO:cmdstanpy:finish chain 3\n",
+      "INFO:cmdstanpy:finish chain 4\n"
+     ]
+    }
+   ],
    "source": [
     "bern_fit = bernoulli_model.sample(data=bern_data)"
    ]
@@ -214,9 +246,99 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>Mean</th>\n",
+       "      <th>MCSE</th>\n",
+       "      <th>StdDev</th>\n",
+       "      <th>5%</th>\n",
+       "      <th>50%</th>\n",
+       "      <th>95%</th>\n",
+       "      <th>N_Eff</th>\n",
+       "      <th>N_Eff/s</th>\n",
+       "      <th>R_hat</th>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>name</th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "      <th></th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>lp__</th>\n",
+       "      <td>-7.267660</td>\n",
+       "      <td>0.016792</td>\n",
+       "      <td>0.710076</td>\n",
+       "      <td>-8.741910</td>\n",
+       "      <td>-6.98903</td>\n",
+       "      <td>-6.750200</td>\n",
+       "      <td>1788.22</td>\n",
+       "      <td>12930.90</td>\n",
+       "      <td>1.00091</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>theta</th>\n",
+       "      <td>0.251933</td>\n",
+       "      <td>0.003337</td>\n",
+       "      <td>0.121042</td>\n",
+       "      <td>0.084919</td>\n",
+       "      <td>0.23354</td>\n",
+       "      <td>0.475669</td>\n",
+       "      <td>1315.97</td>\n",
+       "      <td>9516.05</td>\n",
+       "      <td>1.00363</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "           Mean      MCSE    StdDev        5%      50%       95%    N_Eff  \\\n",
+       "name                                                                        \n",
+       "lp__  -7.267660  0.016792  0.710076 -8.741910 -6.98903 -6.750200  1788.22   \n",
+       "theta  0.251933  0.003337  0.121042  0.084919  0.23354  0.475669  1315.97   \n",
+       "\n",
+       "        N_Eff/s    R_hat  \n",
+       "name                      \n",
+       "lp__   12930.90  1.00091  \n",
+       "theta   9516.05  1.00363  "
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
    "source": [
     "bern_fit.summary()"
    ]
@@ -232,9 +354,42 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "WARNING:cmdstanpy:Processing csv files: /var/folders/sc/0f0wdc_11_xgjs2v52g20fvr0000gn/T/tmpcu006e0e/stan-bernoulli-Method.SAMPLE-1-aszft12v.csv, /var/folders/sc/0f0wdc_11_xgjs2v52g20fvr0000gn/T/tmpcu006e0e/stan-bernoulli-Method.SAMPLE-2-r838n4df.csv, /var/folders/sc/0f0wdc_11_xgjs2v52g20fvr0000gn/T/tmpcu006e0e/stan-bernoulli-Method.SAMPLE-3-pyop7x1l.csv, /var/folders/sc/0f0wdc_11_xgjs2v52g20fvr0000gn/T/tmpcu006e0e/stan-bernoulli-Method.SAMPLE-4-z74wnt9b.csv\n",
+      "\n",
+      "Checking sampler transitions treedepth.\n",
+      "Treedepth satisfactory for all transitions.\n",
+      "\n",
+      "Checking sampler transitions for divergences.\n",
+      "No divergent transitions found.\n",
+      "\n",
+      "Checking E-BFMI - sampler transitions HMC potential energy.\n",
+      "E-BFMI satisfactory for all transitions.\n",
+      "\n",
+      "Effective sample size satisfactory.\n",
+      "\n",
+      "Split R-hat values satisfactory all parameters.\n",
+      "\n",
+      "Processing complete, no problems detected.\n"
+     ]
+    },
+    {
+     "data": {
+      "text/plain": [
+       "'Processing csv files: /var/folders/sc/0f0wdc_11_xgjs2v52g20fvr0000gn/T/tmpcu006e0e/stan-bernoulli-Method.SAMPLE-1-aszft12v.csv, /var/folders/sc/0f0wdc_11_xgjs2v52g20fvr0000gn/T/tmpcu006e0e/stan-bernoulli-Method.SAMPLE-2-r838n4df.csv, /var/folders/sc/0f0wdc_11_xgjs2v52g20fvr0000gn/T/tmpcu006e0e/stan-bernoulli-Method.SAMPLE-3-pyop7x1l.csv, /var/folders/sc/0f0wdc_11_xgjs2v52g20fvr0000gn/T/tmpcu006e0e/stan-bernoulli-Method.SAMPLE-4-z74wnt9b.csv\\n\\nChecking sampler transitions treedepth.\\nTreedepth satisfactory for all transitions.\\n\\nChecking sampler transitions for divergences.\\nNo divergent transitions found.\\n\\nChecking E-BFMI - sampler transitions HMC potential energy.\\nE-BFMI satisfactory for all transitions.\\n\\nEffective sample size satisfactory.\\n\\nSplit R-hat values satisfactory all parameters.\\n\\nProcessing complete, no problems detected.'"
+      ]
+     },
+     "execution_count": 9,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
    "source": [
     "bern_fit.diagnose()"
    ]
@@ -250,7 +405,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
+   "execution_count": 10,
    "metadata": {},
    "outputs": [],
    "source": [
@@ -266,9 +421,23 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "((4000, 8),\n",
+       " Index(['lp__', 'accept_stat__', 'stepsize__', 'treedepth__', 'n_leapfrog__',\n",
+       "        'divergent__', 'energy__', 'theta'],\n",
+       "       dtype='object'))"
+      ]
+     },
+     "execution_count": 11,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
    "source": [
     "bern_drawset.shape, bern_drawset.columns"
    ]
@@ -282,9 +451,20 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
+   "execution_count": 12,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(4000, 1)"
+      ]
+     },
+     "execution_count": 12,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
    "source": [
     "thetas = bern_fit.get_drawset(params=['theta'])\n",
     "thetas.shape\n"
@@ -292,18 +472,94 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
+   "execution_count": 13,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>theta</th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>0</th>\n",
+       "      <td>0.246078</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>1</th>\n",
+       "      <td>0.254398</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>2</th>\n",
+       "      <td>0.326366</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "      theta\n",
+       "0  0.246078\n",
+       "1  0.254398\n",
+       "2  0.326366"
+      ]
+     },
+     "execution_count": 13,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
    "source": [
     "thetas[0:3]"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<matplotlib.axes._subplots.AxesSubplot at 0x11e1325f8>"
+      ]
+     },
+     "execution_count": 15,
+     "metadata": {},
+     "output_type": "execute_result"
+    },
+    {
+     "data": {
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYUAAAD8CAYAAACYebj1AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4wLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvqOYd8AAAIABJREFUeJzt3Xl0XPWZ5//3o81avMiW5EWyFq+AbTDYMtiYLTshxPQkMEBCwBlomiSdTrp75kx6+WXSyfSZ7pmkZ5JOOtNkBSYhJCGLISQkYUnA2GDZ2NjGu7xJ3iRblrVY+/P7o0pGyLJUlnTrVpU+r3PquJavbn0sW3rqfrdr7o6IiAhAWtgBREQkcagoiIjIOSoKIiJyjoqCiIico6IgIiLnqCiIiMg5KgoiInJOYEXBzLLN7DUz22Jm283sHwZos9rM6sxsc/T2QFB5RERkaBkBHrsdeKe7N5tZJvCymf3a3df3a/eEu/95gDlERCRGgRUFjyyVbo4+zIzeRrx8urCw0CsqKkZ6GBGRMWXjxo317l40VLsgzxQws3RgIzAX+Ia7vzpAsw+b2Q3AbuAv3f3wYMesqKigqqpq9MOKiKQwMzsYS7tAB5rdvdvdrwRmAleb2aJ+TZ4CKtz9CuB3wCMDHcfMHjSzKjOrqqurCzKyiMiYFpfZR+5+GngBuLnf8yfdvT368NvA0gt8/cPuXunulUVFQ579iIjIMAU5+6jIzPKj93OA9wA7+7WZ0efhKmBHUHlERGRoQY4pzAAeiY4rpAE/dvenzeyLQJW7rwH+wsxWAV3AKWB1gHlERGQIlmzXU6isrHQNNIuIXBwz2+julUO104pmERE5R0VBRETOCXSdgshoOtvRze92HOdgfQuFE8bxjkumMn1SdtixRFKKioIkhVf21vOZJzZT19R+7rk0gz+5soS/ueUyiiaMCzGdSOpQUZCE98q+elZ/bwNlBbl89a4rWVI2mZqGVn5cVcP31u7npb31fG/1MhaVTAo7qkjS05iCJLT65nY+/cPXKS/I5acPreDaOYVkZ6Yzd+oE/vaWy3jq09eRmWbc/fB6dh1rCjuuSNJTUZCE9qWn36SpvYtvfHQJ+blZ571+6fSJ/PQT15KTlc4Dj26gub0rhJQiqUNFQRLW9iON/HLzEf70+lnMnzbhgu2K83P4t48uoabhLP/0ay2KFxkJFQVJWF9+dheTcjJ58IY5Q7atrJjC6msr+OGrh9h57Ewc0omkJhUFSUh7TzTxwq46HrhuFpNyMmP6ms+8ax7jx2Xw5Wd3B5xOJHWpKEhCeuSVg2RlpPGRa8pi/pr83CxWX1vBczuPs7++JcB0IqlLRUESTlNbJ09uqmHV4mIKxl/c+oN7VpSTmZbG99fuDyidSGpTUZCE8+z247R2dHP31bGfJfSaOiGbDy4u5icba2jt0EwkkYuloiAJ55ebaymbksuSsvxhff2dy0pp7ejm2e3HRjmZSOpTUZCEcqKpjbV767ntymLMbFjHqCyfzMzJOfxsU+0opxNJfSoKklCe2nKUHofbriwe9jHS0owPXVXC2r31HD/TNorpRFKfioIklN9sO8ql0ycwd+qFF6vF4oOLi+lx+K26kEQuioqCJIyGlg42HmzgvQumjfhYc6eOZ3ZhHr998/goJBMZO1QUJGG8sOsEPQ7vumzkRcHMeM/Caazbd5LG1s5RSCcyNqgoSMJ4bscJiiaM4/JR2gL7fQun09XjPL9LZwsisVJRkITQ0dXDH3bX8e7LppKWNrxZR/1dOTOfqRPG8dvtKgoisQqsKJhZtpm9ZmZbzGy7mf3DAG3GmdkTZrbXzF41s4qg8khi23Sogeb2Lm66ZOqoHTMtzXjPgmm8uKuOts7uUTuuSCoL8kyhHXinuy8GrgRuNrPl/drcDzS4+1zgfwP/HGAeSWCv7DtJmsHy2QWjetx3XTaVs53dvLb/1KgeVyRVBVYUPKI5+jAzevN+zW4DHone/ynwLhvuiiVJauv21XN5yaSYd0SN1YrZhWRlpPHirrpRPa5Iqgp0TMHM0s1sM3AC+J27v9qvSQlwGMDdu4BG4LyPimb2oJlVmVlVXZ1+uFNNa0cXrx86zYo5haN+7JysdJbPLuDF3SdG/dgiqSjQouDu3e5+JTATuNrMFg3zOA+7e6W7VxYVFY1uSAndhgMNdPU4184Z3a6jXjfNL6K6roVDJ1sDOb5IKonL7CN3Pw28ANzc76VaoBTAzDKAScDJeGSSxLFu30ky043KismBHP8dl0YGr3W2IDK0IGcfFZlZfvR+DvAeYGe/ZmuA+6L3bweed/f+4w6S4tbtq+eq0snkZmUEcvxZhXmUF+Tywk4VBZGhBHmmMAN4wczeADYQGVN42sy+aGarom2+AxSY2V7gr4DPBZhHElBLexdbaxtZPntKoO9z0/wi1lWf1NRUkSEE89EMcPc3gKsGeP7zfe63AXcElUES35bDp+lxWFoRcFG4dCqPrDvIq/tPceN8jUuJXIhWNEuoNh5sAODK0uFdUCdWK2YXMC4jTV1IIkNQUZBQbTrUwLyp40d9fUJ/2ZnprJhTwB92a0qzyGBUFCQ07s7rh0+zpCyYWUf93TS/iP31LRyob4nL+4kkIxUFCU11fQunWztZWh6nohDdV0lnCyIXpqIgoekdT1hSHux4Qq+KwjzKpuTy0h4VBZELUVGQ0Lx+qIGJ2RnMLhwft/e8fl4h6/adpKOrJ27vKZJMVBQkNK8fOs1VZZNH7foJsbhhfhEtHd1sOtQQt/cUSSYqChKKts5u9pxo5oqZo3OVtVitmFNAepqpC0nkAlQUJBQ7jzXR3eMsLI5vUZiYncmSsnz+uLs+ru8rkixUFCQUW2sbAbg8zmcKANfPK2LbkUZONrfH/b1FEp2KgoRie20jk3MzKZ6UHff3vmF+Ee6wdp825BXpT0VBQrHtSCOLSiYRxoX2Li+ZRH5uJn/UegWR86goSNy1d3Wz61gTi0ri33UEkJ5mrJxbyEt76tBO7SJvp6IgcbfneDOd3c6iOA8y93XDvEKOn2ln9/HmoRuLjCEqChJ3vYPMi0omhpbh+nmR7bM1NVXk7VQUJO621TYyITuDsim5oWUozs9h7tTx2gdJpB8VBYm7bUfOsKg4nEHmvm6YV8Rr+0/pamwifagoSFx19zg7j55hYXF4XUe9rp9fSHtXDxsOnAo7ikjCUFGQuDp4soX2rh4unRF+UVg+q4Cs9DRNTRXpQ0VB4mrXsSYALpk2IeQkkJOVTmXFZF7eq0VsIr0CKwpmVmpmL5jZm2a23cw+M0Cbm8ys0cw2R2+fDyqPJIZdx5swg3nT4rdd9mCum1fIjqNnqGvSlhciEOyZQhfw1+6+AFgOfMrMFgzQ7iV3vzJ6+2KAeSQB7DrWREVBHtmZ6WFHAeC6uYUAvLJPG+SJQIBFwd2Puvum6P0mYAdQEtT7SXLYdbyJ+QlylgCwsHgSk3IyWbtXRUEE4jSmYGYVwFXAqwO8vMLMtpjZr81sYTzySDjaOrs5UN/CJdPDH2TuFdnyooCX99RrywsR4lAUzGw88CTwWXc/0+/lTUC5uy8G/hX4xQWO8aCZVZlZVV2dZookq70nmunxxBhk7mvl3EKONLaxv74l7CgioQu0KJhZJpGC8AN3/1n/1939jLs3R+8/A2SaWeEA7R5290p3rywqKgoysgTo3Myj6YlVFHrHFdSFJBLs7CMDvgPscPd/uUCb6dF2mNnV0TyaH5iidh1vIisjjYqC8La3GEh5QR6lU3J4aY+KgkhGgMdeCXwM2Gpmm6PP/S1QBuDu/xe4HfiEmXUBZ4G7XB27KWvXsSbmFo0nIz3xlsdcN7eQp984Sld3T0LmE4mXwIqCu78MDLq5jbt/Hfh6UBkksew61sSKOQVhxxjQyrmFPP7aYbbWNnJV2eSw44iERh+JJC4az3Zy7Ewb8xNskLnXtXMKMdO4goiKgsRFdV3kYjZzpybOGoW+puRlsbB4osYVZMxTUZC42FcXme45uygv5CQXtnJuIZsONdDa0RV2FJHQqChIXFTXNZORZqFeWGco180tpLPbeW2/ttKWsUtFQeJiX10zZQW5ZCbwzJ5lFVPIykjjZXUhyRiWuD+hklKq61qYU5SY4wm9sjPTWVYxmZc12CxjmIqCBK6ru4eDJ1sTejyh18q5hew81qSttGXMUlGQwNU0nKWjuyfhzxQArp8b2UZFW2nLWKWiIIGrro9MR52TBGcKC4onkp+bqXEFGbNUFCRw+05Ep6MWJv6ZQnqace2cAtbu1VbaMjapKEjgquubmZKXxeS8rLCjxKR3K+1qbaUtY5CKggRu34kWZhcmftdRr95xBW15IWORioIErrq+JSlmHvUqK8ildEqOxhVkTFJRkEC1tHdR39xOeUHyFAWIrG5et+8kXd09YUcRiSsVBQnUwZOtAJQn2IV1hnLd3CKa2rt4o7Yx7CgicaWiIIE6dCoyWFs+JbnOFFbMKYhspa0uJBljVBQkUL1nCmVJdqbQu5W2tryQsUZFQQJ18FQr+bmZTMrJDDvKRbtubhGbDjXQ0q6ttGXsUFGQQB062Up5Am+XPZhzW2kf0FbaMnaoKEigDp5qoSzJZh71qqyYTFZGmsYVZExRUZDAdHb3cOR0W9KeKWRnpnN1xRSNK8iYElhRMLNSM3vBzN40s+1m9pkB2piZfc3M9prZG2a2JKg8En+1DWfp7vGkm47aV+9W2ifOtIUdRSQugjxT6AL+2t0XAMuBT5nZgn5t3g/Mi94eBL4ZYB6Js4OnetcoJGf3EcA7L50KwG/fPB5yEpH4CKwouPtRd98Uvd8E7ABK+jW7DXjUI9YD+WY2I6hMEl+HTkbXKCTxmcL8aeOZXZjHb7YdCzuKSFzEZUzBzCqAq4BX+71UAhzu87iG8wsHZvagmVWZWVVdXV1QMWWUHTzZSnZmGlMnjAs7yrCZGe9bNJ111Sc53doRdhyRwAVeFMxsPPAk8Fl3PzOcY7j7w+5e6e6VRUVFoxtQAnPwVCtlU3Ixs7CjjMj7F02nu8f5nbqQZAyIqSiY2c/M7ANmdlFFxMwyiRSEH7j7zwZoUguU9nk8M/qcpICDJ1soS7LtLQZyeckkSvJz1IUkY0Ksv+T/DfgIsMfM/snMLhnqCyzy8fA7wA53/5cLNFsD3BudhbQcaHT3ozFmkgTm7hw61ZrU4wm9zIz3LZzOS3vqaWrrDDuOSKBiKgru/nt3/yiwBDgA/N7MXjGzj0fPBgayEvgY8E4z2xy93WJmD5nZQ9E2zwDVwF7gW8AnR/KXkcRR39xBW2cPpZNzwo4yKm65fDod3T3qQpKUlxFrQzMrAO4h8ov+deAHwHXAfcBN/du7+8vAoJ3JHrkI7qdijyvJoqYhMh115uTkP1MAWFI2mdIpOfxsUy0fWjIz7DgigYl1TOHnwEtALvBBd1/l7k+4+6eBxL8au8Rd7emzAJSkyJlCWprxoatmsnZfPUeifzeRVBTrmMK33H2Bu/+P3j5/MxsH4O6VgaWTpFXbkFpFAeDDS2biDj9/XXMhJHXFWhT++wDPrRvNIJJaak+fZWJ2BhOzk2/L7AspK8hlWcVkfraphkjPp0jqGbQomNl0M1sK5JjZVWa2JHq7iUhXksiAahrOUpIi4wl93b50JvvqWqg62BB2FJFADDXQ/D5gNZH1A32nlTYBfxtQJkkBtQ1nKU3S3VEH88HFxfzjr3bw6LqDLKuYEnYckVE3aFFw90eAR8zsw+7+ZJwySZJzd2pPn2XFnIKwo4y63KwM/mNlKd9/5QAnPnAZUydmhx1JZFQN1X10T/RuhZn9Vf9bHPJJEmo820lzexczU2iQua97lpfT7c4PXzsUdhSRUTfUQHPvHgXjgQkD3ETOU9M78yg/NYtCRWEeN84v4gevHqKjqyfsOCKjaqjuo3+P/vkP8YkjqaB3jUKqLFwbyH0rKvj49zfwm+3HWLW4OOw4IqMm1sVr/9PMJppZppk9Z2Z1fbqWRN4mFdco9Hfj/CJmFebxvbX7w44iMqpiXafw3ui217cS2ftoLvBfggolya2m4Sw5melMzk2dNQr9paUZ960o5/VDp9l8+HTYcURGTaxFobeb6QPAT9y9MaA8kgJqT7dSMjkn6a+jMJTbK0uZMC5DZwuSUmItCk+b2U5gKfCcmRUBupK5DKj29NmUnXnU1/hxGdxRWcqv3jjK8TP6cZDUEOvW2Z8DrgUq3b0TaCFyfWWR89Q0nE3ZmUf9rb62gm53/t/6g2FHERkVF3MltUuBO83sXuB24L3BRJJk1tLexenWzpQeZO6rrCCXd106jR++eoi2zu6w44iMWKyzjx4Dvkzk+gnLojftjirnGQvTUfv7+MoKTrZ0sGbLkbCjiIxYrBfZqQQWuLaGlCHUpvjCtYFcO6eAS6ZN4HtrD3DH0pkpP8AuqS3W7qNtwPQgg0hqeOuKa2OnKJgZq1dWsOPoGTZq91RJcrEWhULgTTN71szW9N6CDCbJqeb0WbLS0ygaPy7sKHG1anExuVnpPLmpJuwoIiMSa/fRF4IMIamjtuEsxfnZpKWNrS6UvHEZ3LxoOk9vOcp/++BCsjPTw44kMiyxTkn9A5GVzJnR+xuATYN9jZl918xOmNm2C7x+k5k1mtnm6O3zF5ldElDk4jpjp+uor9uXzKSpvYtntx8LO4rIsMU6++hPgZ8C/x59qgT4xRBf9n3g5iHavOTuV0ZvX4wliyS22tNjZ41Cf8tnF1CSn8OTm3QNZ0lesY4pfApYCZwBcPc9wNTBvsDd/wicGlE6SSptnd3UNbWPqemofaWlGf/hqhJe3lPHiSatcJbkFGtRaHf3jt4HZpYBjMb01BVmtsXMfm1mC0fheBKio42RX4Rj9UwBYNWVxfQ4PLtNXUiSnGItCn8ws78FcszsPcBPgKdG+N6bgHJ3Xwz8K4N0R5nZg2ZWZWZVdXV1I3xbCUrvdNSxOqYAMH/aBOZNHc/TbxwNO4rIsMRaFD4H1AFbgT8DngH+fiRv7O5n3L05ev8ZINPMCi/Q9mF3r3T3yqKiopG8rQRoLC5cG8gHrpjBawdOcUKb5EkSinX2UQ+RT/KfdPfb3f1bI13dbGbTLbr008yujmY5OZJjSrhqT58lPc2YMWlsX8z+1itm4A7PbNXZgiSfQYuCRXzBzOqBXcCu6FXXhpw+amaPA+uAS8ysxszuN7OHzOyhaJPbgW1mtgX4GnCXttFIbrUNZ5k+MZuM9IvZZzH1zJ06gUunT+BXKgqShIZavPaXRGYdLXP3/QBmNhv4ppn9pbv/7wt9obvfPdiB3f3rwNcvMq8ksJoxPB21vw9cPoOv/G43xxrbmD7Gz5wkuQz1ke5jwN29BQHA3auBe4B7gwwmyad2DC9c6++WK2YA6kKS5DNUUch09/r+T7p7HZC6F+CVi9bV3cOxM206U4iaUzSey2ZMVBeSJJ2hikLHMF+TMeZ4UzvdPa4zhT5uvWIGGw82nLvGhEgyGKooLDazMwPcmoDL4xFQkoOmo57v1mgX0tO6+I4kkUGLgrunu/vEAW4T3F3dR3JO7WktXOuvvCCPxaX5uiKbJJWxPXdQRo3OFAa2anEx24+cYV9dc9hRRGKioiCjovb0WQrHZ+k6Av3cesUMzGDNZp0tSHJQUZBRUdOgNQoDmTYxm2tmTeGpLUfQ2kxJBioKMipqT2uNwoWsWlxCdX0L24+cCTuKyJBUFGTE3D2ycE1nCgN6/6LpZKYbP39dF9+RxKeiICNW39xBe1ePisIFTM7L4t2XTePnr9fS3tUddhyRQakoyIj1Ls4qGaNXXIvFnctKOdXSwe/fPBF2FJFBqSjIiGk66tCun1dE8aRsfrThUNhRRAaloiAjpoVrQ0tPM+6oLOXlvfXnrlAnkohUFGTEahvOMmFcBpNytMh9MHdUzgTgx1U1IScRuTAVBRkxTUeNzczJudw4v4jHXzukAWdJWCoKMmJauBa7j6+cRV1TO796Q1tqS2JSUZAR05lC7G6YV8icojy+u3a/VjhLQlJRkBE509ZJU1uXzhRiZGZ8fOUsttWeoepgQ9hxRM6joiAjUnMqMh11ptYoxOxDS0qYmJ3B99buH7qxSJwFVhTM7LtmdsLMtl3gdTOzr5nZXjN7w8yWBJVFgnPoVGR6ZXmBikKscrMyuPuaMn6z7Zimp0rCCfJM4fvAzYO8/n5gXvT2IPDNALNIQA5Hi0LpFBWFi3HvigrMjMfWHQw7isjbBFYU3P2PwKlBmtwGPOoR64F8M5sRVB4JxqFTrUzKydQahYtUkp/D+xZO4/HXDtHa0RV2HJFzwhxTKAEO93lcE31OksihU62U6SxhWD6+chZn2rq0e6oklKQYaDazB82sysyq6urqwo4jfRxWURi2yvLJLCyeyPfXHtD0VEkYYRaFWqC0z+OZ0efO4+4Pu3ulu1cWFRXFJZwMrbvHqWk4y8wpmo46HL3TU/ecaOblvfVhxxEBwi0Ka4B7o7OQlgON7q5lnknk+Jk2Orp7dKYwAh9cPIPC8Vl8b+2BsKOIAMFOSX0cWAdcYmY1Zna/mT1kZg9FmzwDVAN7gW8BnwwqiwSjdzqqisLwjctI5yPXlPP8zhPsr28JO44IGUEd2N3vHuJ1Bz4V1PtL8FQURsc9y8v45ot7eeSVA3xh1cKw48gYlxQDzZKYDp9qJc2gWFtcjMjUCdncekUxP6k6THO7pqdKuFQUZNgOnWqlOD+HzHT9Nxqpe5aX09LRzVNbjoQdRcY4/TTLsGmNwuhZUpbP/Gnj+dFrulynhEtFQYbt8KlWSrUR3qgwM+5aVsaWmkbePHIm7DgyhqkoyLCcaeukvrmDWUV5YUdJGR9aUkJWRho/2qCzBQmPioIMy/66yPTJWYUqCqMlPzeL9y+azs9fr+Vshy7XKeFQUZBh6Z1TP0dnCqPqrmVlNLV18cxWreOUcKgoyLBU1zWTZtoye7Qtnz2FWYV56kKS0KgoyLBU17dQOiWXcRnpYUdJKWbGnctK2XCggb0nmsKOI2OQioIMS3Vdi8YTAnL70plkphuPv3Z46MYio0xFQS6au7O/XkUhKIXjx/HehdN5clMNbZ0acJb4UlGQi3b8TDtnO7uZXTQ+7Cgp6yNXl3G6tZNntx8LO4qMMSoKctGq65oBmK0zhcCsmF1AeUEuP3hVA84SXyoKctGqo9NRZ2s6amDS0iIrnF/bf4q9J5rDjiNjiIqCXLQ9x5vIy0pn2oTssKOktDsqIwPO2g9J4klFQS7aruNNzJ8+gbQ0CztKSiscP473LtCAs8SXioJcFHdn17EmLpk2IewoY8LdV5fR0NrJb7ZpwFniQ0VBLkp9cwcNrZ1cMl1FIR6unVPA7KI8vv1yNZGLFYoES0VBLsquY5FVtjpTiI+0NOOB62azrfYM66tPhR1HxgAVBbkou45HisJ8nSnEzYeWlFCQl8W3XqoOO4qMASoKclF2H2uiIC+LwvHjwo4yZmRnpvOxFeU8v/MEu49rPyQJVqBFwcxuNrNdZrbXzD43wOurzazOzDZHbw8EmUdGbtfxJo0nhODeFRXkZaXzf36/O+wokuICKwpmlg58A3g/sAC428wWDND0CXe/Mnr7dlB5ZOR6epw9x5uYr/GEuJuSl8X918/mma3H2FbbGHYcSWFBnilcDex192p37wB+BNwW4PtJwPafbKGlo5uFxRPDjjImPXD9LPJzM/nyb3eFHUVSWJBFoQTou/dvTfS5/j5sZm+Y2U/NrHSgA5nZg2ZWZWZVdXV1QWSVGGytiXxCvXzmpJCTjE0TszP5xI1zeHFXHS/uOhF2HElRYQ80PwVUuPsVwO+ARwZq5O4Pu3ulu1cWFRXFNaC85Y2aRrIz05ir3VFDs3plBbOL8vj/frlN13GWQARZFGqBvp/8Z0afO8fdT7p7e/Tht4GlAeaREdpW28iCGRPJSA/7s8TYNS4jnX/8k8s5fOosX1E3kgQgyJ/uDcA8M5tlZlnAXcCavg3MbEafh6uAHQHmkRHo7nG2HWnkipn5YUcZ81bMKeCe5WV8++X9PL/zeNhxJMUEVhTcvQv4c+BZIr/sf+zu283si2a2KtrsL8xsu5ltAf4CWB1UHhmZ6rpmWju6WVSi8YRE8PcfWMCCGRP5zOObNRtJRlWg/QDu/oy7z3f3Oe7+j9HnPu/ua6L3/8bdF7r7Ynd/h7vvDDKPDN/Ggw0ALCnTmUIiyM5M59v3VTIxJ5N7v/saGw9qCwwZHeoclphsONBAQV6WrsucQIrzc/jBA9cwMTuDux9+la8/v4eOrp6wY0mSU1GQmGw8eIql5ZMx0zUUEklFYR6/+NRK3r1gKl/+7W5u/uofeW7Hce2oKsOmoiBDOtHUxoGTrSyrmBJ2FBlAfm4W//bRpXxv9TJwuP+RKj72nde0T5IMi4qCDGnjgch4QmXF5JCTyGDecelUfvPZG/j8rQvYWtvIrf/6Mk9urAk7liQZFQUZ0st768nLSmdhsWYeJbqsjDT+03WzeO6vb2RJWT5//ZMtfH/t/rBjSRJRUZAhvbSnnhVzCsjK0H+XZFE4fhyP3X8N710wjS889Sa/eL126C8SQUVBhnCgvoVDp1q5Yb62F0k2melpfP0jS7hm1hT+65Nv8EbN6bAjSRJQUZBBvbQnsgHh9fNUFJJRVkYa//bRJRSOH8efPbaRk83tQ3+RjGkqCjKo53eeoHRKDhUFuWFHkWEqGD+Of//YUk62dPDZJzbT3aPpqnJhKgpyQY1nO3l5bz03L5yu9QlJblHJJL64aiEv7annq8/tCTuOJDAVBbmg53Ycp7Pbef/lM4ZuLAnvzmWl3L50Jl97bg8v7NT1GGRgKgpyQc9sPUrxpGyuKtV+R6nAzPjSbYu4bMZEPvvEZg6fag07kiQgFQUZUF1TOy/uquMDV8xQ11EKyclK55sfXUKPO5/8wSbaOnWhHnk7FQUZ0E831tDV49y5rCzsKDLKKgrz+Modi9la28infrCJ9i4VBnmLioKcp6fH+dGGQ1wzawpzp+rSm6novQun89//ZBHP7TzBA49Ucbq1I+xIkiBUFOQ8v9l+jIMnW7lneXnYUSRA9ywNBmlzAAAJfklEQVQv53/dfgXrq09y67++zPrqk2FHkgSgoiBv09PjfO25PcwuyuMWzTpKeXdUlvKTh64F4K6H1/Ppx19nX11zyKkkTCoK8jZrthxh57EmPv3OuaSnaYB5LLiyNJ/f/eWN/MW75vHb7cd497/8gT97rIq1e+vp0UK3MScj7ACSOBpaOvjS02+yuDSfVYtLwo4jcZSTlc5fvWc+964o59FXDvDo+oM8u/04MyfncMfSUj68tISZk7WqfSywZLtCU2VlpVdVVYUdI+V09zh/9thGXtx1gqc+fR2XzZgYdiQJUVtnN89uP8aPqw6zdm9krGFp+WRuuXwGt1w+nRmTckJOKBfLzDa6e+WQ7YIsCmZ2M/BVIB34trv/U7/XxwGPAkuBk8Cd7n5gsGOqKIy+nh7nv63ZzmPrD/KFDy5g9cpZYUeSBHL4VCu/3FzLr7YeY8fRM0CkQNw4v4iVcwu4YmY+menqiU50oRcFM0sHdgPvAWqADcDd7v5mnzafBK5w94fM7C7gP7j7nYMdV0VhdB1rbOPvf7GV3+84wZ9eP4u/+8CCsCNJAquua+aZrUf5zfZjbD9yBnciF2AqmcSi4kksKpnIguKJVBTkkZ2ZHnZc6SMRisIK4Avu/r7o478BcPf/0afNs9E268wsAzgGFPkgoVQURqajq4fjZ9rYVtvIC7tO8NSWo3S78zfvv5TV11Zo9bLErKGlg3XVJ1lffZKttY3sOHqGts4eAMygeFIOswrzKC/IZeqEbArGZ1GQl8WE7ExystLIzkwnJzOdnKzIn9mZ6WSmp2mCQ0BiLQpBDjSXAIf7PK4BrrlQG3fvMrNGoACoH+0wf9hdx5eejpyk9Nact1UeP/9u39r01nN92/V53c9//a3Xzj/O275moOMM0K7vKx5j3r5te9xpaus693xuVjofXDyDT71jLuUFeecHFxnE5Lys6BhDZOpyV3cP1fUt7Dh6hgP1reyvb2Z/fQu/2nqU062dMR83zSIXCMpKTyMzI43MdCMzPY3M9DQGLBcDPDlQu4E+8CRb+blzWSkPXD870PdIitlHZvYg8CBAWdnwtl0YPy6DS6ZN6HPQt/3R+z79X6bv/yMbpN3bj9nn9QHfp++X2PnP2VuvDvw1MR7nbe8ZeTQ5N4tpE8cxf/oEFhVP0iU2ZdRkpKcxf9oE5vf9OYvq6OqhobWD+uZ2Wtq7OdvZzdmObto6I7ez0Vtnl9PZ3RO9vXW/I/q4v4E6FQbsZhjow9rALRNa4fhxgb9HkEWhFijt83hm9LmB2tREu48mERlwfht3fxh4GCLdR8MJs7R8MkvLJw/nS0VkhLIy0pg2MZtpE7PDjiJDCPJj4gZgnpnNMrMs4C5gTb82a4D7ovdvB54fbDxBRESCFdiZQnSM4M+BZ4lMSf2uu283sy8CVe6+BvgO8JiZ7QVOESkcIiISkkDHFNz9GeCZfs99vs/9NuCOIDOIiEjsNMooIiLnqCiIiMg5KgoiInKOioKIiJyjoiAiIuck3dbZZlYHHOzzVCEBbIsRAOUcXco5upIlJyRP1kTLWe7uRUM1Srqi0J+ZVcWyyVPYlHN0KefoSpackDxZkyVnf+o+EhGRc1QURETknFQoCg+HHSBGyjm6lHN0JUtOSJ6syZLzbZJ+TEFEREZPKpwpiIjIKEm6omBmU8zsd2a2J/rnBS+SYGYTzazGzL4ez4zR9x4yp5ldaWbrzGy7mb1hZoNen3qU891sZrvMbK+ZfW6A18eZ2RPR1181s4p4ZeuXY6icf2Vmb0a/f8+ZWXki5uzT7sNm5mYWyqyUWHKa2X+Mfk+3m9kP450xmmGof/cyM3vBzF6P/tvfElLO75rZCTPbdoHXzcy+Fv17vGFmS+Kd8aK5e1LdgP8JfC56/3PAPw/S9qvAD4GvJ2JOYD4wL3q/GDgK5MchWzqwD5gNZAFbgAX92nwS+L/R+3cBT4TwPYwl5zuA3Oj9TyRqzmi7CcAfgfVAZSLmBOYBrwOTo4+nJmjOh4FPRO8vAA7EO2f0vW8AlgDbLvD6LcCviVwIcTnwahg5L+aWdGcKwG3AI9H7jwB/MlAjM1sKTAN+G6dc/Q2Z0913u/ue6P0jwAlgyMUlo+BqYK+7V7t7B/CjaN6++ub/KfAuG+git8EaMqe7v+DurdGH64lc4S/eYvl+AnwJ+GegLZ7h+ogl558C33D3BgB3PxHnjBBbTgcmRu9PAo7EMd9bIdz/SORaMBdyG/CoR6wH8s1sRnzSDU8yFoVp7n40ev8YkV/8b2NmacBXgP8cz2D9DJmzLzO7msinon1BBwNKgMN9HtdEnxuwjbt3AY1AQRyyDZghaqCcfd1P5FNZvA2ZM9ptUOruv4pnsH5i+X7OB+ab2VozW29mN8ct3VtiyfkF4B4zqyFyzZZPxyfaRbvY/8OhC/QiO8NlZr8Hpg/w0t/1feDubmYDTZ/6JPCMu9cE+eF2FHL2HmcG8Bhwn7v3jG7KscHM7gEqgRvDztJf9EPKvwCrQ44SiwwiXUg3ETnr+qOZXe7up0NNdb67ge+7+1fMbAWRKzgu0s/PyCVkUXD3d1/oNTM7bmYz3P1o9JfpQKe3K4DrzeyTwHggy8ya3f2CA4Ah5cTMJgK/Av4uenoZD7VAaZ/HM6PPDdSmxswyiJyin4xPvPMy9BooJ2b2biKF+EZ3b49Ttr6GyjkBWAS8GP2QMh1YY2ar3L0qbilj+37WEOn37gT2m9luIkViQ3wiArHlvB+4GcDd15lZNpG9hsLo7hpMTP+HE0kydh+tAe6L3r8P+GX/Bu7+UXcvc/cKIl1Ij452QYjBkDnNLAv4OZF8P41jtg3APDObFc1wF5G8ffXNfzvwvEdHzuJoyJxmdhXw78CqkPq/YYic7t7o7oXuXhH9P7meSN54FoQhc0b9gshZAmZWSKQ7qTqeIYkt5yHgXQBmdhmQDdTFNWVs1gD3RmchLQca+3QrJ6awR7ov9kakX/s5YA/we2BK9PlK4NsDtF9NOLOPhswJ3AN0Apv73K6MU75bgN1ExjD+LvrcF4n8soLID9lPgL3Aa8DskP69h8r5e+B4n+/fmkTM2a/ti4Qw+yjG76cR6ep6E9gK3JWgORcAa4nMTNoMvDeknI8TmTXYSeQs637gIeChPt/Pb0T/HlvD+ne/mJtWNIuIyDnJ2H0kIiIBUVEQEZFzVBREROQcFQURETlHRUFERM5RURARkXNUFERE5BwVBREROef/B06JJsiWbspVAAAAAElFTkSuQmCC\n",
+      "text/plain": [
+       "<Figure size 432x288 with 1 Axes>"
+      ]
+     },
+     "metadata": {
+      "needs_background": "light"
+     },
+     "output_type": "display_data"
+    }
+   ],
    "source": [
     "bern_drawset.theta.plot.density()"
    ]
@@ -340,9 +596,20 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('theta', array([0.246078, 0.254398, 0.326366]))"
+      ]
+     },
+     "execution_count": 16,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
    "source": [
     "bern_fit.column_names[7], bern_fit.sample[0:3,0,7]"
    ]
@@ -362,9 +629,20 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
+   "execution_count": 17,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "array([0.948194, 0.96125 , 1.06474 , 1.17857 ])"
+      ]
+     },
+     "execution_count": 17,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
    "source": [
     "bern_fit.stepsize"
    ]
@@ -382,12 +660,33 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
+   "execution_count": 18,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('diag_e', array([[0.512243],\n",
+       "        [0.584738],\n",
+       "        [0.390916],\n",
+       "        [0.508692]]))"
+      ]
+     },
+     "execution_count": 18,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
    "source": [
     "bern_fit.metric_type,  bern_fit.metric"
    ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
   }
  ],
  "metadata": {
diff --git a/docs/notebooks/Run Generated Quantities.ipynb b/docs/notebooks/Run Generated Quantities.ipynb
index 75d36f7..37afdc3 100644
--- a/docs/notebooks/Run Generated Quantities.ipynb
+++ b/docs/notebooks/Run Generated Quantities.ipynb
@@ -4,7 +4,7 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "#  Generating new quantities of interest given a existing model, data, and sample.\n",
+    "#  Generating new quantities of interest given an existing model, data, and sample.\n",
     "\n",
     "\n",
     "The [generated quantities block](https://mc-stan.org/docs/reference-manual/program-block-generated-quantities.html)\n",
@@ -212,8 +212,9 @@
    "outputs": [],
    "source": [
     "sample_plus = new_quantities.sample_plus_quantities\n",
-    "print(sample_plus.shape)\n",
-    "print(sample_plus.columns)"
+    "print(type(sample_plus),sample_plus.shape)\n",
+    "names = list(sample_plus.columns.values[7:18])\n",
+    "sample_plus.iloc[0:3, :]"
    ]
   },
   {


Test patch:
diff --git a/test/test_model.py b/test/test_model.py
index 092e897..fb26202 100644
--- a/test/test_model.py
+++ b/test/test_model.py
@@ -96,13 +96,15 @@ class CmdStanModelTest(unittest.TestCase):
         model2.compile()
         self.assertEqual(exe_time,os.path.getmtime(model2.exe_file))
 
+    def test_model_compile_includes(self):
         stan = os.path.join(datafiles_path, 'bernoulli_include.stan')
         exe = os.path.join(datafiles_path, 'bernoulli_include' + EXTENSION)
+        if os.path.exists(exe):
+            os.remove(exe)
+
         here = os.path.dirname(os.path.abspath(__file__))
         datafiles_abspath = os.path.join(here, 'data')
         include_paths = [datafiles_abspath]
-        if os.path.exists(exe):
-            os.remove(exe)
         model = CmdStanModel(stan_file=stan)
         model.compile(include_paths=include_paths)
         self.assertEqual(stan, model.stan_file)
diff --git a/test/test_utils.py b/test/test_utils.py
index cec7a03..0459853 100644
--- a/test/test_utils.py
+++ b/test/test_utils.py
@@ -7,6 +7,8 @@ import shutil
 import string
 import random
 
+import numpy as np
+
 from cmdstanpy import TMPDIR
 from cmdstanpy.utils import (
     EXTENSION,
@@ -22,6 +24,7 @@ from cmdstanpy.utils import (
     rdump,
     rload,
     parse_rdump_value,
+    jsondump
 )
 from cmdstanpy.model import CmdStanModel
 
@@ -99,7 +102,7 @@ class CmdStanPathTest(unittest.TestCase):
 
     def test_dict_to_file(self):
         file_good = os.path.join(datafiles_path, 'bernoulli_output_1.csv')
-        dict_good = {'a': 'A'}
+        dict_good = {'a': 0.5}
         created_tmp = None
         with MaybeDictToFilePath(file_good, dict_good) as (f1, f2):
             self.assertTrue(os.path.exists(f1))
@@ -114,6 +117,39 @@ class CmdStanPathTest(unittest.TestCase):
             with MaybeDictToFilePath(123, dict_good) as (f1, f2):
                 pass
 
+    def test_jsondump(self):
+        dict_list = {'a' : [ 1.0, 2.0, 3.0 ]}
+        file_list = os.path.join(TMPDIR, 'list.json')
+        jsondump(file_list, dict_list)
+        with open(file_list) as fp:
+            self.assertEqual(json.load(fp), dict_list)
+
+        dict_vec = {'a' : np.repeat(3,4)}
+        file_vec = os.path.join(TMPDIR, 'vec.json')
+        jsondump(file_vec, dict_vec)
+        with open(file_vec) as fp:
+            self.assertEqual(json.load(fp), dict_vec)
+
+        dict_zero_vec = {'a' : [ ]}
+        file_zero_vec = os.path.join(TMPDIR, 'empty_vec.json')
+        jsondump(file_zero_vec, dict_zero_vec)
+        with open(file_zero_vec) as fp:
+            self.assertEqual(json.load(fp), dict_zero_vec)
+
+        dict_zero_matrix = {'a' : [[], [], []]}
+        file_zero_matrix = os.path.join(TMPDIR, 'empty_matrix.json')
+        jsondump(file_zero_matrix, dict_zero_matrix)
+        with open(file_zero_matrix) as fp:
+            self.assertEqual(json.load(fp), dict_zero_matrix)
+
+        a = np.zeros(shape=(5,0))
+        dict_zero_matrix = {'a' : a}
+        file_zero_matrix = os.path.join(TMPDIR, 'empty_matrix.json')
+        jsondump(file_zero_matrix, dict_zero_matrix)
+        with open(file_zero_matrix) as fp:
+            self.assertEqual(json.load(fp), dict_zero_matrix)
+
+
 
 class ReadStanCsvTest(unittest.TestCase):
     def test_check_sampler_csv_1(self):
@@ -166,8 +202,7 @@ class ReadStanCsvTest(unittest.TestCase):
 
     def test_check_sampler_csv_thin(self):
         stan = os.path.join(datafiles_path, 'bernoulli.stan')
-        exe = os.path.join(datafiles_path, 'bernoulli' + EXTENSION)
-        bern_model = CmdStanModel(stan_file=stan, exe_file=exe)
+        bern_model = CmdStanModel(stan_file=stan)
         bern_model.compile()
 
         jdata = os.path.join(datafiles_path, 'bernoulli.data.json')