Skip to content

Commit

Permalink
Guide tabs (#146)
Browse files Browse the repository at this point in the history
* added tabs and dep management and design concepts

* updates to dependencies and removal of design

* remove tabsets and update dep management

* use quarto tabsets

* Merge remote-tracking branch 'origin/main'

* use R function guide_tabset to standardize formatting of tabsets

* publish openstatsguide as version 0.1

---------

Co-authored-by: Daniel Sabanes Bove <[email protected]>
Co-authored-by: Daniel Sabanes Bove <[email protected]>
  • Loading branch information
3 people authored Sep 19, 2024
1 parent c55baf4 commit b02b782
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 66 deletions.
3 changes: 3 additions & 0 deletions _quarto.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ website:
text: "Presentations"
- href: hexwall.qmd
text: "TaskView Hexwall"
- text: "Guides"
menu:
- href: guide.qmd
right:
- icon: github
href: https://github.com/openstatsware/website
Expand Down
1 change: 1 addition & 0 deletions data/news.csv
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
Date,Text
09/16/2024,<a href='./guide.html'>`openstatsguide` is published</a>
08/28/2024,<a href='./blog/user-2024'>`openstatsware` at UseR!2024</a>
04/21/2024,<a href='./blog/new-co-chair'>New European working group co-chair</a>
04/08/2024,<a href='./blog/julia_ssd_package'>First Julia package from `openstatsware` published</a>
Expand Down
121 changes: 55 additions & 66 deletions guide.qmd
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
---
title: "openstatsguide"
subtitle: "Minimum Viable Good Practices for High Quality Statistical Software Packages"
author: "0.0-3"
author: "0.1-0"
author-title: "Version"
date: "23 Aug 2024"
date: "16 Sep 2024"
bibliography: references.bib
nocite: |
@*
csl: computational-statistics.csl
---

*Note: This is a beta release of "openstatsguide" to accompany the useR 2024 abstract submission. It is not yet available interactively via the openstatsware.org website and will undergo further expert input before publication of the first release version 0.1.*

# Scope

We encourage developers of statistical software packages to follow this minimum set of good practices around:
Expand All @@ -33,49 +31,45 @@ glue_or_drop <- function(doc, img) {
if (identical(doc, "")) {
NULL
} else {
htmltools::tags$td(
htmltools::tags$details(
htmltools::tags$summary(
htmltools::tags$img(src = img, height = 20)
),
doc
)
paste0(
"## ", htmltools::tags$img(src = img, width = 25, alt = "logo"), "\n",
paste(
paste0(
paste0("[", names(doc), "]"),
paste0("(", doc, ")")
),
collapse = "\n"
)
)
}
}
guide_table <- function(r = "", python = "", julia = "") {
contents <- htmltools::tags$html(
guide_tabset <- function(r = "", python = "", julia = "") {
contents <- paste(
"::: {.panel-tabset}",
glue_or_drop(r, "https://www.r-project.org/logo/Rlogo.svg"),
glue_or_drop(python, "https://s3.dualstack.us-east-2.amazonaws.com/pythondotorg-assets/media/files/python-logo-only.svg"),
glue_or_drop(julia, "https://raw.githubusercontent.com/JuliaLang/julia-logo-graphics/master/images/julia-dots.svg"),
sep = "\n"
)
htmltools::tags$table(
style = htmltools::css(
width = "100%"
),
htmltools::tags$tbody(contents)
":::",
sep = "\n\n"
)
cat(contents, sep = "\n\n")
}
```


## Documentation

Documentation is important for both users and developers to understand all objects in your package, without reading and interpreting the underlying source code.

1. Use **in-line comments** next to functions, classes and other objects to generate their corresponding documentation.

```{r results="asis", echo=FALSE}
guide_table(
r = htmltools::a("roxygen2", href = "https://roxygen2.r-lib.org/"),
python = htmltools::a("docstrings", href = "https://peps.python.org/pep-0257/"),
julia = htmltools::a("docstrings", href = "https://docs.julialang.org/en/v1/manual/documentation/")
guide_tabset(
r = c("roxygen2" = "https://roxygen2.r-lib.org/"),
python = c("docstrings" = "https://peps.python.org/pep-0257/"),
julia = c("docstrings" = "https://docs.julialang.org/en/v1/manual/documentation/")
)
```
2. Do also **document internal functions** and classes for maintenance by future developers.
3. Add **code comments** for ambiguous or complex pieces of internal code, but only after optimizing the code design as much as possible.
Expand All @@ -91,15 +85,13 @@ Vignettes are documents that complement the object documentation by providing a
3. Host your vignettes on a **dedicated website**, which allows users to read the vignettes without installing the package, and simplifies citing the vignettes in other publications.
```{r results="asis", echo=FALSE}
guide_table(
r = htmltools::a("pkgdown", href = "https://pkgdown.r-lib.org/"),
python = htmltools::a("Sphinx", href = "https://www.sphinx-doc.org/en/master/"),
julia = htmltools::a("Documenter", href = "https://documenter.juliadocs.org/")
guide_tabset(
r = c("pkgdown" = "https://pkgdown.r-lib.org/"),
python = c("Sphinx" = "https://www.sphinx-doc.org/en/master/"),
julia = c("Documenter" = "https://documenter.juliadocs.org/")
)
```
## Tests
Tests are a fundamental safety net and development tool to ensure that your package works as expected, both during development as well as on user systems.
Expand All @@ -109,22 +101,21 @@ Tests are a fundamental safety net and development tool to ensure that your pack
2. Write **functional tests** for all user facing functionality ("black box" testing). These tests ensure that the user API is stable when refactoring internal code.
```{r results="asis", echo=FALSE}
guide_table(
r = htmltools::a("testthat", href = "https://testthat.r-lib.org/"),
python = htmltools::a("pytest", href = "https://pytest.org/"),
julia = htmltools::a("Test", href = "https://docs.julialang.org/en/v1/stdlib/Test/")
guide_tabset(
r = c("testthat" = "https://testthat.r-lib.org/"),
python = c("pytest" = "https://pytest.org/"),
julia = c("Test" = "https://docs.julialang.org/en/v1/stdlib/Test/")
)
```
3. In addition, ensure a **good coverage** of your code with your tests as a final check, but only after having unit and functional tests on all levels of the code.
```{r results="asis", echo=FALSE}
guide_table(
r = htmltools::a("covr", href = "https://covr.r-lib.org/"),
python = htmltools::a("Coverage.py", href = "https://coverage.readthedocs.io/"),
julia = htmltools::a("Coverage.jl", href = "https://github.com/JuliaCI/Coverage.jl")
guide_tabset(
r = c("covr" = "https://covr.r-lib.org/"),
python = c("Coverage.py" = "https://coverage.readthedocs.io/"),
julia = c("Coverage.jl" = "https://github.com/JuliaCI/Coverage.jl")
)
```
Expand All @@ -137,25 +128,23 @@ Function definitions should be short, simple and enforce argument types with ass
2. Use **type hints** or types to explain to the user which argument of the function expects which type of input.
```{r results="asis", echo=FALSE}
guide_table(
r = htmltools::a("roxytypes", href = "https://openpharma.github.io/roxytypes/"),
python = htmltools::a("typing", href = "https://docs.python.org/3/library/typing.html"),
julia = htmltools::a("types", href = "https://docs.julialang.org/en/v1/manual/types/")
guide_tabset(
r = c("roxytypes" = "https://openpharma.github.io/roxytypes/"),
python = c("typing" = "https://docs.python.org/3/library/typing.html"),
julia = c("types" = "https://docs.julialang.org/en/v1/manual/types/")
)
```
3. Enforce types and other expected properties of function arguments with **assertions**, which give an early and readable error message to the user instead of failing function code downstream in a less explicable way.
```{r results="asis", echo=FALSE}
guide_table(
r = htmltools::a("checkmate", href = "https://mllg.github.io/checkmate/"),
python = htmltools::a("assertpy", href = "https://pypi.org/project/assertpy/"),
julia = htmltools::a("ArgCheck.jl", href = "https://github.com/jw3126/ArgCheck.jl")
guide_tabset(
r = c("checkmate" = "https://mllg.github.io/checkmate/"),
python = c("assertpy" = "https://pypi.org/project/assertpy/"),
julia = c("ArgCheck.jl" = "https://github.com/jw3126/ArgCheck.jl")
)
```
## Style
A consistent and readable code style that is language idiomatic should be used and enforced by style checks.
Expand All @@ -165,20 +154,20 @@ A consistent and readable code style that is language idiomatic should be used a
2. Use a **formatting tool** to automatically implement a consistent and readable code format.
```{r results="asis", echo=FALSE}
guide_table(
r = htmltools::a("styler", href = "https://styler.r-lib.org/"),
python = htmltools::a("Autopep8", href = "https://pypi.org/project/autopep8/"),
julia = htmltools::a("JuliaFormatter.jl", href = "https://domluna.github.io/JuliaFormatter.jl/")
guide_tabset(
r = c("styler" = "https://styler.r-lib.org/"),
python = c("Autopep8" = "https://pypi.org/project/autopep8/"),
julia = c("JuliaFormatter.jl" = "https://domluna.github.io/JuliaFormatter.jl/")
)
```
3. Use a **style checking** tool to enforce a consistent and readable code style.
```{r results="asis", echo=FALSE}
guide_table(
r = htmltools::a("lintr", href = "https://lintr.r-lib.org/"),
python = htmltools::a("Pylint", href = "https://pypi.org/project/pylint/"),
julia = htmltools::p("Enabled in VScode via", htmltools::a("StaticLint.jl", href = "https://github.com/julia-vscode/StaticLint.jl"))
guide_tabset(
r = c("lintr" = "https://lintr.r-lib.org/"),
python = c("Pylint" = "https://pypi.org/project/pylint/"),
julia = c("StaticLint.jl" = "https://github.com/julia-vscode/StaticLint.jl")
)
```
Expand All @@ -196,13 +185,13 @@ Life cycle management is simplified by reducing dependencies, and should compris
3. Give clear information to users about changes in the package API via maintaining the **change log** and first **deprecating functionality** before removing it.
```{r results="asis", echo=FALSE}
guide_table(
r = htmltools::p(
htmltools::a("lifecycle", href = "https://cran.r-project.org/web/packages/lifecycle/index.html"),
htmltools::a("fledge", href = "https://fledge.cynkra.com/")
guide_tabset(
r = c(
"lifecycle" = "https://cran.r-project.org/web/packages/lifecycle/index.html",
"fledge" = "https://fledge.cynkra.com/"
),
python = htmltools::a("deprecation", href = "https://deprecation.readthedocs.io/"),
julia = htmltools::a("workflow", href = "https://invenia.github.io/blog/2022/06/17/deprecating-in-julia/")
python = c("deprecation" = "https://deprecation.readthedocs.io/"),
julia = c("workflow" = "https://invenia.github.io/blog/2022/06/17/deprecating-in-julia/")
)
```
Expand Down

0 comments on commit b02b782

Please sign in to comment.