├── .circleci └── config.yml ├── .github └── workflows │ └── zenodo.yml ├── .gitignore ├── .zenodo.json ├── CODE_OF_CONDUCT.md ├── Gemfile ├── Guardfile ├── LICENSE ├── Makefile ├── README.md ├── _bibliography └── references.bib ├── _config.yml ├── _data └── toc.yml ├── _includes ├── buttons.html ├── buttons │ ├── binder.html │ ├── download.html │ ├── jupyterhub.html │ ├── nbinteract.html │ └── thebelab.html ├── css_entry.scss ├── fb_tags.html ├── footer.html ├── google_analytics.html ├── head.html ├── js │ ├── interact-update.html │ ├── nbinteract.html │ ├── print.html │ ├── thebelab-cell-button.html │ ├── thebelab-page-config.html │ └── thebelab.html ├── mathjax.html ├── metadata.json ├── page-nav.html ├── search │ └── lunr │ │ ├── lunr-en.js │ │ └── lunr-store.js ├── sidebar.html └── topbar.html ├── _layouts └── default.html ├── _sass ├── components │ ├── _components.book__layout.scss │ ├── _components.book__topbar.scss │ ├── _components.interact-button.scss │ ├── _components.page__footer.scss │ ├── _components.page__nav.scss │ ├── _components.page__onthispage.scss │ ├── _components.search.scss │ └── _components.thebelab.scss ├── hamburgers │ ├── _base.scss │ ├── hamburgers.scss │ └── types │ │ └── _arrowalt.scss ├── main.scss ├── objects │ └── _objects.thebelab-in-cell-button.scss └── page │ ├── components │ ├── _components.hidecells.scss │ ├── _components.page.scss │ └── _components.sidebar-right.scss │ ├── elements │ ├── _elements.links.scss │ ├── _elements.syntax-highlighting.scss │ ├── _elements.tables.scss │ ├── _elements.typography.scss │ └── _elements.variables.scss │ ├── generic │ └── _generic.phone-scrolling.scss │ ├── inuitcss │ ├── elements │ │ ├── _elements.headings.scss │ │ ├── _elements.images.scss │ │ ├── _elements.page.scss │ │ └── _elements.tables.scss │ ├── generic │ │ ├── _generic.box-sizing.scss │ │ ├── _generic.normalize.scss │ │ ├── _generic.reset.scss │ │ └── _generic.shared.scss │ ├── objects │ │ ├── _objects.block.scss │ │ ├── _objects.box.scss │ │ ├── _objects.crop.scss │ │ ├── _objects.flag.scss │ │ ├── _objects.layout.scss │ │ ├── _objects.list-bare.scss │ │ ├── _objects.list-inline.scss │ │ ├── _objects.media.scss │ │ ├── _objects.pack.scss │ │ ├── _objects.ratio.scss │ │ ├── _objects.table.scss │ │ └── _objects.wrapper.scss │ ├── settings │ │ ├── _example.settings.config.scss │ │ ├── _example.settings.global.scss │ │ └── _settings.core.scss │ ├── tools │ │ ├── _tools.clearfix.scss │ │ ├── _tools.font-size.scss │ │ ├── _tools.hidden.scss │ │ └── _tools.mq.scss │ └── utilities │ │ ├── _utilities.clearfix.scss │ │ ├── _utilities.headings.scss │ │ ├── _utilities.hide.scss │ │ ├── _utilities.print.scss │ │ ├── _utilities.responsive-spacings.scss │ │ ├── _utilities.spacings.scss │ │ └── _utilities.widths.scss │ ├── main.scss │ ├── objects │ ├── _objects.copy-button.scss │ └── _objects.tooltip.scss │ └── settings │ └── settings.global.scss ├── assets ├── css │ └── styles.scss ├── custom │ ├── custom.css │ └── custom.js ├── html │ ├── index.html │ └── search_form.html ├── images │ ├── download-solid.svg │ ├── edit-button.svg │ ├── list-solid.svg │ ├── logo_binder.svg │ ├── logo_jupyterhub.svg │ └── search-solid.svg └── js │ ├── page │ ├── anchors.js │ ├── copy-button.js │ ├── documentSelectors.js │ ├── dom-update.js │ ├── hide-cell.js │ └── tocbot.js │ └── scripts.js ├── content ├── LICENSE.md ├── advanced │ ├── advanced.md │ ├── classes.ipynb │ ├── custom_packages.ipynb │ ├── object_oriented_plotting.ipynb │ └── oop.ipynb ├── basics │ ├── and_or.ipynb │ ├── basics.md │ ├── collections.ipynb │ ├── flow_control.ipynb │ ├── functions.ipynb │ ├── loops.ipynb │ ├── numpy_arrays.ipynb │ ├── oop_intro.ipynb │ ├── periodic_table_20.py │ ├── types.ipynb │ └── wavefunction.py ├── contributing.md ├── data_work │ ├── benzene_data.csv │ ├── benzyl_alcohol.csv │ ├── computational_output.txt │ ├── data_work.md │ ├── io.ipynb │ ├── ir_spectra.ipynb │ ├── linear_algebra.ipynb │ ├── mixture.csv │ ├── optimisation.ipynb │ ├── simple_plots.ipynb │ ├── stats.ipynb │ ├── surface_plots.ipynb │ ├── toluene.csv │ └── units_and_uncertainties.ipynb ├── getting_started.md ├── good_practice │ ├── custom_modules.ipynb │ ├── debugging.ipynb │ ├── documentation.ipynb │ ├── good_practice.md │ ├── packages.ipynb │ ├── print_things.py │ ├── raising_errors.ipynb │ └── tests.ipynb ├── images │ ├── AND_logic_gate.png │ ├── AND_logic_gate.svg │ ├── C-3PO_droid.png │ ├── Molecule.png │ ├── SimpleMolecule.png │ ├── a_function.png │ ├── a_function.svg │ ├── acetylene.png │ ├── and.png │ ├── and.svg │ ├── bowl.png │ ├── bowl.svg │ ├── classes.afdesign │ ├── flowchart-3.png │ ├── flowchart-3.svg │ ├── flowchart-4.png │ ├── flowchart-4.svg │ ├── flowchart_1.png │ ├── flowchart_1.svg │ ├── flowchart_2.png │ ├── flowchart_2.svg │ ├── indexing_array_2_2.png │ ├── indexing_array_2_2.svg │ ├── indexing_array_3.png │ ├── indexing_array_3.svg │ ├── indexing_array_z.png │ ├── indexing_array_z.svg │ ├── list_indexing.png │ ├── list_indexing.svg │ ├── list_slicing.png │ ├── list_slicing.svg │ ├── logo │ │ ├── download.svg │ │ ├── edit-button.svg │ │ ├── favicon.ico │ │ ├── jupyter.png │ │ ├── logo.ai │ │ ├── logo.png │ │ └── logo.svg │ ├── monty_hall_goat.png │ ├── netlify-build.png │ ├── netlify-cd.png │ ├── netlify-domain.png │ ├── number_line.png │ ├── number_line.svg │ ├── or.png │ ├── or.svg │ ├── polynomial_1.png │ ├── polynomial_1.svg │ ├── polynomial_1_ball.png │ ├── polynomial_1_ball.svg │ ├── polynomial_2.png │ ├── polynomial_2.svg │ ├── polynomial_2_ball.png │ ├── polynomial_2_ball.svg │ ├── polynomial_3.png │ ├── polynomial_3.svg │ ├── polynomial_3_contour.png │ ├── polynomial_3_contour.svg │ ├── snow_map.jpg │ ├── snow_map2.jpg │ ├── tags_jupyterlab.png │ ├── tags_notebook.png │ ├── thebebinder.png │ ├── x_squared.png │ ├── x_squared.svg │ ├── x_squared_ball.png │ └── x_squared_ball.svg ├── intro.md └── style_guide.md ├── requirements.txt ├── runtime.txt └── scripts ├── __pycache__ └── clean.cpython-37.pyc └── clean.py /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | # NOTE: This is an example CircleCI configuration that 2 | # will build your book and preview its HTML content. 3 | # You will probably have to modify it in order to get it working 4 | # just the way you want. See https://jupyterbook.org/advanced/circleci.html 5 | # for more information 6 | version: 2.1 7 | jobs: 8 | build_page_html: 9 | docker: 10 | - image: circleci/python:3.7-stretch 11 | steps: 12 | - checkout 13 | - run: pip install --user -r requirements.txt 14 | - run: 15 | name: Build site intermediate files 16 | command: jupyter-book build . 17 | 18 | # Persist the built files for the deploy step 19 | - persist_to_workspace: 20 | root: . 21 | paths: 22 | - _build/ 23 | 24 | doc: 25 | docker: 26 | - image: circleci/python:3.7-stretch 27 | steps: 28 | - prepare_jekyll_installation 29 | - run: 30 | name: Build the website 31 | command: bundle exec jekyll build --baseurl /0/html/ 32 | 33 | # Tell Circle to store the documentation output in a folder that we can access later 34 | - store_artifacts: 35 | path: _site/ 36 | destination: html 37 | 38 | # Deploy the built site to jupyter-book.github.io 39 | deploy: 40 | docker: 41 | - image: circleci/python:3.7-stretch 42 | steps: 43 | # Add deployment key fingerprint for CircleCI to use for a push 44 | - add_ssh_keys: 45 | fingerprints: 46 | - "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC2ZOdao1Va5ZtwbQHW2SGB3UiikVWp29fkGB0dgO43okHQ62uQgSDx4DgYzV5I7sa+jIb1z857wFsoZuR0nD/FQmv1Qp0I/W9tOF0tyPYAe+xjQNUudQMLrBB/vOVf8OHPvDNz5e0sVuBpxwYqgHvd/x3i7hpVlk5B+aQ0zE8AC8oqQY57bOf8Hr69Pz89Jv3zbkKZ1mCA1zK/+icwLEUeHg5gC6bts9dWMpKt8+SLrpliVnWHFpcU1asumZ7LaTRsUGt/mm9sH3MuO8FtxFnAgsFfIapI6bjEX3oKX5o1Ki/6R9LpZj0mJfhZrJ2gT2ga+KjGwcdpc2PnPNv8T1f00ihr6+48G0EEF/rL+K7CQHP9BATMHRncdv8hM2HP5RBTNhnSpZn/fNmpmQSY/c0e5HzxKRfkjVi8cSGgMgXNsMA1keX6IbxwX1+5G+MpSAhMq6OkfNQqMW7bLA3XahSOIinth4mB/PiHMU0n9OOstBcC1jw6RBVDzhXNKPihQBO9uWeH9mhruQ9e63PYAv4SunHW6qa9NvOMuYv/AfggctINcNbD5I6zfZWmnwwDFOFqkYXW0+0IJ9c4BBcGBHP2vNj0e0HegqV7HjIu9bUlm6WtBrAebEbD7BkX5Id3vgNd0i3EX2JfZW8rG1IHq8zmrwa/gr8VdVFH1kHAl9VI9Q== a.r.mccluskey@bath.ac.uk" 47 | 48 | - prepare_jekyll_installation 49 | - run: 50 | name: Build the website for deploy 51 | command: bundle exec jekyll build 52 | 53 | # Deploy the built site with ghp-import 54 | - run: 55 | name: Deploying site using ghp-import 56 | command: | 57 | pip install ghp-import 58 | ghp-import -p -f -n ./_site/ -m '[ci skip] deploy' 59 | 60 | 61 | # Tell CircleCI to use this workflow when it builds the site 62 | workflows: 63 | version: 2 64 | default: 65 | jobs: 66 | - build_page_html: 67 | filters: 68 | branches: 69 | ignore: 70 | - gh-pages 71 | - doc: 72 | requires: 73 | - build_page_html 74 | filters: 75 | branches: 76 | ignore: 77 | - gh-pages 78 | - deploy: 79 | requires: 80 | - build_page_html 81 | filters: 82 | branches: 83 | only: 84 | - master 85 | ignore: 86 | - gh-pages 87 | 88 | commands: 89 | prepare_jekyll_installation: 90 | steps: 91 | - checkout 92 | - attach_workspace: 93 | # Must be absolute path or relative path from working_directory 94 | at: /tmp/workspace 95 | 96 | # Grab the the built intermediate files from the last step 97 | - run: 98 | name: Copy over built site files 99 | command: | 100 | rm -rf ./_build 101 | cp -r /tmp/workspace/_build . 102 | 103 | # Install miniconda to test install 104 | - run: 105 | name: install miniconda 106 | command: | 107 | export MINICONDA=$HOME/miniconda 108 | echo "export PATH=$MINICONDA/bin:$PATH" >> $BASH_ENV 109 | source $BASH_ENV 110 | hash -r 111 | wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh 112 | bash miniconda.sh -b -f -p $MINICONDA 113 | conda config --set always_yes yes 114 | conda update conda 115 | conda info -a 116 | conda create -n testenv python=3.7.0 117 | source activate testenv 118 | rm miniconda.sh 119 | 120 | # Install Ruby/Jekyll dependencies 121 | - run: 122 | name: Installing Ruby/Jekyll from conda-forge 123 | command: conda install -c conda-forge rb-github-pages 124 | 125 | # Build the book's HTML w/ the base_url for CircleCI artifacts 126 | - run: 127 | name: Install book Ruby dependencies 128 | command: | 129 | export MINICONDA=$HOME/miniconda 130 | echo "export PATH=$MINICONDA/bin:$PATH" >> $BASH_ENV 131 | source $BASH_ENV 132 | pip install -r requirements.txt 133 | conda install gxx_linux-64 134 | make install -------------------------------------------------------------------------------- /.github/workflows/zenodo.yml: -------------------------------------------------------------------------------- 1 | name: Make release 2 | 3 | on: 4 | schedule: 5 | - cron: '0 0 1 * *' 6 | 7 | jobs: 8 | build: 9 | name: Create Release 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Checkout code 13 | uses: actions/checkout@v2 14 | - name: Get time 15 | id: time 16 | uses: nanzm/get-time-action@v1.0 17 | - name: Create Release 18 | id: create_release 19 | uses: actions/create-release@v1 20 | env: 21 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 22 | with: 23 | tag_name: ${{ steps.time.outputs.time }} 24 | release_name: Release ${{ steps.time.outputs.time }} 25 | body: | 26 | Automated release bot to push zenodo 27 | draft: false 28 | prerelease: false 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | **/.ipynb_checkpoints 3 | .ssh 4 | 5 | # editors 6 | .vscode -------------------------------------------------------------------------------- /.zenodo.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "An Introduction to Python for Chemists", 3 | "creators": [{ 4 | "name": "McCluskey, Andrew R.", 5 | "affiliation": "Diamond Light Source, Harwell Campus,. Didcot, OX11 0DE, UK.; Department of Chemistry, University of Bath, Claverton Down, Bath, BA2 7AY, UK.", 6 | "orcid": "0000-0003-3381-5911" 7 | }, 8 | { 9 | "name": "Dean, Jacob M.", 10 | "affiliation": "Department of Chemistry, University of Bath, Claverton Down, Bath, BA2 7AY, UK.; The Faraday Institution, Quad One, Becquerel Ave, Harwell Campus, Didcot, OX11 0RA.", 11 | "orcid": "0000-0003-3363-4256" 12 | }, 13 | { 14 | "name": "Squires, Alexander G.", 15 | "affiliation": "Department of Chemistry, University of Bath, Claverton Down, Bath, BA2 7AY, UK.", 16 | "orcid": "0000-0001-6967-3690" 17 | }, 18 | { 19 | "name": "Meli, Rocco", 20 | "affiliation": "Department of Biochemistry, University of Oxford, South Parks Rd., Oxford, OX1 3QU, UK.", 21 | "orcid": "0000-0002-2845-3410" 22 | }, 23 | { 24 | "name": "Glass, William G.", 25 | "affiliation": "Department of Biochemistry, University of Oxford, South Parks Rd., Oxford, OX1 3QU, UK.; Memorial Sloan-Kettering Cancer Center, Zuckerman Building 417 E 68th St, NYC.", 26 | "orcid": "0000-0002-4099-9280" 27 | }, 28 | { 29 | "name": "Symington, Adam R.", 30 | "affiliation": "Department of Chemistry, University of Bath, Claverton Down, Bath, BA2 7AY, UK.", 31 | "orcid": "0000-0001-6059-497X" 32 | }, 33 | { 34 | "name": "Morgan, Benjamin J.", 35 | "affiliation": "Department of Chemistry, University of Bath, Claverton Down, Bath, BA2 7AY, UK.", 36 | "orcid": "0000-0002-3056-8233" 37 | } 38 | ], 39 | "description": "An open-source project to develop an introductory textbook covering all aspects of Python programming for chemistry students.", 40 | "access_right": "open", 41 | "license": "CC-BY-4.0", 42 | "grants": [{ 43 | "funder": "Ada Lovelace Centre (STFC)" 44 | }, 45 | { 46 | "funder": "The Faraday Institution" 47 | }, 48 | { 49 | "funder": "The Royal Society", 50 | "code": "UF130329" 51 | } 52 | ] 53 | } 54 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at andrew.mccluskey@diamond.ac.uk. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | group :jekyll_plugins do 4 | gem 'github-pages' 5 | gem 'jekyll-feed', '~> 0.6' 6 | 7 | # Textbook plugins 8 | gem 'jekyll-redirect-from' 9 | gem 'jekyll-scholar' 10 | end 11 | 12 | # Windows does not include zoneinfo files, so bundle the tzinfo-data gem 13 | gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby] 14 | 15 | # Performance-booster for watching directories on Windows 16 | gem 'wdm', '~> 0.1.0' if Gem.win_platform? 17 | 18 | # Development tools 19 | gem 'guard', '~> 2.14.2' 20 | gem 'guard-jekyll-plus', '~> 2.0.2' 21 | gem 'guard-livereload', '~> 2.5.2' -------------------------------------------------------------------------------- /Guardfile: -------------------------------------------------------------------------------- 1 | guard 'jekyll-plus', serve: true do 2 | watch /.*/ 3 | ignore /^_site/ 4 | end 5 | 6 | guard 'livereload' do 7 | watch /.*/ 8 | end 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2019-2020, Python in Chemistry 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: help book clean serve 2 | 3 | help: 4 | @echo "Please use 'make ' where is one of:" 5 | @echo " install to install the necessary dependencies for jupyter-book to build" 6 | @echo " book to convert the content/ folder into Jekyll markdown in _build/" 7 | @echo " clean to clean out site build files" 8 | @echo " runall to run all notebooks in-place, capturing outputs with the notebook" 9 | @echo " serve to serve the repository locally with Jekyll" 10 | @echo " build to build the site HTML and store in _site/" 11 | @echo " site to build the site HTML, store in _site/, and serve with Jekyll" 12 | 13 | 14 | install: 15 | jupyter-book install ./ 16 | 17 | book: 18 | jupyter-book build ./ 19 | 20 | runall: 21 | jupyter-book run ./content 22 | 23 | clean: 24 | python scripts/clean.py 25 | 26 | serve: 27 | bundle exec guard 28 | 29 | build: 30 | jupyter-book build ./ --overwrite 31 | 32 | site: build 33 | bundle exec jekyll build 34 | touch _site/.nojekyll 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # An Introduction to Python for Chemists 2 | 3 | [![intro_python_chemists](https://circleci.com/gh/pythoninchemistry/intro_python_chemists.svg?style=svg)](https://circleci.com/gh/pythoninchemistry/intro_python_chemists) 4 | [![DOI](https://zenodo.org/badge/248480226.svg)](https://zenodo.org/badge/latestdoi/248480226) 5 | 6 | This is an open-source project to develop an introductory textbook covering all aspects of Python programming for chemistry students (at all career positions). 7 | 8 | ## Current aim 9 | 10 | Currently we are in the middle of the **content creation sprint**. 11 | The idea of this is that this sprint will last for at least three months (or until we have all the content we "want"). 12 | During this time, content does not need to be polished and the exact table of contents shape and structure is flexible. 13 | We have some ideas for content that we would like (see the issues), but if you have another idea please feel free. 14 | 15 | In order to be as flexible as possible we are currently not focusing content *order*, so if it is not clear, your should include some prerequisites at the top of the section that you are adding. 16 | 17 | Once this sprint is complete, we will move to a **content curation sprint** where we will work to clean up the content that has been written and develop in more detailed flow for the book, ensuring that each new section build on those previous! 18 | After this curation sprint it may be the case that new content becomes obvious (in which case we will go back to a creation sprint), or we may release the first version of the book. 19 | 20 | The book will **always** exist as a living document, however major releases will be numbered appropriately. 21 | 22 | ## Recognizing contributors 23 | 24 | We welcome and recognize all contributions from writing new content to proof reading to improving figures. 25 | You can see a list of current contributors in the [contributors tab](https://github.com/pythoninchemistry/intro_python_chemists/graphs/contributors). 26 | 27 | If you would like to be involved, please look at the [contributing guidelines](https://github.com/pythoninchemistry/intro_python_chemists/blob/master/content/contributing.md). 28 | 29 | ## On coding style 30 | 31 | In this book we prioritise readibility and understandability of code over everything else. 32 | Therefore, the code herein will **not** necessarily adhere to PEP8 or any other standard, in particular if it sacrifices the educational utility of the material. 33 | **All** issues opened that are based purely on standard adherence **will** be closed without considering. 34 | However, we are open to issues and pull requests that discuss/improve coding style **if** the focus is on making the code clearer for the learner. 35 | 36 | ## License 37 | 38 | Code snippets and examples are covered by an [BSD-3](https://opensource.org/licenses/BSD-3-Clause) license (see `LICENSE` file) (see LICENSE file). Text, images, and any other content is covered by the [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) license (see below). 39 | 40 | Creative Commons License
This work is licensed under a Creative Commons Attribution 4.0 International License. -------------------------------------------------------------------------------- /_data/toc.yml: -------------------------------------------------------------------------------- 1 | # This file contains the order and numbering for all sections in the book. 2 | # 3 | # Each entry has the following schema: 4 | # 5 | # - title: mytitle # Title of chapter or section 6 | # url: /myurl # URL of section relative to the /content/ folder. 7 | # sections: # Contains a list of more entries that make up the chapter's sections 8 | # not_numbered: true # if the section shouldn't have a number in the sidebar 9 | # (e.g. Introduction or appendices) 10 | # expand_sections: true # if you'd like the sections of this chapter to always 11 | # be expanded in the sidebar. 12 | # external: true # Whether the URL is an external link or points to content in the book 13 | # 14 | # Below are some special values that trigger specific behavior: 15 | # - search: true # Will provide a link to a search page 16 | # - divider: true # Will insert a divider in the sidebar 17 | # - header: My Header # Will insert a header with no link in the sidebar 18 | 19 | 20 | - url: /intro 21 | not_numbered: true 22 | title: "Welcome" 23 | 24 | - url: /getting_started 25 | not_numbered: true 26 | 27 | - url: /basics/basics 28 | not_numbered: false 29 | expand_sections: false 30 | sections: 31 | - url: /basics/types 32 | - url: /basics/collections 33 | - url: /basics/numpy_arrays 34 | - url: /basics/functions 35 | - url: /basics/flow_control 36 | - url: /basics/and_or 37 | - url: /basics/loops 38 | - url: /basics/oop_intro 39 | 40 | - url: /good_practice/good_practice 41 | not_numbered: false 42 | expand_sections: false 43 | sections: 44 | - url: /good_practice/documentation 45 | - url: /good_practice/packages 46 | - url: /good_practice/custom_modules 47 | - url: /good_practice/tests 48 | - url: /good_practice/debugging 49 | - url: /good_practice/raising_errors 50 | 51 | - url: /data_work/data_work 52 | not_numbered: false 53 | expand_sections: false 54 | sections: 55 | - url: /data_work/io 56 | - url: /data_work/units_and_uncertainties 57 | - url: /data_work/simple_plots 58 | - url: /data_work/surface_plots 59 | - url: /data_work/stats 60 | - url: /data_work/optimisation 61 | - url: /data_work/ir_spectra 62 | - url: /data_work/linear_algebra 63 | 64 | - url: /advanced/advanced 65 | not_numbered: false 66 | expand_sections: false 67 | sections: 68 | - url: /advanced/oop 69 | - url: /advanced/object_oriented_plotting 70 | - url: /advanced/classes 71 | - url: /advanced/custom_packages 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /_includes/buttons.html: -------------------------------------------------------------------------------- 1 |
2 | {% include buttons/download.html %} 3 | {% if page.interact_link %} 4 | {% include buttons/thebelab.html %} 5 | {% include buttons/nbinteract.html %} 6 | {% include buttons/binder.html %} 7 | {% include buttons/jupyterhub.html %} 8 | {% endif %} 9 |
10 | -------------------------------------------------------------------------------- /_includes/buttons/binder.html: -------------------------------------------------------------------------------- 1 | {% if site.use_binder_button %} 2 | 3 | {% if site.use_jupyterlab %} 4 | {% assign binder_interact_prefix="urlpath=lab/tree/" %} 5 | {% else %} 6 | {% assign binder_interact_prefix="filepath=" %} 7 | {% endif %} 8 | 9 | {% capture interact_url_binder %}v2/gh/{{ site.binder_repo_org }}/{{ site.binder_repo_name }}/{{ site.binder_repo_branch }}?{{ binder_interact_prefix }}{{ page.interact_link | url_encode }}{% endcapture %} 10 | {% capture interact_icon_binder %}{{ site.images_url | relative_url }}/logo_binder.svg{% endcapture %} 11 | 12 | 13 | 14 | {%- endif %} -------------------------------------------------------------------------------- /_includes/buttons/download.html: -------------------------------------------------------------------------------- 1 | {% if site.use_download_button -%} 2 |
3 | 4 |
5 | {% if page.interact_link -%} 6 | 7 | 8 | 9 | {% endif %} 10 | 11 |
12 |
13 | {%- endif %} 14 | -------------------------------------------------------------------------------- /_includes/buttons/jupyterhub.html: -------------------------------------------------------------------------------- 1 | {% if site.use_jupyterhub_button %} 2 | 3 | {% if site.use_jupyterlab %} 4 | {% assign hub_app="lab" %} 5 | {% else %} 6 | {% assign hub_app="notebook" %} 7 | {% endif %} 8 | 9 | {% capture interact_url_jupyterhub %}hub/user-redirect/git-pull?repo={{ site.binder_repo_base }}/{{ site.binder_repo_org }}/{{ site.binder_repo_name }}&branch={{ site.binder_repo_branch }}&subPath={{ page.interact_link | url_encode }}&app={{ hub_app }}{% endcapture %} 10 | {% capture interact_icon_jupyterhub %}{{ site.images_url | relative_url }}/logo_jupyterhub.svg{% endcapture %} 11 | 12 | 13 | {% endif %} 14 | -------------------------------------------------------------------------------- /_includes/buttons/nbinteract.html: -------------------------------------------------------------------------------- 1 | {% if site.use_show_widgets_button and page.has_widgets -%} 2 | 3 | {% endif %} -------------------------------------------------------------------------------- /_includes/buttons/thebelab.html: -------------------------------------------------------------------------------- 1 | {% if site.use_thebelab_button -%} 2 | 3 | {% endif %} -------------------------------------------------------------------------------- /_includes/css_entry.scss: -------------------------------------------------------------------------------- 1 | @import 'inuitcss/settings/settings.core'; 2 | @import 'settings/settings.global.scss'; 3 | 4 | @import 'inuitcss/tools/tools.font-size'; 5 | @import 'inuitcss/tools/tools.clearfix'; 6 | @import 'inuitcss/tools/tools.hidden'; 7 | @import 'inuitcss/tools/tools.mq'; 8 | 9 | @import 'inuitcss/elements/elements.page'; 10 | @import 'inuitcss/elements/elements.headings'; 11 | @import 'inuitcss/elements/elements.images'; 12 | @import 'inuitcss/elements/elements.tables'; 13 | @import 'elements/elements.typography'; 14 | @import 'elements/elements.syntax-highlighting'; 15 | @import 'elements/elements.tables'; 16 | @import 'elements/elements.links'; 17 | 18 | @import 'components/components.textbook__page'; 19 | -------------------------------------------------------------------------------- /_includes/fb_tags.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /_includes/footer.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | -------------------------------------------------------------------------------- /_includes/google_analytics.html: -------------------------------------------------------------------------------- 1 | {% if site.google_analytics.mytrackingcode %} 2 | 3 | 4 | 11 | {% endif %} 12 | -------------------------------------------------------------------------------- /_includes/head.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | {% if page.title %}{{ page.title | escape }}{% else %}{{ site.title | escape }}{% endif %} 7 | 8 | 9 | 10 | 11 | 12 | {% include fb_tags.html %} 13 | 14 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | {% include mathjax.html %} 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | {% include js/nbinteract.html %} 53 | 54 | 55 | {% include js/thebelab.html %} 56 | 57 | 58 | 59 | 60 | 61 | 62 | {% include google_analytics.html %} 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | {% include js/interact-update.html %} 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | {% include js/print.html %} 89 | 90 | -------------------------------------------------------------------------------- /_includes/js/interact-update.html: -------------------------------------------------------------------------------- 1 | {% if site.use_jupyterhub_button or site.use_binder_button %} 2 | 142 | {% endif %} -------------------------------------------------------------------------------- /_includes/js/nbinteract.html: -------------------------------------------------------------------------------- 1 | {% if site.use_show_widgets_button and page.has_widgets %} 2 | 3 | 4 | 5 | 33 | {% endif %} -------------------------------------------------------------------------------- /_includes/js/print.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 33 | -------------------------------------------------------------------------------- /_includes/js/thebelab-cell-button.html: -------------------------------------------------------------------------------- 1 | {% if site.use_thebelab_button -%} 2 | 27 | {% endif %} 28 | -------------------------------------------------------------------------------- /_includes/js/thebelab-page-config.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_includes/js/thebelab.html: -------------------------------------------------------------------------------- 1 | 2 | {% if site.use_thebelab_button %} 3 | 4 | 5 | {% include js/thebelab-cell-button.html %} 6 | 7 | 95 | {% endif %} 96 | -------------------------------------------------------------------------------- /_includes/mathjax.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 29 | 30 | -------------------------------------------------------------------------------- /_includes/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "@context": "http://schema.org", 3 | "@type": "NewsArticle", 4 | "mainEntityOfPage": "{{ page.url | replace:'index.html','' | prepend: site.baseurl | prepend: site.url }}", 5 | "headline": "{% if page.title %}{{ page.title | escape }}{% else %}{{ site.title | escape }}{% endif %}", 6 | "datePublished": "{% if page.date %}{{ page.date | date_to_xmlschema }}{% else %}{{ site.time | date_to_xmlschema }}{% endif %}", 7 | "dateModified": "{% if page.date %}{{ page.date | date_to_xmlschema }}{% else %}{{ site.time | date_to_xmlschema }}{% endif %}", 8 | "description": "{{ page.content | strip_html | strip_newlines | truncate: 160 }}", 9 | "author": { 10 | "@type": "Person", 11 | "name": "{{ site.author }}" 12 | }, 13 | "publisher": { 14 | "@type": "Organization", 15 | "name": "Data 100 at UC Berkeley", 16 | "logo": { 17 | "@type": "ImageObject", 18 | "url": "{{ site.logo | prepend: site.baseurl | prepend: site.url }}", 19 | "width": 60, 20 | "height": 60 21 | } 22 | }, 23 | "image": { 24 | "@type": "ImageObject", 25 | "url": "{{ site.logo | prepend: site.baseurl | prepend: site.url }}", 26 | "height": 60, 27 | "width": 60 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /_includes/page-nav.html: -------------------------------------------------------------------------------- 1 | {% comment %} 2 | Only the URLs from the TOC are used here. The title for 3 | prev/next is pulled from the respective page's metadata. 4 | We loop through the "build" collection to determine the 5 | page title based on the *current* page's next/prev URL. 6 | {% endcomment %} 7 | 38 | -------------------------------------------------------------------------------- /_includes/search/lunr/lunr-en.js: -------------------------------------------------------------------------------- 1 | var initQuery = function() { 2 | // See if we have a search box 3 | var searchInput = document.querySelector('input#lunr_search'); 4 | if (searchInput === null) { 5 | return; 6 | } 7 | 8 | // Function to parse our lunr cache 9 | var idx = lunr(function () { 10 | this.field('title') 11 | this.field('excerpt') 12 | this.field('categories') 13 | this.field('tags') 14 | this.ref('id') 15 | 16 | this.pipeline.remove(lunr.trimmer) 17 | 18 | for (var item in store) { 19 | this.add({ 20 | title: store[item].title, 21 | excerpt: store[item].excerpt, 22 | categories: store[item].categories, 23 | tags: store[item].tags, 24 | id: item 25 | }) 26 | } 27 | }); 28 | 29 | // Run search upon keyup 30 | searchInput.addEventListener('keyup', function () { 31 | var resultdiv = document.querySelector('#results'); 32 | var query = document.querySelector("input#lunr_search").value.toLowerCase(); 33 | var result = 34 | idx.query(function (q) { 35 | query.split(lunr.tokenizer.separator).forEach(function (term) { 36 | q.term(term, { boost: 100 }) 37 | if(query.lastIndexOf(" ") != query.length-1){ 38 | q.term(term, { usePipeline: false, wildcard: lunr.Query.wildcard.TRAILING, boost: 10 }) 39 | } 40 | if (term != ""){ 41 | q.term(term, { usePipeline: false, editDistance: 1, boost: 1 }) 42 | } 43 | }) 44 | }); 45 | 46 | // Empty the results div 47 | while (resultdiv.firstChild) { 48 | resultdiv.removeChild(resultdiv.firstChild); 49 | } 50 | 51 | resultdiv.insertAdjacentHTML('afterbegin', '

'+result.length+' Result(s) found

'); 52 | for (var item in result) { 53 | var ref = result[item].ref; 54 | if(store[ref].teaser){ 55 | var searchitem = 56 | '
'+ 57 | '
'+ 58 | '

'+ 59 | ''+store[ref].title+''+ 60 | '

'+ 61 | '
'+ 62 | ''+ 63 | '
'+ 64 | '

'+store[ref].excerpt.split(" ").splice(0,20).join(" ")+'...

'+ 65 | '
'+ 66 | '
'; 67 | } 68 | else{ 69 | var searchitem = 70 | '
'+ 71 | '
'+ 72 | '

'+ 73 | ''+store[ref].title+''+ 74 | '

'+ 75 | '

'+store[ref].excerpt.split(" ").splice(0,20).join(" ")+'...

'+ 76 | '
'+ 77 | '
'; 78 | } 79 | resultdiv.insertAdjacentHTML('beforeend', searchitem); 80 | } 81 | }); 82 | }; 83 | 84 | initFunction(initQuery); 85 | -------------------------------------------------------------------------------- /_includes/search/lunr/lunr-store.js: -------------------------------------------------------------------------------- 1 | var store = [ 2 | {%- for c in site.collections -%} 3 | {%- if forloop.last -%} 4 | {%- assign l = true -%} 5 | {%- endif -%} 6 | {%- assign docs = c.docs | where_exp:'doc','doc.search != false' -%} 7 | {%- for doc in docs -%} 8 | {%- if doc.header.teaser -%} 9 | {%- capture teaser -%}{{ doc.header.teaser }}{%- endcapture -%} 10 | {%- else -%} 11 | {%- assign teaser = site.teaser -%} 12 | {%- endif -%} 13 | { 14 | "title": {{ doc.title | jsonify }}, 15 | {% assign truncateWords=site.search_max_words_in_content %} 16 | "excerpt": {{ doc.search | jsonify }}, 17 | "categories": {{ doc.categories | jsonify }}, 18 | "tags": {{ doc.tags | jsonify }}, 19 | "url": {{ doc.url | absolute_url | jsonify }}, 20 | "teaser": 21 | {%- if teaser contains "://" -%} 22 | {{ teaser | jsonify }} 23 | {%- else -%} 24 | {{ teaser | absolute_url | jsonify }} 25 | {%- endif -%} 26 | }{%- unless forloop.last and l -%},{%- endunless -%} 27 | {%- endfor -%} 28 | {%- endfor -%}] -------------------------------------------------------------------------------- /_includes/topbar.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | 12 | {% include buttons.html %} 13 |
14 | 15 | 20 | 21 | Search 22 | 23 |
24 | -------------------------------------------------------------------------------- /_layouts/default.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | {% include head.html %} 4 | 5 | 6 | {% include js/thebelab-page-config.html %} 7 | 8 | 9 |
10 | {% include sidebar.html %} 11 | {% if page.search_page != true %} 12 | {% endif %} 13 | {% include topbar.html %} 14 |
15 |
16 | {{ content }} 17 |
18 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /_sass/components/_components.book__layout.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * The website contains two main components: the sidebar and the textbook page. 3 | * This file specifies the layout and includes classes to show/hide the sidebar 4 | * on small screens. 5 | * 6 | * The actual styling for the sidebar and page are located in their respective 7 | * component SCSS files. This file manages the layout and width only. 8 | * 9 | * By default, the sidebar is not visible. 10 | * 11 | * [1]: The entire page is positioned relative so that when the page overflows 12 | * (e.g. sidebar open on small screens) the user can't scroll left/right. 13 | * [2]: The sidebar and the textbook page are positioned absolute so that we 14 | * can use translate() on the textbook page to reveal the sidebar. 15 | * [3]: Setting the background color hides the sidebar when it's behind the 16 | * page (otherwise the page is transparent). 17 | * 18 | * When the sidebar is visible: 19 | * 20 | * [4]: Shift the textbook page over to the left. On small screens, the page 21 | * will overflow since the sidebar takes up most of the screen. 22 | * [5]: On larger screens, the page and sidebar have enough room to read them 23 | * simultaneously, so make sure that the page doesn't overflow. 24 | */ 25 | 26 | $left-sidebar-width: 300px; 27 | $page-max-width: 880px; 28 | $right-sidebar-width: 220px; 29 | $topbar-height: 60px; 30 | 31 | .c-textbook { 32 | /* [1] */ 33 | position: relative; 34 | height: 100vh; 35 | overflow: hidden; 36 | margin: 0 0 0 auto; 37 | } 38 | 39 | .c-topbar { 40 | background-color: $book-background-color; 41 | position: fixed; 42 | top: 0; 43 | height: $topbar-height; 44 | width: 100%; 45 | left: 0; 46 | padding: $spacing-unit-small $spacing-unit-small 0 $spacing-unit-med * 2; 47 | z-index: 1; 48 | transition: top 250ms, transform 250ms ease; // For animations 49 | } 50 | 51 | @include mq($until: tablet) { 52 | .c-topbar.hidetop { 53 | // At desktop, we stop hiding the navbar 54 | top: -250px; 55 | } 56 | } 57 | 58 | .c-textbook__sidebar, 59 | .c-textbook__page { 60 | /* [2] */ 61 | height: 100vh; 62 | overflow: auto; 63 | position: fixed; 64 | background-color: $book-background-color; /* [3] */ 65 | } 66 | 67 | .c-textbook__sidebar { 68 | width: $left-sidebar-width; 69 | top: 0; 70 | left: 0; 71 | } 72 | 73 | .c-textbook__page { 74 | 75 | width: $textbook-page-width; 76 | transition: transform 250ms ease; 77 | left: 0; 78 | padding: 0 $spacing-unit $spacing-unit-small $spacing-unit-small * 3; 79 | overflow-x: visible; 80 | 81 | &:focus { 82 | /* [2] */ 83 | outline: none; 84 | } 85 | } 86 | 87 | .sidebar__right { 88 | // By default we hide the sidebar 89 | display: none; 90 | 91 | // Spacing for the sidebar 92 | width: $right-sidebar-width - $spacing-unit-small; // To account for the small margin on the right 93 | position: relative; 94 | float: right; 95 | z-index: 1; // Keep sidebar under page content 96 | 97 | @include mq($from: tablet) { 98 | // Show right TOC at laptop size 99 | display: block; 100 | } 101 | } 102 | 103 | .js-show-sidebar { 104 | .c-textbook__page, .c-topbar { 105 | /* [4] */ 106 | transform: translate($left-sidebar-width, 0); 107 | 108 | @include mq($from: tablet) { 109 | /* [5] */ 110 | width: calc(100% - #{$left-sidebar-width}); 111 | } 112 | } 113 | } 114 | 115 | .c-textbook__content { 116 | clear: both; 117 | padding-top: $topbar-height * 1.5; 118 | width: 95%; 119 | } 120 | 121 | .c-textbook__content, .c-textbook__footer { 122 | max-width: $page-max-width; 123 | } 124 | 125 | .c-page__nav { 126 | display: flex; 127 | justify-content: space-between; 128 | align-items: center; 129 | padding-top: 30px; 130 | } 131 | 132 | // Make sure that the bottom content has the same width as non-sidebar content 133 | .footer, .c-page__nav { 134 | @include mq($from: laptop) { 135 | width: $textbook-page-with-sidebar-width; 136 | } 137 | } 138 | 139 | // Scrollbar width 140 | ::-webkit-scrollbar { 141 | width: 5px; 142 | background: #f1f1f1; 143 | } 144 | 145 | ::-webkit-scrollbar-thumb { 146 | background: #c1c1c1; 147 | } 148 | 149 | main, nav { 150 | scrollbar-width: thin; 151 | } -------------------------------------------------------------------------------- /_sass/components/_components.book__topbar.scss: -------------------------------------------------------------------------------- 1 | .c-topbar__label { 2 | @include inuit-font-size(12px); 3 | display: inline-block; 4 | margin-left: $spacing-unit-tiny; 5 | vertical-align: middle; 6 | text-transform: uppercase; 7 | } 8 | 9 | .c-topbar { 10 | .hamburger, .buttons { 11 | float: left; 12 | } 13 | 14 | #js-sidebar-toggle { 15 | margin-right: 5px; 16 | padding-top: 4px; 17 | } 18 | 19 | span.hamburger-box { 20 | width: 40px; 21 | height: 30px; 22 | padding-left: 10px; 23 | } 24 | 25 | .c-topbar__buttons { 26 | @include mq($from: tablet) { 27 | width: calc(100% - #{$right-sidebar-width} - 20px) 28 | } 29 | } 30 | 31 | .topbar-right-button { 32 | display: block; 33 | float: right; 34 | padding: 0 1rem; 35 | 36 | img { 37 | width: 20px; 38 | margin-top: 4px; 39 | } 40 | } 41 | } 42 | 43 | // Download buttons 44 | 45 | .download-buttons { 46 | display: none; 47 | position: absolute; 48 | 49 | button { 50 | min-width: 100px !important; 51 | border: 1px white solid !important; 52 | border-radius: 0 !important; 53 | } 54 | } 55 | 56 | .download-buttons-dropdown { 57 | position: relative; 58 | display: inline-block; 59 | 60 | &:hover div.download-buttons { 61 | display: block; 62 | } 63 | 64 | img { 65 | height: 18px; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /_sass/components/_components.interact-button.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Stylings for Interact and Show Widget buttons. 3 | * 4 | * [1]: We abuse CSS selector specificity here since the buttons at the top of 5 | * the notebook might have both .interact-button and .js=nbinteract-widget. 6 | * [2]: We want the top buttons to be large. 7 | * [3]: However, a .js=nbinteract-widget appearing alone midway through the 8 | * notebook should be small. 9 | * 10 | */ 11 | 12 | $color-interact-button: #5a5a5a !default; 13 | 14 | %interact-button { 15 | @include inuit-font-size(14px); 16 | background-color: $color-interact-button; 17 | border-radius: 3px; 18 | border: none; 19 | color: white; 20 | cursor: pointer; 21 | display: inline-block; 22 | font-weight: 700; 23 | /* [2] */ 24 | padding: $spacing-unit-tiny $spacing-unit-med; 25 | text-decoration: none; 26 | 27 | &:hover, 28 | &:focus { 29 | text-decoration: none; 30 | } 31 | } 32 | 33 | .interact-button-logo { 34 | height: 1.35em; 35 | padding-right: 10px; 36 | margin-left: -5px; 37 | } 38 | 39 | .buttons { 40 | margin-bottom: $spacing-unit; 41 | 42 | /* [1] */ 43 | .interact-button { 44 | @extend %interact-button; 45 | } 46 | } 47 | 48 | .js-nbinteract-widget { 49 | @extend %interact-button; 50 | 51 | /* [3] */ 52 | padding: $spacing-unit-tiny $spacing-unit; 53 | margin-bottom: $spacing-unit-small; 54 | } 55 | 56 | // If the interact button link is changed with a REST param 57 | div.interact-context { 58 | display: inline; 59 | padding-left: 1em; 60 | } -------------------------------------------------------------------------------- /_sass/components/_components.page__footer.scss: -------------------------------------------------------------------------------- 1 | .footer { 2 | text-align: center; 3 | font-size: 14px; 4 | padding: 20px; 5 | opacity: 0.7; 6 | margin-bottom: 0px; 7 | } 8 | -------------------------------------------------------------------------------- /_sass/components/_components.page__nav.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Styling for the Next Page / Previous Page links at the bottom of textbook 3 | * pages. 4 | */ 5 | 6 | $color-nav-links: rgba(0, 140, 255, 0.7); 7 | 8 | .c-page__nav__prev, 9 | .c-page__nav__next { 10 | flex: 1; 11 | color: $color-nav-links; 12 | border: 1px solid $color-nav-links; 13 | border-radius: 3px; 14 | padding: $spacing-unit-small 0; 15 | } 16 | 17 | .c-page__nav__next { 18 | text-align: right; 19 | } 20 | -------------------------------------------------------------------------------- /_sass/components/_components.page__onthispage.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Styling for the onthispage elements. 3 | * 4 | * [1]: The sidebar is implemented as ul and li elements so we need to remove 5 | * the bullets and margins. Also make chapter fonts a bit bigger. 6 | * [2]: The entries are tags so we need to remove the default styling. 7 | * [3]: The sidebar divider is just an empty element with a border. 8 | * [4]: The current section needs a higher specificity to override the :hover 9 | * selectors used previously. 10 | * [5]: The logo displayed above the sidebar 11 | * [6]: The footer at the bottom of the sidebar 12 | */ 13 | $color-sidebar-bg: rgba(255, 255, 255, 0) !default; 14 | $color-sidebar-entry: #364149 !default; 15 | $color-sidebar-entry--active: $color-links !default; 16 | $color-sidebar-divider: #bbb !default; 17 | 18 | .c-textbook__sidebar { 19 | background-color: $color-sidebar-bg; 20 | padding: $spacing-unit-small; 21 | 22 | @include inuit-font-size(14px); 23 | border-right: 1px solid rgba(0, 0, 0, 0.07); 24 | opacity: 0.6; 25 | -webkit-transition: opacity 0.2s ease-in-out; 26 | transition: opacity 0.2s ease-in-out; 27 | 28 | &:hover { 29 | opacity: 1; 30 | } 31 | } 32 | 33 | /* [1] */ 34 | .c-sidebar__chapters { 35 | list-style: none; 36 | margin-left: 0; 37 | margin-bottom: 0; 38 | } 39 | 40 | li.c-sidebar__chapter > a { 41 | font-size: 1.2em; 42 | } 43 | 44 | /* [1] */ 45 | .c-sidebar__sections, .c-sidebar__subsections { 46 | list-style: none; 47 | margin-bottom: 0; 48 | } 49 | 50 | .c-sidebar__sections { 51 | margin-left: $spacing-unit-small; 52 | } 53 | 54 | .c-sidebar__subsections { 55 | margin-left: 20px; 56 | } 57 | 58 | /* [2] */ 59 | .c-sidebar__entry { 60 | display: block; 61 | 62 | padding: $spacing-unit-tiny; 63 | 64 | color: $color-sidebar-entry; 65 | text-decoration: none; 66 | 67 | &:hover { 68 | text-decoration: underline; 69 | } 70 | 71 | &:visited { 72 | color: $color-sidebar-entry; 73 | } 74 | } 75 | 76 | /* [4] */ 77 | .c-sidebar__entry--active.c-sidebar__entry--active { 78 | color: $color-sidebar-entry--active; 79 | } 80 | 81 | /* [3] */ 82 | .c-sidebar__divider { 83 | border-top: 1px solid $color-sidebar-divider; 84 | margin: $spacing-unit-tiny; 85 | } 86 | 87 | /* [5] */ 88 | img.textbook_logo { 89 | margin-top: 20px; 90 | max-height: 100px; 91 | margin: 0px auto 20px auto; 92 | display: block; 93 | } 94 | 95 | /* [6] */ 96 | p.sidebar_footer { 97 | text-align: center; 98 | padding: 10px 20px 0px 0px; 99 | font-size: .9em; 100 | } -------------------------------------------------------------------------------- /_sass/components/_components.search.scss: -------------------------------------------------------------------------------- 1 | /* ========================================================================== 2 | SEARCH 3 | ========================================================================== */ 4 | // Taken from https://github.com/mmistakes/minimal-mistakes 5 | // Variables 6 | $large: 1024px !default; 7 | $x-large: 1280px !default; 8 | $type-size-1: 2.441em !default; 9 | $type-size-2: 1.953em !default; 10 | $type-size-3: 1.563em !default; 11 | $type-size-6: 0.75em !default; 12 | $intro-transition: intro 0.3s both !default; 13 | 14 | // Rules 15 | .layout--search { 16 | .archive__item-teaser { 17 | margin-bottom: 0.25em; 18 | } 19 | } 20 | 21 | .search__toggle { 22 | margin-left: 1rem; 23 | margin-right: 1rem; 24 | border: 0; 25 | outline: none; 26 | color: #393e46; 27 | background-color: transparent; 28 | cursor: pointer; 29 | -webkit-transition: 0.2s; 30 | transition: 0.2s; 31 | 32 | &:hover { 33 | color: #000; 34 | } 35 | } 36 | 37 | .search-icon { 38 | width: 100%; 39 | height: 100%; 40 | } 41 | 42 | .search-content { 43 | //display: none; 44 | //visibility: hidden; 45 | padding-top: 1em; 46 | padding-bottom: 1em; 47 | 48 | &__inner-wrap { 49 | width: 100%; 50 | margin-left: auto; 51 | margin-right: auto; 52 | padding-left: 1em; 53 | padding-right: 1em; 54 | -webkit-animation: $intro-transition; 55 | animation: $intro-transition; 56 | -webkit-animation-delay: 0.15s; 57 | animation-delay: 0.15s; 58 | 59 | .search-input { 60 | display: block; 61 | margin-bottom: 0; 62 | padding: 0; 63 | border: none; 64 | outline: none; 65 | box-shadow: none; 66 | background-color: transparent; 67 | font-size: $type-size-3; 68 | } 69 | } 70 | 71 | &.is--visible { 72 | display: block; 73 | visibility: visible; 74 | 75 | &::after { 76 | content: ""; 77 | display: block; 78 | } 79 | } 80 | 81 | .results__found { 82 | margin-top: 0.5em; 83 | font-size: $type-size-6; 84 | } 85 | 86 | .archive__item { 87 | margin-bottom: 2em; 88 | } 89 | 90 | .archive__item-title { 91 | margin-top: 0; 92 | } 93 | 94 | .archive__item-excerpt { 95 | margin-bottom: 0; 96 | } 97 | } -------------------------------------------------------------------------------- /_sass/components/_components.thebelab.scss: -------------------------------------------------------------------------------- 1 | 2 | .thebelab-cell { 3 | // To ensure that thebelab cells are always the top of the Z-stack 4 | position: relative; 5 | z-index: 999; 6 | } 7 | 8 | .thebelab-button { 9 | z-index: 999; 10 | display: inline-block; 11 | padding: 0.35em 1.2em; 12 | margin: 0px 1px; 13 | border-radius: 0.12em; 14 | box-sizing: border-box; 15 | text-decoration: none; 16 | font-family: 'Roboto', sans-serif; 17 | font-weight: 300; 18 | text-align: center; 19 | transition: all 0.2s; 20 | background-color: #dddddd; 21 | border: 0.05em solid white; 22 | color: #000000; 23 | } 24 | 25 | .thebelab-button:hover{ 26 | border: 0.05em solid black; 27 | background-color: #fcfcfc; 28 | } 29 | 30 | 31 | div.jp-OutputArea-output { 32 | padding: 5px; 33 | } 34 | -------------------------------------------------------------------------------- /_sass/hamburgers/_base.scss: -------------------------------------------------------------------------------- 1 | // Hamburger 2 | // ================================================== 3 | .hamburger { 4 | padding: $hamburger-padding-y $hamburger-padding-x; 5 | display: inline-block; 6 | cursor: pointer; 7 | 8 | transition-property: opacity, filter; 9 | transition-duration: $hamburger-hover-transition-duration; 10 | transition-timing-function: $hamburger-hover-transition-timing-function; 11 | 12 | // Normalize (