")
11 | em (enlive/select doc [:.hello :em])]
12 | (enlive/texts em))
13 | ```
14 |
15 | ## Including Enlive
16 |
17 | ## Searching for tags
18 |
--------------------------------------------------------------------------------
/docs/introduction/clojure-libraries.md:
--------------------------------------------------------------------------------
1 | ## Clojure libraries for data science
2 |
3 | - Tablecloth
4 | - dtype-next
5 | - tech.viz
6 | - Oz
7 | - Hanami
8 |
9 |
10 | ## Integration with data science tools
11 |
12 | - [:fontawesome-brands-github: libpython-clj](https://github.com/clj-python/libpython-clj){target=_blank} - Deep Clojure/Python Integration
13 | - [:fontawesome-brands-youtube: Extending Clojure with Python - Chris Nuernberger](https://www.youtube.com/watch?v=vQPW16_jixs){target=_blank}
14 |
--------------------------------------------------------------------------------
/.github/config/markdown-link-check.json:
--------------------------------------------------------------------------------
1 | {
2 | "ignorePatterns": [
3 | {
4 | "pattern": "^http://localhost"
5 | },
6 | {
7 | "pattern": "^mailto:*"
8 | },
9 | {
10 | "pattern": "^#*"
11 | },
12 | {
13 | "pattern": "^https://127.0.0.0/"
14 | }
15 | ],
16 | "timeout": "20s",
17 | "retryOn429": true,
18 | "retryCount": 5,
19 | "fallbackRetryDelay": "30s",
20 | "aliveStatusCodes": [
21 | 200,
22 | 206
23 | ]
24 | }
25 |
--------------------------------------------------------------------------------
/docs/notebooks/clerk/index.md:
--------------------------------------------------------------------------------
1 | # Notebooks: Clerk
2 |
3 | The soon to be released Clerk project is a notebook that is designed with local development as its main focus.
4 |
5 |
6 |
7 |
8 | ## ClojureD presentation
9 |
10 |
11 |
12 |
13 | ## References
14 | * Clerk author [Martin Kavalar](https://twitter.com/mkvlr)
15 |
--------------------------------------------------------------------------------
/docs/data-mining/index.md:
--------------------------------------------------------------------------------
1 | # Data Mining
2 |
3 | The data required is often not provided in an easily consumable form, referred to as unstructured data.
4 |
5 | Data mining techniques like web-scraping and Extra-Transform-Load (ETL) tools can turn unstructured data into something useful.
6 |
7 | > The clojure.core library has a wide range of functions for transforming data into the right shape, as the Clojure language is a data structure.
8 |
9 | - scraping unstructured data sources
10 | - consuming open API data sources
11 | - highlighting reputable and high quality data sources
12 |
13 |
--------------------------------------------------------------------------------
/.github/config/gitleaks.toml:
--------------------------------------------------------------------------------
1 | title = "gitleaks config"
2 |
3 | [allowlist]
4 | description = "global allow lists"
5 | paths = [
6 | '''gitleaks.toml''',
7 | '''(.*?)(jpg|gif|doc|docx|zip|xls|pdf|bin|svg|socket)$''',
8 | '''(go.mod|go.sum)$''',
9 | '''gradle.lockfile''',
10 | '''node_modules''',
11 | '''package-lock.json''',
12 | '''pnpm-lock.yaml''',
13 | '''Database.refactorlog''',
14 | '''vendor''',
15 | ]
16 |
17 | [[rules]]
18 | description = "AWS Example API Key"
19 | id = "aws-example-api-key"
20 | regex = '''AKIAIOSFODNN7EXAMPLE'''
21 | keywords = [
22 | "awstoken",
23 | ]
24 |
--------------------------------------------------------------------------------
/docs/introduction/data-science.md:
--------------------------------------------------------------------------------
1 | # Data Science
2 |
3 | - Statistics and probability
4 | - Linear Algebra
5 | - Mathematical Optimisation
6 | - Calculus
7 |
8 |
9 | ## Future topics
10 |
11 | - Trend analysis
12 | - Principle component analysis
13 | - Basic Modelling (for machine learning)
14 | - Time series [tidyverts](https://tidyverts.org/)
15 | - Data generation - examples of how to generate sample data
16 | - Data sources - what are good data sources and what concepts are they good for exploring
17 | - Identify and simply explain data science concepts and provide understanding / examples of how they can be valuable
18 |
--------------------------------------------------------------------------------
/docs/introduction/data-science-books.md:
--------------------------------------------------------------------------------
1 | # Data Science books
2 |
3 | There are many great data science books and Practicalli will curate a selection of books that are considered investing time into.
4 |
5 | ## Clojure specific data science books
6 |
7 | * [Linear Algebra for Programmers]](https://aiprobook.com/numerical-linear-algebra-for-programmers/)
8 | * [Deep Learning for Programmers](https://aiprobook.com/deep-learning-for-programmers/)
9 | * [Clojure for Data Science](https://www.packtpub.com/product/clojure-for-data-science/9781784397180)
10 |
11 |
12 | ## General Data Science books
13 | * [Python Data Science Handbook](https://jakevdp.github.io/PythonDataScienceHandbook/)
14 | * [R for Data Science](https://r4ds.had.co.nz/)
15 |
--------------------------------------------------------------------------------
/docs/introduction/online-courses.md:
--------------------------------------------------------------------------------
1 | # Online Data Science Courses
2 |
3 |
4 | | Course | Math Level | Language | Tools | Summary |
5 | |--------------------------------------------------------------|-------------|----------|--------------------------------------------------------|-------------------------------|
6 | | [Practical Deep Learning for Coders](https://course.fast.ai) | High School | Python | [Jupiter notebook](https://github.com/fastai/fastbook) | AI Applications Without a PhD |
7 | | | | | | |
8 |
--------------------------------------------------------------------------------
/docs/introduction/what-is-clojure.md:
--------------------------------------------------------------------------------
1 | # What is Clojure?
2 |
3 | Clojure is a general purpose programming language and is used for creating any applications, tools, services across any industry.
4 |
5 | Clojure is a hosted language, so it can run on a Java Virtual machine (especially for high volume data processing). Clojure can also run on JavaScript engines found in web browsers and nodejs.
6 |
7 | Clojure has a very simple syntax and is simple to write and maintain.
8 |
9 | Clojure is very data centric and the standard library has over 500 functions for manipulating and transforming data, so is ideal for data science tasks.
10 |
11 | [Practicalli Clojure will help you get started with Clojure](https://practicalli.github.io/clojure/) and help you create a Clojure development environment with a [Clojure aware editor](http://practicalli.github.io/clojure/clojure-editors/).
12 |
--------------------------------------------------------------------------------
/docs/mathematics/linear-algebra/index.md:
--------------------------------------------------------------------------------
1 | # Mathematics: Linear Algebra
2 |
3 | Linear Algebra comprises of mathematical techniques that help efficiently calculate sums for large data sets
4 |
5 | * dot product
6 | * vectors
7 | * matrix transformation
8 |
9 |
10 | ## References
11 | * [Wikipedia: Linear Algebra](https://en.wikipedia.org/wiki/Linear_algebra)
12 | * [Khan Academy](https://www.khanacademy.org/math/linear-algebra)
13 | * [MIT Open Courseware: Linear Algebra](https://ocw.mit.edu/courses/mathematics/18-06-linear-algebra-spring-2010/)
14 | * [YouTube: Essence of Linear Algebra](https://www.youtube.com/playlist?list=PLZHQObOWTQDPD3MizzM2xVFitgF8hE_ab)
15 | * [UC Davis: Linear Algebra](https://www.math.ucdavis.edu/~linear/linear-guest.pdf)
16 | * FreeCodeCamp: Linear Algebra full college course [part 1](https://www.youtube.com/watch?v=JnTa9XtvmfI) and [part 2](https://www.youtube.com/watch?v=DJ6YwBN7Ya8)
17 |
--------------------------------------------------------------------------------
/docs/notebooks/next-journal/index.md:
--------------------------------------------------------------------------------
1 | # Notbooks: NextJournal
2 |
3 | [NextJournal](https://nextjournal.com/) is a hosted Journal with wide support for programming languages (Clojure, Python, Scala, etc.).
4 |
5 | The [NextJournal](https://nextjournal.com/) platform has been developed with Clojure.
6 |
7 | Enjoy Version Control, Simple Sharing and Collaboration. Set Up Your Data Science Project Within Minutes. Simple Collaboration. Cloud Computing. Features: Automatic Provisioning & Shutdown, Data & Secrets Management, Rapid And Full Reusability.
8 |
9 | Runs anything you can put into a Docker container. Improve your workflow with polyglot notebooks, automatic versioning and real-time collaboration. Save time and money with on-demand provisioning, including GPU support.
10 |
11 |
12 | 
13 |
--------------------------------------------------------------------------------
/docs/data-mining/webscraping/table-data.md:
--------------------------------------------------------------------------------
1 | # Webscraping HTML table data
2 |
3 | Data is often published using HTML tables, as its a very simple language that non-developers can easily pick up.
4 |
5 |
6 |
7 | ## Data in a pre tag
8 | Using pre to create a table in a web page is similar to using a CSV except whitespace is used instead of commas to demarcated the individual elements.
9 |
10 | Data can be put into a vector, optionally grouping each line as a vector within a vector using ``partition`.
11 |
12 | If data should be associated with a name, then use the `map` function to convert the
13 |
14 |
15 | #### Example data
16 | Tables without headings
17 | * [Riverflow reconstructions for England and Wales](https://crudata.uea.ac.uk/cru/data/riverflow/) - University of Eas Anglia Climactic Research Unit
18 |
19 | Tables with headings and comments
20 | * [Cloud Cover by Country](https://crudata.uea.ac.uk/cru/data/hrg/cru_ts_4.01/crucy.1709191757.v4.01/countries/cld/) - University of Eas Anglia Climactic Research Unit
21 |
--------------------------------------------------------------------------------
/.github/config/lychee.toml:
--------------------------------------------------------------------------------
1 |
2 | # ----------------------------------------
3 | # Base URL or website root directory to check relative URLs.
4 | base = "https://practical.li/clojure-data-science"
5 |
6 | # Only test links with the given schemes (e.g. https).
7 | # Omit to check links with any other scheme.
8 | # At the moment, we support http, https, file, and mailto.
9 | scheme = ["https"]
10 |
11 | # ----------------------------------------
12 | # Exclusions
13 |
14 | # Exclude URLs and mail addresses from checking (supports regex).
15 | exclude = ['^https://127.0.0.0', '^https://www\.linkedin\.com', '^https://web\.archive\.org/web/']
16 |
17 | # Exclude these filesystem paths from getting checked.
18 | exclude_path = ["mkdocs.yml", "overrides", "includes", ".github", ".git"]
19 |
20 | # Exclude all private IPs from checking.
21 | # Equivalent to setting `exclude_private`, `exclude_link_local`, and
22 | # `exclude_loopback` to true.
23 | exclude_all_private = true
24 |
25 | # Check mail addresses
26 | include_mail = false
27 | # ----------------------------------------
28 |
--------------------------------------------------------------------------------
/overrides/404.html:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 | {% extends "main.html" %}
7 |
8 |
9 | {% block content %}
10 |
This is not the page you are looking for
11 |
12 |
13 | Sorry we have arrived at a page that does not exist...
14 |
15 |
16 |
17 | Practicalli Clojure Data Science is very early stages
18 |
19 |
20 |
21 | Use the Search bar at the top of the page or left navigation to find the relevant content.
22 |
23 |
38 |
39 | {% endblock %}
40 |
--------------------------------------------------------------------------------
/overrides/partials/palette.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
37 |
--------------------------------------------------------------------------------
/.github/pull_request_template.md:
--------------------------------------------------------------------------------
1 | :memo: Description
2 |
3 |
4 | :white_check_mark: Checklist
5 |
6 | - [ ] Commits should be cryptographically signed (SSH or GPG)
7 |
8 |
9 | ## Practicalli Guidelines
10 |
11 | Please follow these guidelines when submitting a pull request
12 |
13 | - refer to all relevant issues, using `#` followed by the issue number (or paste full link to the issue)
14 | - PR should contain the smallest possible change
15 | - PR should contain a very specific change
16 | - PR should contain only a single commit (squash your commits locally if required)
17 | - Avoid multiple changes across multiple files (raise an issue so we can discuss)
18 | - Avoid a long list of spelling or grammar corrections. These take too long to review and cherry pick.
19 |
20 | ## Submitting articles
21 |
22 | [Create an issue using the article template](https://github.com/practicalli/blog-content/issues/new?assignees=&labels=article&template=article.md&title=Suggested+article+title),
23 | providing as much detail as possible.
24 |
25 | ## Website design
26 |
27 | Suggestions about website design changes are most welcome, especially in terms of usability and accessibility.
28 |
29 | Please raise an issue so we can discuss changes first, especially changes related to aesthetics.
30 |
31 | ## Review process
32 |
33 | All pull requests are reviewed by @practicalli-johnny and feedback provided, usually the same day but please be patient.
34 |
--------------------------------------------------------------------------------
/.github/workflows/changelog-check.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | # Check CHANGELOG.md file updated for every pull request
3 |
4 | name: Changelog Check
5 | on:
6 | pull_request:
7 | paths-ignore:
8 | - "README.md"
9 | types: [opened, synchronize, reopened, ready_for_review, labeled, unlabeled]
10 |
11 | jobs:
12 | changelog:
13 | name: Changelog Update Check
14 | runs-on: ubuntu-latest
15 | steps:
16 | - run: echo "🚀 Job automatically triggered by ${{ github.event_name }}"
17 | - run: echo "🐧 Job running on ${{ runner.os }} server"
18 | - run: echo "🐙 Using ${{ github.ref }} branch from ${{ github.repository }} repository"
19 |
20 | # Git Checkout
21 | - name: Checkout Code
22 | uses: actions/checkout@v4
23 | with:
24 | fetch-depth: 0
25 | sparse-checkout: |
26 | docs
27 | overrides
28 | .github
29 | CHANGELOG.md
30 | - run: echo "🐙 Sparse Checkout of ${{ github.repository }} repository to the CI runner."
31 |
32 | # Changelog Enforcer
33 | - name: Changelog Enforcer
34 | uses: dangoslen/changelog-enforcer@v3
35 | with:
36 | changeLogPath: "CHANGELOG.md"
37 | skipLabels: "skip-changelog-check"
38 |
39 | # Summary and status
40 | - run: echo "🎨 Changelog Enforcer quality checks completed"
41 | - run: echo "🍏 Job status is ${{ job.status }}."
42 |
--------------------------------------------------------------------------------
/docs/notebooks/index.md:
--------------------------------------------------------------------------------
1 | # Clojure Data Science tooling: Notebooks
2 |
3 | Notebooks are interactive documents that include executable code and its results. They are a form of literate programming.
4 |
5 | For over 30 years data scientists have used notebooks for experiments, exploration of data and communicating insights to other data scientist and businesses.
6 |
7 | Software engineers can also use notebooks for development, providing fast feedback and a consistent way to visualise data.
8 |
9 | Open source notebooks include Jupyter (formerly known as iPython) and Apache Zeppelin.
10 |
11 | Hosted offerings include Deepnote, Noteable, Databricks Collaborative Notebooks, Google Colab, Jovian.ml, among others.
12 |
13 | Notebooks are programming language specific or support code for multiple languages like Polynote.
14 |
15 | ## Clojure Notebooks
16 | * NextJournal - hosted platform, written in Clojure, supports multiple programming languages
17 | * Notespace -
18 | * Clerk - Clojure based notebook focused on local development (not yet released)
19 | * Pink Gorilla
20 |
21 |
22 | > #### Hint::Wolfram Mathematica - first computational notebook
23 | > On June 23 1988 Stephan Wolfram first released [Wolfram Mathematica](https://en.wikipedia.org/wiki/Wolfram_Mathematica) that allow machine learning, statistics, symbolic computation, manipulating matrices, plotting functions and various types of data, implementation of algorithms, creation of user interfaces, and interfacing with programs written in other programming languages.
24 |
--------------------------------------------------------------------------------
/docs/install/index.md:
--------------------------------------------------------------------------------
1 | # Install
2 |
3 | Clojure CLI is used to run Clojure code and is extended by a wide range of community tools.
4 |
5 | A [Clojure aware editor](https://practical.li/clojure/clojure-editors/) is highly recommended. Practicalli uses the following
6 |
7 | - [Spacemacs](https://practical.li/spacemacs/) - an extensive and easy to use Emacs configuration
8 | - [Neovim and Conjure](https://practical.li/neovim/) - a lightweight and highly extensible modal editing experience
9 |
10 | Practialli Clojure provides [an overview of Clojure editors available](https://practical.li/clojure/clojure-editors/)
11 |
12 |
13 | ## Install Clojure CLI
14 |
15 | {align=right loading=lazy style="height:64px;width:64px"}
16 |
17 | [Practicalli Clojure Install Guide](https://practical.li/clojure/install/){target=_blank .md-button}
18 |
19 | Clojure CLI provide a simple and configurable way to:
20 |
21 | * Run Clojure programs and tools
22 | * Run an interactive REPL (Read-Eval-Print Loop) and evaluate Clojure expressions, usually with a [Clojure aware editor](https://practical.li/clojure/clojure-editors/)
23 | * Managing dependencies (via tools.deps) from Maven and Git repositories
24 |
25 | Using community tools on top of Clojure CLI tools provides tasks to create, develop, build and deploy Clojure applications and services
26 |
27 | Follow the [Practicalli Clojure Install Guide](https://practical.li/clojure/install/) to install Clojure and supporting tools.
28 |
--------------------------------------------------------------------------------
/.github/workflows/scheduled-version-check.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | # ------------------------------------------
3 | # Scheduled check of versions
4 | # - use as non-urgent report on versions
5 | # - Uses POSIX Cron syntax
6 | # - Minute [0,59]
7 | # - Hour [0,23]
8 | # - Day of the month [1,31]
9 | # - Month of the year [1,12]
10 | # - Day of the week ([0,6] with 0=Sunday)
11 | #
12 | # Using liquidz/anta to check:
13 | # - GitHub workflows
14 | # - deps.edn
15 | # ------------------------------------------
16 |
17 | name: "Scheduled Version Check"
18 | on:
19 | schedule:
20 | # - cron: "0 4 * * *" # at 04:04:04 ever day
21 | # - cron: "0 4 * * 5" # at 04:04:04 ever Friday
22 | - cron: "0 4 1 * *" # at 04:04:04 on first day of month
23 | workflow_dispatch: # Run manually via GitHub Actions Workflow page
24 |
25 | jobs:
26 | scheduled-version-check:
27 | name: "Scheduled Version Check"
28 | runs-on: ubuntu-latest
29 | steps:
30 | - run: echo "🚀 Job automatically triggered by ${{ github.event_name }}"
31 | - run: echo "🐧 Job running on ${{ runner.os }} server"
32 | - run: echo "🐙 Using ${{ github.ref }} branch from ${{ github.repository }} repository"
33 |
34 | - name: Checkout Code
35 | uses: actions/checkout@v4
36 | with:
37 | fetch-depth: 0
38 | sparse-checkout: |
39 | .github
40 | - run: echo "🐙 ${{ github.repository }} repository sparse-checkout to the CI runner."
41 | - name: "Antq Check versions"
42 | uses: liquidz/antq-action@main
43 | with:
44 | excludes: ""
45 | skips: "boot clojure-cli pom shadow-cljs leiningen"
46 |
47 | # Summary
48 | - run: echo "🎨 library versions checked with liquidz/antq"
49 | - run: echo "🍏 Job status is ${{ job.status }}."
50 |
--------------------------------------------------------------------------------
/.github/workflows/publish-book.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | name: Publish Book
3 | on:
4 | # Manually trigger workflow
5 | workflow_dispatch:
6 |
7 | # Run work flow conditional on linter workflow success
8 | workflow_run:
9 | workflows:
10 | - "MegaLinter"
11 | paths:
12 | - "docs/**"
13 | - "includes/**"
14 | - "overrides/**"
15 | - "mkdocs.yaml"
16 | branches:
17 | - main
18 | types:
19 | - completed
20 |
21 | permissions:
22 | contents: write
23 |
24 | jobs:
25 | publish-book:
26 | name: MkDocs Publish
27 | runs-on: ubuntu-latest
28 | steps:
29 | - run: echo "🚀 Job automatically triggered by ${{ github.event_name }}"
30 | - run: echo "🐧 Job running on ${{ runner.os }} server"
31 | - run: echo "🐙 Using ${{ github.ref }} branch from ${{ github.repository }} repository"
32 |
33 | - name: Checkout Code
34 | uses: actions/checkout@v4
35 | with:
36 | fetch-depth: 0
37 | sparse-checkout: |
38 | docs
39 | includes
40 | overrides
41 | - run: echo "🐙 ${{ github.repository }} repository sparse-checkout to the CI runner."
42 |
43 | - name: Setup Python
44 | uses: actions/setup-python@v5
45 | with:
46 | python-version: 3.x
47 |
48 | - name: Cache
49 | uses: actions/cache@v4
50 | with:
51 | key: ${{ github.ref }}
52 | path: .cache
53 |
54 | - run: pip install mkdocs-material mkdocs-callouts mkdocs-glightbox mkdocs-git-revision-date-localized-plugin mkdocs-redirects pillow cairosvg
55 | - run: mkdocs gh-deploy --force
56 | - run: echo "🐙 ."
57 |
58 | # Summary and status
59 | - run: echo "🎨 MkDocs Publish Book workflow completed"
60 | - run: echo "🍏 Job status is ${{ job.status }}."
61 |
--------------------------------------------------------------------------------
/docs/notebooks/notespace/index.md:
--------------------------------------------------------------------------------
1 | # Notespace - data science journal
2 | [Notespace](https://github.com/scicloj/notespace) generates a data science journal from a Clojure namespace, to give a simple to use literate programming experience.
3 |
4 | The [notespace introduction](https://scicloj.github.io/notespace/doc/notespace/v3-experiment1-test/index.html) shows how to create a Clojure namespace into a notespace. Clojure values, generative functions, markdown and graphics are defined using `notespace.kinds` as meta-data on Clojure expressions in the namespace.
5 |
6 | Run notespace listening to all changes, or just show a particular view (useful for large notespace) or even just update a line.
7 |
8 |
9 | ## Example project with notespace
10 | Use the [example Notespace project](https://github.com/practicalli/scicloj-notespace-simple-demo) which contains simple examples and also launches an empty notespace webpage and Portal data inspector window on REPL startup.
11 |
12 | Start a REPL for the project with Leiningen or Clojure CLI tools (version 1.10.1.697 or greater and aliases from [practicalli/clojure-deps-edn](https://github.com/practicalli/clojure-deps-edn))
13 |
14 | ```
15 | lein repl
16 |
17 | clojure -M:env/dev:inspect/portal
18 | ```
19 |
20 | Wait a few seconds for the Portal and Notespace pages to load into your browser.
21 |
22 | Evaluate the `(notespace/listen)` expression and the current namespace is loaded into the Notespace page. If the Notespace page stops updating, evaluate this expression again.
23 |
24 | Wrap values and function calls with the `tap>` function to see the values in the Portal window.
25 |
26 |
27 | > #### Hint::Emacs support - Clojure CLI tools
28 | > the [example Notespace project](https://github.com/practicalli/scicloj-notespace-simple-demo) contains a `.dir-locals.el` file for Clojure CLI tools, using the `:env/dev` and `:inspect/portal-cli` aliases from [practicalli/clojure-deps-edn](https://github.com/practicalli/clojure-deps-edn) user level configuration.
29 | >
30 | > When running `cider-jack-in` the aliases are automatically added to jack-in startup command.
31 |
--------------------------------------------------------------------------------
/.github/workflows/scheduled-stale-check.yaml:
--------------------------------------------------------------------------------
1 | # ----------------------------------------
2 | # Scheduled stale issue & pull request check
3 | #
4 | # Adds 'stale' label after a set piece of time,
5 | # then closes stale issues & pull requests a short period after
6 | #
7 | # Using "Close Stale Issues" action
8 | # https://github.com/marketplace/actions/close-stale-issues
9 | # ----------------------------------------
10 |
11 | name: 'Scheduled stale check'
12 | on:
13 | workflow_dispatch:
14 | schedule:
15 | - cron: "0 1 1 * *" # at 01:00 on first day of month
16 |
17 | jobs:
18 | stale:
19 | runs-on: ubuntu-latest
20 | steps:
21 | - run: echo "🚀 Job automatically triggered by ${{ github.event_name }}"
22 | - run: echo "🐧 Job running on ${{ runner.os }} server"
23 | - run: echo "🐙 Using ${{ github.ref }} branch from ${{ github.repository }} repository"
24 |
25 | - uses: actions/stale@v9
26 | with:
27 | stale-issue-message: 'After 30 days with no activity, the issue was automatically marked stale. Remove stale label or add a comment to prevent the issue being closed in 5 days.'
28 | stale-pr-message: 'After 45 days with no activity, the Pull Request was automatically marked stale. Remove stale label or comment to prevent the PR being closed in 10 days.'
29 | close-issue-message: 'This issue was closed because it has been stalled for 5 days with no activity.'
30 | close-pr-message: 'This PR was closed because it has been stalled for 10 days with no activity.'
31 | days-before-issue-stale: 30
32 | days-before-pr-stale: 45
33 | days-before-issue-close: 5
34 | days-before-pr-close: 10
35 | start-date: '2025-04-05T00:00:00Z' # only affect issues/PRs from date created (ISO 8601 or RFC 2822 format)
36 | any-of-labels: 'future,keep' # labels to keep
37 | exempt-issue-assignees: 'practicalli-johnny'
38 | exempt-pr-assignees: 'practicalli-johnny'
39 |
40 | # Summary
41 | - run: echo "🎨 Issues & Pull Request checked with actions/stale"
42 | - run: echo "🍏 Job status is ${{ job.status }}."
43 |
--------------------------------------------------------------------------------
/docs/mathematics/index.md:
--------------------------------------------------------------------------------
1 | # Math Essentials
2 |
3 | Data Science is an application of several fields of mathematics:
4 |
5 | - Statistics & Probability (process & interpret data)
6 | - Linear Algebra
7 | - Mathematical Optimisation (solving puzzles by finding optimal solution)
8 | - Calculus
9 |
10 | Mathematics uses these fields via experimental design (e.g. A/B testing), data processing and modelling.
11 |
12 | !!! QUOTE
13 | Without mathematics there is no data science... only data - John Stevenson (and probably many others before)
14 |
15 |
16 |
17 |
18 |
19 |
20 | ## Video Tutorials
21 |
22 | [:fontawesome-brands-youtube: Animated Mathematic Theory Explanations](https://www.youtube.com/@3blue1brown){target=_blank .md-button}
23 |
24 | ??? WARNING "Videos and Channels currently being reviewed by Practicalli"
25 |
26 | - [Data Science introduction](https://www.youtube.com/watch?v=ua-CiDNNj30) - Free Code Camp
27 | - [:fontawesome-brands-youtube: Damsel in Data](https://www.youtube.com/@damselindata)
28 | - [:fontawesome-brands-youtube: How to learn math for data science (the minimize effort maximize outcome way)](https://www.youtube.com/watch?v=5wMl5FM2swo)
29 | - [:fontawesome-brands-youtube: Maths For Data Science](https://www.youtube.com/playlist?list=PLwYvzp9lBJVmv6yLK1hDH_Hqosl-lzGOl) - Geek's Lesson
30 | - [:fontawesome-brands-youtube: Thu Vu data analytics](https://www.youtube.com/@Thuvu5)
31 | - [:fontawesome-brands-youtube: Mathematics, statistics for data science and machine learning](https://www.youtube.com/playlist?list=PLeo1K3hjS3uuKaU2nBDwr6zrSOTzNCs0l)
32 | - [Sundas Khalid Data Science, Tech and Career Tips](https://www.youtube.com/@SundasKhalid)
33 |
34 |
35 | - [All Machine Learning Models Explained in 5 Minutes](https://www.youtube.com/watch?v=yN7ypxC7838)
36 |
37 |
38 |
39 | ## Resources
40 |
41 | - [Math for Clojurists](https://alanmarazzi.gitlab.io/blog/posts/2020-3-23-math-for-clojurists/)
42 |
--------------------------------------------------------------------------------
/.github/workflows/megalinter.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | # MegaLinter GitHub Action configuration file
3 | # More info at https://megalinter.io
4 | # All variables described in https://megalinter.io/latest/configuration/
5 |
6 | name: MegaLinter
7 | on:
8 | workflow_dispatch:
9 | pull_request:
10 | branches: [main]
11 | push:
12 | branches: [main]
13 |
14 | # Run Linters in parallel
15 | # Cancel running job if new job is triggered
16 | concurrency:
17 | group: "${{ github.ref }}-${{ github.workflow }}"
18 | cancel-in-progress: true
19 |
20 | jobs:
21 | megalinter:
22 | name: MegaLinter
23 | runs-on: ubuntu-latest
24 | steps:
25 | - run: echo "🚀 Job automatically triggered by ${{ github.event_name }}"
26 | - run: echo "🐧 Job running on ${{ runner.os }} server"
27 | - run: echo "🐙 Using ${{ github.ref }} branch from ${{ github.repository }} repository"
28 |
29 | # Git Checkout
30 | - name: Checkout Code
31 | uses: actions/checkout@v4
32 | with:
33 | fetch-depth: 0
34 | sparse-checkout: |
35 | docs
36 | overrides
37 | .github
38 | - run: echo "🐙 Sparse Checkout of ${{ github.repository }} repository to the CI runner."
39 |
40 | # MegaLinter Configuration
41 | - name: MegaLinter Run
42 | id: ml
43 | ## latest release of major version
44 | uses: oxsecurity/megalinter/flavors/documentation@v8
45 | env:
46 | # ADD CUSTOM ENV VARIABLES OR DEFINE IN MEGALINTER_CONFIG file
47 | MEGALINTER_CONFIG: .github/config/megalinter.yaml
48 |
49 | GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" # report individual linter status
50 | # Validate all source when push on main, else just the git diff with live.
51 | VALIDATE_ALL_CODEBASE: >-
52 | ${{ github.event_name == 'push' && github.ref == 'refs/heads/main'}}
53 |
54 | # Upload MegaLinter artifacts
55 | - name: Archive production artifacts
56 | if: ${{ success() }} || ${{ failure() }}
57 | uses: actions/upload-artifact@v4
58 | with:
59 | name: MegaLinter reports
60 | path: |
61 | megalinter-reports
62 | mega-linter.log
63 |
64 | # Summary and status
65 | - run: echo "🎨 MegaLinter quality checks completed"
66 | - run: echo "🍏 Job status is ${{ job.status }}."
67 |
--------------------------------------------------------------------------------
/SUMMARY.md:
--------------------------------------------------------------------------------
1 | # Summary
2 |
3 | * [Overview](overview.md)
4 | * [Persona](persona/index.md)
5 | * [What is Clojure?](what-is-clojure.md)
6 | * [Recommended books](data-science-books.md)
7 | * [Contributing](contributing.md)
8 |
9 | ## Tooling
10 |
11 | * Literate programming
12 |
13 | * [Notebooks](notebooks/index.md)
14 | * [notespace](notebooks/notespace/index.md)
15 | * [Configure notespace](notebooks/notespace/configure-notespace-project.md)
16 |
17 | * [Clerk](notebooks/clerk/index.md)
18 | * [Next Journal](notebooks/next-journal/index.md)
19 | * [Pink Gorilla](notebooks/pink-gorilla/index.md)
20 |
21 |
22 |
23 | ## Data mining
24 |
25 | * [Data Mining](data-mining/index.md)
26 | * [Web scraping](data-mining/webscraping/index.md)
27 | * [Web Tags to Clojure](data-mining/webscraping/enlive.md)
28 | * [Table data](data-mining/webscraping/table-data.md)
29 |
30 |
31 |
32 |
33 |
34 | ## Data Wrangling
35 |
36 | * [tablecloth](tablecloth/index.md)
37 |
38 | ## Visualisation
39 |
40 | * [Story telling](visualization/story-telling/index.md)
41 | * [Oz](visualization/oz/index.md)
42 | * [Create Project](visualization/oz/create-project.md)
43 | * [Oz](visualization/oz/clojure-spec.md)
44 | * [Generate Static site](visualization/oz/clojure-spec.md)
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 | ## Mathematics
54 |
55 | * [Linear Algebra](mathematics/linear-algebra/index.md)
56 |
57 |
58 |
59 |
60 |
61 |
62 | ### Integration
63 |
64 | * [Python](integration/python/index.md)
65 | * [libpython-clj](https://github.com/clj-python/libpython-clj)
66 |
67 |
68 | ## Collaborative Programming
69 | * [Using a shared server](collaborative-coding/shared-server.md)
70 |
71 |
72 | ## Reference
73 | * [Reference](reference/index.md)
74 | * [Math for Clojure developers](reference/math/math-for-clojure-developers.md)
75 |
76 |
77 | * [Data Files](reference/data-files.md)
78 |
79 |
80 |
81 |
--------------------------------------------------------------------------------
/docs/data-mining/webscraping/index.md:
--------------------------------------------------------------------------------
1 | # Web Scraping unstructured data
2 |
3 |
4 | ## Complexity of JavaScript websites
5 |
6 | * Sparkledriver
7 |
8 |
9 |
10 | ## Tools
11 | * [Enlive](https://github.com/cgrand/enlive)
12 | * [Scoopi](https://github.com/maithilish/scoopi-scraper) - a tool to extract and transform data from web pages
13 | * [demeter](https://github.com/gtebbutt/demeter) - fast, concurrent web scraper with headless JavaScript execution
14 | * [web-scraper](https://github.com/ka2u/web-scraper) - library with fairly good JavaScript support
15 | * [Web Page Summarizer](https://github.com/DFW-Clojure/web-page-summarizer) - gui for getting web pages and summarizing them. Demonstrates enlive and compojure
16 | * [Scraper](https://github.com/cmiles74/scraper) - JavaFX web engine and WebKit
17 | * [Abrade](https://github.com/weavejester/abrade) - scraping web sites, even ones that heavily rely on Javascript. The Java HtmlUnit library is used under the hood
18 | * [Etaoin](https://github.com/igrishaev/etaoin) - Clojure implementation of webdriver protocol
19 |
20 |
21 | ## Example projects
22 | * [parkrun-app](https://github.com/ldnclj/parkrun-app) - enlive
23 | * [clj-scraper](https://github.com/0rca/clj-scraper) - enlive, http-kit, core.async
24 | * [ldnpyvideo](https://github.com/necaris/ldnpyvideo) - Scraper (from pyvideo.org) and web site for London PyCon video meetup
25 | * [nba-scraper](https://github.com/yoyostevo/nba-scraper) - scraping NBA boxscore data from ESPN
26 | * [Clojure web scraping with Enlive](https://ericsomdahl.github.io/posts/2015-03-07-gevents1.html)
27 |
28 |
29 | ## References
30 | * [Practicalli: Web Scraping with Clojure - Hacker news](http://practical.li/blog/posts/web-scraping-with-clojure-hacking-hacker-news/)
31 | * [Clojure Data Analysis Cookbook: Scraping data from tables in web pages](https://subscription.packtpub.com/book/application_development/9781784390297/1/ch01lvl1sec15/scraping-data-from-tables-in-web-pages)
32 | * [ClojureVerse: First time webscraper, could you give any pointers?](https://clojureverse.org/t/first-time-webscraper-could-you-give-any-pointers/7663/6)
33 | * [Web Scraping with Clojure](http://masnun.com/2016/03/20/web-scraping-with-clojure.html) - http-kit and Enlive
34 | * [How to Scrape Modern Websites Without Headless Browsers - Python](https://betterprogramming.pub/how-to-scrape-modern-websites-without-headless-browsers-d871bbd1119e)
35 |
36 |
37 | > #### Hint::Be Respectful of data sources
38 | > Avoid high number of requests to websites with unstructured data, they are unlikely to have much capacity to serve requests. Consider downloading the content locally to minimise the requests to the website.
39 |
--------------------------------------------------------------------------------
/docs/introduction/persona.md:
--------------------------------------------------------------------------------
1 | # Persona
2 |
3 | Persona help identify commonality of experience and approaches for people in the realm of data science and software engineering.
4 |
5 |
6 | ## Jane - mid-level Clojure developer
7 |
8 | Jane is a Clojure developer with a couple of years commercial experience
9 | Jane has no data science experience
10 | She has a project to create a dashboard to visualise covid19 data for her company
11 | And has to find useful tools and data sources to build the dashboard
12 |
13 | An expanded version of the Jane Clojure developer persona:
14 |
15 | Jane is a Clojure developer with a couple of years commercial experience and a year prior to that as a hobby
16 | Jane has no data science experience but has seen TED talks and tutorials on visualising data
17 | Jane has a project to create a dashboard to visualise covid19 data for her company
18 | And has to find useful tools and data sources to build the dashboard
19 | Jane visits the Government website for the country she resides in and finds various data sets in JSON and CSV formats
20 | Jane choose to use Clojure CLI tools for the Clojure project to make use of the community tooling that helps visualise data as she is transforming it (Portal, Reveal)
21 | Jane uses Spacemacs (Emacs / Cider) as its is a tool she is familiar with and Cider has simple to use debug and data inspector tools. Jane started with LightTable but that project is no longer active. She has also tried VS Code and Calva, but Cider is more stable and mature, has more features and better structural editing support.
22 | The data wrangling libraries Jane is considering are clojure.data.json and clojure.data.csv as they are already included in Clojure
23 | Jane has heard of other libraries for manipulating data, but doesnt know if they are relevant or easy to use
24 | Jane will try using Oz for visualisations as she likes the idea of Vega & Vega lite as a data language, because it reminds her of the approach taken with Clojure itself.
25 |
26 |
27 | ## Jada - experienced data scientist
28 | Jada
29 | - statisticians
30 | - machine learning
31 | - visualisation
32 | - computer vision
33 | - ML Ops
34 | - Probabilistic ???
35 |
36 |
37 |
38 | Jamie is a analyst using data science for the last year as a company doing X
39 | and has completed X data science course
40 | and works with several more experienced data scientist who are using some python and R to build data models.
41 |
42 |
43 | Jenny is new to coding and has an interest in data science and machine learning and has no real experience in any of these.
44 | doesnt know what she doesnt know
45 | doesnt know where to start looking
46 |
47 |
48 | Jennifer has several years experience of R and Python (and occasionally wrangled a few C++ libraries)
49 | Jennifer is curious about Clojure because ???
50 | - listened to a talk on Simple made Easy and wishes that R and Python would make some of the work simpler
51 | -
52 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | # ------------------------------------------
2 | # Practicalli: Makefile
3 | #
4 | # Consistent set of targets to support local book development
5 | # ------------------------------------------
6 |
7 | # .PHONY: ensures target used rather than matching file name
8 | # https://makefiletutorial.com/#phony
9 | .PHONY: all clean docs lint pre-commit-check test
10 |
11 | # ------- Makefile Variables --------- #
12 | # run help if no target specified
13 | .DEFAULT_GOAL := help
14 |
15 | # Column the target description is printed from
16 | HELP-DESCRIPTION-SPACING := 24
17 |
18 | # Tool Commands
19 | MEGALINTER_RUNNER := npx mega-linter-runner --flavor documentation --env "'MEGALINTER_CONFIG=.github/config/megalinter.yaml'" --env "'VALIDATE_ALL_CODEBASE=true'" --remove-container
20 | MKDOCS_SERVER := mkdocs serve --dev-addr localhost:7777
21 |
22 | # Makefile file and directory name wildcard
23 | EDN-FILES := $(wildcard *.edn)
24 | # ------------------------------------ #
25 |
26 | # ------ Quality Checks ------------ #
27 | pre-commit-check: lint
28 |
29 | lint: ## Run MegaLinter with custom configuration (node.js required)
30 | $(info --------- MegaLinter Runner ---------)
31 | $(MEGALINTER_RUNNER)
32 |
33 | lint-fix: ## Run MegaLinter with custom configuration (node.js required)
34 | $(info --------- MegaLinter Runner ---------)
35 | $(MEGALINTER_RUNNER) --fix
36 |
37 | lint-clean: ## Clean MegaLinter report information
38 | $(info --------- MegaLinter Clean Reports ---------)
39 | - rm -rf ./megalinter-reports
40 |
41 | megalinter-upgrade: ## Upgrade MegaLinter config to latest version
42 | $(info --------- MegaLinter Upgrade Config ---------)
43 | npx mega-linter-runner@latest --upgrade
44 | # ------------------------------------ #
45 |
46 | # --- Documentation Generation ------ #
47 | python-venv: ## Enable Python Virtual Environment for MkDocs
48 | $(info --------- Mkdocs Local Server ---------)
49 | source ~/.local/venv/bin/activate
50 |
51 | docs: ## Build and run mkdocs in local server (python venv)
52 | $(info --------- Mkdocs Local Server ---------)
53 | source ~/.local/venv/bin/activate && $(MKDOCS_SERVER)
54 |
55 | docs-changed: ## Build only changed files and run mkdocs in local server (python venv)
56 | $(info --------- Mkdocs Local Server ---------)
57 | source ~/.local/venv/bin/activate && $(MKDOCS_SERVER) --dirtyreload
58 |
59 | docs-build: ## Build mkdocs (python venv)
60 | $(info --------- Mkdocs Local Server ---------)
61 | source ~/.local/venv/bin/activate && mkdocs build
62 | # ------------------------------------ #
63 |
64 | # ------------ Help ------------------ #
65 | # Source: https://nedbatchelder.com/blog/201804/makefile_help_target.html
66 |
67 | help: ## Describe available tasks in Makefile
68 | @grep '^[a-zA-Z]' $(MAKEFILE_LIST) | \
69 | sort | \
70 | awk -F ':.*?## ' 'NF==2 {printf "\033[36m %-$(HELP-DESCRIPTION-SPACING)s\033[0m %s\n", $$1, $$2}'
71 | # ------------------------------------ #
72 |
--------------------------------------------------------------------------------
/overrides/partials/header.html:
--------------------------------------------------------------------------------
1 |
2 | {% set class = "md-header" %} {% if "navigation.tabs.sticky" in features %} {%
3 | set class = class ~ " md-header--shadow md-header--lifted" %} {% elif
4 | "navigation.tabs" not in features %} {% set class = class ~ " md-header--shadow"
5 | %} {% endif %}
6 |
7 |
8 |
9 |
74 |
75 |
76 | {% if "navigation.tabs.sticky" in features %} {% if "navigation.tabs" in
77 | features %} {% include "partials/tabs.html" %} {% endif %} {% endif %}
78 |
79 |
--------------------------------------------------------------------------------
/.github/config/megalinter.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | # Configuration file for MegaLinter
3 | #
4 | # General configuration:
5 | # https://megalinter.io/latest/configuration/
6 | #
7 | # Specific Linters:
8 | # https://megalinter.io/latest/supported-linters/
9 |
10 | # ------------------------
11 | # Validate all files if true
12 | # or new / edited files if false
13 | VALIDATE_ALL_CODEBASE: false
14 |
15 | # ------------------------
16 | # Linters
17 |
18 | # Run linters in parallel
19 | PARALLEL: true
20 |
21 | # ENABLE specific linters, all other linters automatically disabled
22 | ENABLE:
23 | # - CLOJURE
24 | - CREDENTIALS
25 | - DOCKERFILE
26 | - MAKEFILE
27 | - MARKDOWN
28 | - GIT
29 | - SPELL
30 | - YAML
31 | - REPOSITORY
32 |
33 | # Linter specific configuration
34 |
35 | # CLOJURE_CLJ_KONDO_CONFIG_FILE: ".github/config/clj-kondo-ci-config.edn"
36 | # CLOJURE_CLJ_KONDO_ARGUMENTS: "--lint deps.edn"
37 | # CLOJURE_CLJ_KONDO_FILTER_REGEX_EXCLUDE: "dev|develop"
38 | # CLOJURE_CLJ_KONDO_FILTER_REGEX_EXCLUDE: "resources"
39 |
40 | # CREDENTIALS_SECRETLINT_DISABLE_ERRORS: true
41 | CREDENTIALS_SECRETLINT_CONFIG_FILE: ".github/config/secretlintrc.json"
42 |
43 | MARKDOWN_MARKDOWNLINT_CONFIG_FILE: ".github/config/markdown-lint.jsonc"
44 | MARKDOWN_MARKDOWNLINT_FILTER_REGEX_EXCLUDE: ".github/pull_request_template.md|CHANGELOG.md|README.md|GLOSSARY.md|java-17-flags.md|abbreviations.md"
45 | # MARKDOWN_MARKDOWNLINT_DISABLE_ERRORS: true
46 | MARKDOWN_MARKDOWN_LINK_CHECK_CONFIG_FILE: ".github/config/markdown-link-check.json"
47 | # MARKDOWN_MARKDOWN_LINK_CHECK_CLI_LINT_MODE: "project"
48 | # MARKDOWN_MARKDOWN_LINK_CHECK_DISABLE_ERRORS: false
49 | MARKDOWN_REMARK_LINT_DISABLE_ERRORS: true
50 | # MARKDOWN_MARKDOWN_TABLE_FORMATTER_DISABLE_ERRORS: false
51 |
52 | REPOSITORY_GITLEAKS_CONFIG_FILE: ".github/config/gitleaks.toml"
53 | REPOSITORY_TRUFFLEHOG_DISABLE_ERRORS: true # Errors only as warnings
54 |
55 | # SPELL_CSPELL_DISABLE_ERRORS: true
56 | SPELL_MISSPELL_DISABLE_ERRORS: true
57 | SPELL_LYCHEE_CONFIG_FILE: ".github/config/lychee.toml"
58 | SPELL_LYCHEE_DISABLE_ERRORS: true # Errors are only warnings
59 |
60 | # YAML_PRETTIER_FILTER_REGEX_EXCLUDE: (docs/)
61 | # YAML_YAMLLINT_FILTER_REGEX_EXCLUDE: (docs/)
62 |
63 | # Explicitly disable linters to ensure they are never run
64 | # DISABLE:
65 | # - COPYPASTE # checks for excessive copy-pastes
66 | # - SPELL # spell checking - often creates many false positives
67 | # - CSS #
68 |
69 | # Disable linter features
70 | DISABLE_LINTERS:
71 | - YAML_PRETTIER # draconian format rules
72 | - SPELL_CSPELL # many clojure references causing false positives
73 | - YAML_YAMLLINT # vague error mesages, investigation required
74 | - REPOSITORY_GIT_DIFF # warnings about LF to CRLF
75 | - REPOSITORY_SECRETLINT # reporting errors in its own config file
76 | # - REPOSITORY_DEVSKIM # unnecessary URL TLS checks
77 | - REPOSITORY_CHECKOV # fails on root user in Dockerfile
78 | - REPOSITORY_SECRETLINT
79 |
80 | # Ignore all errors and return without error status
81 | # DISABLE_ERRORS: true
82 |
83 | # ------------------------
84 |
85 | # ------------------------
86 | # Reporting
87 |
88 | # Activate sources reporter
89 | UPDATED_SOURCES_REPORTER: false
90 |
91 | # Show Linter timings in summary table at end of run
92 | SHOW_ELAPSED_TIME: true
93 |
94 | # Upload reports to file.io
95 | FILEIO_REPORTER: false
96 | # ------------------------
97 |
98 | # ------------------------
99 | # Over-ride errors
100 |
101 | # detect errors but do not block CI passing
102 | # DISABLE_ERRORS: true
103 | # ------------------------
104 |
--------------------------------------------------------------------------------
/docs/assets/stylesheets/extra.css:
--------------------------------------------------------------------------------
1 | [data-md-color-scheme="default"] {
2 | --md-default-bg-color: hsla(208, 100%, 96%, 0.94);
3 | --md-code-bg-color: hsla(208, 80%, 88%, 0.64);
4 | --md-code-hl-color: hsla(208, 88%, 80%, 0.92);
5 | --md-admonition-bg-color: hsla(208, 80%, 92%, 0.92);
6 | --md-typeset-kbd-color: hsla(208, 100%, 98%, 0.98);
7 | }
8 |
9 | /* Custom Admonitions */
10 |
11 |
12 | :root {
13 | /* Clojure Idiom*/
14 | --md-admonition-icon--clojure-idiom: url(https://raw.githubusercontent.com/practicalli/graphic-design/c40cc063cc5bb07525b524d8a3d638e2f42bc38a/logos/clojure-logo-bullet.svg);
15 |
16 | /* Round corners */
17 | --base-border-radius: 0.5rem;
18 | }
19 |
20 | /*Admonitions colors*/
21 | .md-typeset .admonition.clojure-idiom,
22 | .md-typeset details.clojure-idiom {
23 | border-color: rgb(43, 155, 70);
24 | }
25 | .md-typeset .clojure-idiom > .admonition-title,
26 | .md-typeset .clojure-idiom > summary {
27 | background-color: rgba(43, 155, 70, 0.1);
28 | }
29 | .md-typeset .clojure-idiom > .admonition-title::before,
30 | .md-typeset .clojure-idiom > summary::before {
31 | background-color: rgb(250, 250, 250);
32 | background-image: var(--md-admonition-icon--clojure-idiom);
33 | -webkit-mask-image: var(--md-admonition-icon--clojure-idiom);
34 | mask-image: var(--md-admonition-icon--clojure-idiom);
35 | }
36 |
37 |
38 | /* Change font family of filename present on top of code block. */
39 | .highlight span.filename {
40 | border-bottom: none;
41 | border-radius: var(--base-border-radius);
42 | display: inline;
43 | font-family: var(--md-code-font-family);
44 | border-bottom-left-radius: 0;
45 | border-bottom-right-radius: 0;
46 | margin-bottom: 5px;
47 | text-align: center;
48 | }
49 | .highlight span.filename + pre > code {
50 | border-radius: var(--base-border-radius);
51 | border-top-left-radius: 0;
52 | }
53 | .md-typeset pre > code {
54 | border-radius: var(--base-border-radius);
55 | }
56 |
57 | /* Grid Cards */
58 | .md-typeset .grid.cards > ul > li {
59 | border-radius: var(--base-border-radius);
60 | }
61 | .md-typeset .grid.cards > ul > li:hover {
62 | box-shadow: 0 0 0.2rem #ffffff40;
63 | }
64 |
65 | /* Markdown Button */
66 | .md-typeset .md-button {
67 | border-radius: var(--base-border-radius);
68 | }
69 |
70 | /* Critic, Mark */
71 | ins.critic,
72 | del.critic {
73 | text-decoration: none;
74 | }
75 |
76 | .md-typeset .critic,
77 | .md-typeset mark {
78 | border-radius: 0.2rem;
79 | padding: 0 0.2rem;
80 | }
81 |
82 | .md-typeset mark {
83 | box-shadow: 0 0 0 0.1rem var(--md-typeset-mark-color);
84 | }
85 |
86 | .md-typeset ins.critic {
87 | box-shadow: 0 0 0 0.1rem var(--md-typeset-ins-color);
88 | }
89 |
90 | .md-typeset del.critic {
91 | box-shadow: 0 0 0 0.1rem var(--md-typeset-del-color);
92 | }
93 |
94 | /* Forms */
95 | .md-search__form {
96 | border-radius: var(--base-border-radius);
97 | }
98 |
99 | [data-md-toggle="search"]:checked ~ .md-header .md-search__form {
100 | border-top-right-radius: var(--base-border-radius);
101 | border-top-left-radius: var(--base-border-radius);
102 | }
103 |
104 | [dir="ltr"] .md-search__output {
105 | border-bottom-right-radius: var(--base-border-radius);
106 | border-bottom-left-radius: var(--base-border-radius);
107 | }
108 |
109 | /* Blog - index.md */
110 | .md-post--excerpt {
111 | background-color: var(--md-accent-fg-color--transparent);
112 | box-shadow: 0 0 0 1rem var(--md-accent-fg-color--transparent);
113 | border-radius: var(--base-border-radius);
114 | }
115 |
116 | /* Table */
117 | .md-typeset table:not([class]) {
118 | border-radius: var(--base-border-radius);
119 | }
120 |
--------------------------------------------------------------------------------
/docs/notebooks/notespace/configure-notespace-project.md:
--------------------------------------------------------------------------------
1 | ## Run Notespace on REPL startup
2 | [Example Notespace project](https://github.com/practicalli/scicloj-notespace-simple-demo) is a project with simple examples and also launches an empty notespace webpage on REPL startup.
3 |
4 | {% tabs deps="Clojure CLI tools", lein="Leiningnen" %}
5 |
6 | {% content "deps" %}
7 | Use a deps.edn file that includes the `scicloj/notespace` library
8 |
9 |
10 | ## Creating a new project
11 | Use Clojure CLI tools ([:project/new](http://practicalli.github.io/clojure/clojure-tools/projects/create.html)) to create a project.
12 |
13 | ```
14 | clojure -X:project/new :template app :name practicalli/notespace-demo
15 | ```
16 |
17 | Edit the `deps.edn` file
18 |
19 | Add `scicloj/notespace` library as dependency
20 |
21 | Use [practicalli/clojure-deps-edn](http://practicalli.github.io/clojure/clojure-tools/install/community-tools.html) user configuration or add an `:env/dev` and `:inspect/portal-clj` aliases to the project `deps.edn` file
22 |
23 | ```
24 | {:paths ["src" "resources"]
25 | :deps
26 | {org.clojure/clojure {:mvn/version "1.10.1"}
27 | scicloj/notespace {:mvn/version "3-alpha3-SNAPSHOT"}}
28 | :aliases
29 | {:env/dev {:extra-paths ["dev"]}
30 | :inspect/portal-cli {:extra-deps {djblue/portal {:mvn/version "0.6.4"}}}}}
31 | ```
32 |
33 |
34 | {% content "lein" %}
35 | ## Creating a new project
36 | Use Leinigen to create a new project
37 |
38 | ```
39 | lein new app practicalli/notespace-demo
40 | ```
41 |
42 | Edit the project.clj file
43 |
44 | Add notespace as a dependency to the project configuration
45 |
46 | add a `:dev` profile with `:resource-paths` which adds the `dev` directory to class path. Leiningen uses the `:dev` profile unless another profile is specified.
47 |
48 | ```
49 | (defproject practicalli/notespace-demo "0.1.0-SNAPSHOT"
50 | :description "Notespace journal - simple demo"
51 | :url "https://practicalli.github.io/data-science/notebooks/notespace/"
52 | :license {:name "Creative Commons Attribution Share-Alike 4.0 International"
53 | :url "https://creativecommons.org"}
54 | :dependencies [[org.clojure/clojure "1.10.1"]
55 | [scicloj/notespace "3-alpha3"]]
56 | :main ^:skip-aot practicalli.notespace-demo
57 | :target-path "target/%s"
58 | :profiles {:dev {:resource-paths ["dev"]
59 | :dependencies [[djblue/portal "0.6.4"]]}
60 | :uberjar {:aot :all}})
61 | ```
62 |
63 | {% endtabs %}
64 |
65 |
66 | ## Add namespace to start notespace with REPL
67 | Create a `dev/user.clj` source code file
68 |
69 | Add a `user` namespace definition that requires notespace and portal
70 |
71 | Add a call to start notespace
72 |
73 | Add a call to start Portal and connect it to the REPL as a tap> source
74 |
75 | Add notespace and portal helper functions
76 |
77 | ```
78 | (ns user
79 | (:require [notespace.api :as notespace]
80 | [portal.api :as inspect]))
81 |
82 | ;; Start Notespace
83 | (notespace/init-with-browser)
84 |
85 | ;; Start Portal
86 | ;; Open a portal inspector window using default nord theme
87 | (inspect/open {:portal.colors/theme :portal.colors/solarized-light})
88 |
89 | ;; Add portal as a tap> target
90 | (inspect/tap)
91 |
92 |
93 | (comment
94 |
95 | ;; Notespace helpers
96 | ;;;;;;;;;;;;;;;;;;;;;;
97 |
98 | ;; Initialise notespace, headless or open browser
99 | (notespace/init)
100 | (notespace/init-with-browser)
101 |
102 |
103 | ;; Portal helpers
104 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
105 |
106 | ;; Open Portal window with nord theme (default)
107 | (inspect/open)
108 |
109 | ;; Open Portal window with solarized-dark theme
110 | (inspect/open {:portal.colors/theme :portal.colors/solarized-dark})
111 |
112 | ;; Open Portal window with solarized-light theme
113 | (inspect/open {:portal.colors/theme :portal.colors/solarized-light})
114 |
115 | ;; Clear all values in the portal inspector window
116 | (inspect/clear)
117 |
118 | ;; Close the portal window
119 | (inspect/close)
120 |
121 | ) ;; End of rich comment block
122 |
123 | ```
124 |
125 |
126 |
127 |
128 |
129 | ## Run a REPL for the project
130 |
131 | {% tabs depsstart="Clojure CLI tools", leinstart="Leiningnen" %}
132 |
133 | {% content "depsstart" %}
134 | Open a terminal and run a REPL using the `:env/dev` and `:inspect/portal-cli` aliases
135 |
136 | ```
137 | clojure -M:env/dev:inspect/portal-cli
138 | ```
139 |
140 |
141 | {% content "leinstart" %}
142 | Open a terminal and start a REPL with Leinigen, using the `:dev` profile by default
143 |
144 | ```
145 | lein repl
146 |
147 | ```
148 |
149 |
150 | {% endtabs %}
151 |
--------------------------------------------------------------------------------
/docs/assets/favicon.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/docs/assets/stylesheets/practicalli-light.css:
--------------------------------------------------------------------------------
1 | // ----------------------------------------------------------------------------
2 | // Rules
3 | // ----------------------------------------------------------------------------
4 |
5 | // Color variables
6 | :root {
7 | @extend %root;
8 |
9 | // Primary color shades
10 | --md-primary-fg-color: hsla(#{hex2hsl($clr-indigo-500)}, 1);
11 | --md-primary-fg-color--light: hsla(#{hex2hsl($clr-indigo-400)}, 1);
12 | --md-primary-fg-color--dark: hsla(#{hex2hsl($clr-indigo-700)}, 1);
13 | --md-primary-bg-color: hsla(0, 0%, 100%, 1);
14 | --md-primary-bg-color--light: hsla(0, 0%, 100%, 0.7);
15 |
16 | // Accent color shades
17 | --md-accent-fg-color: hsla(#{hex2hsl($clr-indigo-a200)}, 1);
18 | --md-accent-fg-color--transparent: hsla(#{hex2hsl($clr-indigo-a200)}, 0.1);
19 | --md-accent-bg-color: hsla(0, 0%, 100%, 1);
20 | --md-accent-bg-color--light: hsla(0, 0%, 100%, 0.7);
21 | }
22 |
23 | // ----------------------------------------------------------------------------
24 |
25 | // Allow to explicitly use color schemes in nested content
26 | [data-md-color-scheme="practicalli"] {
27 | @extend %root;
28 | }
29 |
30 | // ----------------------------------------------------------------------------
31 | // Placeholders
32 | // ----------------------------------------------------------------------------
33 |
34 | // Default theme, i.e. light mode
35 | %root {
36 |
37 | // Default color shades
38 | --md-default-fg-color: hsla(0, 0%, 0%, 0.87);
39 | --md-default-fg-color--light: hsla(0, 0%, 0%, 0.54);
40 | --md-default-fg-color--lighter: hsla(0, 0%, 0%, 0.32);
41 | --md-default-fg-color--lightest: hsla(0, 0%, 0%, 0.07);
42 | --md-default-bg-color: hsla(53, 90%, 90%, 1);
43 | --md-default-bg-color--light: hsla(53, 90%, 90%, 0.7);
44 | --md-default-bg-color--lighter: hsla(53, 90%, 90%, 0.3);
45 | --md-default-bg-color--lightest: hsla(53, 90%, 90%, 0.12);
46 |
47 | // Code color shades
48 | --md-code-fg-color: hsla(200, 18%, 26%, 1);
49 | --md-code-bg-color: hsla(0, 0%, 96%, 1);
50 |
51 | // Code highlighting color shades
52 | --md-code-hl-color: hsla(#{hex2hsl($clr-yellow-a200)}, 0.5);
53 | --md-code-hl-number-color: hsla(0, 67%, 50%, 1);
54 | --md-code-hl-special-color: hsla(340, 83%, 47%, 1);
55 | --md-code-hl-function-color: hsla(291, 45%, 50%, 1);
56 | --md-code-hl-constant-color: hsla(250, 63%, 60%, 1);
57 | --md-code-hl-keyword-color: hsla(219, 54%, 51%, 1);
58 | --md-code-hl-string-color: hsla(150, 63%, 30%, 1);
59 | --md-code-hl-name-color: var(--md-code-fg-color);
60 | --md-code-hl-operator-color: var(--md-default-fg-color--light);
61 | --md-code-hl-punctuation-color: var(--md-default-fg-color--light);
62 | --md-code-hl-comment-color: var(--md-default-fg-color--light);
63 | --md-code-hl-generic-color: var(--md-default-fg-color--light);
64 | --md-code-hl-variable-color: var(--md-default-fg-color--light);
65 |
66 | // Typeset color shades
67 | --md-typeset-color: var(--md-default-fg-color);
68 |
69 | // Typeset `a` color shades
70 | --md-typeset-a-color: var(--md-primary-fg-color);
71 |
72 | // Typeset `mark` color shades
73 | --md-typeset-mark-color: hsla(#{hex2hsl($clr-yellow-a200)}, 0.5);
74 |
75 | // Typeset `del` and `ins` color shades
76 | --md-typeset-del-color: hsla(6, 90%, 60%, 0.15);
77 | --md-typeset-ins-color: hsla(150, 90%, 44%, 0.15);
78 |
79 | // Typeset `kbd` color shades
80 | --md-typeset-kbd-color: hsla(0, 0%, 98%, 1);
81 | --md-typeset-kbd-accent-color: hsla(0, 100%, 100%, 1);
82 | --md-typeset-kbd-border-color: hsla(0, 0%, 72%, 1);
83 |
84 | // Typeset `table` color shades
85 | --md-typeset-table-color: hsla(0, 0%, 0%, 0.12);
86 |
87 | // Admonition color shades
88 | --md-admonition-fg-color: var(--md-default-fg-color);
89 | --md-admonition-bg-color: var(--md-default-bg-color);
90 |
91 | // Footer color shades
92 | --md-footer-fg-color: hsla(0, 0%, 100%, 1);
93 | --md-footer-fg-color--light: hsla(0, 0%, 100%, 0.7);
94 | --md-footer-fg-color--lighter: hsla(0, 0%, 100%, 0.3);
95 | --md-footer-bg-color: hsla(0, 0%, 0%, 0.87);
96 | --md-footer-bg-color--dark: hsla(0, 0%, 0%, 0.32);
97 |
98 | // Shadow depth 1
99 | --md-shadow-z1:
100 | 0 #{px2rem(4px)} #{px2rem(10px)} hsla(0, 0%, 0%, 0.05),
101 | 0 0 #{px2rem(1px)} hsla(0, 0%, 0%, 0.1);
102 |
103 | // Shadow depth 2
104 | --md-shadow-z2:
105 | 0 #{px2rem(4px)} #{px2rem(10px)} hsla(0, 0%, 0%, 0.1),
106 | 0 0 #{px2rem(1px)} hsla(0, 0%, 0%, 0.25);
107 |
108 | // Shadow depth 3
109 | --md-shadow-z3:
110 | 0 #{px2rem(4px)} #{px2rem(10px)} hsla(0, 0%, 0%, 0.2),
111 | 0 0 #{px2rem(1px)} hsla(0, 0%, 0%, 0.35);
112 | }
113 |
--------------------------------------------------------------------------------
/docs/introduction/contributing.md:
--------------------------------------------------------------------------------
1 | # Contributing to Practicalli
2 |
3 | Practicalli books are written in markdown and use MkDocs to generate the published website via a GitHub workflow. MkDocs can also run a local server using the `make docs` target from the `Makefile`
4 |
5 | By submitting content ideas and corrections you are agreeing they can be used in this book under the [Creative Commons Attribution ShareAlike 4.0 International license](https://creativecommons.org/licenses/by-sa/4.0/){target=_blank}. Attribution will be detailed via [GitHub contributors](https://github.com/practicalli/clojure-data-science/graphs/contributors){target=_blank}.
6 |
7 | All content and interaction with any persons or systems must be done so with respect and within the Practicalli Code of Conduct.
8 |
9 | ## Book status
10 |
11 | [](https://github.com/practicalli/clojure-data-science/actions/workflows/megalinter.yaml)[](https://github.com/practicalli/clojure-data-science/actions/workflows/publish-book.yaml){target=_blank}
12 | [](https://github.com/practicalli/clojure-data-science/actions/workflows/pages/pages-build-deployment){target=_blank}
13 |
14 | [](https://github.com/practicalli/clojure-practicalli-content/issues){target=_blank}
15 | [](https://github.com/practicalli/clojure-practicalli-content/pulls){target=_blank}
16 |
17 | 
18 | 
19 |
20 | ## Submit and issue or idea
21 |
22 | If something doesnt seem quite right or something is missing from the book, please [raise an issue via the GitHub repository](https://github.com/practicalli/clojure-data-science/issues){target=_blank} explaining in as much detail as you can.
23 |
24 | Raising an issue before creating a pull request will save you and the maintainer time.
25 |
26 | ## Considering a Pull request?
27 |
28 | !!! INFO "Pull Request Commits must be cryptographically signed"
29 | All commits contributed to Practicalli must be signed via a legitimate SSH or GPG key to avoid the risk of commit spoofing.
30 |
31 | [Configure commit signing with SSH key - Practicalli Engineering](https://practical.li/engineering-playbook/source-control/git-configuration/#commit-signing-with-ssh-key){target=_blank .md-button}
32 |
33 | All pull requests must include an entry in CHANGELOG.md or will not be merged. A changelog entry allows the community to follow the changes to the book.
34 |
35 | Each pull request will have a number of CI workflows run against the contribution, checking the format of the content and if a changelog entry has been provided.
36 |
37 | Please keep pull requests small and focused, as they are much quicker to review and easier to accept. Ideally PR's should be for a specific page or at most a section.
38 |
39 | A PR with a list of changes across different sections will be closed without merging as these take considerable time to review.
40 |
41 | Issues such as grammar improvements are typically a sign of a rushed section that requires a rewrite, so a pull request to fix a typeographic error will probably not be merged. Raise an issue, or post a thread in the [:globe_with_meridians: Clojurians Slack #practicall channel](https://clojurians.slack.com/messages/practicalli)
42 |
43 | ## Thank you to everyone that has contributed
44 |
45 | * [SciCloj community](https://scicloj.github.io/){target=_blank .md-button} and Daniel Slutsky
46 | * Dave Leepmann and [Applied](http://www.appliedscience.studio/articles/covid19.html{target=_blank .md-button})
47 | * Clojure Data Science community on Zulip
48 |
49 | A huge thank you to Rich Hickey and the team at Cognitect for creating and continually guiding the Clojure language. Special thank you to Alex Miller who has provided excellent advice on working with Clojure and the CLI tooling.
50 |
51 | The Clojure community has been highly supportive of everyone using Clojure and I'd like to thank everyone for the feedback and contributions. I would also like to thank everyone that has joined in with the [London Clojurins community](https://www.meetup.com/London-Clojurians/){target=_blank}, [ClojureBridgeLondon](https://clojurebridgelondon.github.io/){target=_blank}, [Clojurians Slack community](http://clojurians.net/){target=_blank}, [Clojurians Zulip](https://clojurians.zulipchat.com/){target=_blank} community and [Clojureverse community](https://clojureverse.org/){target=_blank}.
52 |
53 | Thank you to everyone who sponsors the Practicalli websites and videos and for the [Clojurists Together sponsorship](https://www.clojuriststogether.org/){target=_blank}, it helps me continue the work at a much faster pace.
54 |
55 | Special thanks to [Bruce Durling](https://twitter.com/otfrom){target=_blank} for getting me into Cloure in the first place.
56 |
57 | 
58 |
--------------------------------------------------------------------------------
/docs/index.md:
--------------------------------------------------------------------------------
1 | # Practicalli Clojure Data Science
2 |
3 | 
4 |
5 | !!! WARNING "Alpha stage book"
6 | Currently the book is a collection of various external references with a small amount of commercial experience captured.
7 |
8 |
9 | A guide to writing Clojure services and using tools to support a range of data science activities.
10 |
11 | Topics will include data mining, data transformation and visualisation tools, techniques and libraries. Guides will take a story telling approach using visualisation tools to ensure a meaningful context in which design decisions are taken.
12 |
13 | Data Science is a vast subject area so this guide will recommend numerous resources that go deeper into specific areas.
14 |
15 | !!! QUOTE "John Stevenson, Practicalli"
16 | Without good data, there is no science
17 |
18 |
19 | ## Data Engineering
20 |
21 | Data Science relies on effecive data engineering workflow
22 |
23 | {loading=lazy}
24 |
25 |
26 | !!! HINT "Dont skimp on the data"
27 | Effecive models require a good history of data to work with and evolve the capabilities of a model.
28 |
29 | If there is data to collect, then it should be collected by default and only dropped if proved to be of no value over (a long period of) time.
30 |
31 | Not capturing data from the ealiest possible time can greatly limit or at least delay the creation of more effective models.
32 |
33 |
34 |
35 | > This guide does not claim to make any attempt to teach you how to be a professional data scientist.
36 |
37 |
38 | [:fontawesome-solid-book-open: Data Mining](data-mining/){.md-button}
39 |
40 | [:fontawesome-solid-book-open: Data Transformation](data-transformation/){.md-button}
41 |
42 | [:fontawesome-solid-book-open: Story telling with data](visualisation/){.md-button}
43 |
44 |
45 | ## Practicalli projects
46 |
47 | [:fontawesome-brands-github: Simple Covid19 dashboard](https://github.com/practicalli/covid19-dashboard) - import data from CSV, simple data wrangling and creating a website dashboard using Oz for a vega-lite based visualisation and CSS for highlighting specific data points
48 |
49 | 
50 |
51 | [:fontawesome-brands-github: Oz Visualisation examples](https://github.com/practicalli/oz-visualisations) - learn some of the capabilities of Oz and demonstrate how to create a range of visualisations
52 |
53 | 
54 |
55 | - Ascii visualisation
56 |
57 | - Visualising survey data
58 |
59 |
60 | ## SciCloj community
61 |
62 | A community of people using Clojure and other tools to create amazing things in the realm of science
63 |
64 | - [Homepage](https://scicloj.github.io/){target=_blank}
65 | - [:fontawesome-brands-youtube: SciCloj YouTube channel](https://www.youtube.com/channel/UCaoZzhNzq-H7YiQczXKuXuw/){target=_blank}
66 | - [GitHub repository](https://github.com/scicloj/){target=_blank}
67 | - [SciCloj discussions](https://scicloj.github.io/pages/chat_streams/){target=_blank} on [Zulip Clojurians](http://clojurians.zulipchat.com/){target=_blank}
68 |
69 |
70 | ## Resources
71 |
72 | - [Interactive Programming for Artificial Intelligence](https://aiprobook.com/){target=_blank} - learn artificial intelligence programming skills
73 | - [dragan.rocks - articles on data science with Clojure](https://dragan.rocks/){target=_blank}
74 | - [clojuredatascience.com](http://clojuredatascience.com/){target=_blank} - Henry Garner
75 | - [:fontawesome-brands-youtube: Kaggle CareerCon 2019](https://www.youtube.com/playlist?list=PLqFaTIg4myu-npFrYu6cO7h7AI6bkcOlL)
76 |
77 | ## Navigate the book
78 |
79 | Use the mouse or built-in key bindings to navigate the pages of the book
80 |
81 | - ++p++ , ++comma++ : go to previous page
82 | - ++n++ , ++period++ : go to next page
83 |
84 | Use the search box to quickly find a specific topic
85 |
86 | - ++f++ , ++s++ , ++slash++ : open search dialog
87 | - ++arrow-down++ , ++arrow-up++ : select next / previous result
88 | - ++esc++ , ++tab++ : close search dialog
89 | - ++enter++ : follow selected result
90 |
91 |
92 | ## Sponsor Practicalli
93 |
94 | [{ align=left loading=lazy }](https://github.com/sponsors/practicalli-johnny/)
95 |
96 | All sponsorship funds are used to support the continued development of [Practicalli series of books and videos](https://practical.li/){target=_blank}, although most work is done at personal cost and time.
97 |
98 | Thanks to [Cognitect](https://www.cognitect.com/){target=_blank}, [Nubank](https://nubank.com.br/){target=_blank} and a wide range of other [sponsors](https://github.com/sponsors/practicalli-johnny#sponsors){target=_blank} from the Clojure community for your continued support
99 |
100 |
101 | ## Creative commons license
102 |
103 |
104 |
105 | This work is licensed under a Creative Commons Attribution 4.0 ShareAlike License (including images & stylesheets).
106 |
37 |
38 | ??? HINT "Evaluate Clojure in a Terminal UI REPL"
39 | Entering expressions at the REPL prompt evaluates the expression immediately, returning the result directly underneath
40 | {loading=lazy}
41 | {loading=lazy}
42 |
43 | ## Rich Comment blocks - living documentation
44 |
45 | The `(comment ,,,)` function wraps code that is only run directly by the developer using a [Clojure aware editor](https://practical.li/clojure/clojure-editors/){target=_blank}.
46 |
47 | Expressions in rich comment blocks can represent how to use the functions that make up the namespace API. For example, starting/restarting the system, updating the database, etc. Expressions provide examples of calling functions with typical arguments and make a project more accessible and easier to work with.
48 |
49 | !!! EXAMPLE "Clojure Rich Comment to manage a service"
50 | ```clojure
51 | (ns practicalli.gameboard.service)
52 |
53 | (defn app-server-start [port] ,,,)
54 | (defn app-server-start [] ,,,)
55 | (defn app-server-restart [] ,,,)
56 |
57 | (defn -main
58 | "Start the service using system components"
59 | [& options] ,,,)
60 |
61 | (comment
62 | (-main)
63 | (app-server-start 8888)
64 | (app-server-stop)
65 | (app-server-restart 8888)
66 |
67 | (System/getenv "PORT")
68 | (def environment (System/getenv))
69 | (def system-properties (System/getProperties))
70 | ) ; End of rich comment block
71 | ```
72 |
73 | Rich comment blocks are very useful for rapidly iterating over different design decisions by including the same function but with different implementations. Hide [clj-kondo linter](https://practical.li/clojure/clojure-cli/install/code-analysis.html){target=_blank} warnings for redefined vars (`def`, `defn`) when using this approach.
74 |
75 | ```clojure
76 | ;; Rich comment block with redefined vars ignored
77 | #_{:clj-kondo/ignore [:redefined-var]}
78 | (comment
79 | (defn value-added-tax []
80 | ;; algorithm design - first try)
81 |
82 | (defn value-added-tax []
83 | ;; algorithm design - second try)
84 |
85 | ) ;; End of rich comment block
86 | ```
87 |
88 | The "Rich" in the name is an honourary mention to Rich Hickey, the author and benevolent dictator of Clojure design.
89 |
90 | ## Design Journal
91 |
92 | A journal of design decisions makes the code easier to understand and maintain. Code examples of design decisions and alternative design discussions are captured, reducing the time spent revisiting those discussions.
93 |
94 | Journals simplify the developer on-boarding processes as the journey through design decisions are already documented.
95 |
96 | A Design Journal is usually created in a separate namespace, although it may start as a rich comment at the bottom of a namespace.
97 |
98 | A journal should cover the following aspects
99 |
100 | * Relevant expressions use to test assumptions about design options.
101 | * Examples of design choices not taken and discussions why (saves repeating the same design discussions)
102 | * Expressions that can be evaluated to explain how a function or parts of a function work
103 |
104 | The design journal can be used to create meaningful documentation for the project very easily and should prevent time spent on repeating the same conversations.
105 |
106 | !!! HINT "Example design journal"
107 | [Design journal for TicTacToe game using Reagent, ClojureScript and Scalable Vector Graphics](https://github.com/practicalli-john/tictactoe-reagent/blob/master/src/tictactoe_reagent/core.cljs#L124){target=_blank}
108 |
109 | ## Viewing data structures
110 |
111 | Pretty print shows the structure of results from function calls in a human-friendly form, making it easier for a developer to parse and more likely to notice incorrect results.
112 |
113 | Tools to view and navigate code
114 |
115 | * [:fontawesome-solid-book-open: Cider inspector](https://practical.li/spacemacs/evaluating-clojure/inspect/){target=_blank} is an effective way to navigate nested data and page through large data sets.
116 | * [:fontawesome-solid-book-open: Portal Inspector](https://practical.li/clojure/clojure-tools/data-inspector/portal){target=_blank} to visualise many kinds of data in many different forms.
117 |
118 | 
119 |
120 |
121 | ## Code Style and idiomatic Clojure
122 |
123 | Clojure aware editors should automatically apply formatting that follows the [:globe_with_meridians: Clojure Style guide](https://github.com/bbatsov/clojure-style-guide){target=_blank}.
124 |
125 | Live linting with [clj-kondo](:fontawesome-brands-github: } suggests common idioms and highlights a wide range of syntax errors as code is written, minimizing bugs and therefore speeding up the development process.
126 |
127 | 
128 | 
129 |
130 | !!! INFO "Clojure LSP is build on top of clj-kondo"
131 | [:fontawesome-solid-book-open: Clojure LSP](https://practical.li/clojure/clojure-editors/clojure-lsp/){target=_blank} uses clj-kondo static analysis to provide a standard set of development tools (format, refactor, auto-complete, syntax highlighting, syntax & idiom warnings, code navigation, etc).
132 |
133 | Clojure LSP can be used with any Clojure aware editor that provides an LSP client, e.g. [:fontawesome-solid-book-open: Spacemacs](https://practical.li/spacemacs/install-spacemacs/clojure-lsp/){target=_blank}, [:fontawesome-solid-book-open: Doom Emacs](https://practical.li/doom-emacs/install/clojure-configuration/#clojure-cli){target=_blank}, [:fontawesome-solid-book-open: Neovim](https://practical.li/neovim/repl-driven-development/){target=_blank}, VSCode.
134 |
135 | !!! INFO "Clojure Style Guide"
136 | The [:globe_with_meridians: Clojure Style guide](https://github.com/bbatsov/clojure-style-guide){target=_blank} provides examples of common formatting approaches, although the development team should decide which of these to adopt. Emacs `clojure-mode` will automatically format code and so will Clojure LSP (via cljfmt). These tools are configurable and should be tailored to the teams standard.
137 |
138 | ## Data and Function specifications
139 |
140 | [:fontawesome-solid-book-open: Clojure spec](https://practical.li/clojure/clojure-spec/){target=_blank} is used to define a contract on incoming and outgoing data, to ensure it is of the correct form.
141 |
142 | As data structures are identified in REPL experiments, create data specification to validate the keys and value types of that data.
143 |
144 | ```clojure
145 | ;; ---------------------------------------------------
146 | ;; Address specifications
147 | (spec/def ::house-number string?)
148 | (spec/def ::street string?)
149 | (spec/def ::postal-code string?)
150 | (spec/def ::city string?)
151 | (spec/def ::country string?)
152 | (spec/def ::additional string?)
153 |
154 | (spec/def ::address ; Composite data specification
155 | (spec/keys
156 | :req-un [::street ::postal-code ::city ::country]
157 | :opt-un [::house-number ::additional]))
158 | ;; ---------------------------------------------------
159 | ```
160 |
161 | As the public API is designed, specifications for each functions arguments are added to validate the correct data is used when calling those functions.
162 |
163 | [:fontawesome-solid-book-open: Generative testing](https://practical.li/clojure/clojure-spec/generative-testing/){target=_blank} provides a far greater scope of test values used incorporated into unit tests. Data uses clojure.spec to randomly generate data for testing on each test run.
164 |
165 | ## Test Driven Development and REPL Driven Development
166 |
167 | {align=right loading=lazy}
168 |
169 | Test Driven Development (TDD) and REPL Driven Development (RDD) complement each other as they both encourage incremental changes and continuous feedback.
170 |
171 | > Test Driven Development fits well with Hammock Time, as good design comes from deep thought
172 |
173 | * RDD enables rapid design experiments so different approaches can easily and quickly be evaluated .
174 | * TDD focuses the results of the REPL experiments into design decisions, codified as unit tests. These tests guide the correctness of specific implementations and provide critical feedback when changes break that design.
175 |
176 | [:fontawesome-solid-book-open: Unit tests](https://practical.li/clojure/testing/unit-testing/){target=_blank} should support the public API of each namespace in a project to help prevent regressions in the code. Its far more efficient in terms of thinking time to define unit tests as the design starts to stabilize than as an after thought.
177 |
178 | `clojure.test` library is part of the Clojure standard library that provides a simple way to start writing unit tests.
179 |
180 | [:fontawesome-solid-book-open: Clojure spec](https://practical.li/clojure/clojure-spec/){target=_blank} can also be used for generative testing, providing far greater scope in values used when running unit tests. Specifications can be defined for values and functions.
181 |
182 | Clojure has a number of [:fontawesome-solid-book-open: test runners](https://practical.li/clojure/testing/test-runners/){target=_blank} available. Kaocha is a test runner that will run unit tests and function specification checks.
183 |
184 | !!! Hint "Automate local test runner"
185 | Use [:fontawesome-solid-book-open: kaocha test runner](https://practical.li/clojure/testing/test-runners/kaocha-test-runner/){target=_blank} in watch mode to run tests and specification check automatically (when changes are saved)
186 | ```bash
187 | clojure -X:test/watch
188 | ```
189 |
190 | ## Continuous Integration and Deployment
191 |
192 | Add a [:fontawesome-solid-book-open: continuous integration service](https://practical.li/clojure/continuous-integration/){target=_blank} to run tests and builds code on every shared commit. Spin up testable review deployments when commits pushed to a pull request branch, before pushing commits to the main deployment branch, creating an effective pipeline to gain further feedback.
193 |
194 | * [:globe_with_meridians: CircleCI](https://practical.li/clojure/continuous-integration/circle-ci/){target=_blank} provides a simple to use service that supports Clojure projects.
195 | * [:globe_with_meridians: GitHub Workflows](https://docs.github.com/en/actions/using-workflows){target=_blank} and [GitHub actions marketplace](https://github.com/marketplace?type=actions){target=_blank} to quickly build a tailored continuous integration service, e.g. [Setup Clojure GitHub Action](https://github.com/marketplace/actions/setup-clojure){target=_blank}.
196 | * [:globe_with_meridians: GitLab CI](https://docs.gitlab.com/ee/ci/introduction/index.html){target=_blank}
197 |
198 | 
199 |
200 | ## Live Coding with Data - Stuart Halloway
201 |
202 | There are few novel features of programming languages, but each combination has different properties. The combination of dynamic, hosted, functional and extended Lisp in Clojure gives developers the tools for making effective programs. The ways in which Clojure's unique combination of features can yield a highly effective development process.
203 |
204 | Over more than a decade we have developed an effective approach to writing code in Clojure whose power comes from composing many of its key features. As different as Clojure programs are from e.g. Java programs, so to can and should be the development experience. You are not in Kansas anymore!
205 |
206 | This talk presents a demonstration of the leverage you can get when writing programs in Clojure, with examples, based on my experiences as a core developer of Clojure and Datomic.
207 |
208 |
209 |
210 |
211 |
--------------------------------------------------------------------------------
/docs/introduction/writing-tips.md:
--------------------------------------------------------------------------------
1 | # Writing tips for MkDocs
2 |
3 | Making the docs more engaging using the [mkdocs-material theme reference guide](https://squidfunk.github.io/mkdocs-material/reference/){target=_blank}
4 |
5 | ??? INFO "Configuring Colors"
6 | [Material for MkDocs - Changing the colors](https://squidfunk.github.io/mkdocs-material/setup/changing-the-colors/){target=_blank} lists the primary and accent colors available.
7 |
8 | [HSL Color Picker](https://hslpicker.com/) for codes to modify the theme style, overriding colors in `docs/assets/stylesheets/extra.css`
9 |
10 |
11 | ## Hypertext links
12 |
13 | Links open in the same browser window/tab by default.
14 |
15 | Add `{target=_blank}` to the end of a link to configure opening in a new tab
16 |
17 | ```markdown
18 | [link text](url){target=_blank}
19 | ```
20 |
21 | ## Buttons
22 |
23 | Convert any link into a button by adding `{.md-button}` class names to end of the markdown for a link, which uses `.md-button-primary` by default. Include `target=_blank` for buttons with links to external sites.
24 |
25 | ```
26 | [link text](http://practical.li/blog){.md-button target=_blank}
27 | ```
28 |
29 | Or specify a different class
30 |
31 | ```
32 | [link text](http://practical.li/blog){.md-button .md-button-primary}
33 | ```
34 |
35 | Add an icon to the button
36 |
37 | [:fontawesome-brands-github: Practicalli Issues](http://practical.li/blog){ .md-button .md-button-primary }
38 | [:octicons-heart-fill-24: Practicalli Blog](http://practical.li/blog){ .md-button .md-button-primary }
39 |
40 | ```markdown
41 | [:fontawesome-brands-github: Practicalli Issues](http://practical.li/blog){ .md-button .md-button-primary }
42 | [:octicons-heart-fill-24: Practicalli Blog](http://practical.li/blog){ .md-button .md-button-primary }
43 | ```
44 |
45 | [Search all supported icons](https://squidfunk.github.io/mkdocs-material/reference/icons-emojis/){target=_blank .md-button}
46 |
47 | ## YouTube video
48 |
49 | Use an iframe element to include a YouTube video, wrapping in a paragraph tag with center alignment to place the video in a centered horizontal position
50 |
51 | ```html
52 |
53 |
54 |
55 | ```
56 |
57 | > mkdocs material does not have direct support for adding a YouTube video via markdown.
58 |
59 |
60 | ## Admonitions
61 |
62 | [Supported admonition types](https://squidfunk.github.io/mkdocs-material/reference/admonitions/#supported-types)
63 |
64 | !!! NOTE
65 | Use `!!!` followed by `NOTE`
66 |
67 | !!! NOTE "Adding a title"
68 | Use `!!!` followed by `NOTE` and a `"title in double quotes"`
69 |
70 | !!! NOTE ""
71 | Shh, no title bar just the text...
72 | Use `!!!` followed by `NOTE` and a `""` empty double quotes
73 |
74 | !!! ABSTRACT
75 | Use `!!!` followed by `ABSTRACT`
76 |
77 | !!! INFO
78 | Use `!!!` followed by `INFO`
79 |
80 | !!! TIP
81 | Use `!!!` followed by `TIP`
82 |
83 | !!! SUCCESS
84 | Use `!!!` followed by `SUCCESS`
85 |
86 | !!! QUESTION
87 | Use `!!!` followed by `QUESTION`
88 |
89 | !!! WARNING
90 | Use `!!!` followed by `WARNING`
91 |
92 | !!! FAILURE
93 | Use `!!!` followed by `FAILURE`
94 |
95 | !!! DANGER
96 | Use `!!!` followed by `DANGER`
97 |
98 | !!! BUG
99 | Use `!!!` followed by `BUG`
100 |
101 | !!! EXAMPLE
102 | Use `!!!` followed by `EXAMPLE`
103 |
104 | !!! QUOTE
105 | Use `!!!` followed by `QUOTE`
106 |
107 |
108 |
109 | ### Collapsing admonitions
110 |
111 | ??? NOTE
112 | Collapse those admonitions using `???` instead of `!!!`
113 |
114 | ??? NOTE "Replace with a title"
115 | Use `???` followed by `NOTE` and a `"title in double quotes"`
116 |
117 |
118 | ???+ NOTE "Expanded by default"
119 | Use `???+`, note the `+` character, followed by `NOTE` and a `"title in double quotes"`
120 |
121 |
122 | ### Inline blocks
123 |
124 | Inline blocks of text to make a very specific callout within text
125 |
126 | !!! info inline
127 |
128 | Lorem ipsum dolor sit amet, consectetur
129 | adipiscing elit. Nulla et euismod nulla.
130 | Curabitur feugiat, tortor non consequat
131 | finibus, justo purus auctor massa, nec
132 | semper lorem quam in massa.
133 |
134 |
135 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor massa, nec semper lorem quam in massa.
136 |
137 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor massa, nec semper lorem quam in massa.
138 |
139 | Adding something to then end of text is probably my favourite
140 |
141 | !!! info inline end
142 |
143 | Lorem ipsum dolor sit amet, consectetur
144 | adipiscing elit. Nulla et euismod nulla.
145 | Curabitur feugiat, tortor non consequat
146 | finibus, justo purus auctor massa, nec
147 | semper lorem quam in massa.
148 |
149 |
150 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor massa, nec semper lorem quam in massa.
151 |
152 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor massa, nec semper lorem quam in massa.
153 |
154 |
155 |
156 | ## Code blocks
157 |
158 | Code blocks include a copy icon automatically
159 |
160 | Syntax highlighting in code blocks
161 |
162 | ```clojure
163 | (defn my-function ; Write a simple function
164 | "With a lovely doc-string"
165 | [arguments]
166 | (map inc [1 2 3]))
167 | ```
168 |
169 | Give the code block a title using `title=""` after the backtics and language name
170 |
171 |
172 | ```clojure title="src/practicalli/gameboard.clj"
173 | (defn my-function
174 | "With a lovely doc-string"
175 | [arguments]
176 | (map inc [1 2 3]))
177 | ```
178 |
179 | We all like line numbers, especially when you can set the starting line
180 |
181 | ```clojure linenums="42" title="src/practicalli/gameboard.clj"
182 | (defn my-function
183 | "With a lovely doc-string"
184 | [arguments]
185 | (map inc [1 2 3]))
186 | ```
187 |
188 | Add `linenums=42` to start line numbers from 42 onward
189 |
190 | ```
191 | clojure linenums="42" title="src/practicalli/gameboard.clj"
192 | ```
193 |
194 |
195 | ### Annotations
196 |
197 | Annotations in a code block help to highlight important aspects. Use the comment character for the language followed by a space and a number in brackets
198 |
199 | For example, in a shell code block, use `# (1)` where 1 is the number of the annotation
200 |
201 | Use a number after the code block to add the text for the annotation, e.g. `1.`. Ensure there is a space between the code block and the annotation text.
202 |
203 | ```shell
204 | ls -la $HOME/Downloads # (1)
205 | ```
206 |
207 | 1. :woman_raising_hand: I'm a code annotation! I can contain `code`, __formatted text__, images, ... basically anything that can be written in Markdown.
208 |
209 |
210 | Code blocks with annotation, add `!` after the annotation number to suppress the `#` character
211 |
212 | ```clojure
213 | (defn helper-function
214 | "Doc-string with description of function purpose" ; (1)!
215 | [data]
216 | (merge {:fish 1} data)
217 | )
218 | ```
219 |
220 | 1. Always include a doc-string in every function to describe the purpose of that function, identifying why it was added and what its value is.
221 |
222 |
223 | GitHub action example with multiple annotations
224 |
225 | ``` yaml
226 | name: ci # (1)!
227 | on:
228 | push:
229 | branches:
230 | - master # (2)!
231 | - main
232 | permissions:
233 | contents: write
234 | jobs:
235 | deploy:
236 | runs-on: ubuntu-latest
237 | steps:
238 | - uses: actions/checkout@v3
239 | - uses: actions/setup-python@v4
240 | with:
241 | python-version: 3.x
242 | - run: pip install mkdocs-material # (3)!
243 | - run: mkdocs gh-deploy --force
244 | ```
245 |
246 | 1. You can change the name to your liking.
247 |
248 | 2. At some point, GitHub renamed `master` to `main`. If your default branch
249 | is named `master`, you can safely remove `main`, vice versa.
250 |
251 | 3. This is the place to install further [MkDocs plugins] or Markdown
252 | extensions with `pip` to be used during the build:
253 |
254 | ``` sh
255 | pip install \
256 | mkdocs-material \
257 | mkdocs-awesome-pages-plugin \
258 | ...
259 | ```
260 |
261 |
262 | ### Highlight lines in code blocks
263 |
264 | Add highlight line meta data to a code block after the opening backticks and code block language.
265 |
266 | `hl_lines="2"` highlights line 2 in the codeblock
267 |
268 | ```clojure hl_lines="4 5 6"
269 | (defn my-function
270 | "With a lovely doc-string"
271 | [arguments]
272 | (map
273 | inc
274 | [1 2 3]))
275 | ```
276 |
277 | ### Embed external files
278 |
279 | `--8<--` in a code block inserts code from a source code file or other text file
280 |
281 | Specify a local file from the root of the book project (the directory containing mkdocs.yml)
282 |
283 | ??? EXAMPLE "Scheduled Version Check GitHub Workflow from source code file"
284 | ```yaml title="scheduled version check"
285 | --8<-- ".github/workflows/scheduled-version-check.yaml"
286 | ```
287 |
288 | ??? EXAMPLE "Practicalli Project Templates"
289 | ```markdown title="Emacs project configuration - .dir-locals.el"
290 | --8<-- "https://raw.githubusercontent.com/practicalli/project-templates/main/.dir-locals.el"
291 | ```
292 |
293 | !!! HINT "Code example reuse"
294 | Use an embedded local or external file (URL) when the same content is required in more than one place in the book.
295 |
296 | An effective way of sharing code and configuration mutliple times in a book or across multiple books.
297 |
298 | ## Content tabs
299 |
300 | Create in page tabs that can also be
301 |
302 | Setting up a project
303 |
304 | === "Clojure CLI"
305 | ```shell
306 | clojure -T:project/new :template app :name practicalli/gameboard
307 | ```
308 |
309 |
310 | === "Leiningen"
311 | ```shell
312 | lein new app practicalli/gameboard
313 | ```
314 |
315 |
316 | Or nest the content tabs in an admonition
317 |
318 |
319 | !!! INFO "Run a terminal REPL"
320 |
321 | === "Clojure CLI"
322 | ```shell
323 | clojure -T:repl/rebel
324 | ```
325 |
326 |
327 | === "Leiningen"
328 | ```shell
329 | lein repl
330 | ```
331 |
332 |
333 | ## Diagrams
334 |
335 | Neat flow diagrams
336 |
337 | [Diagrams - Material for MkDocs](https://squidfunk.github.io/mkdocs-material/reference/diagrams/){target=_blank .md-button}
338 |
339 | ``` mermaid
340 | graph LR
341 | A[Start] --> B{Error?};
342 | B -->|Yes| C[Hmm...];
343 | C --> D[Debug];
344 | D --> B;
345 | B ---->|No| E[Yay!];
346 | ```
347 |
348 |
349 | UML Sequence Diagrams
350 |
351 | ``` mermaid
352 | sequenceDiagram
353 | Alice->>John: Hello John, how are you?
354 | loop Healthcheck
355 | John->>John: Fight against hypochondria
356 | end
357 | Note right of John: Rational thoughts!
358 | John-->>Alice: Great!
359 | John->>Bob: How about you?
360 | Bob-->>John: Jolly good!
361 | ```
362 |
363 | state transition diagrams
364 |
365 | ``` mermaid
366 | stateDiagram-v2
367 | state fork_state <>
368 | [*] --> fork_state
369 | fork_state --> State2
370 | fork_state --> State3
371 |
372 | state join_state <>
373 | State2 --> join_state
374 | State3 --> join_state
375 | join_state --> State4
376 | State4 --> [*]
377 | ```
378 |
379 | Class diagrams - not needed for Clojure
380 |
381 | Entity relationship diagrams are handy though
382 |
383 | ``` mermaid
384 | erDiagram
385 | CUSTOMER ||--o{ ORDER : places
386 | ORDER ||--|{ LINE-ITEM : contains
387 | LINE-ITEM {
388 | customer-name string
389 | unit-price int
390 | }
391 | CUSTOMER }|..|{ DELIVERY-ADDRESS : uses
392 | ```
393 |
394 |
395 | ## Keyboard keys
396 |
397 | Represent key bindings with [Keyboard keys](https://facelessuser.github.io/pymdown-extensions/extensions/keys/#extendingmodifying-key-map-index){target=_blank}. Each number and alphabet character has their own key.
398 |
399 | * ++1++ `++1++` for numbers
400 | * ++"l"++ `++"l"++` for lowercase character
401 | * ++u++ `++u++` for uppercase character or `++"U"++` for consistency
402 |
403 | [Punctionation keys](https://facelessuser.github.io/pymdown-extensions/extensions/keys/#punctuation-keys){target=_blank} use their name
404 |
405 | * ++spc++ `++spc++`
406 | * ++comma++ `++comma++`
407 | * ++arrow-left++ `++arrow-left++`
408 |
409 | For key sequences, place a space between each keyboard character
410 |
411 | * ++spc++ ++"g"++ ++"s"++ `++spc++ ++"g"++ ++"s"++`
412 |
413 | For key combinations, use join they key identifies with a `+`
414 |
415 | * ++meta+x++ `++meta+x++`
416 | * ++ctrl+alt+del++ `++ctrl+alt+del++`
417 |
418 | [MkDocs keyboard keys reference](https://facelessuser.github.io/pymdown-extensions/extensions/keys/#extendingmodifying-key-map-index){target=_blank .md-button}
419 |
420 | ## Images
421 |
422 | Markdown images can be appended with material tags to set the size of the image, whether to appear on light or dark theme and support lazy image loading in browsers
423 |
424 | === "Size"
425 | `{style="height:150px;width:150px"}` specifies the image size
426 | ```markdown
427 | {style="height:150px;width:150px"}
428 | ```
429 |
430 | {style="height:150px;width:150px"}
431 |
432 |
433 | === "Lazy Loading"
434 |
435 | `{loading=lazy}` specifies an image should lazily load in the browser
436 | ```markdown
437 | {loading=lazy}
438 | ```
439 |
440 | === "Align"
441 |
442 | `{aligh=left}` or `{aligh=right}` specifies the page alignment of an image.
443 | ```markdown
444 | {align=right}
445 | {align=right}
446 | ```
447 |
448 | {align=left style="height:64px;width:64px"}
449 | {align=right style="height:64px;width:64px"}
450 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor massa, nec semper lorem quam in massa.
451 |
452 |
453 | === "Theme Specific"
454 |
455 | `` or `` specifies the theme the image should be shown, allowing different versions of images to be shown based on the theme.
456 | ```markdown
457 | {style="height:150px;width:150px"}
458 | {style="height:150px;width:150px"}
459 | ```
460 | Use the theme toggle in the top nav bar to see the icon change between light and dark.
461 | {style="height:150px;width:150px"}
462 | {style="height:150px;width:150px"}
463 |
464 | > Requires the [color pallet toggle](https://squidfunk.github.io/mkdocs-material/setup/changing-the-colors/#color-palette-toggle)
465 |
466 |
467 | === "All Image Attributes"
468 | Alight right, lazy load and set image to 150x150
469 |
470 | ```markdown
471 | {align=right loading=lazy style="height:64px;width:64px"}
472 | {align=right loading=lazy style="height:64px;width:64px"}
473 | ```
474 |
475 | {align=right loading=lazy style="height:64px;width:64px"}
476 | {align=left loading=lazy style="height:64px;width:64px"}
477 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor massa, nec semper lorem quam in massa.
478 |
479 |
480 | ## Lists
481 |
482 | Task lists
483 |
484 | - [x] Lorem ipsum dolor sit amet, consectetur adipiscing elit
485 | - [ ] Vestibulum convallis sit amet nisi a tincidunt
486 | * [x] In hac habitasse platea dictumst
487 | * [x] In scelerisque nibh non dolor mollis congue sed et metus
488 | * [ ] Praesent sed risus massa
489 | - [ ] Aenean pretium efficitur erat, donec pharetra, ligula non scelerisque
490 |
491 | !!! EXAMPLE "Task List example"
492 | ```markdown
493 | - [x] Lorem ipsum dolor sit amet, consectetur adipiscing elit
494 | - [ ] Vestibulum convallis sit amet nisi a tincidunt
495 | * [x] In hac habitasse platea dictumst
496 | * [x] In scelerisque nibh non dolor mollis congue sed et metus
497 | * [ ] Praesent sed risus massa
498 | - [ ] Aenean pretium efficitur erat, donec pharetra, ligula non scelerisque
499 | ```
500 |
501 | ## Tooltips
502 |
503 | The humble tool tip
504 |
505 | [Hover me](https://example.com "I'm a tooltip!")
506 |
507 | with references
508 |
509 | [Hover me][example]
510 |
511 | [example]: https://example.com "I'm a tooltip!"
512 |
513 |
514 | Icon tool tip with a title
515 |
516 | :material-information-outline:{ title="Important information" }
517 |
518 |
519 | ### Abreviations
520 |
521 | The HTML specification is maintained by the W3C.
522 |
523 | *[HTML]: Hyper Text Markup Language
524 | *[W3C]: World Wide Web Consortium
525 |
526 |
527 |
528 | ## Magic links
529 |
530 | [MagicLink](https://facelessuser.github.io/pymdown-extensions/extensions/magiclink/) can auto-link HTML, FTP, and email links. It can auto-convert repository links (GitHub, GitLab, and Bitbucket) and display them in a more concise, shorthand format.
531 |
532 | [Email Practicalli](mailto:info@)
533 |
534 | [Practicalli Neovim](https://github.com/practicalli/neovim)
535 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Attribution-ShareAlike 4.0 International
2 |
3 | =======================================================================
4 |
5 | Creative Commons Corporation ("Creative Commons") is not a law firm and
6 | does not provide legal services or legal advice. Distribution of
7 | Creative Commons public licenses does not create a lawyer-client or
8 | other relationship. Creative Commons makes its licenses and related
9 | information available on an "as-is" basis. Creative Commons gives no
10 | warranties regarding its licenses, any material licensed under their
11 | terms and conditions, or any related information. Creative Commons
12 | disclaims all liability for damages resulting from their use to the
13 | fullest extent possible.
14 |
15 | Using Creative Commons Public Licenses
16 |
17 | Creative Commons public licenses provide a standard set of terms and
18 | conditions that creators and other rights holders may use to share
19 | original works of authorship and other material subject to copyright
20 | and certain other rights specified in the public license below. The
21 | following considerations are for informational purposes only, are not
22 | exhaustive, and do not form part of our licenses.
23 |
24 | Considerations for licensors: Our public licenses are
25 | intended for use by those authorized to give the public
26 | permission to use material in ways otherwise restricted by
27 | copyright and certain other rights. Our licenses are
28 | irrevocable. Licensors should read and understand the terms
29 | and conditions of the license they choose before applying it.
30 | Licensors should also secure all rights necessary before
31 | applying our licenses so that the public can reuse the
32 | material as expected. Licensors should clearly mark any
33 | material not subject to the license. This includes other CC-
34 | licensed material, or material used under an exception or
35 | limitation to copyright. More considerations for licensors:
36 | wiki.creativecommons.org/Considerations_for_licensors
37 |
38 | Considerations for the public: By using one of our public
39 | licenses, a licensor grants the public permission to use the
40 | licensed material under specified terms and conditions. If
41 | the licensor's permission is not necessary for any reason--for
42 | example, because of any applicable exception or limitation to
43 | copyright--then that use is not regulated by the license. Our
44 | licenses grant only permissions under copyright and certain
45 | other rights that a licensor has authority to grant. Use of
46 | the licensed material may still be restricted for other
47 | reasons, including because others have copyright or other
48 | rights in the material. A licensor may make special requests,
49 | such as asking that all changes be marked or described.
50 | Although not required by our licenses, you are encouraged to
51 | respect those requests where reasonable. More_considerations
52 | for the public:
53 | wiki.creativecommons.org/Considerations_for_licensees
54 |
55 | =======================================================================
56 |
57 | Creative Commons Attribution-ShareAlike 4.0 International Public
58 | License
59 |
60 | By exercising the Licensed Rights (defined below), You accept and agree
61 | to be bound by the terms and conditions of this Creative Commons
62 | Attribution-ShareAlike 4.0 International Public License ("Public
63 | License"). To the extent this Public License may be interpreted as a
64 | contract, You are granted the Licensed Rights in consideration of Your
65 | acceptance of these terms and conditions, and the Licensor grants You
66 | such rights in consideration of benefits the Licensor receives from
67 | making the Licensed Material available under these terms and
68 | conditions.
69 |
70 |
71 | Section 1 -- Definitions.
72 |
73 | a. Adapted Material means material subject to Copyright and Similar
74 | Rights that is derived from or based upon the Licensed Material
75 | and in which the Licensed Material is translated, altered,
76 | arranged, transformed, or otherwise modified in a manner requiring
77 | permission under the Copyright and Similar Rights held by the
78 | Licensor. For purposes of this Public License, where the Licensed
79 | Material is a musical work, performance, or sound recording,
80 | Adapted Material is always produced where the Licensed Material is
81 | synched in timed relation with a moving image.
82 |
83 | b. Adapter's License means the license You apply to Your Copyright
84 | and Similar Rights in Your contributions to Adapted Material in
85 | accordance with the terms and conditions of this Public License.
86 |
87 | c. BY-SA Compatible License means a license listed at
88 | creativecommons.org/compatiblelicenses, approved by Creative
89 | Commons as essentially the equivalent of this Public License.
90 |
91 | d. Copyright and Similar Rights means copyright and/or similar rights
92 | closely related to copyright including, without limitation,
93 | performance, broadcast, sound recording, and Sui Generis Database
94 | Rights, without regard to how the rights are labeled or
95 | categorized. For purposes of this Public License, the rights
96 | specified in Section 2(b)(1)-(2) are not Copyright and Similar
97 | Rights.
98 |
99 | e. Effective Technological Measures means those measures that, in the
100 | absence of proper authority, may not be circumvented under laws
101 | fulfilling obligations under Article 11 of the WIPO Copyright
102 | Treaty adopted on December 20, 1996, and/or similar international
103 | agreements.
104 |
105 | f. Exceptions and Limitations means fair use, fair dealing, and/or
106 | any other exception or limitation to Copyright and Similar Rights
107 | that applies to Your use of the Licensed Material.
108 |
109 | g. License Elements means the license attributes listed in the name
110 | of a Creative Commons Public License. The License Elements of this
111 | Public License are Attribution and ShareAlike.
112 |
113 | h. Licensed Material means the artistic or literary work, database,
114 | or other material to which the Licensor applied this Public
115 | License.
116 |
117 | i. Licensed Rights means the rights granted to You subject to the
118 | terms and conditions of this Public License, which are limited to
119 | all Copyright and Similar Rights that apply to Your use of the
120 | Licensed Material and that the Licensor has authority to license.
121 |
122 | j. Licensor means the individual(s) or entity(ies) granting rights
123 | under this Public License.
124 |
125 | k. Share means to provide material to the public by any means or
126 | process that requires permission under the Licensed Rights, such
127 | as reproduction, public display, public performance, distribution,
128 | dissemination, communication, or importation, and to make material
129 | available to the public including in ways that members of the
130 | public may access the material from a place and at a time
131 | individually chosen by them.
132 |
133 | l. Sui Generis Database Rights means rights other than copyright
134 | resulting from Directive 96/9/EC of the European Parliament and of
135 | the Council of 11 March 1996 on the legal protection of databases,
136 | as amended and/or succeeded, as well as other essentially
137 | equivalent rights anywhere in the world.
138 |
139 | m. You means the individual or entity exercising the Licensed Rights
140 | under this Public License. Your has a corresponding meaning.
141 |
142 |
143 | Section 2 -- Scope.
144 |
145 | a. License grant.
146 |
147 | 1. Subject to the terms and conditions of this Public License,
148 | the Licensor hereby grants You a worldwide, royalty-free,
149 | non-sublicensable, non-exclusive, irrevocable license to
150 | exercise the Licensed Rights in the Licensed Material to:
151 |
152 | a. reproduce and Share the Licensed Material, in whole or
153 | in part; and
154 |
155 | b. produce, reproduce, and Share Adapted Material.
156 |
157 | 2. Exceptions and Limitations. For the avoidance of doubt, where
158 | Exceptions and Limitations apply to Your use, this Public
159 | License does not apply, and You do not need to comply with
160 | its terms and conditions.
161 |
162 | 3. Term. The term of this Public License is specified in Section
163 | 6(a).
164 |
165 | 4. Media and formats; technical modifications allowed. The
166 | Licensor authorizes You to exercise the Licensed Rights in
167 | all media and formats whether now known or hereafter created,
168 | and to make technical modifications necessary to do so. The
169 | Licensor waives and/or agrees not to assert any right or
170 | authority to forbid You from making technical modifications
171 | necessary to exercise the Licensed Rights, including
172 | technical modifications necessary to circumvent Effective
173 | Technological Measures. For purposes of this Public License,
174 | simply making modifications authorized by this Section 2(a)
175 | (4) never produces Adapted Material.
176 |
177 | 5. Downstream recipients.
178 |
179 | a. Offer from the Licensor -- Licensed Material. Every
180 | recipient of the Licensed Material automatically
181 | receives an offer from the Licensor to exercise the
182 | Licensed Rights under the terms and conditions of this
183 | Public License.
184 |
185 | b. Additional offer from the Licensor -- Adapted Material.
186 | Every recipient of Adapted Material from You
187 | automatically receives an offer from the Licensor to
188 | exercise the Licensed Rights in the Adapted Material
189 | under the conditions of the Adapter's License You apply.
190 |
191 | c. No downstream restrictions. You may not offer or impose
192 | any additional or different terms or conditions on, or
193 | apply any Effective Technological Measures to, the
194 | Licensed Material if doing so restricts exercise of the
195 | Licensed Rights by any recipient of the Licensed
196 | Material.
197 |
198 | 6. No endorsement. Nothing in this Public License constitutes or
199 | may be construed as permission to assert or imply that You
200 | are, or that Your use of the Licensed Material is, connected
201 | with, or sponsored, endorsed, or granted official status by,
202 | the Licensor or others designated to receive attribution as
203 | provided in Section 3(a)(1)(A)(i).
204 |
205 | b. Other rights.
206 |
207 | 1. Moral rights, such as the right of integrity, are not
208 | licensed under this Public License, nor are publicity,
209 | privacy, and/or other similar personality rights; however, to
210 | the extent possible, the Licensor waives and/or agrees not to
211 | assert any such rights held by the Licensor to the limited
212 | extent necessary to allow You to exercise the Licensed
213 | Rights, but not otherwise.
214 |
215 | 2. Patent and trademark rights are not licensed under this
216 | Public License.
217 |
218 | 3. To the extent possible, the Licensor waives any right to
219 | collect royalties from You for the exercise of the Licensed
220 | Rights, whether directly or through a collecting society
221 | under any voluntary or waivable statutory or compulsory
222 | licensing scheme. In all other cases the Licensor expressly
223 | reserves any right to collect such royalties.
224 |
225 |
226 | Section 3 -- License Conditions.
227 |
228 | Your exercise of the Licensed Rights is expressly made subject to the
229 | following conditions.
230 |
231 | a. Attribution.
232 |
233 | 1. If You Share the Licensed Material (including in modified
234 | form), You must:
235 |
236 | a. retain the following if it is supplied by the Licensor
237 | with the Licensed Material:
238 |
239 | i. identification of the creator(s) of the Licensed
240 | Material and any others designated to receive
241 | attribution, in any reasonable manner requested by
242 | the Licensor (including by pseudonym if
243 | designated);
244 |
245 | ii. a copyright notice;
246 |
247 | iii. a notice that refers to this Public License;
248 |
249 | iv. a notice that refers to the disclaimer of
250 | warranties;
251 |
252 | v. a URI or hyperlink to the Licensed Material to the
253 | extent reasonably practicable;
254 |
255 | b. indicate if You modified the Licensed Material and
256 | retain an indication of any previous modifications; and
257 |
258 | c. indicate the Licensed Material is licensed under this
259 | Public License, and include the text of, or the URI or
260 | hyperlink to, this Public License.
261 |
262 | 2. You may satisfy the conditions in Section 3(a)(1) in any
263 | reasonable manner based on the medium, means, and context in
264 | which You Share the Licensed Material. For example, it may be
265 | reasonable to satisfy the conditions by providing a URI or
266 | hyperlink to a resource that includes the required
267 | information.
268 |
269 | 3. If requested by the Licensor, You must remove any of the
270 | information required by Section 3(a)(1)(A) to the extent
271 | reasonably practicable.
272 |
273 | b. ShareAlike.
274 |
275 | In addition to the conditions in Section 3(a), if You Share
276 | Adapted Material You produce, the following conditions also apply.
277 |
278 | 1. The Adapter's License You apply must be a Creative Commons
279 | license with the same License Elements, this version or
280 | later, or a BY-SA Compatible License.
281 |
282 | 2. You must include the text of, or the URI or hyperlink to, the
283 | Adapter's License You apply. You may satisfy this condition
284 | in any reasonable manner based on the medium, means, and
285 | context in which You Share Adapted Material.
286 |
287 | 3. You may not offer or impose any additional or different terms
288 | or conditions on, or apply any Effective Technological
289 | Measures to, Adapted Material that restrict exercise of the
290 | rights granted under the Adapter's License You apply.
291 |
292 |
293 | Section 4 -- Sui Generis Database Rights.
294 |
295 | Where the Licensed Rights include Sui Generis Database Rights that
296 | apply to Your use of the Licensed Material:
297 |
298 | a. for the avoidance of doubt, Section 2(a)(1) grants You the right
299 | to extract, reuse, reproduce, and Share all or a substantial
300 | portion of the contents of the database;
301 |
302 | b. if You include all or a substantial portion of the database
303 | contents in a database in which You have Sui Generis Database
304 | Rights, then the database in which You have Sui Generis Database
305 | Rights (but not its individual contents) is Adapted Material,
306 |
307 | including for purposes of Section 3(b); and
308 | c. You must comply with the conditions in Section 3(a) if You Share
309 | all or a substantial portion of the contents of the database.
310 |
311 | For the avoidance of doubt, this Section 4 supplements and does not
312 | replace Your obligations under this Public License where the Licensed
313 | Rights include other Copyright and Similar Rights.
314 |
315 |
316 | Section 5 -- Disclaimer of Warranties and Limitation of Liability.
317 |
318 | a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
319 | EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
320 | AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
321 | ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
322 | IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
323 | WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
324 | PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
325 | ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
326 | KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
327 | ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
328 |
329 | b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
330 | TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
331 | NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
332 | INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
333 | COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
334 | USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
335 | ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
336 | DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
337 | IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
338 |
339 | c. The disclaimer of warranties and limitation of liability provided
340 | above shall be interpreted in a manner that, to the extent
341 | possible, most closely approximates an absolute disclaimer and
342 | waiver of all liability.
343 |
344 |
345 | Section 6 -- Term and Termination.
346 |
347 | a. This Public License applies for the term of the Copyright and
348 | Similar Rights licensed here. However, if You fail to comply with
349 | this Public License, then Your rights under this Public License
350 | terminate automatically.
351 |
352 | b. Where Your right to use the Licensed Material has terminated under
353 | Section 6(a), it reinstates:
354 |
355 | 1. automatically as of the date the violation is cured, provided
356 | it is cured within 30 days of Your discovery of the
357 | violation; or
358 |
359 | 2. upon express reinstatement by the Licensor.
360 |
361 | For the avoidance of doubt, this Section 6(b) does not affect any
362 | right the Licensor may have to seek remedies for Your violations
363 | of this Public License.
364 |
365 | c. For the avoidance of doubt, the Licensor may also offer the
366 | Licensed Material under separate terms or conditions or stop
367 | distributing the Licensed Material at any time; however, doing so
368 | will not terminate this Public License.
369 |
370 | d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
371 | License.
372 |
373 |
374 | Section 7 -- Other Terms and Conditions.
375 |
376 | a. The Licensor shall not be bound by any additional or different
377 | terms or conditions communicated by You unless expressly agreed.
378 |
379 | b. Any arrangements, understandings, or agreements regarding the
380 | Licensed Material not stated herein are separate from and
381 | independent of the terms and conditions of this Public License.
382 |
383 |
384 | Section 8 -- Interpretation.
385 |
386 | a. For the avoidance of doubt, this Public License does not, and
387 | shall not be interpreted to, reduce, limit, restrict, or impose
388 | conditions on any use of the Licensed Material that could lawfully
389 | be made without permission under this Public License.
390 |
391 | b. To the extent possible, if any provision of this Public License is
392 | deemed unenforceable, it shall be automatically reformed to the
393 | minimum extent necessary to make it enforceable. If the provision
394 | cannot be reformed, it shall be severed from this Public License
395 | without affecting the enforceability of the remaining terms and
396 | conditions.
397 |
398 | c. No term or condition of this Public License will be waived and no
399 | failure to comply consented to unless expressly agreed to by the
400 | Licensor.
401 |
402 | d. Nothing in this Public License constitutes or may be interpreted
403 | as a limitation upon, or waiver of, any privileges and immunities
404 | that apply to the Licensor or You, including from the legal
405 | processes of any jurisdiction or authority.
406 |
407 |
408 | =======================================================================
409 |
410 | Creative Commons is not a party to its public
411 | licenses. Notwithstanding, Creative Commons may elect to apply one of
412 | its public licenses to material it publishes and in those instances
413 | will be considered the “Licensor.” The text of the Creative Commons
414 | public licenses is dedicated to the public domain under the CC0 Public
415 | Domain Dedication. Except for the limited purpose of indicating that
416 | material is shared under a Creative Commons public license or as
417 | otherwise permitted by the Creative Commons policies published at
418 | creativecommons.org/policies, Creative Commons does not authorize the
419 | use of the trademark "Creative Commons" or any other trademark or logo
420 | of Creative Commons without its prior written consent including,
421 | without limitation, in connection with any unauthorized modifications
422 | to any of its public licenses or any other arrangements,
423 | understandings, or agreements concerning use of licensed material. For
424 | the avoidance of doubt, this paragraph does not form part of the
425 | public licenses.
426 |
427 | Creative Commons may be contacted at creativecommons.org.
428 |
--------------------------------------------------------------------------------