diff --git a/README.md b/README.md index 5349f23..ea05a92 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ them. | 11/19 and 11/21 | R packages II | | | | 11/26 and 11/28 (off) | Automatic Reports with GitHub Actions | [slides](https://UofUEpiBio.github.io/PHS7045-advanced-programming/15-autoreport/slides.html) ([source](https://github.com/UofUEpiBio/PHS7045-advanced-programming//tree/main/15-autoreport/slides.qmd)) | | | 12/03 and 12/05 (hybrid) | Final Prep (Hackathon) | | | -| 12/12 | Final | | | +| 12/10 (pkg) and 12/12 (talk) | Final ([Requirements](https://UofUEpiBio.github.io/PHS7045-advanced-programming/exams/final.html)) | | | ## Assignment workflow diff --git a/exams/02-final.html b/exams/02-final.html index dea0e6b..47908d3 100644 --- a/exams/02-final.html +++ b/exams/02-final.html @@ -2,7 +2,7 @@
- + @@ -19,6 +19,40 @@ width: 0.8em; margin: 0 0.8em 0.2em -1em; vertical-align: middle; } + +pre > code.sourceCode { white-space: pre; position: relative; } +pre > code.sourceCode > span { line-height: 1.25; } +pre > code.sourceCode > span:empty { height: 1.2em; } +.sourceCode { overflow: visible; } +code.sourceCode > span { color: inherit; text-decoration: inherit; } +div.sourceCode { margin: 1em 0; } +pre.sourceCode { margin: 0; } +@media screen { +div.sourceCode { overflow: auto; } +} +@media print { +pre > code.sourceCode { white-space: pre-wrap; } +pre > code.sourceCode > span { display: inline-block; text-indent: -5em; padding-left: 5em; } +} +pre.numberSource code +{ counter-reset: source-line 0; } +pre.numberSource code > span +{ position: relative; left: -4em; counter-increment: source-line; } +pre.numberSource code > span > a:first-child::before +{ content: counter(source-line); +position: relative; left: -1em; text-align: right; vertical-align: baseline; +border: none; display: inline-block; +-webkit-touch-callout: none; -webkit-user-select: none; +-khtml-user-select: none; -moz-user-select: none; +-ms-user-select: none; user-select: none; +padding: 0 4px; width: 4em; +} +pre.numberSource { margin-left: 3em; padding-left: 4px; } +div.sourceCode +{ } +@media screen { +pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; } +} @@ -36,7 +70,49 @@ composed: false, }); +const layoutMarginEls = () => { + // Find any conflicting margin elements and add margins to the + // top to prevent overlap + const marginChildren = window.document.querySelectorAll( + ".column-margin.column-container > *, .margin-caption, .aside" + ); + + let lastBottom = 0; + for (const marginChild of marginChildren) { + if (marginChild.offsetParent !== null) { + // clear the top margin so we recompute it + marginChild.style.marginTop = null; + const top = marginChild.getBoundingClientRect().top + window.scrollY; + if (top < lastBottom) { + const marginChildStyle = window.getComputedStyle(marginChild); + const marginBottom = parseFloat(marginChildStyle["marginBottom"]); + const margin = lastBottom - top + marginBottom; + marginChild.style.marginTop = `${margin}px`; + } + const styles = window.getComputedStyle(marginChild); + const marginTop = parseFloat(styles["marginTop"]); + lastBottom = top + marginChild.getBoundingClientRect().height + marginTop; + } + } +}; + window.document.addEventListener("DOMContentLoaded", function (_event) { + // Recompute the position of margin elements anytime the body size changes + if (window.ResizeObserver) { + const resizeObserver = new window.ResizeObserver( + throttle(() => { + layoutMarginEls(); + if ( + window.document.body.getBoundingClientRect().width < 990 && + isReaderMode() + ) { + quartoToggleReader(); + } + }, 50) + ); + resizeObserver.observe(window.document.body); + } + const tocEl = window.document.querySelector('nav.toc-active[role="doc-toc"]'); const sidebarEl = window.document.getElementById("quarto-sidebar"); const leftTocEl = window.document.getElementById("quarto-sidebar-toc-left"); @@ -83,7 +159,7 @@ if (link.href.indexOf("#") !== -1) { const anchor = link.href.split("#")[1]; const heading = window.document.querySelector( - `[data-anchor-id=${anchor}]` + `[data-anchor-id="${anchor}"]` ); if (heading) { // Add the class @@ -123,8 +199,10 @@ window.innerHeight + window.pageYOffset >= window.document.body.offsetHeight ) { + // This is the no-scroll case where last section should be the active one sectionIndex = 0; } else { + // This finds the last section visible on screen that should be made active sectionIndex = [...sections].reverse().findIndex((section) => { if (section) { return window.pageYOffset >= section.offsetTop - sectionMargin; @@ -306,6 +384,7 @@ for (const child of el.children) { child.style.opacity = 0; child.style.overflow = "hidden"; + child.style.pointerEvents = "none"; } nexttick(() => { @@ -347,6 +426,7 @@ const clone = child.cloneNode(true); clone.style.opacity = 1; + clone.style.pointerEvents = null; clone.style.display = null; toggleContents.append(clone); } @@ -421,6 +501,7 @@ for (const child of el.children) { child.style.opacity = 1; child.style.overflow = null; + child.style.pointerEvents = null; } const placeholderEl = window.document.getElementById( @@ -462,32 +543,6 @@ }; }; - // Find any conflicting margin elements and add margins to the - // top to prevent overlap - const marginChildren = window.document.querySelectorAll( - ".column-margin.column-container > * " - ); - - const layoutMarginEls = () => { - let lastBottom = 0; - for (const marginChild of marginChildren) { - if (marginChild.offsetParent !== null) { - // clear the top margin so we recompute it - marginChild.style.marginTop = null; - const top = marginChild.getBoundingClientRect().top + window.scrollY; - if (top < lastBottom) { - const margin = lastBottom - top; - marginChild.style.marginTop = `${margin}px`; - } - const styles = window.getComputedStyle(marginChild); - const marginTop = parseFloat(styles["marginTop"]); - lastBottom = - top + marginChild.getBoundingClientRect().height + marginTop; - } - } - }; - nexttick(layoutMarginEls); - const tabEls = document.querySelectorAll('a[data-bs-toggle="tab"]'); for (const tabEl of tabEls) { const id = tabEl.getAttribute("data-bs-target"); @@ -497,7 +552,6 @@ ); if (columnEl) tabEl.addEventListener("shown.bs.tab", function (event) { - const el = event.srcElement; if (el) { const visibleCls = `${el.id}-margin-content`; @@ -755,6 +809,7 @@ // Process the collapse state if this is an UL if (el.tagName === "UL") { if (tocOpenDepth === -1 && depth > 1) { + // toc-expand: false el.classList.add("collapse"); } else if ( depth <= tocOpenDepth || @@ -773,10 +828,9 @@ }; // walk the TOC and expand / collapse any items that should be shown - if (tocEl) { - walk(tocEl, 0); updateActiveLink(); + walk(tocEl, 0); } // Throttle the scroll event and walk peridiocally @@ -795,6 +849,10 @@ window.addEventListener( "resize", throttle(() => { + if (tocEl) { + updateActiveLink(); + walk(tocEl, 0); + } if (!isReaderMode()) { hideOverlappedSidebars(); } @@ -915,10 +973,10 @@ } - + - - + @@ -2984,38 +3097,38 @@There are two due dates: Thursday, May 2nd (presentation) and May 4th (R package), 2023.
+The R package is due by the end of Tuesday December 10th.
+The in-class presentation will be Thursday, December 12th.
This will be an extension of the package submitted for the midterm. The new component will be agreed upon on the week of April 17th.
+Expand upon midterm project with a new component and create an R package. The new component will be agreed upon on by Thursday November 21.
The presentation (May 2nd):
-The time allocation will be the same as the midterm (7 minutes).
It Should be presented with slides (PowerPoint/quarto::revealjs/google slides/etc.)
It should have the following structure (roughly):
-Review of the problem which highlights the issue or “why” the problem needs solving (may consider including visuals to highlight the issue; ~2 slides)
Overview of the package until the midterm (~1 slide)
The new feature of the package (~ 1 slide each)
Problem/motive
Solution
Example
Grading will be based on the following:
+The presentation:
+The R package (May 4th ):
-Add a new function/feature to the R package using parallel computing or Rcpp
(a must.)
The package should pass R CMD check
s using macOS, Ubuntu, and Windows for the R release and development versions (x6 R CMD check
s). Notes are OK, but warnings are not.
The package should pass the R CMD check
on Ubuntu using the R release version with the option --as-cran
(more strict R CMD check
.)
The R package:
+The grade will be based on clear communication and coding.
+You can install this package from the source using the following commands from the command line:
+R CMD build .
+R CMD INSTALL egpkg2024_1.0.tar.gz
The first command builds a tar.gz file that can be shared. This is what you share when you submit to CRAN. The second command installs the package in your computer. Notice that this approach builds the vignettes, making them available to your R session. Recall you can access vignettes using the vignette
command like this:
vignette(package="dplyr")
Which will list the vignettes available to the dplyr R package (learn more typing ?vignette
in your R console).