mirror of
https://github.com/ImperialCollegeLondon/ReCoDE_MCMCFF.git
synced 2025-06-26 08:51:16 +02:00
Add WIP chapter 2
This commit is contained in:
parent
654c5a89a4
commit
98b9b6bafa
@ -26,23 +26,189 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "6327bffe-5a27-4643-929e-a9d41672cd2c",
|
||||
"id": "5e745b48-9cde-49d1-b91b-b04282f6d30d",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Packaging\n",
|
||||
"Before we proceed I want to get some tests running. We'll use these to test the correctness of our code and also to check that we don't break anything that previously worked as we make changes and improvments. Checking you haven't broken something is called a regression test.\n",
|
||||
"\n",
|
||||
"Now that we have some code, we're going to factor it out into a little python package, this has a few benefits:\n",
|
||||
" - foo\n",
|
||||
" - bah"
|
||||
"Table of Contents:\n",
|
||||
"- Setting up the directory structure of the project\n",
|
||||
"- Creating a python package\n",
|
||||
"- Testing!"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "70c12053-ab4c-4a2b-a31a-16f01776419f",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Directory Structure\n",
|
||||
"More info:\n",
|
||||
"- [General Python Packaging advice](https://packaging.python.org/en/latest/tutorials/packaging-projects/)\n",
|
||||
"- [Packaging for pytest](https://docs.pytest.org/en/6.2.x/goodpractices.html)\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"Before we can do any testing, it is best practice to structure and then package your code up as a python project up. You don't have to do it like this but but it carrys with it the benefit that many only tutorial _expect_ you to do it like this and generally you want to reduce friction for yourself later. \n",
|
||||
"\n",
|
||||
"Like all things progamming, there are many opinions about how python projects should be structured, as I write this the structure of this repository is this: (This is the lightly edited output of the `tree` command if you're interested) \n",
|
||||
"```\n",
|
||||
".\n",
|
||||
"├── CITATION.cff\n",
|
||||
"├── LICENSE\n",
|
||||
"├── README.md\n",
|
||||
"├── requirements.txt\n",
|
||||
"├── code\n",
|
||||
"│ ├── README.md\n",
|
||||
"│ ├── pyproject.toml\n",
|
||||
"│ ├── setup.cfg\n",
|
||||
"│ ├── src\n",
|
||||
"│ │ └── MCFF\n",
|
||||
"│ │ ├── __init__.py\n",
|
||||
"│ │ ├── ising_model.py\n",
|
||||
"│ │ └── mcmc.py\n",
|
||||
"│ └── tests\n",
|
||||
"│ ├── test_energy.py\n",
|
||||
"│ └── test_energy_using_hypothesis.py\n",
|
||||
"└── learning\n",
|
||||
" └── ...\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"It's looks pretty intimidating! But let's quickly go through it, at the top level of most projects you'll find on Github and elsewhere you'll find files to do with the project as a whole:\n",
|
||||
"- `README.md` - An intro to the project\n",
|
||||
"- `LICENSE` - The software license that governs this project, there are a few standard ones people use.\n",
|
||||
"- `requirements.txt` or `environment.yaml` (or both) this list what python packages the project needs in a standard format\n",
|
||||
"- `CITATION.cff` This is the new standard way to describe how a work should be cited, v useful for academic software.\n",
|
||||
"\n",
|
||||
"Then below that you will usually have directories breaking the project up into main categories, here I have `code/` and `learning/` but it would be more typical to have what is in `code` at the top level.\n",
|
||||
"\n",
|
||||
"Inside `code/` we have a standard python package directory structure.\n",
|
||||
"\n",
|
||||
"## Packaging\n",
|
||||
"There are a few things going on here, our actual code lives in `MCFF/` which is wrapped up inside a `src` folder, the `src` thing is a convention related to pytests, check [Packaging for pytest](https://docs.pytest.org/en/6.2.x/goodpractices.html) if you want the gory details.\n",
|
||||
"\n",
|
||||
"Inside `MCFF/` we have our files that will become submodules so that in python we will be able to do things like:\n",
|
||||
"\n",
|
||||
"```python\n",
|
||||
"from MCFF.ising_model import all_up_state, all_down_state, random_state\n",
|
||||
"from MCFF import mcmc\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"`pyproject.toml` and `setup.cfg` are the current way to describe the metadat about a python package like how it should be installed and who the author is etc, but typically you just copy the standard layouts and build from there. The empty `__init__.py` file flags that this folder is a python module.\n",
|
||||
"\n",
|
||||
"*NB* The [General Python Packaging advice](https://packaging.python.org/en/latest/tutorials/packaging-projects/) says to use `requires = [\"setuptools>=42\"]` but this did not work on my system, I founded removing the version restriction on setuptools seemed to fix the problem. Don't be afraid to google it if you're having problems.\n",
|
||||
"\n",
|
||||
"pyproject.toml:\n",
|
||||
"```\n",
|
||||
"[build-system]\n",
|
||||
"requires = [\"setuptools\"]\n",
|
||||
"build-backend = \"setuptools.build_meta\"\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"requirements.txt\n",
|
||||
"```\n",
|
||||
"ipykernel\n",
|
||||
"numpy\n",
|
||||
"scipy\n",
|
||||
"matplotlib\n",
|
||||
"numba\n",
|
||||
"```\n",
|
||||
"`ipykernel` is there because it lets you run the envronment in a jupyter notebook easily. \n",
|
||||
"\n",
|
||||
"setup.cfg\n",
|
||||
"```\n",
|
||||
"[metadata]\n",
|
||||
"name = MCFF\n",
|
||||
"version = 0.0.1\n",
|
||||
"author = Tom Hodson\n",
|
||||
"author_email = tch14@ic.ac.uk\n",
|
||||
"description = A small example package\n",
|
||||
"long_description = file: README.md\n",
|
||||
"long_description_content_type = text/markdown\n",
|
||||
"url = None\n",
|
||||
"classifiers =\n",
|
||||
" Programming Language :: Python :: 3\n",
|
||||
" License :: OSI Approved :: MIT License\n",
|
||||
" Operating System :: OS Independent\n",
|
||||
"\n",
|
||||
"[options]\n",
|
||||
"package_dir = \n",
|
||||
" = src\n",
|
||||
"packages = find:\n",
|
||||
"python_requires = >=3.6\n",
|
||||
"\n",
|
||||
"[options.packages.find]\n",
|
||||
"where = src\n",
|
||||
"```\n",
|
||||
"Phew, that was a lot. Python packaging has been evolving a lot over the years and the consequence is there is a lot of out of date advice and there are many other ways to do this. You're best bet to figure out what the current best practice is is to consult offical sources like python.org\n",
|
||||
"\n",
|
||||
"Once all that is setup, cd to the `code/` folder and install the module using:\n",
|
||||
"```bash\n",
|
||||
"pip install --editable .\n",
|
||||
"```\n",
|
||||
"The dot means we should install MCFF from the current directory and `--editable` means to do it as an editable package so that we can edit the files in MCFF and not have to reinstall. This is really useful for development."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "553ac586-39c4-4a3e-bf54-af89f46b8ba3",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Testing\n",
|
||||
"Ok we can finally start writing and running some tests! Check out the [pytest website](https://docs.pytest.org/en/7.1.x/getting-started.html) for a tutorial on how to write tests in pytest and head over to the [Turing Way](https://the-turing-way.netlify.app/reproducible-research/testing.html) for a great introduction to testing in general. \n",
|
||||
"\n",
|
||||
"I copied some of the initial tests that we did in chapter 1 into `test_energy.py` installed pytest into my development environemnt with `pip install pytest` and now I can run\n",
|
||||
"```sh\n",
|
||||
"python -m pytest\n",
|
||||
"```\n",
|
||||
"And get a lovely output!"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "58bef986-9d69-4ef6-8a64-9eaf29c3424e",
|
||||
"execution_count": 3,
|
||||
"id": "17186d0c-982c-45e4-b88f-c87d73b8d1a7",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<script id=\"asciicast-498583\" src=\"https://asciinema.org/a/498583.js\" async></script>\n"
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.HTML object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"%%html\n",
|
||||
"<script id=\"asciicast-498583\" src=\"https://asciinema.org/a/498583.js\" async></script>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "d8ab0ff0-e916-4903-9a2d-c85ad2d6a713",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"[](https://asciinema.org/a/498583)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "a43c40eb-127e-4caf-8abf-b62931539130",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"https://docs.pytest.org/en/6.2.x/goodpractices.html\n",
|
||||
"\n",
|
||||
"Now make sure you have pytest installed in this environment and then run it:\n",
|
||||
"```\n",
|
||||
"pip install pytest\n",
|
||||
"python -m pytest\n",
|
||||
"```\n",
|
||||
"If you just run `pytest` you may run into issues where the you run pytest in the wrong python environment and it will complain to you that it can't find MCFF."
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
|
Loading…
x
Reference in New Issue
Block a user