<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://info.stat.cmu.edu/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Skipper</id>
	<title>Stat DS Computing Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://info.stat.cmu.edu/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Skipper"/>
	<link rel="alternate" type="text/html" href="https://info.stat.cmu.edu/index.php?title=Special:Contributions/Skipper"/>
	<updated>2026-11-05T01:34:23Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.9</generator>
	<entry>
		<id>https://info.stat.cmu.edu/index.php?title=ACCESS&amp;diff=337</id>
		<title>ACCESS</title>
		<link rel="alternate" type="text/html" href="https://info.stat.cmu.edu/index.php?title=ACCESS&amp;diff=337"/>
		<updated>2025-09-03T03:22:53Z</updated>

		<summary type="html">&lt;p&gt;Skipper: Replaced content with &amp;quot;This will shortly be updated to add easy access to ACCESS On-Ramps: &amp;lt;div id=&amp;quot;resource-catalog-react&amp;quot;&amp;gt;&amp;lt;/div&amp;gt; &amp;lt;noscript&amp;gt;This page loads an interactive catalog that requires...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This will shortly be updated to add easy access to ACCESS On-Ramps: &amp;lt;div id=&amp;quot;resource-catalog-react&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;noscript&amp;gt;This page loads an interactive catalog that requires JavaScript.&amp;lt;/noscript&amp;gt;&lt;/div&gt;</summary>
		<author><name>Skipper</name></author>
	</entry>
	<entry>
		<id>https://info.stat.cmu.edu/index.php?title=MediaWiki:Common.js&amp;diff=336</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://info.stat.cmu.edu/index.php?title=MediaWiki:Common.js&amp;diff=336"/>
		<updated>2025-09-03T03:22:13Z</updated>

		<summary type="html">&lt;p&gt;Skipper: Created page with &amp;quot;/* Any JavaScript here will be loaded for all users on every page load. */ // Load Bootstrap Icons CSS (site-wide) (function () {   if (document.getElementById(&amp;#039;bi-cdn-link&amp;#039;))...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* Any JavaScript here will be loaded for all users on every page load. */&lt;br /&gt;
// Load Bootstrap Icons CSS (site-wide)&lt;br /&gt;
(function () {&lt;br /&gt;
  if (document.getElementById(&#039;bi-cdn-link&#039;)) return;&lt;br /&gt;
  var link = document.createElement(&#039;link&#039;);&lt;br /&gt;
  link.id = &#039;bi-cdn-link&#039;;&lt;br /&gt;
  link.rel = &#039;stylesheet&#039;;&lt;br /&gt;
  link.href = &#039;https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css&#039;;&lt;br /&gt;
  document.head.appendChild(link);&lt;br /&gt;
})();&lt;br /&gt;
&lt;br /&gt;
// ACCESS On-Ramps embed via ES module, mounted when placeholder div is present&lt;br /&gt;
(function () {&lt;br /&gt;
  function mountOnRamps() {&lt;br /&gt;
    var target = document.getElementById(&#039;resource-catalog-react&#039;);&lt;br /&gt;
    if (!target) return; // Only act on pages that have the placeholder&lt;br /&gt;
&lt;br /&gt;
    // Build a &amp;lt;script type=&amp;quot;module&amp;quot;&amp;gt; that mirrors ACCESS instructions&lt;br /&gt;
    var script = document.createElement(&#039;script&#039;);&lt;br /&gt;
    script.type = &#039;module&#039;;&lt;br /&gt;
    script.textContent = `&lt;br /&gt;
      const baseUrl = &amp;quot;https://esm.sh/@xras/ui@onramps_v1/dist&amp;quot;;&lt;br /&gt;
      import {&lt;br /&gt;
        onRampsResourceCatalog,&lt;br /&gt;
        shadowTarget,&lt;br /&gt;
      } from &amp;quot;https://esm.sh/@xras/ui@onramps_v1/dist/xras-ui.js&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
      onRampsResourceCatalog({&lt;br /&gt;
        target: shadowTarget(&lt;br /&gt;
          document.getElementById(&amp;quot;resource-catalog-react&amp;quot;),&lt;br /&gt;
          { accessStyles: true, baseUrl }&lt;br /&gt;
        ),&lt;br /&gt;
        onRamps: true,&lt;br /&gt;
        baseUrl&lt;br /&gt;
      });&lt;br /&gt;
    `;&lt;br /&gt;
    document.body.appendChild(script);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Run after the page is ready (and after MediaWiki’s JS pipelines)&lt;br /&gt;
  if (document.readyState === &#039;loading&#039;) {&lt;br /&gt;
    document.addEventListener(&#039;DOMContentLoaded&#039;, mountOnRamps);&lt;br /&gt;
  } else {&lt;br /&gt;
    mountOnRamps();&lt;br /&gt;
  }&lt;br /&gt;
})();&lt;/div&gt;</summary>
		<author><name>Skipper</name></author>
	</entry>
	<entry>
		<id>https://info.stat.cmu.edu/index.php?title=ACCESS&amp;diff=335</id>
		<title>ACCESS</title>
		<link rel="alternate" type="text/html" href="https://info.stat.cmu.edu/index.php?title=ACCESS&amp;diff=335"/>
		<updated>2025-09-03T03:18:38Z</updated>

		<summary type="html">&lt;p&gt;Skipper: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
The&amp;amp;nbsp;NSF’s&amp;amp;nbsp;ACCESS&amp;amp;nbsp;(Advanced Cyberinfrastructure Coordination Ecosystem: Services &amp;amp; Support) program builds upon the successes of the 11-year&amp;amp;nbsp;XSEDE&amp;amp;nbsp;project.&lt;br /&gt;
&lt;br /&gt;
NSF funded supercomputers, like PSC are available via the ACCESS federated system. &amp;amp;nbsp;Besides parallel or memory-intensive computing options, there are many GPU resources available to ACCESS users via the Credit Marketplace.&lt;br /&gt;
&lt;br /&gt;
#If you are a Graduate Student, all you need is&amp;amp;nbsp;&#039;&#039;&#039;an account&#039;&#039;&#039;,&#039;&#039;&#039;&amp;amp;nbsp;&#039;&#039;&#039;your&#039;&#039;&#039;&amp;amp;nbsp;CV&#039;&#039;&#039;, a&amp;amp;nbsp;&#039;&#039;&#039;1-paragraph abstract&#039;&#039;&#039;&amp;amp;nbsp;and&amp;amp;nbsp;&#039;&#039;&#039;a letter from your advisor&#039;&#039;&#039;. &amp;amp;nbsp;(Carl has a template letter your advisor can sign.) With these 4 items, you can complete a simple form and get up to 400,000 CPU-hours to exchange for access to most of the nation&#039;s supercomputing cyberinfrastructure. Check out the following [https://allocations.access-ci.org/preparing-your-explore-access-request link].&lt;br /&gt;
#If you previously held an XSEDE account, you can login here:&amp;amp;nbsp;[https://identity.access-ci.org/new-user-federated https://identity.access-ci.org/new-user-federated]&amp;amp;nbsp;and complete your account transition from XSEDE to ACCESS by selecting “ACCESS CI (XSEDE)” and subsequently login using Andrew Web Login. &amp;amp;nbsp;You will then be guided through a short verification process similar to any other website.&amp;amp;nbsp;&lt;br /&gt;
#If you are&amp;amp;nbsp;&#039;&#039;&#039;new&#039;&#039;&#039;&amp;amp;nbsp;to the department or supercomputing in general,&amp;amp;nbsp;I set up a new account so you will be able to access (no pun intended) these resources easily now or in the future. &amp;amp;nbsp;Visit&amp;amp;nbsp;[https://identity.access-ci.org/new-user-federated https://identity.access-ci.org/new-user-federated]&amp;amp;nbsp;to set up a new account - &amp;amp;nbsp;make sure to choose “&#039;&#039;&#039;Carnegie Mellon University&#039;&#039;&#039;”!&amp;amp;nbsp;&lt;br /&gt;
#The interface to the Supercomputing Credit Market is still being improved, but we are working on documentation to address that.&lt;br /&gt;
&lt;br /&gt;
This will shortly be updated to add easy access to ACCESS On-Ramps: &amp;lt;div id=&amp;quot;resource-catalog-react&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;noscript&amp;gt;This page loads an interactive catalog that requires JavaScript.&amp;lt;/noscript&amp;gt;&lt;/div&gt;</summary>
		<author><name>Skipper</name></author>
	</entry>
	<entry>
		<id>https://info.stat.cmu.edu/index.php?title=Parallelization_in_python&amp;diff=202</id>
		<title>Parallelization in python</title>
		<link rel="alternate" type="text/html" href="https://info.stat.cmu.edu/index.php?title=Parallelization_in_python&amp;diff=202"/>
		<updated>2025-05-16T14:46:25Z</updated>

		<summary type="html">&lt;p&gt;Skipper: Replaced incorrectly migrated page with correct content.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;This article is still being developed - released earlier to align with Department seminar.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In python, parallelization is a bit more of a “wild west” in terms of the number of packages that can help you parallelize your processes (for a long . This wiki will attempt to present minor examples of some along with an outline of things to think about in selecting the library you end up using. In general, the process in python involves&lt;br /&gt;
&lt;br /&gt;
# defining a function that captures what you want to have parallelized&lt;br /&gt;
# call that function repeatedly in the the parallelization package way (which often looks like a list-recursive call).&lt;br /&gt;
&lt;br /&gt;
There are a few different general frameworks to accomplish this.&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;general wrappers&#039;&#039;&#039;, define the cores you’ll be using and then wrap that around the function call in a list-recursive way&lt;br /&gt;
# &#039;&#039;&#039;just in time compilers&#039;&#039;&#039;, in addition to providing parallelization tools these packages provide decorators (e.g. &amp;lt;code&amp;gt;@jit&amp;lt;/code&amp;gt;) for functions that allow for just in time compilation of the python function into lower level machine code (like &amp;lt;code&amp;gt;C++&amp;lt;/code&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
We will discuss a python package that is build specifically to parallelize jobs inside &#039;&#039;&#039;jupyter notebooks&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
= Non-parallelized: single core example =&lt;br /&gt;
&lt;br /&gt;
We naturally want to compare a parallelization approach with the base single core analysis, which can be done with the code as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;#base for-loop&lt;br /&gt;
import numpy as np&lt;br /&gt;
from sklearn.linear_model import LinearRegression&lt;br /&gt;
&lt;br /&gt;
my_k = list(np.arange(14)+1)*20&lt;br /&gt;
&lt;br /&gt;
def my_simulation(k):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    estamine the polynomial fit of degree k&#039;s MSE for a linear&lt;br /&gt;
    relationship&lt;br /&gt;
&lt;br /&gt;
    Parameters&lt;br /&gt;
    ----------&lt;br /&gt;
    k : int&lt;br /&gt;
    degree of polynomial fit&lt;br /&gt;
&lt;br /&gt;
    Returns&lt;br /&gt;
    -------&lt;br /&gt;
    mse of fit based on 30 points applied to a test set of 10000 points&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    x = np.random.uniform(size=30,low=-3,high=3)&lt;br /&gt;
    y = 2*x + 2* np.random.normal(size=30)&lt;br /&gt;
    y = y.reshape(-1,1)&lt;br /&gt;
    X_poly = np.concatenate([x.reshape(-1,1)**kk&lt;br /&gt;
                          for kk in np.arange(1,k+1,dtype = int)],&lt;br /&gt;
                          axis = 1)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    x0 = np.random.uniform(size=10000,low=-3,high=3)&lt;br /&gt;
    y0 = 2*x0 + 2*np.random.normal(size=10000)&lt;br /&gt;
    y0 = y0.reshape(-1,1)&lt;br /&gt;
    X0_poly = np.concatenate([x0.reshape(-1,1)**kk&lt;br /&gt;
                          for kk in np.arange(1,k+1,dtype = int)],&lt;br /&gt;
                          axis = 1)&lt;br /&gt;
&lt;br /&gt;
    my_lm = LinearRegression().fit(X_poly,y)&lt;br /&gt;
    y0_hat = my_lm.predict(X0_poly)&lt;br /&gt;
&lt;br /&gt;
    return(np.mean((y0-y0_hat)**2))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;%%timeit -n3&lt;br /&gt;
&lt;br /&gt;
[my_simulation(k) for k in my_k]&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;676 ms ± 37.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
= General python parallelization packages =&lt;br /&gt;
&lt;br /&gt;
As mentioned there are a lot of package to do general parallelization. Two commonly used ones are &amp;lt;code&amp;gt;joblib&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;multiprocessing&amp;lt;/code&amp;gt;. &amp;lt;code&amp;gt;joblib&amp;lt;/code&amp;gt; looks a bit more like list-recursion and &amp;lt;code&amp;gt;multiprocessing&amp;lt;/code&amp;gt; uses functions like &amp;lt;code&amp;gt;.map()&amp;lt;/code&amp;gt;. &amp;lt;code&amp;gt;multiprocessing&amp;lt;/code&amp;gt; can have problems with &amp;lt;code&amp;gt;ipython&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;jupyter notebook&amp;lt;/code&amp;gt;s (though &amp;lt;code&amp;gt;joblib&amp;lt;/code&amp;gt; wraps it and &amp;lt;code&amp;gt;multiprocess&amp;lt;/code&amp;gt; is just a different fork of &amp;lt;code&amp;gt;multiprocessing&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;code&amp;gt;multiprocessing&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;multiprocess&amp;lt;/code&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;multiprocessing&amp;lt;/code&amp;gt; package is actually built into python, and works in a pretty straightforward manner. It also allows for synchronous vs asynchronous parallelization, where synchronous means the order of the jobs must be followed and asynchronous where the order of jobs need not be followed. Many statistical uses of parallelization does not need synchronous parallelization.&lt;br /&gt;
&lt;br /&gt;
There since both approaches have the same syntax we’ll be using &amp;lt;code&amp;gt;multiprocess&amp;lt;/code&amp;gt; (as it works with &amp;lt;code&amp;gt;ipython&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;jupyter notebooks&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
=== parallelization ===&lt;br /&gt;
&lt;br /&gt;
First, you need to identify the number of cores you have:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;import multiprocess as mp&lt;br /&gt;
#import multiprocessing as mp&lt;br /&gt;
&lt;br /&gt;
num_cores = mp.cpu_count()&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==== synchronous ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;%%timeit&lt;br /&gt;
&lt;br /&gt;
with mp.Pool(processes=num_cores-2) as p:&lt;br /&gt;
  results = p.map(my_simulation, my_k)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;209 ms ± 24.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==== asynchronous ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;%%timeit&lt;br /&gt;
&lt;br /&gt;
with mp.Pool(processes=num_cores-2) as p:&lt;br /&gt;
    results = p.map_async(my_simulation, my_k).get() # not clear why I needed to use .get() to get something returnable for async&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;48.9 ms ± 3.08 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
== &amp;lt;code&amp;gt;joblib&amp;lt;/code&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;joblib&amp;lt;/code&amp;gt; package is pretty straightforward and requires you to structure things in terms of list-recursion with a few wrappers to help the process work as desired.&lt;br /&gt;
&lt;br /&gt;
=== setup ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;import joblib&lt;br /&gt;
&lt;br /&gt;
num_cores = joblib.cpu_count()&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== implimentation ===&lt;br /&gt;
&lt;br /&gt;
To use &amp;lt;code&amp;gt;joblib&amp;lt;/code&amp;gt; functionality we can import the functions &amp;lt;code&amp;gt;Parallel&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;delayed&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;from joblib import Parallel, delayed&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
We then can move our list-recursive example into our &amp;lt;code&amp;gt;joblib&amp;lt;/code&amp;gt; structure. We wrap &amp;lt;code&amp;gt;Parallel(...)()&amp;lt;/code&amp;gt; around the old of the inside of the list-recursion and &amp;lt;code&amp;gt;delayed()&amp;lt;/code&amp;gt; around the functions that will be repeated multiple times.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;%% timeit&lt;br /&gt;
&lt;br /&gt;
r = Parallel(n_jobs=num_cores-2)(delayed(my_simulation)(k) for k in my_k)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;172 ms ± 23.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Add-ons ===&lt;br /&gt;
&lt;br /&gt;
There are multiple add-ons that can be desirable&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: decimal;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;&#039;&#039;&#039;verbosity&#039;&#039;&#039; can be added with a single parameter use (as seen below) - the large the value, the more messages:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;r = Parallel(n_jobs=num_cores-2, verbose=10)(delayed(my_simulation)(k) for k in my_k)&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;&#039;&#039;&#039;multiple parameters&#039;&#039;&#039; can be passed with redefinitions of functions to take groupings. To replace multiple for-loops often the function &amp;lt;code&amp;gt;itertools.product()&amp;lt;/code&amp;gt; is used for the parameters.&amp;lt;/p&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Just in Time compilers + parallelization =&lt;br /&gt;
&lt;br /&gt;
TODO: &amp;lt;code&amp;gt;numba&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;cython&amp;lt;/code&amp;gt;. The idea of these is to compile the function you will be using the first time you use it and then never compile it again (speeding up the actual use of the function). That is then combined with standard parallelization&lt;br /&gt;
&lt;br /&gt;
= Jupyter notebook: &amp;lt;code&amp;gt;ipyparallel&amp;lt;/code&amp;gt; =&lt;br /&gt;
&lt;br /&gt;
For those that heavily use jupyter notebooks and nothing else (which this author personally doesn’t encourage), the package &amp;lt;code&amp;gt;ipyparallel&amp;lt;/code&amp;gt; nicely works inside jupyter notebooks (but so does many of the other packages above like &amp;lt;code&amp;gt;joblib&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;multiprocess&amp;lt;/code&amp;gt;, etc.). One nice this about this package is the verbosity, etc. works intellegently in the notebook. This package also works with &amp;lt;code&amp;gt;numba.jit&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;cython&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Before opening your &amp;lt;code&amp;gt;jupyter notebook&amp;lt;/code&amp;gt; you’ll want to make sure the extension is enabled - which can be down from the command line with the following command or inside the &amp;lt;code&amp;gt;jupyter notebook&amp;lt;/code&amp;gt; extensions tab.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;ipcluster nbextension enable&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
And then you’ll need to go to the “IPython Clusters” tab in &amp;lt;code&amp;gt;jupyter noteook&amp;lt;/code&amp;gt; and start some parallel clusters.&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;code&amp;gt;ipyparallel&amp;lt;/code&amp;gt; parallelization ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;import ipyparallel as ipp&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
For direct execution we define &amp;lt;code&amp;gt;dv&amp;lt;/code&amp;gt; and provide it with what it needs…&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;rc = ipp.Client()&lt;br /&gt;
dv = rc[:] # direct view&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== passing things to each cluster ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ipyparallel&amp;lt;/code&amp;gt; provides ways for the user to pass only the necessary items to the the clusters (as to not overload the clusters with too many things).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: decimal;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;passing packages all together&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;with dv.sync_imports():&lt;br /&gt;
    from sklearn.linear_model import LinearRegression&lt;br /&gt;
    # getting dependencies on the clusters&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;passing variable over:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Below is just an example - we don’t need to pass &amp;lt;code&amp;gt;my_k&amp;lt;/code&amp;gt; since &amp;lt;code&amp;gt;dv&amp;lt;/code&amp;gt; will directly get it when we wnat to use it.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;dv[&amp;quot;my_k&amp;quot;] = my_k&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;we can also use the &amp;lt;code&amp;gt;%px&amp;lt;/code&amp;gt; magick to run lines of code on all servers. Given I think &amp;lt;code&amp;gt;numpy&amp;lt;/code&amp;gt; is cooler as &amp;lt;code&amp;gt;np&amp;lt;/code&amp;gt; I actually have to do it this way, not the &amp;lt;code&amp;gt;dv.sync_imports&amp;lt;/code&amp;gt; way.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;%px import numpy as np&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== actual functionality ===&lt;br /&gt;
&lt;br /&gt;
The actual functionality is very similar to &amp;lt;code&amp;gt;multiprocess&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;multiprocessing&amp;lt;/code&amp;gt; with &amp;lt;code&amp;gt;maps&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;apply&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== synchronous ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;%%timeit&lt;br /&gt;
results = dv.map_sync(my_simulation, my_k)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;201 ms ± 34.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==== asynchronous ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;%%timeit&lt;br /&gt;
results = dv.map_async(my_simulation, my_k).get() # not clear why I needed to use .get() to get something returnable for async&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;209 ms ± 28.1 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
= additional topics and resources =&lt;br /&gt;
&lt;br /&gt;
# [https://ray.io/ &amp;lt;code&amp;gt;Ray&amp;lt;/code&amp;gt; python package] allows paralleilization across multiple computers&lt;br /&gt;
# [https://people.duke.edu/~ccc14/sta-663-2018/notebooks/S14A_Parallel_Programming_Introduction.html Duke’s statistical computing course] provides a set of examples for multiple python parallelization packages |&lt;/div&gt;</summary>
		<author><name>Skipper</name></author>
	</entry>
	<entry>
		<id>https://info.stat.cmu.edu/index.php?title=Main_Page&amp;diff=194</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://info.stat.cmu.edu/index.php?title=Main_Page&amp;diff=194"/>
		<updated>2025-02-24T15:37:26Z</updated>

		<summary type="html">&lt;p&gt;Skipper: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Anyone can read this wiki. &amp;amp;nbsp;If you want to write/edit stuff in the wiki, you will need to log in with your account provided by the Statistics &amp;amp; Data Science Department computing group. This Wiki is intended to be a repository for instruction, information and ideas related to the many computing environments available to members and affiliates of the Statistics &amp;amp; Data Science Department.&lt;br /&gt;
&lt;br /&gt;
== Getting to know the computing resources &amp;amp; getting support ==&lt;br /&gt;
&lt;br /&gt;
If you&#039;re interested in knowing about what resources you have access to (and/or) what resources you have access to that might solve a problem you&#039;re having, please visit our [[What_resources_when|&amp;quot;what resources when&amp;quot; article]].&lt;br /&gt;
&lt;br /&gt;
To get support that is beyond this website please attend office hours below and/or email [mailto:remarks@stat.cmu.edu remarks@stat.cmu.edu] for support (for more details about how the support ticketing works through [mailto:remarks@stat.cmu.edu remarks@stat.cmu.edu] + ServiceNow please see the [[Service_now|ServiceNow]] article).&lt;br /&gt;
&lt;br /&gt;
Reset your StatDS password here - https://util.stat.cmu.edu/passwordreset/&lt;br /&gt;
&lt;br /&gt;
== Department Contacts ==&lt;br /&gt;
&lt;br /&gt;
• [mailto:events@stat.cmu.edu events@stat.cmu.edu]: seminars, conferences &amp;amp; workshops, and calendar updates&lt;br /&gt;
&lt;br /&gt;
• [mailto:news@stat.cmu.edu news@stat.cmu.edu]: dept/dept member-related public news &amp;amp; announcements&lt;br /&gt;
&lt;br /&gt;
• [mailto:lists@stat.cmu.edu lists@stat.cmu.edu]: department email lists&lt;br /&gt;
&lt;br /&gt;
• [mailto:webmaster@stat.cmu.edu webmaster@stat.cmu.edu]: website updates&lt;br /&gt;
&lt;br /&gt;
• [mailto:remarks@stat.cmu.edu remarks@stat.cmu.edu]: computer/tech requests&lt;br /&gt;
&lt;br /&gt;
• [mailto:rooms@stat.cmu.edu rooms@stat.cmu.edu]: request space for TA office hours&lt;br /&gt;
&lt;br /&gt;
• [mailto:reimbursements@stat.cmu.edu reimbursements@stat.cmu.edu]: travel and reimbursement requests&lt;br /&gt;
&lt;br /&gt;
== Computing Office Hours ==&lt;br /&gt;
&lt;br /&gt;
These office hour opportunities provide a dedicated time for you to come ask questions about research computing.&amp;amp;nbsp; These include code advice, how to access certain resources, what the best resources are for your project, or to learn about new connections to help you progress in your education and research. Staff Office hour times will be sent out each week on Monday as a calendar invite; accept any of the invitations to add it to your personal calendar. PhD TA Office Hours are below, unless a different time is&amp;amp;nbsp;communicated.&lt;br /&gt;
&lt;br /&gt;
#PhD TA Office Hours are held by Alex Shen in Baker 136E on Tuesdays from 3 pm to 5 pm&lt;br /&gt;
#Staff Office Hours are held by appointment  by Carl Skipper in BH 129G.  Schedule via [mailto:lists@stat.cmu.edu email].&lt;br /&gt;
&lt;br /&gt;
See [[Computing_office_hour_usage|computing office hour usage]] for what office hours can be used for.&lt;br /&gt;
&lt;br /&gt;
== Computing Wiki Pages ==&lt;br /&gt;
&lt;br /&gt;
=== General Computing (personal computing) ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Printing&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*[[Department_Printers|Department Printers]] &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Virtual environments&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
#[[Virtual Environment Introduction|Why use virtual environments?]]&lt;br /&gt;
#R&#039;s [[Renv]]&lt;br /&gt;
#Python&#039;s [[Python_virtual_environments|virtual environments (2 options)]] &lt;br /&gt;
#Old instructions for [[Conda with Python (Reference Only)|conda with Python]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[[Parallel_computing|Parallelization]]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
#[[Parallelization_in_r|R-specific parallelization]] &lt;br /&gt;
#[[Parallelization_in_python|Python-specific parallelization]] &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Package development&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
#[[Developing_R_packages|R package development]] &lt;br /&gt;
#[[Developing_python_packages|Python package development]] &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Version Control&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
See the guide provided in the site of [https://36-750.github.io/tools/version-control/ 36750 - Statistical Computing]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Reference management&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
#Zotero &lt;br /&gt;
#Mendeley &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Integrated Development Environments (IDEs)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
#[[VSCode|VSCode]] &lt;br /&gt;
#PyCharm &lt;br /&gt;
#RStudio &lt;br /&gt;
#Eclipse &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Containers&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
#[[Introduction_to_containers|Introduction to containers]] &lt;br /&gt;
#[[Docker,_and_why-you-should-use-it-for-your-research|Docker, and why-you-should-use-it-for-your-research]] &lt;br /&gt;
#[[Tutorials|Basic tutorial]] &lt;br /&gt;
#[[Running_Docker_locally_and_on_Hydras|Running Docker locally and on Hydras]] &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Text Editors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
#Vim &lt;br /&gt;
#Nano &lt;br /&gt;
#Emacs &lt;br /&gt;
#Atom &lt;br /&gt;
#Sublime &lt;br /&gt;
&lt;br /&gt;
See also the guide provided in the site of [https://36-750.github.io/tools/editors/ 36750 - Statistical Computing]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Web Hosting&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
#[[How_to_host_your_webpage_under_stat.cmu.edu|How to host your webpage under stat.cmu.edu]] &lt;br /&gt;
#[[Bulding_your_website_with_Hugo|Bulding your website with Hugo]] &lt;br /&gt;
&#039;&#039;&#039;AI Tools&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* [[ChatGPT and other LLMs]]&lt;br /&gt;
&lt;br /&gt;
*[[github_copilot|GitHub Copilot]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Miscellanea&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
#[[Windows_Subsystem_for_Linux_(WSL)_and_Python|Windows&amp;amp;nbsp;Subsystem for Linux (WSL) and Python]] &lt;br /&gt;
#[[Amphetamine|Amphetamine: How to keep your computer awake]] &lt;br /&gt;
&lt;br /&gt;
=== General Department Computing Resources ===&lt;br /&gt;
&lt;br /&gt;
*Fall 2021 [[Computing_seminar_resources|Computing Seminar Resources]] (video and slides) &lt;br /&gt;
*[[Linux_and_department_servers|Department Servers]]. This wiki introduces you to the &#039;&#039;&#039;hydra&#039;&#039;&#039; servers, basic Linux commands, and more. &lt;br /&gt;
*#[[Terminal_multiplexers|Terminal multiplexers (screen and tmux)]]. This wiki presents tools for use on the &#039;&#039;hydra&#039;&#039; that can allow you to run jobs even when your not on the server, and much much more! &lt;br /&gt;
*#[[Python_on_the_server|Python on the server]]. This wiki introduces uses command line approaches to running &amp;lt;code&amp;gt;python&amp;lt;/code&amp;gt; on a virtual machine, and how to use jupyter notebooks through the server as well. &lt;br /&gt;
*#[[R_on_the_server|R on the server]]. This wiki introduces uses command line approaches to running &amp;lt;code&amp;gt;R&amp;lt;/code&amp;gt; on a virtual machine. &lt;br /&gt;
*#[[Terminal_automation|Terminal automation]]. This wiki introduces approaches to automate Linux/OS command line calls. &lt;br /&gt;
*##[[Bash_files|Bash files]]. This wiki presents potential uses of Bash files including automated file/folder creation, parallelization and much more! &lt;br /&gt;
*##[[Make|Make]]. This wiki presents potential uses of &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; and Makefiles including automated workflow and dependency tracking &lt;br /&gt;
*##[[Jumping_to_frequently_used_folders_and_automating_environment_setups|Jumping to frequently used folders and automating environment setups]] &lt;br /&gt;
&lt;br /&gt;
*[[Department_GPU_Servers|Department GPU Servers]] &lt;br /&gt;
*[[GPU_Cluster|GPU Cluster]] &lt;br /&gt;
*[[PSC|PSC]] &lt;br /&gt;
*#[[ACCESS|ACCESS]] &lt;br /&gt;
*#[[Slurm|Slurm]]. This wiki introduces the job management system uses at PSC. &lt;br /&gt;
*#[[Parallelization_on_PSC/Bridges-2|Parallelization_on_PSC/Bridges-2]] &lt;br /&gt;
*#[[Access_PSC_compute_nodes_directly_from_VSCode|Access PSC compute nodes directly from VSCode]] &lt;br /&gt;
&lt;br /&gt;
*Azure &lt;br /&gt;
*#[[Azure_getting_started|Azure: getting started]]. This wiki walks you through the steps to create a virtual machine through Azure &lt;br /&gt;
*#[[How_to_obtain_a_virtual_machine_with_a_GPU|How to obtain a virtual machine with a GPU]] &lt;br /&gt;
*#[[Attach_a_disk_to_a_virtual_machine|Attach a disk to a virtual machine]] &lt;br /&gt;
&lt;br /&gt;
== Ideas for the Wiki ==&lt;br /&gt;
&lt;br /&gt;
Please see the [[TODO|TODO page]] to post suggestions and errata.&lt;br /&gt;
&lt;br /&gt;
== Using the Wiki ==&lt;br /&gt;
&lt;br /&gt;
*Here is some&amp;amp;nbsp;[[Generic_Wiki_Information|Generic Wiki Information]]&amp;amp;nbsp;that you may be interested in, such as a users&#039; guide and other resources for Wiki users.&lt;/div&gt;</summary>
		<author><name>Skipper</name></author>
	</entry>
	<entry>
		<id>https://info.stat.cmu.edu/index.php?title=Main_Page&amp;diff=193</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://info.stat.cmu.edu/index.php?title=Main_Page&amp;diff=193"/>
		<updated>2025-02-24T15:37:00Z</updated>

		<summary type="html">&lt;p&gt;Skipper: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Anyone can read this wiki. &amp;amp;nbsp;If you want to write/edit stuff in the wiki, you will need to log in with your account provided by the Statistics &amp;amp; Data Science Department computing group. This Wiki is intended to be a repository for instruction, information and ideas related to the many computing environments available to members and affiliates of the Statistics &amp;amp; Data Science Department.&lt;br /&gt;
&lt;br /&gt;
== Getting to know the computing resources &amp;amp; getting support ==&lt;br /&gt;
&lt;br /&gt;
If you&#039;re interested in knowing about what resources you have access to (and/or) what resources you have access to that might solve a problem you&#039;re having, please visit our [[What_resources_when|&amp;quot;what resources when&amp;quot; article]].&lt;br /&gt;
&lt;br /&gt;
To get support that is beyond this website please attend office hours below and/or email [mailto:remarks@stat.cmu.edu remarks@stat.cmu.edu] for support (for more details about how the support ticketing works through [mailto:remarks@stat.cmu.edu remarks@stat.cmu.edu] + ServiceNow please see the [[Service_now|ServiceNow]] article).&lt;br /&gt;
&lt;br /&gt;
Reset your StatDS password here - https://util.stat.cmu.edu/passwordreset/&lt;br /&gt;
&lt;br /&gt;
== Department Contacts ==&lt;br /&gt;
&lt;br /&gt;
• [mailto:events@stat.cmu.edu events@stat.cmu.edu]: seminars, conferences &amp;amp; workshops, and calendar updates&lt;br /&gt;
&lt;br /&gt;
• [mailto:news@stat.cmu.edu news@stat.cmu.edu]: dept/dept member-related public news &amp;amp; announcements&lt;br /&gt;
&lt;br /&gt;
• [mailto:lists@stat.cmu.edu lists@stat.cmu.edu]: department email lists&lt;br /&gt;
&lt;br /&gt;
• [mailto:webmaster@stat.cmu.edu webmaster@stat.cmu.edu]: website updates&lt;br /&gt;
&lt;br /&gt;
• [mailto:remarks@stat.cmu.edu remarks@stat.cmu.edu]: computer/tech requests&lt;br /&gt;
&lt;br /&gt;
• [mailto:rooms@stat.cmu.edu rooms@stat.cmu.edu]: request space for TA office hours&lt;br /&gt;
&lt;br /&gt;
• [mailto:reimbursements@stat.cmu.edu reimbursements@stat.cmu.edu]: travel and reimbursement requests&lt;br /&gt;
&lt;br /&gt;
== Computing Office Hours ==&lt;br /&gt;
&lt;br /&gt;
These office hour opportunities provide a dedicated time for you to come ask questions about research computing.&amp;amp;nbsp; These include code advice, how to access certain resources, what the best resources are for your project, or to learn about new connections to help you progress in your education and research. Staff Office hour times will be sent out each week on Monday as a calendar invite; accept any of the invitations to add it to your personal calendar. PhD TA Office Hours are below, unless a different time is&amp;amp;nbsp;communicated.&lt;br /&gt;
&lt;br /&gt;
#PhD TA Office Hours are held by Alex Shen in Baker 136E on Tuesdays from 3 pm to 5 pm&lt;br /&gt;
#Staff Office Hours are held by appointment  by Carl Skipper in BH 129G.  Schedule via .&lt;br /&gt;
&lt;br /&gt;
See [[Computing_office_hour_usage|computing office hour usage]] for what office hours can be used for.&lt;br /&gt;
&lt;br /&gt;
== Computing Wiki Pages ==&lt;br /&gt;
&lt;br /&gt;
=== General Computing (personal computing) ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Printing&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*[[Department_Printers|Department Printers]] &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Virtual environments&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
#[[Virtual Environment Introduction|Why use virtual environments?]]&lt;br /&gt;
#R&#039;s [[Renv]]&lt;br /&gt;
#Python&#039;s [[Python_virtual_environments|virtual environments (2 options)]] &lt;br /&gt;
#Old instructions for [[Conda with Python (Reference Only)|conda with Python]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[[Parallel_computing|Parallelization]]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
#[[Parallelization_in_r|R-specific parallelization]] &lt;br /&gt;
#[[Parallelization_in_python|Python-specific parallelization]] &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Package development&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
#[[Developing_R_packages|R package development]] &lt;br /&gt;
#[[Developing_python_packages|Python package development]] &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Version Control&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
See the guide provided in the site of [https://36-750.github.io/tools/version-control/ 36750 - Statistical Computing]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Reference management&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
#Zotero &lt;br /&gt;
#Mendeley &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Integrated Development Environments (IDEs)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
#[[VSCode|VSCode]] &lt;br /&gt;
#PyCharm &lt;br /&gt;
#RStudio &lt;br /&gt;
#Eclipse &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Containers&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
#[[Introduction_to_containers|Introduction to containers]] &lt;br /&gt;
#[[Docker,_and_why-you-should-use-it-for-your-research|Docker, and why-you-should-use-it-for-your-research]] &lt;br /&gt;
#[[Tutorials|Basic tutorial]] &lt;br /&gt;
#[[Running_Docker_locally_and_on_Hydras|Running Docker locally and on Hydras]] &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Text Editors&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
#Vim &lt;br /&gt;
#Nano &lt;br /&gt;
#Emacs &lt;br /&gt;
#Atom &lt;br /&gt;
#Sublime &lt;br /&gt;
&lt;br /&gt;
See also the guide provided in the site of [https://36-750.github.io/tools/editors/ 36750 - Statistical Computing]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Web Hosting&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
#[[How_to_host_your_webpage_under_stat.cmu.edu|How to host your webpage under stat.cmu.edu]] &lt;br /&gt;
#[[Bulding_your_website_with_Hugo|Bulding your website with Hugo]] &lt;br /&gt;
&#039;&#039;&#039;AI Tools&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* [[ChatGPT and other LLMs]]&lt;br /&gt;
&lt;br /&gt;
*[[github_copilot|GitHub Copilot]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Miscellanea&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
#[[Windows_Subsystem_for_Linux_(WSL)_and_Python|Windows&amp;amp;nbsp;Subsystem for Linux (WSL) and Python]] &lt;br /&gt;
#[[Amphetamine|Amphetamine: How to keep your computer awake]] &lt;br /&gt;
&lt;br /&gt;
=== General Department Computing Resources ===&lt;br /&gt;
&lt;br /&gt;
*Fall 2021 [[Computing_seminar_resources|Computing Seminar Resources]] (video and slides) &lt;br /&gt;
*[[Linux_and_department_servers|Department Servers]]. This wiki introduces you to the &#039;&#039;&#039;hydra&#039;&#039;&#039; servers, basic Linux commands, and more. &lt;br /&gt;
*#[[Terminal_multiplexers|Terminal multiplexers (screen and tmux)]]. This wiki presents tools for use on the &#039;&#039;hydra&#039;&#039; that can allow you to run jobs even when your not on the server, and much much more! &lt;br /&gt;
*#[[Python_on_the_server|Python on the server]]. This wiki introduces uses command line approaches to running &amp;lt;code&amp;gt;python&amp;lt;/code&amp;gt; on a virtual machine, and how to use jupyter notebooks through the server as well. &lt;br /&gt;
*#[[R_on_the_server|R on the server]]. This wiki introduces uses command line approaches to running &amp;lt;code&amp;gt;R&amp;lt;/code&amp;gt; on a virtual machine. &lt;br /&gt;
*#[[Terminal_automation|Terminal automation]]. This wiki introduces approaches to automate Linux/OS command line calls. &lt;br /&gt;
*##[[Bash_files|Bash files]]. This wiki presents potential uses of Bash files including automated file/folder creation, parallelization and much more! &lt;br /&gt;
*##[[Make|Make]]. This wiki presents potential uses of &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; and Makefiles including automated workflow and dependency tracking &lt;br /&gt;
*##[[Jumping_to_frequently_used_folders_and_automating_environment_setups|Jumping to frequently used folders and automating environment setups]] &lt;br /&gt;
&lt;br /&gt;
*[[Department_GPU_Servers|Department GPU Servers]] &lt;br /&gt;
*[[GPU_Cluster|GPU Cluster]] &lt;br /&gt;
*[[PSC|PSC]] &lt;br /&gt;
*#[[ACCESS|ACCESS]] &lt;br /&gt;
*#[[Slurm|Slurm]]. This wiki introduces the job management system uses at PSC. &lt;br /&gt;
*#[[Parallelization_on_PSC/Bridges-2|Parallelization_on_PSC/Bridges-2]] &lt;br /&gt;
*#[[Access_PSC_compute_nodes_directly_from_VSCode|Access PSC compute nodes directly from VSCode]] &lt;br /&gt;
&lt;br /&gt;
*Azure &lt;br /&gt;
*#[[Azure_getting_started|Azure: getting started]]. This wiki walks you through the steps to create a virtual machine through Azure &lt;br /&gt;
*#[[How_to_obtain_a_virtual_machine_with_a_GPU|How to obtain a virtual machine with a GPU]] &lt;br /&gt;
*#[[Attach_a_disk_to_a_virtual_machine|Attach a disk to a virtual machine]] &lt;br /&gt;
&lt;br /&gt;
== Ideas for the Wiki ==&lt;br /&gt;
&lt;br /&gt;
Please see the [[TODO|TODO page]] to post suggestions and errata.&lt;br /&gt;
&lt;br /&gt;
== Using the Wiki ==&lt;br /&gt;
&lt;br /&gt;
*Here is some&amp;amp;nbsp;[[Generic_Wiki_Information|Generic Wiki Information]]&amp;amp;nbsp;that you may be interested in, such as a users&#039; guide and other resources for Wiki users.&lt;/div&gt;</summary>
		<author><name>Skipper</name></author>
	</entry>
	<entry>
		<id>https://info.stat.cmu.edu/index.php?title=ACCESS&amp;diff=186</id>
		<title>ACCESS</title>
		<link rel="alternate" type="text/html" href="https://info.stat.cmu.edu/index.php?title=ACCESS&amp;diff=186"/>
		<updated>2025-01-30T19:42:19Z</updated>

		<summary type="html">&lt;p&gt;Skipper: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
The&amp;amp;nbsp;NSF’s&amp;amp;nbsp;ACCESS&amp;amp;nbsp;(Advanced Cyberinfrastructure Coordination Ecosystem: Services &amp;amp; Support) program builds upon the successes of the 11-year&amp;amp;nbsp;XSEDE&amp;amp;nbsp;project.&lt;br /&gt;
&lt;br /&gt;
NSF funded supercomputers, like PSC are available via the ACCESS federated system. &amp;amp;nbsp;Besides parallel or memory-intensive computing options, there are many GPU resources available to ACCESS users via the Credit Marketplace.&lt;br /&gt;
&lt;br /&gt;
#If you are a Graduate Student, all you need is&amp;amp;nbsp;&#039;&#039;&#039;an account&#039;&#039;&#039;,&#039;&#039;&#039;&amp;amp;nbsp;&#039;&#039;&#039;your&#039;&#039;&#039;&amp;amp;nbsp;CV&#039;&#039;&#039;, a&amp;amp;nbsp;&#039;&#039;&#039;1-paragraph abstract&#039;&#039;&#039;&amp;amp;nbsp;and&amp;amp;nbsp;&#039;&#039;&#039;a letter from your advisor&#039;&#039;&#039;. &amp;amp;nbsp;With these 4 items, you can complete a simple form and get up to 400,000 cpu-hours to exchange for access to most of the nations supercomputing cyberinfrastructure. Checkout the following [https://allocations.access-ci.org/preparing-your-explore-access-request link].&amp;lt;br/&amp;gt; &amp;amp;nbsp; &lt;br /&gt;
#If you previously held an XSEDE account, you can login here:&amp;amp;nbsp;[https://identity.access-ci.org/new-user-federated https://identity.access-ci.org/new-user-federated]&amp;amp;nbsp;and complete your account transition from XSEDE to ACCESS by selecting “ACCESS CI (XSEDE)” and subsequently login using Andrew Web Login. &amp;amp;nbsp;You will then be guided through a short verification process similar to any other website.&amp;lt;br/&amp;gt; &amp;amp;nbsp; &lt;br /&gt;
#If you are&amp;amp;nbsp;&#039;&#039;&#039;new&#039;&#039;&#039;&amp;amp;nbsp;to the department or supercomputing in general,&amp;amp;nbsp;I set up a new account so you will be able to access (no pun intended) these resources easily now or in the future. &amp;amp;nbsp;Visit&amp;amp;nbsp;[https://identity.access-ci.org/new-user-federated https://identity.access-ci.org/new-user-federated]&amp;amp;nbsp;to set up a new account - &amp;amp;nbsp;make sure to choose “&#039;&#039;&#039;Carnegie Mellon University&#039;&#039;&#039;”!&amp;lt;br/&amp;gt; &amp;amp;nbsp; &lt;br /&gt;
#The interface to the Supercomputing Credit Market is still being improved, but we are working on documentation to address that.&lt;br /&gt;
&lt;br /&gt;
This will shortly be updated to add easy access to ACCESS On-Ramps: &amp;lt;div id=&amp;quot;resource-catalog-react&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Skipper</name></author>
	</entry>
	<entry>
		<id>https://info.stat.cmu.edu/index.php?title=How_to_obtain_a_virtual_machine_with_a_GPU&amp;diff=170</id>
		<title>How to obtain a virtual machine with a GPU</title>
		<link rel="alternate" type="text/html" href="https://info.stat.cmu.edu/index.php?title=How_to_obtain_a_virtual_machine_with_a_GPU&amp;diff=170"/>
		<updated>2024-11-14T19:54:25Z</updated>

		<summary type="html">&lt;p&gt;Skipper: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This page is ARCHIVED.  Our agreement with Microsoft to gain Azure virtual machines is over and you should explore our other GPU options for the department.  These include our [[Department GPU Servers]] and the shared Dietrich [[GPU Cluster]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;-------------------------------------------------------------------------------------------------------------------------------------------------------------------------&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following is the process to request access to a virtual machine (VM) with GPU on Azure&lt;br /&gt;
&lt;br /&gt;
#Determine the Azure Service and VM Family size you are looking for and calculate the total CPU quantity needed. (For example, a Standard_NC6s_v3 has 1 GPU (Nvidia V100)&amp;amp;nbsp;but 6 CPU, so you would request 6 CPU)fff &lt;br /&gt;
#From within the subscription, start the CPU Quota increase request process and ensure the appropriate Azure service is specified. (Ex: Virtual Machine, Azure Machine Learning, Azure Lab Services) &lt;br /&gt;
#Work with Azure Support on the request. &lt;br /&gt;
#If Support denies the request, e-mail Carl or the PhD Computing TA and they will give you the email of the right point of contact.&amp;amp;nbsp;He will escalate your Support Incident number to our internal contact and work with Azure Support on getting the request approved. &lt;br /&gt;
#Requests that get approved are typically fulfilled within 48 hours of escalation. &lt;br /&gt;
&lt;br /&gt;
Steps 1 and 2 are detailed in the figure below. Step 3 entails communicating via email with a Microsoft Support Engineer.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Please note: The NCasT4v3, ND A100 v4, NDM A100 v4, and NDv2 are constrained globally, and we are not able to support sponsorship requests for these SKUs for the foreseeable future.&#039;&#039;&#039;&amp;amp;nbsp;Please also keep in mind that due to constraints, the number of GPUs and the region you select may need to be adjusted depending on the demand in the region. In some instances, choosing a different region, VM Family, and/or different quantity of GPUs may yield a different result.&lt;br /&gt;
&lt;br /&gt;
In the (usually rare) case that the deployment of the approved VM does not go through completely, note that there is a known issue that prevents the CUDA extension to be installed correctly. If this happens, you can install it manually by following this [https://learn.microsoft.com/en-us/azure/virtual-machines/linux/n-series-driver-setup guide]. Since this is a quite involved process, if you find yourself stuck we suggest to go to the PhD computing office hours and/or contact Carl.&lt;br /&gt;
&lt;br /&gt;
[[File:3200px-Azure vm quota request.png|1600x1000px|Azure vm quota request.png]]&lt;/div&gt;</summary>
		<author><name>Skipper</name></author>
	</entry>
	<entry>
		<id>https://info.stat.cmu.edu/index.php?title=How_to_obtain_a_virtual_machine_with_a_GPU&amp;diff=169</id>
		<title>How to obtain a virtual machine with a GPU</title>
		<link rel="alternate" type="text/html" href="https://info.stat.cmu.edu/index.php?title=How_to_obtain_a_virtual_machine_with_a_GPU&amp;diff=169"/>
		<updated>2024-11-14T19:50:42Z</updated>

		<summary type="html">&lt;p&gt;Skipper: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This page is ARCHIVED.  Our agreement with Microsoft to gain Azure virtual machines is over and you should explore our other GPU options for the department.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following is the process to request access to a virtual machine (VM) with GPU on Azure&lt;br /&gt;
&lt;br /&gt;
#Determine the Azure Service and VM Family size you are looking for and calculate the total CPU quantity needed. (For example, a Standard_NC6s_v3 has 1 GPU (Nvidia V100)&amp;amp;nbsp;but 6 CPU, so you would request 6 CPU)fff &lt;br /&gt;
#From within the subscription, start the CPU Quota increase request process and ensure the appropriate Azure service is specified. (Ex: Virtual Machine, Azure Machine Learning, Azure Lab Services) &lt;br /&gt;
#Work with Azure Support on the request. &lt;br /&gt;
#If Support denies the request, e-mail Carl or the PhD Computing TA and they will give you the email of the right point of contact.&amp;amp;nbsp;He will escalate your Support Incident number to our internal contact and work with Azure Support on getting the request approved. &lt;br /&gt;
#Requests that get approved are typically fulfilled within 48 hours of escalation. &lt;br /&gt;
&lt;br /&gt;
Steps 1 and 2 are detailed in the figure below. Step 3 entails communicating via email with a Microsoft Support Engineer.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Please note: The NCasT4v3, ND A100 v4, NDM A100 v4, and NDv2 are constrained globally, and we are not able to support sponsorship requests for these SKUs for the foreseeable future.&#039;&#039;&#039;&amp;amp;nbsp;Please also keep in mind that due to constraints, the number of GPUs and the region you select may need to be adjusted depending on the demand in the region. In some instances, choosing a different region, VM Family, and/or different quantity of GPUs may yield a different result.&lt;br /&gt;
&lt;br /&gt;
In the (usually rare) case that the deployment of the approved VM does not go through completely, note that there is a known issue that prevents the CUDA extension to be installed correctly. If this happens, you can install it manually by following this [https://learn.microsoft.com/en-us/azure/virtual-machines/linux/n-series-driver-setup guide]. Since this is a quite involved process, if you find yourself stuck we suggest to go to the PhD computing office hours and/or contact Carl.&lt;br /&gt;
&lt;br /&gt;
[[File:3200px-Azure vm quota request.png|1600x1000px|Azure vm quota request.png]]&lt;/div&gt;</summary>
		<author><name>Skipper</name></author>
	</entry>
	<entry>
		<id>https://info.stat.cmu.edu/index.php?title=How_to_obtain_a_virtual_machine_with_a_GPU&amp;diff=97</id>
		<title>How to obtain a virtual machine with a GPU</title>
		<link rel="alternate" type="text/html" href="https://info.stat.cmu.edu/index.php?title=How_to_obtain_a_virtual_machine_with_a_GPU&amp;diff=97"/>
		<updated>2024-05-24T02:41:50Z</updated>

		<summary type="html">&lt;p&gt;Skipper: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
The following is the process to request access to a virtual machine (VM) with GPU on Azure&lt;br /&gt;
&lt;br /&gt;
#Determine the Azure Service and VM Family size you are looking for and calculate the total CPU quantity needed. (For example, a Standard_NC6s_v3 has 1 GPU (Nvidia V100)&amp;amp;nbsp;but 6 CPU, so you would request 6 CPU)fff &lt;br /&gt;
#From within the subscription, start the CPU Quota increase request process and ensure the appropriate Azure service is specified. (Ex: Virtual Machine, Azure Machine Learning, Azure Lab Services) &lt;br /&gt;
#Work with Azure Support on the request. &lt;br /&gt;
#If Support denies the request, e-mail Carl or the PhD Computing TA and they will give you the email of the right point of contact.&amp;amp;nbsp;He will escalate your Support Incident number to our internal contact and work with Azure Support on getting the request approved. &lt;br /&gt;
#Requests that get approved are typically fulfilled within 48 hours of escalation. &lt;br /&gt;
&lt;br /&gt;
Steps 1 and 2 are detailed in the figure below. Step 3 entails communicating via email with a Microsoft Support Engineer.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Please note: The NCasT4v3, ND A100 v4, NDM A100 v4, and NDv2 are constrained globally, and we are not able to support sponsorship requests for these SKUs for the foreseeable future.&#039;&#039;&#039;&amp;amp;nbsp;Please also keep in mind that due to constraints, the number of GPUs and the region you select may need to be adjusted depending on the demand in the region. In some instances, choosing a different region, VM Family, and/or different quantity of GPUs may yield a different result.&lt;br /&gt;
&lt;br /&gt;
In the (usually rare) case that the deployment of the approved VM does not go through completely, note that there is a known issue that prevents the CUDA extension to be installed correctly. If this happens, you can install it manually by following this [https://learn.microsoft.com/en-us/azure/virtual-machines/linux/n-series-driver-setup guide]. Since this is a quite involved process, if you find yourself stuck we suggest to go to the PhD computing office hours and/or contact Carl.&lt;br /&gt;
&lt;br /&gt;
[[File:3200px-Azure vm quota request.png|1600x1000px|Azure vm quota request.png]]&lt;/div&gt;</summary>
		<author><name>Skipper</name></author>
	</entry>
	<entry>
		<id>https://info.stat.cmu.edu/index.php?title=File:3200px-Azure_vm_quota_request.png&amp;diff=96</id>
		<title>File:3200px-Azure vm quota request.png</title>
		<link rel="alternate" type="text/html" href="https://info.stat.cmu.edu/index.php?title=File:3200px-Azure_vm_quota_request.png&amp;diff=96"/>
		<updated>2024-05-24T02:41:32Z</updated>

		<summary type="html">&lt;p&gt;Skipper: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;test&lt;/div&gt;</summary>
		<author><name>Skipper</name></author>
	</entry>
	<entry>
		<id>https://info.stat.cmu.edu/index.php?title=Azure_getting_started&amp;diff=95</id>
		<title>Azure getting started</title>
		<link rel="alternate" type="text/html" href="https://info.stat.cmu.edu/index.php?title=Azure_getting_started&amp;diff=95"/>
		<updated>2024-05-24T02:39:32Z</updated>

		<summary type="html">&lt;p&gt;Skipper: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Azure =&lt;br /&gt;
&lt;br /&gt;
== Respectiful use of Azure resources ==&lt;br /&gt;
&lt;br /&gt;
Ensure you’re not wasting precious department Azure credits - when you are not using your virtual machine, please shut it down (and then relaunch it when you need to use it). You can shut-down and relauch a server on the resource page. The overview for your virtual machine might look something like the image below. To turn off your machine click the “Stop” button on the “Overview” tab, and to launch your machine click the “Start” button. Every time you launch your machine it’s likely that the IP address will have changed, so use the “Connect” button to figure out the new IP address (though it is also listed on the Overview page). The “Connect” page (which appears in the second image) will also remind you of what your username for the virtual machine is.&lt;br /&gt;
&lt;br /&gt;
[[File:1600px-Azure on off.png|frameless|800px|turning on and off server to save department money]]&lt;br /&gt;
&lt;br /&gt;
[[File:1600px-Azure connect.png|frameless|800px|connecting to your server&#039;s IP address when it changes]]&lt;br /&gt;
&lt;br /&gt;
= Getting started: create an Azure virtual machine =&lt;br /&gt;
&lt;br /&gt;
== Getting an account on portal.azure.com ==&lt;br /&gt;
&lt;br /&gt;
The first step is to complete [https://docs.google.com/forms/d/1ZrynhmPAyLAS-TlIN5iPcQSPBbwzVJe1MPbqgYYejRs this form] &amp;amp;nbsp;asking for an account on Azure. This should prompt a set of emails from Carl. In this process, you’ll be (1) creating an account on portal.azure.com with your @andrew.cmu.edu email address and (2) getting connected to the statistics department resources.&lt;br /&gt;
&lt;br /&gt;
=== Debugging account access ===&lt;br /&gt;
&lt;br /&gt;
If you log onto portal.azure.com and it suggests that you are not connected to the statistics department (it will offer free trials), then you are not correctly connected. This may be due to errors in either of the above.&lt;br /&gt;
&lt;br /&gt;
To check if you’re able to connect to the department resources, go to the top right corner (with your andrew email address) and click it. You’ll see an option “Switch directory”. Click it. The hope is in the potential startup directories, you’ll see one called “Default Directory” as seen in the image below.&lt;br /&gt;
&lt;br /&gt;
[[File:Azure user on portal.png|frameless|200px|User account on portal.azure.com]]&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
[[File:1600px-Azure directory options.png|frameless|800px|understanding and debugging directory options (starting out)]]&lt;br /&gt;
&lt;br /&gt;
== Creating a Resource ==&lt;br /&gt;
&lt;br /&gt;
Creating a virtual on Azure can be a bit complicated (which is why other resources like the department servers are available for certain types of computing).&lt;br /&gt;
&lt;br /&gt;
The first thing to do is click the “create a resource” button on your azure home page (should look something like this:)&lt;br /&gt;
&lt;br /&gt;
[[File:Azure create new.png|frameless|300px|create new server button]]&lt;br /&gt;
&lt;br /&gt;
You can also do so in the &amp;lt;code&amp;gt;All resources&amp;lt;/code&amp;gt; &amp;gt; &amp;lt;code&amp;gt;+ Create&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
For statistical computing we select a resource from the &amp;lt;code&amp;gt;AI + Machine Learning&amp;lt;/code&amp;gt; tab on the left side and then select &amp;lt;code&amp;gt;Data Science Virtual Machine - Ubuntu 18.04&amp;lt;/code&amp;gt; for a linux virtual machine. This selection will look something like the image below:&lt;br /&gt;
&lt;br /&gt;
[[File:Azure select resource type.png|frameless|700px|Selecting which type of virtual server to use]]&lt;br /&gt;
&lt;br /&gt;
=== Defining your Resource ===&lt;br /&gt;
&lt;br /&gt;
There are a lot of options to create your resource, but you can ignore a lot of these.&lt;br /&gt;
&lt;br /&gt;
==== Basics ====&lt;br /&gt;
&lt;br /&gt;
Below is 2 images of the first “Basics” page. You will need to&lt;br /&gt;
&lt;br /&gt;
#fill out / select your “Resource group” &lt;br /&gt;
#define your “Virtual machine name” (might we recommend (username)-(CPU/GPU)-cores(#)-(RAM)-(index). For example “bpleroy-GPU-cores4-27-1”. &lt;br /&gt;
#select the size of the machine (relative to it’s cores and types of cores). You will see available options. If you do not see an option that meets your needs, please message remarks@stat.cmu.edu / go see Carl and describe your question. You can also click &amp;quot;see all images&amp;quot; to explore a list of options (some which are not available to CMU Stats). If you are looking for GPU in this list filter by &amp;quot;family&amp;quot; and &amp;quot;GPU&amp;quot; for the family. &lt;br /&gt;
#finally, we recommend using a ssh public key (which will be downloaded at the end of the set-up process). We recommend you change your “Username” to your andrew id but you can leave it as “azureuser” if you’d like (we recommend such things since you may forget and it&#039;s natural to have it consistent across your servers). &lt;br /&gt;
&lt;br /&gt;
[[File:1400px-Azure basics 1.png|frameless|700px|setting up new server, basic page (1)]]&lt;br /&gt;
&lt;br /&gt;
[[File:1400px-Azure basics 2.png|frameless|700px|setting up new server, basic page (2)]]&lt;br /&gt;
&lt;br /&gt;
==== Disks ====&lt;br /&gt;
&lt;br /&gt;
The second pages is about “Disks” although creating storage on Azure is complicated it’s a very necessary procedure. Click “Create and attache a new disk”. You will then have to select the right size. Generally, disks smaller than 512 GB are cheap for the department but 1 TB + are more costly. You personal computer likely has between 128 - 512 GB (maybe 1TB), but it’s really unlikely you’ll need too much for your project.&lt;br /&gt;
&lt;br /&gt;
[[File:1400px-Azure disk creation.png|frameless|700px|creating a disk]]&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
==== Network and Management ====&lt;br /&gt;
&lt;br /&gt;
There isn’t really anything necessary for you to do on these tabs.&lt;br /&gt;
&lt;br /&gt;
==== Advanced ====&lt;br /&gt;
&lt;br /&gt;
If you are using GPUs you’ll need to add the NVDIA extension for GPUs.&lt;br /&gt;
&lt;br /&gt;
==== Tags are also not necessary ====&lt;br /&gt;
&lt;br /&gt;
==== Done? ====&lt;br /&gt;
&lt;br /&gt;
You did it! Save your ssh key (&amp;lt;code&amp;gt;.pem&amp;lt;/code&amp;gt; file) in a location where you plan to call the server from. Also note that you will &#039;&#039;&#039;still&#039;&#039;&#039; need to correctly link your data disk you just created (which is discussed in the next step).&lt;br /&gt;
&lt;br /&gt;
=== Connecting your data disk ===&lt;br /&gt;
&lt;br /&gt;
This process is slightly complex (and can have implications if you don’t do it correctly). We recommend you follow the [https://docs.microsoft.com/en-us/azure/virtual-machines/linux/attach-disk-portal azure docs].&lt;br /&gt;
&lt;br /&gt;
==== step 1: finding and identifying your disk ====&lt;br /&gt;
&lt;br /&gt;
on the server run something like:&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;lsblk -o NAME,HCTL,SIZE,MOUNTPOINT | grep -i &amp;quot;sd&amp;quot;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
you should see a list something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;sda     3:0:0:0      128G&lt;br /&gt;
sdb     0:0:0:0      150G&lt;br /&gt;
├─sdb1             149.9G /&lt;br /&gt;
├─sdb14                4M&lt;br /&gt;
└─sdb15              106M /boot/efi&lt;br /&gt;
sdc     1:0:1:0      176G&lt;br /&gt;
└─sdc1               176G /mnt&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
now, on portal for the same VM, look at your disks (left side: Settings &amp;gt; Disks) and examine the size of your disk you added (for mine it’s 128G). As such we can conclude that my disk that needs mounting is &amp;lt;code&amp;gt;sda&amp;lt;/code&amp;gt; (this might not be the same for you - and is not the same in the azure docs).&lt;br /&gt;
&lt;br /&gt;
==== step 2: partitioning a new disk ====&lt;br /&gt;
&lt;br /&gt;
Copied form the azure docs (but changed for my disk name)&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;sudo parted /dev/sda --script mklabel gpt mkpart xfspart xfs 0% 100%&lt;br /&gt;
sudo mkfs.xfs /dev/sda1&lt;br /&gt;
sudo partprobe /dev/sda1&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== step 3: mount the disk ====&lt;br /&gt;
&lt;br /&gt;
Create a directory to mount the file system using mkdir. The following example creates a directory at &amp;lt;code&amp;gt;/datadrive&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;sudo mkdir /datadrive&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use mount to then mount the filesystem. The following example mounts the &amp;lt;code&amp;gt;/dev/sda1&amp;lt;/code&amp;gt; partition to the &amp;lt;code&amp;gt;/datadrive&amp;lt;/code&amp;gt; mount point:&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;sudo mount /dev/sda1 /datadrive&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Now we have&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;lsblk -o NAME,HCTL,SIZE,MOUNTPOINT | grep -i &amp;quot;sd&amp;quot;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;sda     3:0:0:0      128G&lt;br /&gt;
└─sda1               128G /datadrive&lt;br /&gt;
sdb     0:0:0:0      150G&lt;br /&gt;
├─sdb1             149.9G /&lt;br /&gt;
├─sdb14                4M&lt;br /&gt;
└─sdb15              106M /boot/efi&lt;br /&gt;
sdc     1:0:1:0      176G&lt;br /&gt;
└─sdc1               176G /mnt&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== step 4: … ====&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;sudo blkid&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;/dev/sdb1: LABEL=&amp;quot;cloudimg-rootfs&amp;quot; UUID=&amp;quot;1fe704c3-9cec-4cb5-b634-2e46f6bd9f90&amp;quot; TYPE=&amp;quot;ext4&amp;quot; PARTUUID=&amp;quot;318ec118-9248-4203-9cd5-7cb8c36f04d6&amp;quot;&lt;br /&gt;
/dev/sdb15: LABEL=&amp;quot;UEFI&amp;quot; UUID=&amp;quot;52A4-029B&amp;quot; TYPE=&amp;quot;vfat&amp;quot; PARTUUID=&amp;quot;2332d2b4-222e-425d-866e-227b42f3979d&amp;quot;&lt;br /&gt;
/dev/sdc1: UUID=&amp;quot;9cc09cc7-c65d-4fe4-a397-75679a438c1c&amp;quot; TYPE=&amp;quot;ext4&amp;quot; PARTUUID=&amp;quot;2b584de2-01&amp;quot;&lt;br /&gt;
/dev/sda1: UUID=&amp;quot;a2ba271d-e5a4-4416-84d2-b9408864b53b&amp;quot; TYPE=&amp;quot;xfs&amp;quot; PARTLABEL=&amp;quot;xfspart&amp;quot; PARTUUID=&amp;quot;77452866-0b43-4485-9956-673377498608&amp;quot;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== step 5: creating alias link to datadrive ====&lt;br /&gt;
&lt;br /&gt;
To create a symbolic link to your a &amp;lt;code&amp;gt;workspace&amp;lt;/code&amp;gt; folder to the &amp;lt;code&amp;gt;/datadrive&amp;lt;/code&amp;gt; you can do the following.&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;ln -s /datadrive ~/workspace &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Afterwards, everything in the &amp;lt;code&amp;gt;workspace&amp;lt;/code&amp;gt; will actually be stored on your new &amp;lt;code&amp;gt;/datadrive&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== step 6: making sure you have correct permissions ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ls -al /&amp;lt;/code&amp;gt; (might show you don’t have access (write, read, execute) to the /datadrive), so we did&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;sudo chmod 777 datadrive&amp;lt;/code&amp;gt; …&lt;br /&gt;
&lt;br /&gt;
[https://www.hostinger.com/tutorials/how-to-create-symbolic-links-in-linux/ https://www.hostinger.com/tutorials/how-to-create-symbolic-links-in-linux/]&lt;br /&gt;
&lt;br /&gt;
=== Connecting to your server and moving files ===&lt;br /&gt;
&lt;br /&gt;
To connect to your server you will need to know (1) where you&#039;re ssh key is (often called &amp;lt;code&amp;gt;_server_name_.pem&amp;lt;/code&amp;gt; (this should have been downloaded at the end of the creation of your server). &#039;&#039;&#039;Note that the first time your connect you need to make sure you have the correct permissions - see the connect page for the correct &amp;lt;code&amp;gt;cmod&amp;lt;/code&amp;gt; command you need to use!&#039;&#039;&#039; (2) your username defined in the [[Azure_getting_started#Basics|Basics]] step&lt;br /&gt;
&lt;br /&gt;
You will also need to know what IP address your server is currently using. This can before on the connect page of your server (as seen in the second image in this article). Then you&#039;re type something like&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh -i _my_ssh_key_.pem _user_name_@_IP_address_ &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To pass files to and from your server with &amp;lt;code&amp;gt;scp&amp;lt;/code&amp;gt;, we will imagine you are on your home computer. Then do as follows:&lt;br /&gt;
&lt;br /&gt;
#&#039;&#039;&#039;server to local&#039;&#039;&#039; &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
scp -i _my_ssh_key_.pem _user_name_@_IP_address_:/full/path/to/files/on/server/my_script.R /local/path/to/files/on/local/computer/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#&#039;&#039;&#039;local to server&#039;&#039;&#039; &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
scp -i _my_ssh_key_.pem /local/path/to/files/on/local/computer/my_script.R _user_name_@_IP_address_:/full/path/to/files/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To pass directories (and do the full thing you&#039;ll need to do the same as above but add&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
scp -i _my_ssh_key.pem -r ...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Skipper</name></author>
	</entry>
	<entry>
		<id>https://info.stat.cmu.edu/index.php?title=Azure_getting_started&amp;diff=94</id>
		<title>Azure getting started</title>
		<link rel="alternate" type="text/html" href="https://info.stat.cmu.edu/index.php?title=Azure_getting_started&amp;diff=94"/>
		<updated>2024-05-24T02:37:27Z</updated>

		<summary type="html">&lt;p&gt;Skipper: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Azure =&lt;br /&gt;
&lt;br /&gt;
== Respectiful use of Azure resources ==&lt;br /&gt;
&lt;br /&gt;
Ensure you’re not wasting precious department Azure credits - when you are not using your virtual machine, please shut it down (and then relaunch it when you need to use it). You can shut-down and relauch a server on the resource page. The overview for your virtual machine might look something like the image below. To turn off your machine click the “Stop” button on the “Overview” tab, and to launch your machine click the “Start” button. Every time you launch your machine it’s likely that the IP address will have changed, so use the “Connect” button to figure out the new IP address (though it is also listed on the Overview page). The “Connect” page (which appears in the second image) will also remind you of what your username for the virtual machine is.&lt;br /&gt;
&lt;br /&gt;
[[File:1600px-Azure on off.png|frameless|800px|turning on and off server to save department money]]&lt;br /&gt;
&lt;br /&gt;
[[File:1600px-Azure connect.png|frameless|800px|connecting to your server&#039;s IP address when it changes]]&lt;br /&gt;
&lt;br /&gt;
= Getting started: create an Azure virtual machine =&lt;br /&gt;
&lt;br /&gt;
== Getting an account on portal.azure.com ==&lt;br /&gt;
&lt;br /&gt;
The first step is to complete [https://docs.google.com/forms/d/1ZrynhmPAyLAS-TlIN5iPcQSPBbwzVJe1MPbqgYYejRs this form] &amp;amp;nbsp;asking for an account on Azure. This should prompt a set of emails from Carl. In this process, you’ll be (1) creating an account on portal.azure.com with your @andrew.cmu.edu email address and (2) getting connected to the statistics department resources.&lt;br /&gt;
&lt;br /&gt;
=== Debugging account access ===&lt;br /&gt;
&lt;br /&gt;
If you log onto portal.azure.com and it suggests that you are not connected to the statistics department (it will offer free trials), then you are not correctly connected. This may be due to errors in either of the above.&lt;br /&gt;
&lt;br /&gt;
To check if you’re able to connect to the department resources, go to the top right corner (with your andrew email address) and click it. You’ll see an option “Switch directory”. Click it. The hope is in the potential startup directories, you’ll see one called “Default Directory” as seen in the image below.&lt;br /&gt;
&lt;br /&gt;
[[File:Azure user on portal.png|frameless|200px|User account on portal.azure.com]]&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
[[File:Azure directory options.png|frameless|800px|understanding and debugging directory options (starting out)]]&lt;br /&gt;
&lt;br /&gt;
== Creating a Resource ==&lt;br /&gt;
&lt;br /&gt;
Creating a virtual on Azure can be a bit complicated (which is why other resources like the department servers are available for certain types of computing).&lt;br /&gt;
&lt;br /&gt;
The first thing to do is click the “create a resource” button on your azure home page (should look something like this:)&lt;br /&gt;
&lt;br /&gt;
[[File:Azure create new.png|frameless|300px|create new server button]]&lt;br /&gt;
&lt;br /&gt;
You can also do so in the &amp;lt;code&amp;gt;All resources&amp;lt;/code&amp;gt; &amp;gt; &amp;lt;code&amp;gt;+ Create&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
For statistical computing we select a resource from the &amp;lt;code&amp;gt;AI + Machine Learning&amp;lt;/code&amp;gt; tab on the left side and then select &amp;lt;code&amp;gt;Data Science Virtual Machine - Ubuntu 18.04&amp;lt;/code&amp;gt; for a linux virtual machine. This selection will look something like the image below:&lt;br /&gt;
&lt;br /&gt;
[[File:Azure select resource type.png|frameless|700px|Selecting which type of virtual server to use]]&lt;br /&gt;
&lt;br /&gt;
=== Defining your Resource ===&lt;br /&gt;
&lt;br /&gt;
There are a lot of options to create your resource, but you can ignore a lot of these.&lt;br /&gt;
&lt;br /&gt;
==== Basics ====&lt;br /&gt;
&lt;br /&gt;
Below is 2 images of the first “Basics” page. You will need to&lt;br /&gt;
&lt;br /&gt;
#fill out / select your “Resource group” &lt;br /&gt;
#define your “Virtual machine name” (might we recommend (username)-(CPU/GPU)-cores(#)-(RAM)-(index). For example “bpleroy-GPU-cores4-27-1”. &lt;br /&gt;
#select the size of the machine (relative to it’s cores and types of cores). You will see available options. If you do not see an option that meets your needs, please message remarks@stat.cmu.edu / go see Carl and describe your question. You can also click &amp;quot;see all images&amp;quot; to explore a list of options (some which are not available to CMU Stats). If you are looking for GPU in this list filter by &amp;quot;family&amp;quot; and &amp;quot;GPU&amp;quot; for the family. &lt;br /&gt;
#finally, we recommend using a ssh public key (which will be downloaded at the end of the set-up process). We recommend you change your “Username” to your andrew id but you can leave it as “azureuser” if you’d like (we recommend such things since you may forget and it&#039;s natural to have it consistent across your servers). &lt;br /&gt;
&lt;br /&gt;
[[File:1400px-Azure basics 1.png|frameless|700px|setting up new server, basic page (1)]]&lt;br /&gt;
&lt;br /&gt;
[[File:1400px-Azure basics 2.png|frameless|700px|setting up new server, basic page (2)]]&lt;br /&gt;
&lt;br /&gt;
==== Disks ====&lt;br /&gt;
&lt;br /&gt;
The second pages is about “Disks” although creating storage on Azure is complicated it’s a very necessary procedure. Click “Create and attache a new disk”. You will then have to select the right size. Generally, disks smaller than 512 GB are cheap for the department but 1 TB + are more costly. You personal computer likely has between 128 - 512 GB (maybe 1TB), but it’s really unlikely you’ll need too much for your project.&lt;br /&gt;
&lt;br /&gt;
[[File:1400px-Azure disk creation.png|frameless|700px|creating a disk]]&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
==== Network and Management ====&lt;br /&gt;
&lt;br /&gt;
There isn’t really anything necessary for you to do on these tabs.&lt;br /&gt;
&lt;br /&gt;
==== Advanced ====&lt;br /&gt;
&lt;br /&gt;
If you are using GPUs you’ll need to add the NVDIA extension for GPUs.&lt;br /&gt;
&lt;br /&gt;
==== Tags are also not necessary ====&lt;br /&gt;
&lt;br /&gt;
==== Done? ====&lt;br /&gt;
&lt;br /&gt;
You did it! Save your ssh key (&amp;lt;code&amp;gt;.pem&amp;lt;/code&amp;gt; file) in a location where you plan to call the server from. Also note that you will &#039;&#039;&#039;still&#039;&#039;&#039; need to correctly link your data disk you just created (which is discussed in the next step).&lt;br /&gt;
&lt;br /&gt;
=== Connecting your data disk ===&lt;br /&gt;
&lt;br /&gt;
This process is slightly complex (and can have implications if you don’t do it correctly). We recommend you follow the [https://docs.microsoft.com/en-us/azure/virtual-machines/linux/attach-disk-portal azure docs].&lt;br /&gt;
&lt;br /&gt;
==== step 1: finding and identifying your disk ====&lt;br /&gt;
&lt;br /&gt;
on the server run something like:&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;lsblk -o NAME,HCTL,SIZE,MOUNTPOINT | grep -i &amp;quot;sd&amp;quot;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
you should see a list something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;sda     3:0:0:0      128G&lt;br /&gt;
sdb     0:0:0:0      150G&lt;br /&gt;
├─sdb1             149.9G /&lt;br /&gt;
├─sdb14                4M&lt;br /&gt;
└─sdb15              106M /boot/efi&lt;br /&gt;
sdc     1:0:1:0      176G&lt;br /&gt;
└─sdc1               176G /mnt&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
now, on portal for the same VM, look at your disks (left side: Settings &amp;gt; Disks) and examine the size of your disk you added (for mine it’s 128G). As such we can conclude that my disk that needs mounting is &amp;lt;code&amp;gt;sda&amp;lt;/code&amp;gt; (this might not be the same for you - and is not the same in the azure docs).&lt;br /&gt;
&lt;br /&gt;
==== step 2: partitioning a new disk ====&lt;br /&gt;
&lt;br /&gt;
Copied form the azure docs (but changed for my disk name)&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;sudo parted /dev/sda --script mklabel gpt mkpart xfspart xfs 0% 100%&lt;br /&gt;
sudo mkfs.xfs /dev/sda1&lt;br /&gt;
sudo partprobe /dev/sda1&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== step 3: mount the disk ====&lt;br /&gt;
&lt;br /&gt;
Create a directory to mount the file system using mkdir. The following example creates a directory at &amp;lt;code&amp;gt;/datadrive&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;sudo mkdir /datadrive&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use mount to then mount the filesystem. The following example mounts the &amp;lt;code&amp;gt;/dev/sda1&amp;lt;/code&amp;gt; partition to the &amp;lt;code&amp;gt;/datadrive&amp;lt;/code&amp;gt; mount point:&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;sudo mount /dev/sda1 /datadrive&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Now we have&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;lsblk -o NAME,HCTL,SIZE,MOUNTPOINT | grep -i &amp;quot;sd&amp;quot;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;sda     3:0:0:0      128G&lt;br /&gt;
└─sda1               128G /datadrive&lt;br /&gt;
sdb     0:0:0:0      150G&lt;br /&gt;
├─sdb1             149.9G /&lt;br /&gt;
├─sdb14                4M&lt;br /&gt;
└─sdb15              106M /boot/efi&lt;br /&gt;
sdc     1:0:1:0      176G&lt;br /&gt;
└─sdc1               176G /mnt&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== step 4: … ====&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;sudo blkid&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;/dev/sdb1: LABEL=&amp;quot;cloudimg-rootfs&amp;quot; UUID=&amp;quot;1fe704c3-9cec-4cb5-b634-2e46f6bd9f90&amp;quot; TYPE=&amp;quot;ext4&amp;quot; PARTUUID=&amp;quot;318ec118-9248-4203-9cd5-7cb8c36f04d6&amp;quot;&lt;br /&gt;
/dev/sdb15: LABEL=&amp;quot;UEFI&amp;quot; UUID=&amp;quot;52A4-029B&amp;quot; TYPE=&amp;quot;vfat&amp;quot; PARTUUID=&amp;quot;2332d2b4-222e-425d-866e-227b42f3979d&amp;quot;&lt;br /&gt;
/dev/sdc1: UUID=&amp;quot;9cc09cc7-c65d-4fe4-a397-75679a438c1c&amp;quot; TYPE=&amp;quot;ext4&amp;quot; PARTUUID=&amp;quot;2b584de2-01&amp;quot;&lt;br /&gt;
/dev/sda1: UUID=&amp;quot;a2ba271d-e5a4-4416-84d2-b9408864b53b&amp;quot; TYPE=&amp;quot;xfs&amp;quot; PARTLABEL=&amp;quot;xfspart&amp;quot; PARTUUID=&amp;quot;77452866-0b43-4485-9956-673377498608&amp;quot;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== step 5: creating alias link to datadrive ====&lt;br /&gt;
&lt;br /&gt;
To create a symbolic link to your a &amp;lt;code&amp;gt;workspace&amp;lt;/code&amp;gt; folder to the &amp;lt;code&amp;gt;/datadrive&amp;lt;/code&amp;gt; you can do the following.&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;ln -s /datadrive ~/workspace &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Afterwards, everything in the &amp;lt;code&amp;gt;workspace&amp;lt;/code&amp;gt; will actually be stored on your new &amp;lt;code&amp;gt;/datadrive&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== step 6: making sure you have correct permissions ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ls -al /&amp;lt;/code&amp;gt; (might show you don’t have access (write, read, execute) to the /datadrive), so we did&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;sudo chmod 777 datadrive&amp;lt;/code&amp;gt; …&lt;br /&gt;
&lt;br /&gt;
[https://www.hostinger.com/tutorials/how-to-create-symbolic-links-in-linux/ https://www.hostinger.com/tutorials/how-to-create-symbolic-links-in-linux/]&lt;br /&gt;
&lt;br /&gt;
=== Connecting to your server and moving files ===&lt;br /&gt;
&lt;br /&gt;
To connect to your server you will need to know (1) where you&#039;re ssh key is (often called &amp;lt;code&amp;gt;_server_name_.pem&amp;lt;/code&amp;gt; (this should have been downloaded at the end of the creation of your server). &#039;&#039;&#039;Note that the first time your connect you need to make sure you have the correct permissions - see the connect page for the correct &amp;lt;code&amp;gt;cmod&amp;lt;/code&amp;gt; command you need to use!&#039;&#039;&#039; (2) your username defined in the [[Azure_getting_started#Basics|Basics]] step&lt;br /&gt;
&lt;br /&gt;
You will also need to know what IP address your server is currently using. This can before on the connect page of your server (as seen in the second image in this article). Then you&#039;re type something like&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh -i _my_ssh_key_.pem _user_name_@_IP_address_ &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To pass files to and from your server with &amp;lt;code&amp;gt;scp&amp;lt;/code&amp;gt;, we will imagine you are on your home computer. Then do as follows:&lt;br /&gt;
&lt;br /&gt;
#&#039;&#039;&#039;server to local&#039;&#039;&#039; &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
scp -i _my_ssh_key_.pem _user_name_@_IP_address_:/full/path/to/files/on/server/my_script.R /local/path/to/files/on/local/computer/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#&#039;&#039;&#039;local to server&#039;&#039;&#039; &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
scp -i _my_ssh_key_.pem /local/path/to/files/on/local/computer/my_script.R _user_name_@_IP_address_:/full/path/to/files/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To pass directories (and do the full thing you&#039;ll need to do the same as above but add&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
scp -i _my_ssh_key.pem -r ...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Skipper</name></author>
	</entry>
	<entry>
		<id>https://info.stat.cmu.edu/index.php?title=File:1400px-Azure_disk_creation.png&amp;diff=93</id>
		<title>File:1400px-Azure disk creation.png</title>
		<link rel="alternate" type="text/html" href="https://info.stat.cmu.edu/index.php?title=File:1400px-Azure_disk_creation.png&amp;diff=93"/>
		<updated>2024-05-24T02:36:56Z</updated>

		<summary type="html">&lt;p&gt;Skipper: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;test&lt;/div&gt;</summary>
		<author><name>Skipper</name></author>
	</entry>
	<entry>
		<id>https://info.stat.cmu.edu/index.php?title=File:1400px-Azure_basics_2.png&amp;diff=92</id>
		<title>File:1400px-Azure basics 2.png</title>
		<link rel="alternate" type="text/html" href="https://info.stat.cmu.edu/index.php?title=File:1400px-Azure_basics_2.png&amp;diff=92"/>
		<updated>2024-05-24T02:36:21Z</updated>

		<summary type="html">&lt;p&gt;Skipper: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;test&lt;/div&gt;</summary>
		<author><name>Skipper</name></author>
	</entry>
	<entry>
		<id>https://info.stat.cmu.edu/index.php?title=File:1400px-Azure_basics_1.png&amp;diff=91</id>
		<title>File:1400px-Azure basics 1.png</title>
		<link rel="alternate" type="text/html" href="https://info.stat.cmu.edu/index.php?title=File:1400px-Azure_basics_1.png&amp;diff=91"/>
		<updated>2024-05-24T02:35:37Z</updated>

		<summary type="html">&lt;p&gt;Skipper: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;test&lt;/div&gt;</summary>
		<author><name>Skipper</name></author>
	</entry>
	<entry>
		<id>https://info.stat.cmu.edu/index.php?title=File:Azure_select_resource_type.png&amp;diff=90</id>
		<title>File:Azure select resource type.png</title>
		<link rel="alternate" type="text/html" href="https://info.stat.cmu.edu/index.php?title=File:Azure_select_resource_type.png&amp;diff=90"/>
		<updated>2024-05-24T02:34:52Z</updated>

		<summary type="html">&lt;p&gt;Skipper: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;test&lt;/div&gt;</summary>
		<author><name>Skipper</name></author>
	</entry>
	<entry>
		<id>https://info.stat.cmu.edu/index.php?title=File:Azure_create_new.png&amp;diff=89</id>
		<title>File:Azure create new.png</title>
		<link rel="alternate" type="text/html" href="https://info.stat.cmu.edu/index.php?title=File:Azure_create_new.png&amp;diff=89"/>
		<updated>2024-05-24T02:34:12Z</updated>

		<summary type="html">&lt;p&gt;Skipper: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;test&lt;/div&gt;</summary>
		<author><name>Skipper</name></author>
	</entry>
	<entry>
		<id>https://info.stat.cmu.edu/index.php?title=File:1600px-Azure_directory_options.png&amp;diff=88</id>
		<title>File:1600px-Azure directory options.png</title>
		<link rel="alternate" type="text/html" href="https://info.stat.cmu.edu/index.php?title=File:1600px-Azure_directory_options.png&amp;diff=88"/>
		<updated>2024-05-24T02:33:27Z</updated>

		<summary type="html">&lt;p&gt;Skipper: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;test&lt;/div&gt;</summary>
		<author><name>Skipper</name></author>
	</entry>
	<entry>
		<id>https://info.stat.cmu.edu/index.php?title=File:Azure_user_on_portal.png&amp;diff=87</id>
		<title>File:Azure user on portal.png</title>
		<link rel="alternate" type="text/html" href="https://info.stat.cmu.edu/index.php?title=File:Azure_user_on_portal.png&amp;diff=87"/>
		<updated>2024-05-24T02:32:32Z</updated>

		<summary type="html">&lt;p&gt;Skipper: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Azure user portal&lt;/div&gt;</summary>
		<author><name>Skipper</name></author>
	</entry>
	<entry>
		<id>https://info.stat.cmu.edu/index.php?title=Azure_getting_started&amp;diff=86</id>
		<title>Azure getting started</title>
		<link rel="alternate" type="text/html" href="https://info.stat.cmu.edu/index.php?title=Azure_getting_started&amp;diff=86"/>
		<updated>2024-05-24T02:31:13Z</updated>

		<summary type="html">&lt;p&gt;Skipper: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Azure =&lt;br /&gt;
&lt;br /&gt;
== Respectiful use of Azure resources ==&lt;br /&gt;
&lt;br /&gt;
Ensure you’re not wasting precious department Azure credits - when you are not using your virtual machine, please shut it down (and then relaunch it when you need to use it). You can shut-down and relauch a server on the resource page. The overview for your virtual machine might look something like the image below. To turn off your machine click the “Stop” button on the “Overview” tab, and to launch your machine click the “Start” button. Every time you launch your machine it’s likely that the IP address will have changed, so use the “Connect” button to figure out the new IP address (though it is also listed on the Overview page). The “Connect” page (which appears in the second image) will also remind you of what your username for the virtual machine is.&lt;br /&gt;
&lt;br /&gt;
[[File:1600px-Azure on off.png|frameless|800px|turning on and off server to save department money]]&lt;br /&gt;
&lt;br /&gt;
[[File:1600px-Azure connect.png|frameless|800px|connecting to your server&#039;s IP address when it changes]]&lt;br /&gt;
&lt;br /&gt;
= Getting started: create an Azure virtual machine =&lt;br /&gt;
&lt;br /&gt;
== Getting an account on portal.azure.com ==&lt;br /&gt;
&lt;br /&gt;
The first step is to complete [https://docs.google.com/forms/d/1ZrynhmPAyLAS-TlIN5iPcQSPBbwzVJe1MPbqgYYejRs this form] &amp;amp;nbsp;asking for an account on Azure. This should prompt a set of emails from Carl. In this process, you’ll be (1) creating an account on portal.azure.com with your @andrew.cmu.edu email address and (2) getting connected to the statistics department resources.&lt;br /&gt;
&lt;br /&gt;
=== Debugging account access ===&lt;br /&gt;
&lt;br /&gt;
If you log onto portal.azure.com and it suggests that you are not connected to the statistics department (it will offer free trials), then you are not correctly connected. This may be due to errors in either of the above.&lt;br /&gt;
&lt;br /&gt;
To check if you’re able to connect to the department resources, go to the top right corner (with your andrew email address) and click it. You’ll see an option “Switch directory”. Click it. The hope is in the potential startup directories, you’ll see one called “Default Directory” as seen in the image below.&lt;br /&gt;
&lt;br /&gt;
[[File:Azure user on portal.png|frameless|200px|User account on portal.azure.com]]&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
[[File:Azure directory options.png|frameless|800px|understanding and debugging directory options (starting out)]]&lt;br /&gt;
&lt;br /&gt;
== Creating a Resource ==&lt;br /&gt;
&lt;br /&gt;
Creating a virtual on Azure can be a bit complicated (which is why other resources like the department servers are available for certain types of computing).&lt;br /&gt;
&lt;br /&gt;
The first thing to do is click the “create a resource” button on your azure home page (should look something like this:)&lt;br /&gt;
&lt;br /&gt;
[[File:Azure create new.png|frameless|300px|create new server button]]&lt;br /&gt;
&lt;br /&gt;
You can also do so in the &amp;lt;code&amp;gt;All resources&amp;lt;/code&amp;gt; &amp;gt; &amp;lt;code&amp;gt;+ Create&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
For statistical computing we select a resource from the &amp;lt;code&amp;gt;AI + Machine Learning&amp;lt;/code&amp;gt; tab on the left side and then select &amp;lt;code&amp;gt;Data Science Virtual Machine - Ubuntu 18.04&amp;lt;/code&amp;gt; for a linux virtual machine. This selection will look something like the image below:&lt;br /&gt;
&lt;br /&gt;
[[File:Azure select resource type.png|frameless|700px|Selecting which type of virtual server to use]]&lt;br /&gt;
&lt;br /&gt;
=== Defining your Resource ===&lt;br /&gt;
&lt;br /&gt;
There are a lot of options to create your resource, but you can ignore a lot of these.&lt;br /&gt;
&lt;br /&gt;
==== Basics ====&lt;br /&gt;
&lt;br /&gt;
Below is 2 images of the first “Basics” page. You will need to&lt;br /&gt;
&lt;br /&gt;
#fill out / select your “Resource group” &lt;br /&gt;
#define your “Virtual machine name” (might we recommend (username)-(CPU/GPU)-cores(#)-(RAM)-(index). For example “bpleroy-GPU-cores4-27-1”. &lt;br /&gt;
#select the size of the machine (relative to it’s cores and types of cores). You will see available options. If you do not see an option that meets your needs, please message remarks@stat.cmu.edu / go see Carl and describe your question. You can also click &amp;quot;see all images&amp;quot; to explore a list of options (some which are not available to CMU Stats). If you are looking for GPU in this list filter by &amp;quot;family&amp;quot; and &amp;quot;GPU&amp;quot; for the family. &lt;br /&gt;
#finally, we recommend using a ssh public key (which will be downloaded at the end of the set-up process). We recommend you change your “Username” to your andrew id but you can leave it as “azureuser” if you’d like (we recommend such things since you may forget and it&#039;s natural to have it consistent across your servers). &lt;br /&gt;
&lt;br /&gt;
[[File:Azure basics 1.png|frameless|700px|setting up new server, basic page (1)]]&lt;br /&gt;
&lt;br /&gt;
[[File:Azure basics 2.png|frameless|700px|setting up new server, basic page (2)]]&lt;br /&gt;
&lt;br /&gt;
==== Disks ====&lt;br /&gt;
&lt;br /&gt;
The second pages is about “Disks” although creating storage on Azure is complicated it’s a very necessary procedure. Click “Create and attache a new disk”. You will then have to select the right size. Generally, disks smaller than 512 GB are cheap for the department but 1 TB + are more costly. You personal computer likely has between 128 - 512 GB (maybe 1TB), but it’s really unlikely you’ll need too much for your project.&lt;br /&gt;
&lt;br /&gt;
[[File:Azure disk creation.png|frameless|700px|creating a disk]]&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
==== Network and Management ====&lt;br /&gt;
&lt;br /&gt;
There isn’t really anything necessary for you to do on these tabs.&lt;br /&gt;
&lt;br /&gt;
==== Advanced ====&lt;br /&gt;
&lt;br /&gt;
If you are using GPUs you’ll need to add the NVDIA extension for GPUs.&lt;br /&gt;
&lt;br /&gt;
==== Tags are also not necessary ====&lt;br /&gt;
&lt;br /&gt;
==== Done? ====&lt;br /&gt;
&lt;br /&gt;
You did it! Save your ssh key (&amp;lt;code&amp;gt;.pem&amp;lt;/code&amp;gt; file) in a location where you plan to call the server from. Also note that you will &#039;&#039;&#039;still&#039;&#039;&#039; need to correctly link your data disk you just created (which is discussed in the next step).&lt;br /&gt;
&lt;br /&gt;
=== Connecting your data disk ===&lt;br /&gt;
&lt;br /&gt;
This process is slightly complex (and can have implications if you don’t do it correctly). We recommend you follow the [https://docs.microsoft.com/en-us/azure/virtual-machines/linux/attach-disk-portal azure docs].&lt;br /&gt;
&lt;br /&gt;
==== step 1: finding and identifying your disk ====&lt;br /&gt;
&lt;br /&gt;
on the server run something like:&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;lsblk -o NAME,HCTL,SIZE,MOUNTPOINT | grep -i &amp;quot;sd&amp;quot;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
you should see a list something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;sda     3:0:0:0      128G&lt;br /&gt;
sdb     0:0:0:0      150G&lt;br /&gt;
├─sdb1             149.9G /&lt;br /&gt;
├─sdb14                4M&lt;br /&gt;
└─sdb15              106M /boot/efi&lt;br /&gt;
sdc     1:0:1:0      176G&lt;br /&gt;
└─sdc1               176G /mnt&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
now, on portal for the same VM, look at your disks (left side: Settings &amp;gt; Disks) and examine the size of your disk you added (for mine it’s 128G). As such we can conclude that my disk that needs mounting is &amp;lt;code&amp;gt;sda&amp;lt;/code&amp;gt; (this might not be the same for you - and is not the same in the azure docs).&lt;br /&gt;
&lt;br /&gt;
==== step 2: partitioning a new disk ====&lt;br /&gt;
&lt;br /&gt;
Copied form the azure docs (but changed for my disk name)&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;sudo parted /dev/sda --script mklabel gpt mkpart xfspart xfs 0% 100%&lt;br /&gt;
sudo mkfs.xfs /dev/sda1&lt;br /&gt;
sudo partprobe /dev/sda1&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== step 3: mount the disk ====&lt;br /&gt;
&lt;br /&gt;
Create a directory to mount the file system using mkdir. The following example creates a directory at &amp;lt;code&amp;gt;/datadrive&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;sudo mkdir /datadrive&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use mount to then mount the filesystem. The following example mounts the &amp;lt;code&amp;gt;/dev/sda1&amp;lt;/code&amp;gt; partition to the &amp;lt;code&amp;gt;/datadrive&amp;lt;/code&amp;gt; mount point:&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;sudo mount /dev/sda1 /datadrive&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Now we have&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;lsblk -o NAME,HCTL,SIZE,MOUNTPOINT | grep -i &amp;quot;sd&amp;quot;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;sda     3:0:0:0      128G&lt;br /&gt;
└─sda1               128G /datadrive&lt;br /&gt;
sdb     0:0:0:0      150G&lt;br /&gt;
├─sdb1             149.9G /&lt;br /&gt;
├─sdb14                4M&lt;br /&gt;
└─sdb15              106M /boot/efi&lt;br /&gt;
sdc     1:0:1:0      176G&lt;br /&gt;
└─sdc1               176G /mnt&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== step 4: … ====&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;sudo blkid&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;/dev/sdb1: LABEL=&amp;quot;cloudimg-rootfs&amp;quot; UUID=&amp;quot;1fe704c3-9cec-4cb5-b634-2e46f6bd9f90&amp;quot; TYPE=&amp;quot;ext4&amp;quot; PARTUUID=&amp;quot;318ec118-9248-4203-9cd5-7cb8c36f04d6&amp;quot;&lt;br /&gt;
/dev/sdb15: LABEL=&amp;quot;UEFI&amp;quot; UUID=&amp;quot;52A4-029B&amp;quot; TYPE=&amp;quot;vfat&amp;quot; PARTUUID=&amp;quot;2332d2b4-222e-425d-866e-227b42f3979d&amp;quot;&lt;br /&gt;
/dev/sdc1: UUID=&amp;quot;9cc09cc7-c65d-4fe4-a397-75679a438c1c&amp;quot; TYPE=&amp;quot;ext4&amp;quot; PARTUUID=&amp;quot;2b584de2-01&amp;quot;&lt;br /&gt;
/dev/sda1: UUID=&amp;quot;a2ba271d-e5a4-4416-84d2-b9408864b53b&amp;quot; TYPE=&amp;quot;xfs&amp;quot; PARTLABEL=&amp;quot;xfspart&amp;quot; PARTUUID=&amp;quot;77452866-0b43-4485-9956-673377498608&amp;quot;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== step 5: creating alias link to datadrive ====&lt;br /&gt;
&lt;br /&gt;
To create a symbolic link to your a &amp;lt;code&amp;gt;workspace&amp;lt;/code&amp;gt; folder to the &amp;lt;code&amp;gt;/datadrive&amp;lt;/code&amp;gt; you can do the following.&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;ln -s /datadrive ~/workspace &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Afterwards, everything in the &amp;lt;code&amp;gt;workspace&amp;lt;/code&amp;gt; will actually be stored on your new &amp;lt;code&amp;gt;/datadrive&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== step 6: making sure you have correct permissions ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ls -al /&amp;lt;/code&amp;gt; (might show you don’t have access (write, read, execute) to the /datadrive), so we did&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;sudo chmod 777 datadrive&amp;lt;/code&amp;gt; …&lt;br /&gt;
&lt;br /&gt;
[https://www.hostinger.com/tutorials/how-to-create-symbolic-links-in-linux/ https://www.hostinger.com/tutorials/how-to-create-symbolic-links-in-linux/]&lt;br /&gt;
&lt;br /&gt;
=== Connecting to your server and moving files ===&lt;br /&gt;
&lt;br /&gt;
To connect to your server you will need to know (1) where you&#039;re ssh key is (often called &amp;lt;code&amp;gt;_server_name_.pem&amp;lt;/code&amp;gt; (this should have been downloaded at the end of the creation of your server). &#039;&#039;&#039;Note that the first time your connect you need to make sure you have the correct permissions - see the connect page for the correct &amp;lt;code&amp;gt;cmod&amp;lt;/code&amp;gt; command you need to use!&#039;&#039;&#039; (2) your username defined in the [[Azure_getting_started#Basics|Basics]] step&lt;br /&gt;
&lt;br /&gt;
You will also need to know what IP address your server is currently using. This can before on the connect page of your server (as seen in the second image in this article). Then you&#039;re type something like&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh -i _my_ssh_key_.pem _user_name_@_IP_address_ &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To pass files to and from your server with &amp;lt;code&amp;gt;scp&amp;lt;/code&amp;gt;, we will imagine you are on your home computer. Then do as follows:&lt;br /&gt;
&lt;br /&gt;
#&#039;&#039;&#039;server to local&#039;&#039;&#039; &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
scp -i _my_ssh_key_.pem _user_name_@_IP_address_:/full/path/to/files/on/server/my_script.R /local/path/to/files/on/local/computer/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#&#039;&#039;&#039;local to server&#039;&#039;&#039; &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
scp -i _my_ssh_key_.pem /local/path/to/files/on/local/computer/my_script.R _user_name_@_IP_address_:/full/path/to/files/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To pass directories (and do the full thing you&#039;ll need to do the same as above but add&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
scp -i _my_ssh_key.pem -r ...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Skipper</name></author>
	</entry>
	<entry>
		<id>https://info.stat.cmu.edu/index.php?title=File:1600px-Azure_on_off.png&amp;diff=85</id>
		<title>File:1600px-Azure on off.png</title>
		<link rel="alternate" type="text/html" href="https://info.stat.cmu.edu/index.php?title=File:1600px-Azure_on_off.png&amp;diff=85"/>
		<updated>2024-05-24T02:30:55Z</updated>

		<summary type="html">&lt;p&gt;Skipper: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;test&lt;/div&gt;</summary>
		<author><name>Skipper</name></author>
	</entry>
	<entry>
		<id>https://info.stat.cmu.edu/index.php?title=File:1600px-Azure_connect.png&amp;diff=84</id>
		<title>File:1600px-Azure connect.png</title>
		<link rel="alternate" type="text/html" href="https://info.stat.cmu.edu/index.php?title=File:1600px-Azure_connect.png&amp;diff=84"/>
		<updated>2024-05-24T02:30:15Z</updated>

		<summary type="html">&lt;p&gt;Skipper: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;test&lt;/div&gt;</summary>
		<author><name>Skipper</name></author>
	</entry>
	<entry>
		<id>https://info.stat.cmu.edu/index.php?title=Amphetamine&amp;diff=83</id>
		<title>Amphetamine</title>
		<link rel="alternate" type="text/html" href="https://info.stat.cmu.edu/index.php?title=Amphetamine&amp;diff=83"/>
		<updated>2024-05-24T02:22:33Z</updated>

		<summary type="html">&lt;p&gt;Skipper: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Modern laptops implement several functionalities to reduce power usage, e.g. by&amp;amp;nbsp;putting drives to sleep, dimming the display, or going into sleep or hibernate modes. This is especially true for Macs.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;span style=&amp;quot;font-size:larger;&amp;quot;&amp;gt;What if you need your laptop to stay awake for a fixed period of time for particular reasons?&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For example, what if you have a job running locally either from the terminal or from a Python notebook in VSCode?&amp;amp;nbsp;&#039;&#039;&#039;Enter Amphetamine!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== What is Amphetamine? ==&lt;br /&gt;
[[File:1000px-Amphetamine.png|500x500px|Amphetamine.png]]&lt;br /&gt;
&lt;br /&gt;
Amphetamine is a &#039;&#039;&#039;free&#039;&#039;&#039; utility by William Gustafson that lets you click, schedule, or trigger Mac alertness from the menu bar.&amp;amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
In the simplest case, you can choose an item from the menu: Indefinitely keeps your Mac awake until canceled, but you can also select a duration, while a given app remains running, or until a file is downloaded. The last one, for example, works by asking you to pick an observation interval after which Amphetamine checks if the file has changed in size so it can predict that the file has completed its download.&lt;br /&gt;
&lt;br /&gt;
For &#039;&#039;&#039;research purposes&#039;&#039;&#039;, Amphetamine comes particularly handy when we need a process to keep running in the background without having to monitor the laptop constantly to avoid it going to sleep. This happens especially often with &#039;&#039;&#039;VSCode&#039;&#039;&#039; when connected to a remote machine via &#039;&#039;&#039;SSH&#039;&#039;&#039;. If a &#039;&#039;&#039;Jupyter notebook&#039;&#039;&#039; is running through a remote ssh connection, any cell running will be interrupted if the connection drops, which happens if the Mac goes to sleep. Amphetamine easily prevents this issue: it&#039;s enought to start a session indefintely and stop it when the job has finished.&amp;amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
Keep an eye on your battery consumption though! The price to pay for Amphetamine sessions (especially those that prevent any kind of sleep mode) is increased battery consumption.&amp;amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
== Amphetamine Enhancer ==&lt;br /&gt;
&lt;br /&gt;
Amphetamine Enhancer is a helper application that enhances a couple of Amphetamine&#039;s features. In its 1.0 release, Amphetamine Enhancer adds the following abilities to Amphetamine:&lt;br /&gt;
&lt;br /&gt;
• Adds a fail-safe for the &#039;&#039;&#039;closed-display mode&#039;&#039;&#039; feature found in Amphetamine 5.0+&amp;lt;br/&amp;gt; • Gives Amphetamine 5.0+ the ability to use all running processes with Triggers and app-based sessions&lt;br /&gt;
&lt;br /&gt;
== Download ==&lt;br /&gt;
&lt;br /&gt;
For Mac users, the app is freely available on the [https://apps.apple.com/us/app/amphetamine/id937984704?mt=12 App Store].&amp;amp;nbsp;Windows users can download Amphetamine from the [https://apps.microsoft.com/detail/9NBLGGH4WHSP?hl=en-US&amp;amp;gl=US Microsoft Store].&lt;br /&gt;
&lt;br /&gt;
Amphetamine Enhancer is freely available for download on [https://github.com/x74353/Amphetamine-Enhancer Github].&lt;br /&gt;
&lt;br /&gt;
Check this [https://zoomadmin.com/HowToInstall/UbuntuPackage/amphetamine article]&amp;amp;nbsp;for a guide on how to install Amphetamine for Ubuntu.&lt;/div&gt;</summary>
		<author><name>Skipper</name></author>
	</entry>
	<entry>
		<id>https://info.stat.cmu.edu/index.php?title=File:1000px-Amphetamine.png&amp;diff=82</id>
		<title>File:1000px-Amphetamine.png</title>
		<link rel="alternate" type="text/html" href="https://info.stat.cmu.edu/index.php?title=File:1000px-Amphetamine.png&amp;diff=82"/>
		<updated>2024-05-24T02:22:14Z</updated>

		<summary type="html">&lt;p&gt;Skipper: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;test&lt;/div&gt;</summary>
		<author><name>Skipper</name></author>
	</entry>
	<entry>
		<id>https://info.stat.cmu.edu/index.php?title=Tutorials&amp;diff=81</id>
		<title>Tutorials</title>
		<link rel="alternate" type="text/html" href="https://info.stat.cmu.edu/index.php?title=Tutorials&amp;diff=81"/>
		<updated>2024-05-24T02:19:16Z</updated>

		<summary type="html">&lt;p&gt;Skipper: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This tutorial is supposed to serve&amp;amp;nbsp;as a simple self-contained example that shows how to build a Docker image for a project that might be of interest in our department: a simple application using PyTorch.&lt;br /&gt;
&lt;br /&gt;
To complete this tutorial, we will rely on [[Python_virtual_environments|conda]]&amp;amp;nbsp;Python version 3.8 or later. You also need to have installed Docker (see [https://docs.docker.com/desktop/ download and install Docker]).&lt;br /&gt;
&lt;br /&gt;
== Example application ==&lt;br /&gt;
&lt;br /&gt;
Create a directory named&amp;amp;nbsp;&amp;lt;code&amp;gt;docker&amp;amp;nbsp;&amp;lt;/code&amp;gt;and create a conda environment with Python and PyTorch installed in it. Don&#039;t forget to activate the environment before installing packages!&lt;br /&gt;
&lt;br /&gt;
Then, create a&amp;amp;nbsp;&amp;lt;code&amp;gt;test_docker.py&amp;amp;nbsp;&amp;lt;/code&amp;gt;file and add the following simple lines:&lt;br /&gt;
&amp;lt;pre&amp;gt;import torch&lt;br /&gt;
&lt;br /&gt;
a = torch.Tensor([1, 2, 3, 4, 5])&lt;br /&gt;
&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    print(a)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Inherit from an existing image =&lt;br /&gt;
&lt;br /&gt;
== Create a Dockerfile for Python ==&lt;br /&gt;
&lt;br /&gt;
Inside the&amp;amp;nbsp;&amp;lt;code&amp;gt;docker&amp;amp;nbsp;&amp;lt;/code&amp;gt;directory&amp;amp;nbsp;create a&amp;amp;nbsp;&amp;lt;code&amp;gt;Dockerfile&amp;lt;/code&amp;gt;&amp;amp;nbsp;(simply by tipying &amp;lt;code&amp;gt;touch Dockerfile&amp;lt;/code&amp;gt;) and add a line that tells Docker &amp;lt;u&amp;gt;what base image to use&amp;lt;/u&amp;gt; for the application.&lt;br /&gt;
&amp;lt;pre&amp;gt;# syntax=docker/dockerfile:1&lt;br /&gt;
&lt;br /&gt;
FROM python:3.8-slim-buster&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Docker images can inherit from other images. Therefore, instead of creating your own base image, you can use the official Python image that has all the tools and packages needed to run a Python application.&lt;br /&gt;
&lt;br /&gt;
To make things easier when running the remaining commands, create a &amp;lt;u&amp;gt;working directory&amp;lt;/u&amp;gt;. This instructs Docker to use this path as the default location for all subsequent commands. This means you can use relative file paths based on the working directory instead of full file paths.&lt;br /&gt;
&amp;lt;pre&amp;gt;WORKDIR /path/to/your/project/dir&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now we would like the Docker image to install all the necessary packages we have in the environment. When installing Python, conda automatically downloads the &amp;lt;code&amp;gt;pip&amp;amp;nbsp;&amp;lt;/code&amp;gt;package manager as well.&amp;amp;nbsp;We can then use it&amp;amp;nbsp;to create a requirements file by typing&lt;br /&gt;
&amp;lt;pre&amp;gt;pip list --format=freeze &amp;gt; requirements.txt&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in the terminal, within the&amp;amp;nbsp;&amp;lt;code&amp;gt;docker&amp;lt;/code&amp;gt; directory. Then we need to make sure the requirements file will be in the image. The&amp;amp;nbsp;&amp;lt;code&amp;gt;COPY&amp;lt;/code&amp;gt;&amp;amp;nbsp;command takes two parameters. The first parameter tells Docker what file(s) you would like to copy into the image. The second parameter tells Docker where to copy that file(s) to. For this example, copy the&amp;amp;nbsp;&amp;lt;code&amp;gt;requirements.txt&amp;lt;/code&amp;gt;&amp;amp;nbsp;file into the working directory:&lt;br /&gt;
&amp;lt;pre&amp;gt;COPY requirements.txt requirements.txt&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With the&amp;amp;nbsp;&amp;lt;code&amp;gt;requirements.txt&amp;lt;/code&amp;gt;&amp;amp;nbsp;file inside the image, you can use the&amp;amp;nbsp;&amp;lt;code&amp;gt;RUN&amp;lt;/code&amp;gt;&amp;amp;nbsp;command to run&amp;amp;nbsp;&amp;lt;code&amp;gt;pip&amp;amp;nbsp;install&amp;lt;/code&amp;gt;. This works exactly the same as running&amp;amp;nbsp;&amp;lt;code&amp;gt;pip&amp;amp;nbsp;install&amp;lt;/code&amp;gt;&amp;amp;nbsp;locally on a machine, but this time pip installs the modules into the image.&lt;br /&gt;
&amp;lt;pre&amp;gt;RUN pip install -r requirements.txt&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At this point, you have an image based on Python version 3.8 and have installed the dependencies. The next step is to add the source code into the image. Use the&amp;amp;nbsp;&amp;lt;code&amp;gt;COPY&amp;lt;/code&amp;gt;&amp;amp;nbsp;command as with the&amp;amp;nbsp;&amp;lt;code&amp;gt;requirements.txt&amp;lt;/code&amp;gt;&amp;amp;nbsp;file.&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;pre&amp;gt;COPY test_docker.py test_docker.py&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, tell Docker what command to run when the image is executed inside a container using the&amp;amp;nbsp;&amp;lt;code&amp;gt;CMD&amp;lt;/code&amp;gt;&amp;amp;nbsp;command.&lt;br /&gt;
&amp;lt;pre&amp;gt;CMD [&amp;quot;python&amp;quot;, &amp;quot;test_docker.py&amp;quot;]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The complete&amp;lt;code&amp;gt;&amp;amp;nbsp;Dockerfile&amp;amp;nbsp;&amp;lt;/code&amp;gt;should look like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;# syntax=docker/dockerfile:1&lt;br /&gt;
FROM python:3.8-slim-buster&lt;br /&gt;
WORKDIR /path/to/your/project/dir&lt;br /&gt;
COPY requirements.txt requirements.txt&lt;br /&gt;
RUN pip install -r requirements.txt&lt;br /&gt;
COPY test_docker.py test_docker.py&lt;br /&gt;
CMD [&amp;quot;python&amp;quot;, &amp;quot;test_docker.py&amp;quot;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Build an image ==&lt;br /&gt;
&lt;br /&gt;
Now that you’ve created the Dockerfile, let’s build the image. To do this, use the&amp;amp;nbsp;&amp;lt;code&amp;gt;docker build&amp;lt;/code&amp;gt;&amp;amp;nbsp;command. The&amp;amp;nbsp;&amp;lt;code&amp;gt;docker build&amp;lt;/code&amp;gt;&amp;amp;nbsp;command builds Docker images from a Dockerfile and a “context”. A build’s context is the set of files located in the specified PATH or URL. The Docker build process can access any of the files located in this context.&lt;br /&gt;
&lt;br /&gt;
The build command optionally takes a&amp;amp;nbsp;&amp;lt;code&amp;gt;--tag&amp;lt;/code&amp;gt;&amp;amp;nbsp;flag. The tag sets the name of the image and an optional tag in the format&amp;amp;nbsp;&amp;lt;code&amp;gt;name:tag. &amp;lt;/code&amp;gt;Don&#039;t forget to open the Docker Desktop application before running the build command, otherwise the Docker deamon will not be running and the command will not work.&lt;br /&gt;
&lt;br /&gt;
If everything went well, you should see something like this:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;code&amp;gt;[[File:1704px-Docker build.png|900x500px|RTENOTITLE]]&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Run the image ==&lt;br /&gt;
&lt;br /&gt;
Now that we have an image, we can run that image and see if our application is running correctly.&lt;br /&gt;
&lt;br /&gt;
A container is a normal operating system process except that this process is isolated in that it has its own file system, its own networking, and its own isolated process tree separate from the host.&lt;br /&gt;
&lt;br /&gt;
To run an image inside of a container, we use the&amp;amp;nbsp;&amp;lt;code&amp;gt;docker run&amp;lt;/code&amp;gt;&amp;amp;nbsp;command. The&amp;amp;nbsp;&amp;lt;code&amp;gt;docker run&amp;lt;/code&amp;gt;&amp;amp;nbsp;command requires one parameter which is the name of the image. Let’s start our image and make sure it is running correctly. Run the following command in your terminal.&lt;br /&gt;
&amp;lt;pre&amp;gt;docker run test-docker&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If everything goes well, you should see the desired output printed in the terminal (in this case, a simple PyTorch Tensor).&lt;br /&gt;
&lt;br /&gt;
= Creating new base images =&lt;br /&gt;
&lt;br /&gt;
Most Dockerfiles start from a parent image. If you need to completely control the contents of your image, you might need to create a base image instead. Here’s the difference:&lt;br /&gt;
&lt;br /&gt;
*A&amp;amp;nbsp;[https://docs.docker.com/glossary/#parent-image parent image]&amp;amp;nbsp;is the image that your image is based on. It refers to the contents of the&amp;amp;nbsp;&amp;lt;code&amp;gt;FROM&amp;lt;/code&amp;gt;&amp;amp;nbsp;directive in the Dockerfile. Each subsequent declaration in the Dockerfile modifies this parent image. Most Dockerfiles start from a parent image, rather than a base image. However, the terms are sometimes used interchangeably. &lt;br /&gt;
*A&amp;amp;nbsp;[https://docs.docker.com/glossary/#base-image base image]&amp;amp;nbsp;has&amp;amp;nbsp;&amp;lt;code&amp;gt;FROM scratch&amp;lt;/code&amp;gt;&amp;amp;nbsp;in its Dockerfile. &lt;br /&gt;
&lt;br /&gt;
See&amp;amp;nbsp;this [https://docs.docker.com/build/building/base-images/ link] for details.&lt;/div&gt;</summary>
		<author><name>Skipper</name></author>
	</entry>
	<entry>
		<id>https://info.stat.cmu.edu/index.php?title=File:1704px-Docker_build.png&amp;diff=80</id>
		<title>File:1704px-Docker build.png</title>
		<link rel="alternate" type="text/html" href="https://info.stat.cmu.edu/index.php?title=File:1704px-Docker_build.png&amp;diff=80"/>
		<updated>2024-05-24T02:18:59Z</updated>

		<summary type="html">&lt;p&gt;Skipper: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;test&lt;/div&gt;</summary>
		<author><name>Skipper</name></author>
	</entry>
	<entry>
		<id>https://info.stat.cmu.edu/index.php?title=VSCode&amp;diff=79</id>
		<title>VSCode</title>
		<link rel="alternate" type="text/html" href="https://info.stat.cmu.edu/index.php?title=VSCode&amp;diff=79"/>
		<updated>2024-05-24T02:12:22Z</updated>

		<summary type="html">&lt;p&gt;Skipper: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
VSCode is an open-source IDE maintained by Microsoft, and it is considered a “lightweight” code editor. In comparison with full integrated development environment (IDE) editors which occupy gigabytes of disk space, VS Code uses less than 200MB when installed. Despite the “lightweight” term, Visual Studio Code offers a massive number of features (via so-called “extensions”) which keep increasing and improving with every new update.&amp;amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
Resources:&lt;br /&gt;
&lt;br /&gt;
#[https://code.visualstudio.com/docs Official documentation] &lt;br /&gt;
#[https://code.visualstudio.com/download Download] &lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
== Basic Usage ==&lt;br /&gt;
&lt;br /&gt;
Some good extensions:&amp;amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
#Python (and Pylance) &lt;br /&gt;
#Jupyter &lt;br /&gt;
#R &lt;br /&gt;
#LaTeX Workshop &lt;br /&gt;
#Remote - SSH &lt;br /&gt;
#autoDocstring &lt;br /&gt;
&lt;br /&gt;
== Remote Development and Prototyping via SSH ==&lt;br /&gt;
&lt;br /&gt;
In this section we will learn how to use VSCode to manage, develop, and test code that we have stored on a remote server (like [https://www.stat.cmu.edu/computewiki/index.php/Linux_and_department_servers Hydras], [https://www.stat.cmu.edu/computewiki/index.php/Azure_getting_started Azure], etc...).&lt;br /&gt;
&lt;br /&gt;
This is particularly useful to &amp;lt;u&amp;gt;avoid&amp;lt;/u&amp;gt; painful workflows that see us doing the following:&lt;br /&gt;
&lt;br /&gt;
#develop locally on our laptop &lt;br /&gt;
#&amp;lt;font face=&amp;quot;monospace&amp;quot;&amp;gt;scp&amp;lt;/font&amp;gt; some scripts to the remote server and run them (assuming we have consistent environments) &lt;br /&gt;
#&amp;lt;font face=&amp;quot;monospace&amp;quot;&amp;gt;scp&amp;amp;nbsp;&amp;lt;/font&amp;gt;the results to the local laptop &lt;br /&gt;
#repeat from 1 &lt;br /&gt;
&lt;br /&gt;
Ideally, we want to be able to use the remote server only as the computational workhorse, while leveraging the GUI of our local operative system. Doing this in VSCode is extremely simple:&lt;br /&gt;
&lt;br /&gt;
#In the left toolbar, click on the “Extensions” button and search for SSH. The correct one is hte one developed by Microsoft (blue icon). Click on the install button.&lt;br /&gt;
&lt;br /&gt;
[[File:Ssh.png|1000x1000px|RTENOTITLE]] &lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;ol start=&amp;quot;2&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Once the extension is installed, click on the small green button at the very bottom-left of the window (the one with a symbol similar to &amp;gt;&amp;lt;). A pop-up window at the top will open: click on “Connect to Host”&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;At this point, we have two alternatives: &lt;br /&gt;
#&amp;amp;nbsp;add a new SSH host manually, which will prompt another small window where to enter the connection details (similar to what one does from the terminal) &lt;br /&gt;
#or&amp;amp;nbsp;&#039;&#039;&#039;&amp;lt;u&amp;gt;better&amp;lt;/u&amp;gt;&#039;&#039;&#039;, if we have a SSH&amp;amp;nbsp;&amp;lt;code&amp;gt;config&amp;amp;nbsp;&amp;lt;/code&amp;gt;file in the &amp;lt;code&amp;gt;.ssh&amp;amp;nbsp;&amp;lt;/code&amp;gt;directory, VSCode will automatically list the possible remote servers that are specified in this file. If we specified a path to a key, then VSCode will connect automatically. If instead the remote server requires a password (as it is the case for Hydras), then we will be prompted with another window to enter it. As an example:&lt;br /&gt;
[[File:Hosts.png|RTENOTITLE]]&lt;br /&gt;
&amp;amp;nbsp;[[File:Ssh config.png|RTENOTITLE]] &lt;br /&gt;
&amp;lt;ol start=&amp;quot;4&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Congratulations! You are now connected to a remote server through VSCode. By clicking on the “Explorer”&amp;amp;nbsp;button at the top in the left-side toolbar, you can navigate the file system of the server, develop and run code, etc. Everything you do and see is actually being hosted, run, and saved remotely.&amp;amp;nbsp;&lt;br /&gt;
[[File:Remote file.png|1000x1000px|RTENOTITLE]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
== Managing environments within VSCode ==&lt;br /&gt;
&lt;br /&gt;
Since each project might (and should) have its own development environment that you setup, with dependencies and packages that make it unique for the tasks of this project, VSCode allows to easily choose which interpreter&amp;amp;nbsp;to use.&amp;amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
We simply have to click at the bottom right&amp;amp;nbsp;of the window, on the button that shows the current Python (or other language) version that we are using. This will open a prompt to choose the environment among those present on the&amp;amp;nbsp;machine we are developing on:&lt;br /&gt;
&lt;br /&gt;
[[File:Env.png|1000x1000px|Env.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
== Support for Jupyter Notebooks (even remote!) within VSCode ==&lt;br /&gt;
&lt;br /&gt;
In one of the previous section we learned how to setup VSCode for remote development. A great feature of the workflow that we have just enabled is that we can run Jupyter Notebooks (and produce plots, tables, etc...) that are hosted remotely while seeing the output on our local laptop within VSCode (this works also if we are running things locally). Doing so is very easy:&lt;br /&gt;
&lt;br /&gt;
#Click on the “Extensions” button on the left toolbar and download the Jupyter&amp;amp;nbsp;extension &lt;br /&gt;
&lt;br /&gt;
[[File:Jupyter.png|1000x1000px|Jupyter.png]]&lt;br /&gt;
&amp;lt;ol start=&amp;quot;2&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Open a .ipynb file and choose the kernel (interpreter for the correct project environment) from the button that appears at the top right of the opened notebook&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Choose kernel.png|1000x1000px|Choose kernel.png]]&lt;br /&gt;
&amp;lt;ol start=&amp;quot;3&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Happy coding!&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Support for RStudio (even remote!) within VSCode ==&lt;br /&gt;
&lt;br /&gt;
Install the R extension, which provides support for the&amp;amp;nbsp;[https://www.r-project.org/ R programming language], including features such as extended syntax highlighting, R language service based on code analysis, interacting with R terminals, viewing data, plots, workspace variables, help pages, managing packages, and working with&amp;amp;nbsp;[https://rmarkdown.rstudio.com/ R Markdown]&amp;amp;nbsp;documents.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Miscellanea ==&lt;br /&gt;
&lt;br /&gt;
=== Amphetamine ===&lt;br /&gt;
&lt;br /&gt;
If you need your laptop to stay awake while there&#039;s a process running --- you are running some cell in a notebook via remote SSH --- check out this [[Amphetamine|article in the wiki]].&lt;br /&gt;
&lt;br /&gt;
=== Tunnelling ===&lt;br /&gt;
&lt;br /&gt;
Disclaimer: this is particularly useful for PSC (Pittsburgh Supercomuting Center) users, as it allows to connect directly to a compute node on PSC and have things like Jupyter Notebooks run via VSCode without problems. This solution bypasses a problem incurred when connecting via SSH from VSCode, which caused to land on the login nodes. These have very little memory and basically do not support any computation.&lt;br /&gt;
&lt;br /&gt;
Instructions for creating a VS code tunnel to PSC:&lt;br /&gt;
&lt;br /&gt;
*First set up code CLI on PSC: [https://dev.to/burkeholland/introducing-vs-code-remote-tunnels-connect-to-remote-machines-with-ease-3nlg https://dev.to/burkeholland/introducing-vs-code-remote-tunnels-connect-to-remote-machines-with-ease-3nlg&amp;amp;nbsp;] &lt;br /&gt;
*Then run the following: &lt;br /&gt;
&amp;lt;pre&amp;gt;    curl -Lk &#039;https://code.visualstudio.com/sha/download?build=stable&amp;amp;os=cli-alpine-x64&#039; --output vscode_cli.tar.gz&lt;br /&gt;
    tar -xf vscode_cli.tar.gz&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp;This will create a &amp;quot;code&amp;quot; executable file which we need to add to the path. Open &amp;lt;code&amp;gt;.bashrc&amp;lt;/code&amp;gt;&amp;amp;nbsp;(or &amp;lt;code&amp;gt;.zshrc&amp;amp;nbsp;&amp;lt;/code&amp;gt;if you have a recent Mac) and edit the line that exports the path to be&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;pre&amp;gt;export PATH=&amp;quot;/jet/home/&amp;lt;username&amp;gt;:$PATH&amp;quot;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Restart the shell and check that &amp;quot;which code&amp;quot; finds the installation. &lt;br /&gt;
*Next, install the remote tunnels and remote ssh extensions on VS code. &lt;br /&gt;
**These are found in the extensions menu &lt;br /&gt;
**After installation there should be a blue &amp;quot;open remote window&amp;quot; (&amp;gt;&amp;lt; symbol) in the bottom left of the VS code window. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Next, we set up the tunnel: [https://dev.to/burkeholland/introducing-vs-code-remote-tunnels-connect-to-remote-machines-with-ease-3nlg https://dev.to/burkeholland/introducing-vs-code-remote-tunnels-connect-to-remote-machines-with-ease-3nlg&amp;amp;nbsp;] &lt;br /&gt;
**Start interactive job &lt;br /&gt;
**Run &amp;lt;code&amp;gt;code tunnel&amp;lt;/code&amp;gt;&amp;amp;nbsp;and follow the instructions. I recommend logging in via GitHub the first time and occasionally you will be asked to name the machine. By default it will name it based off of the node you are currently interacting with; however, the tunnel will connect to any node at PSC via the same setup so I recommend you name it something generic related to PSC. You will eventually see a message like “Open this link in your browser https://vscode.dev/tunnel/&amp;lt;machine name&amp;gt;” &lt;br /&gt;
**On VS Code on your local machine, click the blue &amp;quot;open remote window&amp;quot; (&amp;gt;&amp;lt; symbol) in the bottom left and select Connect to Tunnel. &lt;br /&gt;
**Select GitHub and then the machine that matches &amp;lt;machine name&amp;gt; in the link shown on the remote location. This should reload your VS code window to be running on the remote server, but if you started an interactive job it is running on a compute node. &lt;br /&gt;
**To stop the connection, run &amp;quot;ctrl + c&amp;quot; &lt;br /&gt;
**If you need to deregister the tunnel run &amp;quot;code tunnel unregister&amp;quot; however, this should be unnecessary &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For any future connection you run this same set of steps, as&amp;amp;nbsp;I haven&#039;t found a way to avoid re logging in via github every time.&lt;/div&gt;</summary>
		<author><name>Skipper</name></author>
	</entry>
	<entry>
		<id>https://info.stat.cmu.edu/index.php?title=File:Choose_kernel.png&amp;diff=78</id>
		<title>File:Choose kernel.png</title>
		<link rel="alternate" type="text/html" href="https://info.stat.cmu.edu/index.php?title=File:Choose_kernel.png&amp;diff=78"/>
		<updated>2024-05-24T02:12:11Z</updated>

		<summary type="html">&lt;p&gt;Skipper: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;test&lt;/div&gt;</summary>
		<author><name>Skipper</name></author>
	</entry>
	<entry>
		<id>https://info.stat.cmu.edu/index.php?title=File:Jupyter.png&amp;diff=77</id>
		<title>File:Jupyter.png</title>
		<link rel="alternate" type="text/html" href="https://info.stat.cmu.edu/index.php?title=File:Jupyter.png&amp;diff=77"/>
		<updated>2024-05-24T02:11:47Z</updated>

		<summary type="html">&lt;p&gt;Skipper: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;test&lt;/div&gt;</summary>
		<author><name>Skipper</name></author>
	</entry>
	<entry>
		<id>https://info.stat.cmu.edu/index.php?title=File:Env.png&amp;diff=76</id>
		<title>File:Env.png</title>
		<link rel="alternate" type="text/html" href="https://info.stat.cmu.edu/index.php?title=File:Env.png&amp;diff=76"/>
		<updated>2024-05-24T02:11:24Z</updated>

		<summary type="html">&lt;p&gt;Skipper: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Env&lt;/div&gt;</summary>
		<author><name>Skipper</name></author>
	</entry>
	<entry>
		<id>https://info.stat.cmu.edu/index.php?title=File:Remote_file.png&amp;diff=75</id>
		<title>File:Remote file.png</title>
		<link rel="alternate" type="text/html" href="https://info.stat.cmu.edu/index.php?title=File:Remote_file.png&amp;diff=75"/>
		<updated>2024-05-24T02:10:34Z</updated>

		<summary type="html">&lt;p&gt;Skipper: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;RTENOTITLE&lt;/div&gt;</summary>
		<author><name>Skipper</name></author>
	</entry>
	<entry>
		<id>https://info.stat.cmu.edu/index.php?title=File:Hosts.png&amp;diff=74</id>
		<title>File:Hosts.png</title>
		<link rel="alternate" type="text/html" href="https://info.stat.cmu.edu/index.php?title=File:Hosts.png&amp;diff=74"/>
		<updated>2024-05-24T02:09:34Z</updated>

		<summary type="html">&lt;p&gt;Skipper: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;RTENOTITLE&lt;/div&gt;</summary>
		<author><name>Skipper</name></author>
	</entry>
	<entry>
		<id>https://info.stat.cmu.edu/index.php?title=VSCode&amp;diff=73</id>
		<title>VSCode</title>
		<link rel="alternate" type="text/html" href="https://info.stat.cmu.edu/index.php?title=VSCode&amp;diff=73"/>
		<updated>2024-05-24T02:08:31Z</updated>

		<summary type="html">&lt;p&gt;Skipper: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
VSCode is an open-source IDE maintained by Microsoft, and it is considered a “lightweight” code editor. In comparison with full integrated development environment (IDE) editors which occupy gigabytes of disk space, VS Code uses less than 200MB when installed. Despite the “lightweight” term, Visual Studio Code offers a massive number of features (via so-called “extensions”) which keep increasing and improving with every new update.&amp;amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
Resources:&lt;br /&gt;
&lt;br /&gt;
#[https://code.visualstudio.com/docs Official documentation] &lt;br /&gt;
#[https://code.visualstudio.com/download Download] &lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
== Basic Usage ==&lt;br /&gt;
&lt;br /&gt;
Some good extensions:&amp;amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
#Python (and Pylance) &lt;br /&gt;
#Jupyter &lt;br /&gt;
#R &lt;br /&gt;
#LaTeX Workshop &lt;br /&gt;
#Remote - SSH &lt;br /&gt;
#autoDocstring &lt;br /&gt;
&lt;br /&gt;
== Remote Development and Prototyping via SSH ==&lt;br /&gt;
&lt;br /&gt;
In this section we will learn how to use VSCode to manage, develop, and test code that we have stored on a remote server (like [https://www.stat.cmu.edu/computewiki/index.php/Linux_and_department_servers Hydras], [https://www.stat.cmu.edu/computewiki/index.php/Azure_getting_started Azure], etc...).&lt;br /&gt;
&lt;br /&gt;
This is particularly useful to &amp;lt;u&amp;gt;avoid&amp;lt;/u&amp;gt; painful workflows that see us doing the following:&lt;br /&gt;
&lt;br /&gt;
#develop locally on our laptop &lt;br /&gt;
#&amp;lt;font face=&amp;quot;monospace&amp;quot;&amp;gt;scp&amp;lt;/font&amp;gt; some scripts to the remote server and run them (assuming we have consistent environments) &lt;br /&gt;
#&amp;lt;font face=&amp;quot;monospace&amp;quot;&amp;gt;scp&amp;amp;nbsp;&amp;lt;/font&amp;gt;the results to the local laptop &lt;br /&gt;
#repeat from 1 &lt;br /&gt;
&lt;br /&gt;
Ideally, we want to be able to use the remote server only as the computational workhorse, while leveraging the GUI of our local operative system. Doing this in VSCode is extremely simple:&lt;br /&gt;
&lt;br /&gt;
#In the left toolbar, click on the “Extensions” button and search for SSH. The correct one is hte one developed by Microsoft (blue icon). Click on the install button.&lt;br /&gt;
&lt;br /&gt;
[[File:Ssh.png|1000x1000px|RTENOTITLE]] &lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;ol start=&amp;quot;2&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Once the extension is installed, click on the small green button at the very bottom-left of the window (the one with a symbol similar to &amp;gt;&amp;lt;). A pop-up window at the top will open: click on “Connect to Host”&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;At this point, we have two alternatives: &lt;br /&gt;
#&amp;amp;nbsp;add a new SSH host manually, which will prompt another small window where to enter the connection details (similar to what one does from the terminal) &lt;br /&gt;
#or&amp;amp;nbsp;&#039;&#039;&#039;&amp;lt;u&amp;gt;better&amp;lt;/u&amp;gt;&#039;&#039;&#039;, if we have a SSH&amp;amp;nbsp;&amp;lt;code&amp;gt;config&amp;amp;nbsp;&amp;lt;/code&amp;gt;file in the &amp;lt;code&amp;gt;.ssh&amp;amp;nbsp;&amp;lt;/code&amp;gt;directory, VSCode will automatically list the possible remote servers that are specified in this file. If we specified a path to a key, then VSCode will connect automatically. If instead the remote server requires a password (as it is the case for Hydras), then we will be prompted with another window to enter it. As an example:[[File:Ssh config.png|RTENOTITLE]] &lt;br /&gt;
&amp;lt;ol start=&amp;quot;4&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Congratulations! You are now connected to a remote server through VSCode. By clicking on the “Explorer”&amp;amp;nbsp;button at the top in the left-side toolbar, you can navigate the file system of the server, develop and run code, etc. Everything you do and see is actually being hosted, run, and saved remotely.&amp;amp;nbsp;[[File:Remote file.png|1000x1000px|Remote file.png]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
== Managing environments within VSCode ==&lt;br /&gt;
&lt;br /&gt;
Since each project might (and should) have its own development environment that you setup, with dependencies and packages that make it unique for the tasks of this project, VSCode allows to easily choose which interpreter&amp;amp;nbsp;to use.&amp;amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
We simply have to click at the bottom right&amp;amp;nbsp;of the window, on the button that shows the current Python (or other language) version that we are using. This will open a prompt to choose the environment among those present on the&amp;amp;nbsp;machine we are developing on:&lt;br /&gt;
&lt;br /&gt;
[[File:Env.png|1000x1000px|Env.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
== Support for Jupyter Notebooks (even remote!) within VSCode ==&lt;br /&gt;
&lt;br /&gt;
In one of the previous section we learned how to setup VSCode for remote development. A great feature of the workflow that we have just enabled is that we can run Jupyter Notebooks (and produce plots, tables, etc...) that are hosted remotely while seeing the output on our local laptop within VSCode (this works also if we are running things locally). Doing so is very easy:&lt;br /&gt;
&lt;br /&gt;
#Click on the “Extensions” button on the left toolbar and download the Jupyter&amp;amp;nbsp;extension &lt;br /&gt;
&lt;br /&gt;
[[File:Jupyter.png|1000x1000px|Jupyter.png]]&lt;br /&gt;
&amp;lt;ol start=&amp;quot;2&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Open a .ipynb file and choose the kernel (interpreter for the correct project environment) from the button that appears at the top right of the opened notebook&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Choose kernel.png|1000x1000px|Choose kernel.png]]&lt;br /&gt;
&amp;lt;ol start=&amp;quot;3&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Happy coding!&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Support for RStudio (even remote!) within VSCode ==&lt;br /&gt;
&lt;br /&gt;
Install the R extension, which provides support for the&amp;amp;nbsp;[https://www.r-project.org/ R programming language], including features such as extended syntax highlighting, R language service based on code analysis, interacting with R terminals, viewing data, plots, workspace variables, help pages, managing packages, and working with&amp;amp;nbsp;[https://rmarkdown.rstudio.com/ R Markdown]&amp;amp;nbsp;documents.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Miscellanea ==&lt;br /&gt;
&lt;br /&gt;
=== Amphetamine ===&lt;br /&gt;
&lt;br /&gt;
If you need your laptop to stay awake while there&#039;s a process running --- you are running some cell in a notebook via remote SSH --- check out this [[Amphetamine|article in the wiki]].&lt;br /&gt;
&lt;br /&gt;
=== Tunnelling ===&lt;br /&gt;
&lt;br /&gt;
Disclaimer: this is particularly useful for PSC (Pittsburgh Supercomuting Center) users, as it allows to connect directly to a compute node on PSC and have things like Jupyter Notebooks run via VSCode without problems. This solution bypasses a problem incurred when connecting via SSH from VSCode, which caused to land on the login nodes. These have very little memory and basically do not support any computation.&lt;br /&gt;
&lt;br /&gt;
Instructions for creating a VS code tunnel to PSC:&lt;br /&gt;
&lt;br /&gt;
*First set up code CLI on PSC: [https://dev.to/burkeholland/introducing-vs-code-remote-tunnels-connect-to-remote-machines-with-ease-3nlg https://dev.to/burkeholland/introducing-vs-code-remote-tunnels-connect-to-remote-machines-with-ease-3nlg&amp;amp;nbsp;] &lt;br /&gt;
*Then run the following: &lt;br /&gt;
&amp;lt;pre&amp;gt;    curl -Lk &#039;https://code.visualstudio.com/sha/download?build=stable&amp;amp;os=cli-alpine-x64&#039; --output vscode_cli.tar.gz&lt;br /&gt;
    tar -xf vscode_cli.tar.gz&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp;This will create a &amp;quot;code&amp;quot; executable file which we need to add to the path. Open &amp;lt;code&amp;gt;.bashrc&amp;lt;/code&amp;gt;&amp;amp;nbsp;(or &amp;lt;code&amp;gt;.zshrc&amp;amp;nbsp;&amp;lt;/code&amp;gt;if you have a recent Mac) and edit the line that exports the path to be&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;pre&amp;gt;export PATH=&amp;quot;/jet/home/&amp;lt;username&amp;gt;:$PATH&amp;quot;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Restart the shell and check that &amp;quot;which code&amp;quot; finds the installation. &lt;br /&gt;
*Next, install the remote tunnels and remote ssh extensions on VS code. &lt;br /&gt;
**These are found in the extensions menu &lt;br /&gt;
**After installation there should be a blue &amp;quot;open remote window&amp;quot; (&amp;gt;&amp;lt; symbol) in the bottom left of the VS code window. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Next, we set up the tunnel: [https://dev.to/burkeholland/introducing-vs-code-remote-tunnels-connect-to-remote-machines-with-ease-3nlg https://dev.to/burkeholland/introducing-vs-code-remote-tunnels-connect-to-remote-machines-with-ease-3nlg&amp;amp;nbsp;] &lt;br /&gt;
**Start interactive job &lt;br /&gt;
**Run &amp;lt;code&amp;gt;code tunnel&amp;lt;/code&amp;gt;&amp;amp;nbsp;and follow the instructions. I recommend logging in via GitHub the first time and occasionally you will be asked to name the machine. By default it will name it based off of the node you are currently interacting with; however, the tunnel will connect to any node at PSC via the same setup so I recommend you name it something generic related to PSC. You will eventually see a message like “Open this link in your browser https://vscode.dev/tunnel/&amp;lt;machine name&amp;gt;” &lt;br /&gt;
**On VS Code on your local machine, click the blue &amp;quot;open remote window&amp;quot; (&amp;gt;&amp;lt; symbol) in the bottom left and select Connect to Tunnel. &lt;br /&gt;
**Select GitHub and then the machine that matches &amp;lt;machine name&amp;gt; in the link shown on the remote location. This should reload your VS code window to be running on the remote server, but if you started an interactive job it is running on a compute node. &lt;br /&gt;
**To stop the connection, run &amp;quot;ctrl + c&amp;quot; &lt;br /&gt;
**If you need to deregister the tunnel run &amp;quot;code tunnel unregister&amp;quot; however, this should be unnecessary &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For any future connection you run this same set of steps, as&amp;amp;nbsp;I haven&#039;t found a way to avoid re logging in via github every time.&lt;/div&gt;</summary>
		<author><name>Skipper</name></author>
	</entry>
	<entry>
		<id>https://info.stat.cmu.edu/index.php?title=File:Ssh_config.png&amp;diff=72</id>
		<title>File:Ssh config.png</title>
		<link rel="alternate" type="text/html" href="https://info.stat.cmu.edu/index.php?title=File:Ssh_config.png&amp;diff=72"/>
		<updated>2024-05-24T02:08:16Z</updated>

		<summary type="html">&lt;p&gt;Skipper: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;RTENOTITLE&lt;/div&gt;</summary>
		<author><name>Skipper</name></author>
	</entry>
	<entry>
		<id>https://info.stat.cmu.edu/index.php?title=File:Ssh.png&amp;diff=71</id>
		<title>File:Ssh.png</title>
		<link rel="alternate" type="text/html" href="https://info.stat.cmu.edu/index.php?title=File:Ssh.png&amp;diff=71"/>
		<updated>2024-05-24T02:04:53Z</updated>

		<summary type="html">&lt;p&gt;Skipper: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;RTENOTITLE&lt;/div&gt;</summary>
		<author><name>Skipper</name></author>
	</entry>
	<entry>
		<id>https://info.stat.cmu.edu/index.php?title=Developing_python_packages&amp;diff=70</id>
		<title>Developing python packages</title>
		<link rel="alternate" type="text/html" href="https://info.stat.cmu.edu/index.php?title=Developing_python_packages&amp;diff=70"/>
		<updated>2024-05-24T02:00:16Z</updated>

		<summary type="html">&lt;p&gt;Skipper: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This wiki presents a motivational example of a lot of properties of python packages and how to use them. Please see [[packages motivation]] for motivation about why you should utilize the package framework while doing research. This material captures the basics presented by [https://py-pkgs.org/ py-pkgs], (recently) developed by UBC professors. As such you’ll find that python packages online may have different structures. Still, &amp;lt;code&amp;gt;py-pkgs&amp;lt;/code&amp;gt; provides a lot of helpful tools to automate python package development. The &amp;lt;code&amp;gt;py-pkgs&amp;lt;/code&amp;gt; project was actually started to mirror the helpful [[Developing_R_packages|package development tools in &amp;lt;code&amp;gt;R&amp;lt;/code&amp;gt;]]. Note that this wiki page does provide additional commentary but the process proposed is very similar to &amp;lt;code&amp;gt;py-pkgs&amp;lt;/code&amp;gt;’s approach.&lt;br /&gt;
&lt;br /&gt;
== Foundations (what tools will be used) ==&lt;br /&gt;
&lt;br /&gt;
In the package development pipeline that is proposed by &amp;lt;code&amp;gt;py-pkgs&amp;lt;/code&amp;gt; we have a few very power packages to help you develop an &amp;lt;code&amp;gt;python&amp;lt;/code&amp;gt; package as painlessly as possible.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;poetry&amp;lt;/code&amp;gt; help build a python package&lt;br /&gt;
* &amp;lt;code&amp;gt;cookiecutter&amp;lt;/code&amp;gt; helps utilize pre-made templates (for our package’s files)&lt;br /&gt;
* &amp;lt;code&amp;gt;pytest&amp;lt;/code&amp;gt; provides clean and standardized tools for testing&lt;br /&gt;
* (numpy style code) provides rubrics for documentation&lt;br /&gt;
&lt;br /&gt;
== Building an python package ==&lt;br /&gt;
&lt;br /&gt;
This process is slightly different than the one we demonstrated in the [[Developing_R_packages]] wiki (we set up the structure of the package and then link to github).&lt;br /&gt;
&lt;br /&gt;
=== Step 1: Creating a minimal source package ===&lt;br /&gt;
&lt;br /&gt;
A python (&#039;&#039;source&#039;&#039;) package just files in a directory, formatted in a specific way.&lt;br /&gt;
&lt;br /&gt;
To create the bare bones python package, we will be using the packages &amp;lt;code&amp;gt;poetry&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;cookiecutter&amp;lt;/code&amp;gt;, so if you haven’t already done so, install those two packages (we’ll be using &amp;lt;code&amp;gt;conda&amp;lt;/code&amp;gt;) by typing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;conda install -c conda-forge poetry cookiecutter&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&#039;&#039;Note that this line is taken directly from [https://py-pkgs.org/02-setup py-pkgs/02-setup], and it is possible that some day these packages can be installed wit ha simple &amp;lt;code&amp;gt;conda install poetry cookiecutter&amp;lt;/code&amp;gt;.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Now&#039;&#039;&#039;, to actually start setting up your python package we will first use &amp;lt;code&amp;gt;cookiecutter&amp;lt;/code&amp;gt; to copy a package structure provided by &amp;lt;code&amp;gt;py-pkgs&amp;lt;/code&amp;gt; by running the following in our terminal:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;cookiecutter https://github.com/UBC-MDS/cookiecutter-ubc-mds.git&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
This will prompt you to answer a set of questions including &lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; the author name (can include caps and spaces) &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; github username &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; package name (can include caps and spaces) &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; package slug name (can included underscores but no spaces) &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; a short package description (can include caps and spaces) &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; version number (we recommend either 0.0.1 or 0.1.0) &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; python version 8. open source license (they list the options) &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; if the package should include github actions (we suggest no for now, and plan to have wikis help with this later) &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note: our package for this example will be named &amp;lt;code&amp;gt;tartanpy&amp;lt;/code&amp;gt;&#039;&#039; (an a copy of the &amp;quot;final&amp;quot; product can be found on [https://github.com/benjaminleroy/tartanpy|github].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note: the cookiecutter template from &amp;lt;code&amp;gt;py-pkg&amp;lt;/code&amp;gt;s (aka the one above) is still under construction - so it might look slightly different in the future.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This will create a &amp;lt;code&amp;gt;tartanpy&amp;lt;/code&amp;gt; folder with the following items:&lt;br /&gt;
&lt;br /&gt;
# Directory &amp;lt;code&amp;gt;src/&amp;lt;/code&amp;gt; (where all the function source code goes)&lt;br /&gt;
# Directory &amp;lt;code&amp;gt;docs/&amp;lt;/code&amp;gt; (where all the pretty looking documentation goes &#039;&#039;&#039;- auto generated&#039;&#039;&#039;)&lt;br /&gt;
# Directory &amp;lt;code&amp;gt;tests/&amp;lt;/code&amp;gt; (where you’ll store your test, with a placeholder test file)&lt;br /&gt;
# &amp;lt;code&amp;gt;pyproject.toml&amp;lt;/code&amp;gt; file (a description file about your package, which includes the things you entered when you ran the &amp;lt;code&amp;gt;cookiecutter&amp;lt;/code&amp;gt; call)&lt;br /&gt;
# &amp;lt;code&amp;gt;LICENSE&amp;lt;/code&amp;gt; (booler plate License - don’t really need to deal with this)&lt;br /&gt;
# A set of &amp;lt;code&amp;gt;.md&amp;lt;/code&amp;gt; files for document things like general info for viewers (&amp;lt;code&amp;gt;README.md&amp;lt;/code&amp;gt;), info for contributors and their conduct (&amp;lt;code&amp;gt;CONTRIBUTING.md&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;CONDUCT.md&amp;lt;/code&amp;gt;) and a file to include information on changes you’ve made &amp;lt;code&amp;gt;CHANGELOG.md&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
[[File:1200px-Tartanpy folder.png|300px|frame|left|initial directory items]]&lt;br /&gt;
&lt;br /&gt;
==== pyproject.toml file meta-data ====&lt;br /&gt;
&lt;br /&gt;
There are few ways for packages to store their meta-data, and &amp;lt;code&amp;gt;py-pkgs&amp;lt;/code&amp;gt;’s path is through the &amp;lt;code&amp;gt;pyproject.toml&amp;lt;/code&amp;gt;. Other options include things like &amp;lt;code&amp;gt;setup.py&amp;lt;/code&amp;gt; files. If you made a mistake when answering questions via your cookiecutter prompts you can change them by opening up the &amp;lt;code&amp;gt;pyproject.toml&amp;lt;/code&amp;gt; file. Our example package’s &amp;lt;code&amp;gt;pyproject.toml&amp;lt;/code&amp;gt; file looks like the image below&lt;br /&gt;
&lt;br /&gt;
[[File:1200px-Tartanpy pyproject description.png|300px|frame|left|initialized description file]]&lt;br /&gt;
&lt;br /&gt;
In a &amp;lt;code&amp;gt;pyproject.toml&amp;lt;/code&amp;gt; file you’ll notice that each section is headed by a &amp;lt;code&amp;gt;[info]&amp;lt;/code&amp;gt; heading. Notice that three of the sections in the image above have &amp;lt;code&amp;gt;tool.poetry&amp;lt;/code&amp;gt; headers. This means that the package &amp;lt;code&amp;gt;poetry&amp;lt;/code&amp;gt; can update these sections. As we showcase the power of this package you may find that using poetry to update a lot of these fields is more desirable than manually doing it yourself.&lt;br /&gt;
&lt;br /&gt;
=== Step 2: Setting up a Github repo ===&lt;br /&gt;
&lt;br /&gt;
Version control (and discussed in Stat Computing) is a very useful tool to help streamline file management and provide piece of mind. Oftentimes, you will want to have a copy of the repository not just on your personal computer but online (to help with sharing, just in case your computer dies, it’s cool, etc.). As such these steps will walk you through how to set up a github repo for your new package and how to connect that repo to a new python package. This step will mirror thoughts in [https://py-pkgs.org/03-how-to-package-a-python#set-up-remote-version-control py-pkgs/03-how-to-package-a-python].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: decimal;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;&#039;&#039;&#039;In &amp;lt;code&amp;gt;Github&amp;lt;/code&amp;gt;&#039;&#039;&#039;, do the following&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;go to the top-level directory (i.e., &amp;lt;code&amp;gt;github.com/&amp;lt;your user name&amp;gt;&amp;lt;/code&amp;gt;)&amp;lt;/p&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;click on “+” at top right, and select “New repository”&amp;lt;/p&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;name the repository (e.g., “tartan_python”). Note that if you’d like to share your package with others via pypi you’ll need to make your package name unique!&amp;lt;/p&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;provide a short description of the repository (don’t leave completely blank!)&amp;lt;/p&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;keep the repository public (as students you have access to free private repos https://education.github.com/pack, but for purposes of this example we will keep the repo public)&amp;lt;/p&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;&#039;&#039;&#039;do not&#039;&#039;&#039; initalize with a README, .gitignore, or license (It even says “Skip this step if you’re importing an exisiting repo”!!!)&amp;lt;/p&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;click on “Create Repository”&amp;lt;/p&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;&#039;&#039;&#039;…then in your terminal, do the following&#039;&#039;&#039;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;First, initialize your repository with&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;git init&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;then add all &amp;lt;code&amp;gt;cookiecutter&amp;lt;/code&amp;gt; files and create your initial commit with &amp;lt;code&amp;gt;bash  git add .  git commit -m &amp;quot;initial package setup&amp;quot;&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;setup connection to github by adding a a remote, your main branch and pushing your first commit with&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;git remote add origin https://github.com/benjaminleroy/tartanpy.git&lt;br /&gt;
git branch -M main&lt;br /&gt;
git push -u origin main&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&#039;&#039;Note that github provides you with walk throughs that mirror what was recommended above and showcases 2 approaches if you want to use the command line (&amp;lt;code&amp;gt;https&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;) as well as how you might do it with github desktop. So helpful - thanks github!&#039;&#039;&amp;lt;/p&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Step 3: Writing a function ===&lt;br /&gt;
&lt;br /&gt;
All of your python code needs to go in &amp;lt;code&amp;gt;.py&amp;lt;/code&amp;gt; files in the &amp;lt;code&amp;gt;src/tartanpy/&amp;lt;/code&amp;gt; directory. Suppose our first set of functions deal with communicating to the user - then we might make a &amp;lt;code&amp;gt;communicate.py&amp;lt;/code&amp;gt; file in &amp;lt;code&amp;gt;src/tartanpy/&amp;lt;/code&amp;gt; folder. &amp;lt;br&amp;gt; Inside this file, let’s image we add the following function&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;def call_scotty_demo(your_name):&lt;br /&gt;
&lt;br /&gt;
    name_length = len(your_name)&lt;br /&gt;
&lt;br /&gt;
    # say Hiiiiii&lt;br /&gt;
    hi_string = &amp;quot;\n&amp;quot; +\&lt;br /&gt;
        &amp;quot;-&amp;quot; * (name_length + 8) + &amp;quot;\n&amp;quot; +\&lt;br /&gt;
        &amp;quot;| Hi &amp;quot; + your_name + &amp;quot;! | \n&amp;quot; +\&lt;br /&gt;
        &amp;quot;|   &amp;quot; + &amp;quot;-&amp;quot; * (name_length + 4) + &amp;quot;\n&amp;quot; +\&lt;br /&gt;
        &amp;quot;| /\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    scotty_string = &amp;quot;&amp;quot;+\&lt;br /&gt;
        &amp;quot; |/  |\\_/|          \n&amp;quot; +\&lt;br /&gt;
        &amp;quot; |   |q p|   /}      \n&amp;quot; +\&lt;br /&gt;
        &amp;quot; |   ( 0 )\&amp;quot;\&amp;quot;\&amp;quot;\\   \n&amp;quot; +\&lt;br /&gt;
        &amp;quot;  \\  |\&amp;quot;-\&amp;quot;`    |    \n&amp;quot; +\&lt;br /&gt;
        &amp;quot;     || /=\\\\  |     \n&amp;quot; +\&lt;br /&gt;
        &amp;quot;     \&amp;quot;&#039;\&amp;quot;  &#039;\&amp;quot;\&amp;quot;\&amp;quot;&#039;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    print(hi_string + scotty_string)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
To get access to this function we can use &amp;lt;code&amp;gt;poetry&amp;lt;/code&amp;gt; to locally install our package with the bash command below (that needs to be run in the top folder of our package)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;poetry install&amp;lt;/pre&amp;gt;&lt;br /&gt;
&#039;&#039;Note that without poetry this could be done with a &amp;lt;code&amp;gt;pip install -e .&amp;lt;/code&amp;gt; in the same directory and this would actually not require running this line of code every time we update the package. On the other hand - we’ll show the versatility of &amp;lt;code&amp;gt;poetry&amp;lt;/code&amp;gt; in the rest of the article.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To utilize our function we can then open up a interactive python instance (e.g. &amp;lt;code&amp;gt;ipython&amp;lt;/code&amp;gt; in your terminal) and then run&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;In [1]: from tartanpy import communicate&lt;br /&gt;
&lt;br /&gt;
In [2]: communicate.call_scotty_demo(&amp;quot;Andrew Carnegie&amp;quot;)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
which will return:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;-----------------------&lt;br /&gt;
| Hi Andrew Carnegie! |&lt;br /&gt;
|   -------------------&lt;br /&gt;
| /&lt;br /&gt;
 |/  |\_/|&lt;br /&gt;
 |   |q p|   /}&lt;br /&gt;
 |   ( 0 )&amp;quot;&amp;quot;&amp;quot;\&lt;br /&gt;
  \  |&amp;quot;-&amp;quot;`    |&lt;br /&gt;
     || /=\\  |&lt;br /&gt;
     &amp;quot;&#039;&amp;quot;  &#039;&amp;quot;&amp;quot;&amp;quot;&#039;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Note that &amp;lt;code&amp;gt;poetry install&amp;lt;/code&amp;gt; can be called over and over if you keep updating your function files and will re-load the newest verion of all your functions.&lt;br /&gt;
&lt;br /&gt;
==== Additional notes: ====&lt;br /&gt;
&lt;br /&gt;
===== Understanding &amp;lt;code&amp;gt;__init__.py&amp;lt;/code&amp;gt; =====&lt;br /&gt;
&lt;br /&gt;
For &amp;lt;code&amp;gt;python&amp;lt;/code&amp;gt; packages you’ll always have an &amp;lt;code&amp;gt;__init__.py&amp;lt;/code&amp;gt; file in this directory. We currently have to import the &amp;lt;code&amp;gt;communicate&amp;lt;/code&amp;gt; file from &amp;lt;code&amp;gt;tartanpy&amp;lt;/code&amp;gt; in order to get access to our amazing function. To make this function come directly with the package, in the &amp;lt;code&amp;gt;__init__.py&amp;lt;/code&amp;gt; file we can write&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;from .communicate import call_scotty_demo&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&#039;&#039;Note the dot in &amp;lt;code&amp;gt;.communicate&amp;lt;/code&amp;gt; says “in this same directory as this current file”, and we don’t have to include the &amp;lt;code&amp;gt;.py&amp;lt;/code&amp;gt; file link at the end.&#039;&#039; Additionally This approach &#039;&#039;&#039;only&#039;&#039;&#039; imports call_scotty_demo to the global package, we could use &amp;lt;code&amp;gt;... import *&amp;lt;/code&amp;gt; to import all functions (but this approach is smart if we had helper functions we didn’t really need to share with the end user).*&lt;br /&gt;
&lt;br /&gt;
With the above change, we can then do (the &amp;lt;code&amp;gt;poetry&amp;lt;/code&amp;gt; part still needs to be at the top directory):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;poetry install&lt;br /&gt;
ipython&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
and then in the ipython shell:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;In [1]: import tartanpy&lt;br /&gt;
&lt;br /&gt;
In [2]: tartanpy.call_scotty_demo(&amp;quot;Andrew Mellon&amp;quot;)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
which will return:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;---------------------&lt;br /&gt;
| Hi Andrew Mellon! |&lt;br /&gt;
|   -----------------&lt;br /&gt;
| /&lt;br /&gt;
 |/  |\_/|&lt;br /&gt;
 |   |q p|   /}&lt;br /&gt;
 |   ( 0 )&amp;quot;&amp;quot;&amp;quot;\&lt;br /&gt;
  \  |&amp;quot;-&amp;quot;`    |&lt;br /&gt;
     || /=\\  |&lt;br /&gt;
     &amp;quot;&#039;&amp;quot;  &#039;&amp;quot;&amp;quot;&amp;quot;&#039;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===== Using external packages =====&lt;br /&gt;
&lt;br /&gt;
[You&#039;ll want to read the next section as well for a full understanding of dealing with external packages.]&lt;br /&gt;
&lt;br /&gt;
Suppose I wished to truncate really long names I’m greeting but also give the user a warning that I’m going to do so. I’d need to use the &amp;lt;code&amp;gt;warnings&amp;lt;/code&amp;gt; package. To use this in our package I’d need to change our &amp;lt;code&amp;gt;communicate.py&amp;lt;/code&amp;gt; file to&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;import warnings&lt;br /&gt;
&lt;br /&gt;
def call_scotty_demo(your_name):&lt;br /&gt;
    if len(your_name) &amp;gt; 30:&lt;br /&gt;
        warnings.warn(&amp;quot;your name is beyond 30 characters, &amp;quot;+\&lt;br /&gt;
                        &amp;quot;has been truncated&amp;quot;)&lt;br /&gt;
        your_name = your_name[:30]&lt;br /&gt;
&lt;br /&gt;
    name_length = len(your_name)&lt;br /&gt;
&lt;br /&gt;
    # say Hiiiiii&lt;br /&gt;
    hi_string = &amp;quot;\n&amp;quot; +\&lt;br /&gt;
        &amp;quot;-&amp;quot; * (name_length + 8) + &amp;quot;\n&amp;quot; +\&lt;br /&gt;
        &amp;quot;| Hi &amp;quot; + your_name + &amp;quot;! | \n&amp;quot; +\&lt;br /&gt;
        &amp;quot;|   &amp;quot; + &amp;quot;-&amp;quot; * (name_length + 4) + &amp;quot;\n&amp;quot; +\&lt;br /&gt;
        &amp;quot;| /\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    scotty_string = &amp;quot;&amp;quot;+\&lt;br /&gt;
        &amp;quot; |/  |\\_/|          \n&amp;quot; +\&lt;br /&gt;
        &amp;quot; |   |q p|   /}      \n&amp;quot; +\&lt;br /&gt;
        &amp;quot; |   ( 0 )\&amp;quot;\&amp;quot;\&amp;quot;\\   \n&amp;quot; +\&lt;br /&gt;
        &amp;quot;  \\  |\&amp;quot;-\&amp;quot;`    |    \n&amp;quot; +\&lt;br /&gt;
        &amp;quot;     || /=\\\\  |     \n&amp;quot; +\&lt;br /&gt;
        &amp;quot;     \&amp;quot;&#039;\&amp;quot;  &#039;\&amp;quot;\&amp;quot;\&amp;quot;&#039;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    print(hi_string + scotty_string)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Notice that we have to impot the &amp;lt;code&amp;gt;warnings&amp;lt;/code&amp;gt; package at the top of our function file.&lt;br /&gt;
&lt;br /&gt;
Now we have the additional funcitonality (after reloading with &amp;lt;code&amp;gt;poetry&amp;lt;/code&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;In [1]: import tartanpy&lt;br /&gt;
&lt;br /&gt;
In [2]: tartanpy.call_scotty_demo(&amp;quot;Oski Bear, your a wonderful, but slightly creepy Berkeley Bear&amp;quot;)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
which returns&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;.../tartanpy/src/tartanpy/communicate.py:6: UserWarning: your name is beyond 30 characters, has been truncated&lt;br /&gt;
  warnings.warn(&amp;quot;your name is beyond 30 characters, &amp;quot;+\&lt;br /&gt;
&lt;br /&gt;
--------------------------------------&lt;br /&gt;
| Hi Oski Bear, your a wonderful, b! |&lt;br /&gt;
|   ----------------------------------&lt;br /&gt;
| /&lt;br /&gt;
 |/  |\_/|&lt;br /&gt;
 |   |q p|   /}&lt;br /&gt;
 |   ( 0 )&amp;quot;&amp;quot;&amp;quot;\&lt;br /&gt;
  \  |&amp;quot;-&amp;quot;`    |&lt;br /&gt;
     || /=\\  |&lt;br /&gt;
     &amp;quot;&#039;&amp;quot;  &#039;&amp;quot;&amp;quot;&amp;quot;&#039;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==== Using external packages: declaring dependences &amp;amp; Using local functions in other files ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: decimal;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;&#039;&#039;&#039;Declaring dependencies&#039;&#039;&#039;: The &amp;lt;code&amp;gt;warnings&amp;lt;/code&amp;gt; module is actually a built in python package, but suppose we also needed to use &amp;lt;code&amp;gt;numpy&amp;lt;/code&amp;gt; in our package. For example, suppose we created another &amp;lt;code&amp;gt;.py&amp;lt;/code&amp;gt; file called &amp;lt;code&amp;gt;utils.py&amp;lt;/code&amp;gt;, in it we had&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;import numpy as np&lt;br /&gt;
&lt;br /&gt;
def _top_and_bottom(name_length):&lt;br /&gt;
    length_vec = np.array([8,4]) + name_length&lt;br /&gt;
    return(length_vec)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;The first thing we’d need to do (so the code works for others) is to tell the package we require the installation of &amp;lt;code&amp;gt;numpy&amp;lt;/code&amp;gt; for anyone using our package. We do so by running&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;poetry add numpy&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;This will update our &amp;lt;code&amp;gt;pyproject.toml&amp;lt;/code&amp;gt; and add asssociated dependences (there are none for &amp;lt;code&amp;gt;numpy&amp;lt;/code&amp;gt;), and will put that note under &amp;lt;code&amp;gt;[tool.poetry.dependencies]&amp;lt;/code&amp;gt;.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&#039;&#039;Note: as of 8/20/21 this also required restricting my python version (in the &amp;lt;code&amp;gt;pyproject.toml&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;python = &amp;quot;?=3.8,&amp;lt;3.11&amp;quot;&amp;lt;/code&amp;gt;)&amp;lt;/p&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;&#039;&#039;&#039;Internal Functions&#039;&#039;&#039;: To use our interal function &amp;lt;code&amp;gt;_top_and_bottom&amp;lt;/code&amp;gt; we might change the &amp;lt;code&amp;gt;communicate.py&amp;lt;/code&amp;gt; file to:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;import warnings&lt;br /&gt;
from .utils import _top_and_bottom&lt;br /&gt;
&lt;br /&gt;
def call_scotty_demo(your_name):&lt;br /&gt;
    # import warnings&lt;br /&gt;
    if len(your_name) &amp;gt; 30:&lt;br /&gt;
        warnings.warn(&amp;quot;your name is beyond 30 characters, &amp;quot;+\&lt;br /&gt;
                        &amp;quot;has been truncated&amp;quot;)&lt;br /&gt;
        your_name = your_name[:30]&lt;br /&gt;
&lt;br /&gt;
    name_length = len(your_name)&lt;br /&gt;
&lt;br /&gt;
    tb_info = _top_and_bottom(name_length)&lt;br /&gt;
&lt;br /&gt;
    # say Hiiiiii&lt;br /&gt;
    hi_string = &amp;quot;\n&amp;quot; +\&lt;br /&gt;
        &amp;quot;-&amp;quot; * tb_info[0] + &amp;quot;\n&amp;quot; +\&lt;br /&gt;
        &amp;quot;| Hi &amp;quot; + your_name + &amp;quot;! | \n&amp;quot; +\&lt;br /&gt;
        &amp;quot;|   &amp;quot; + &amp;quot;-&amp;quot; * tb_info[1] + &amp;quot;\n&amp;quot; +\&lt;br /&gt;
        &amp;quot;| /\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    ...&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Notice that to give &amp;lt;code&amp;gt;call_scotty_demo&amp;lt;/code&amp;gt; and all functions in the &amp;lt;code&amp;gt;communicate.py&amp;lt;/code&amp;gt; file access to &amp;lt;code&amp;gt;_top_and_bottom&amp;lt;/code&amp;gt; we had to import it using &amp;lt;code&amp;gt;from .utils import _top_and_bottom&amp;lt;/code&amp;gt;. Additionally, it’s best practice to use add a &amp;lt;code&amp;gt;_&amp;lt;/code&amp;gt; at the beginning of a function name if you plan to keep it internal.&amp;lt;/p&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Step 4: Documenting your functions ===&lt;br /&gt;
&lt;br /&gt;
Python documentation is simplier than R documentation as when you look at the documentation of a python function you just get show a docstring at the head of function. In this section we’ll discuss a bit about the extra support poetry can do so that you can generate a localized website for your documentation (that you could upload to [https:://readthedocs.org readthedocs] later).&lt;br /&gt;
&lt;br /&gt;
For documentation to be easily publishable at a later date we recommend that your docstrings follow the &amp;lt;code&amp;gt;numpydoc&amp;lt;/code&amp;gt; format (more details can be found at [https://numpydoc.readthedocs.io/en/latest/format.html#docstring-standard numpydoc.readthedocs]). Using this guideline we can document &amp;lt;code&amp;gt;call_scotty_demo&amp;lt;/code&amp;gt; as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;def call_scotty_demo(your_name):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    Greet Scotty, the Scottie Dog&lt;br /&gt;
&lt;br /&gt;
    Scotty, the Scottie Dog greets your by name!&lt;br /&gt;
&lt;br /&gt;
    Parameters&lt;br /&gt;
    ----------&lt;br /&gt;
    your_name: str&lt;br /&gt;
        string of your name (max length 30 characters)&lt;br /&gt;
&lt;br /&gt;
    Returns&lt;br /&gt;
    -------&lt;br /&gt;
    None&lt;br /&gt;
        Though scotty appears on your screen and says Hi to you.&lt;br /&gt;
&lt;br /&gt;
    Examples&lt;br /&gt;
    --------&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import tartanpy&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; tartanpy.call_scotty_demo(&amp;quot;Andrew Carnegie&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    -----------------------&lt;br /&gt;
    | Hi Andrew Carnegie! |&lt;br /&gt;
    |   -------------------&lt;br /&gt;
    | /&lt;br /&gt;
    |/  |\_/|&lt;br /&gt;
    |   |q p|   /}&lt;br /&gt;
    |   ( 0 )\&amp;quot;\&amp;quot;\&amp;quot;\\&lt;br /&gt;
     \\  |\&amp;quot;-\&amp;quot;`    |&lt;br /&gt;
        || /=\\\\  |&lt;br /&gt;
        \&amp;quot;&#039;\&amp;quot;  &#039;\&amp;quot;\&amp;quot;\&amp;quot;&#039;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    ...&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The basic structure of the documention is decently straight forward with the title / description of your function first, followed by (1) Parameters header with the parameter name, the type, and the description in the format above (2) Returns header followed by similar structure as Parameters. Adding (3) examples with standard python lines can be helpful as well.&lt;br /&gt;
&lt;br /&gt;
After reloading the package you could see that&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;In [1]: import tartanpy&lt;br /&gt;
&lt;br /&gt;
In [2]: ?tartanpy.call_scotty_demo&lt;br /&gt;
Signature: tartanpy.call_scotty_demo(your_name)&lt;br /&gt;
Docstring:&lt;br /&gt;
Greet Scotty, the Scottie Dog&lt;br /&gt;
&lt;br /&gt;
Scotty, the Scottie Dog greets your by name!&lt;br /&gt;
&lt;br /&gt;
Parameters&lt;br /&gt;
----------&lt;br /&gt;
your_name: str&lt;br /&gt;
    string of your name (max length 30 characters)&lt;br /&gt;
&lt;br /&gt;
Returns&lt;br /&gt;
-------&lt;br /&gt;
None&lt;br /&gt;
    Though scotty appears on your screen and says Hi to you.&lt;br /&gt;
&lt;br /&gt;
Examples&lt;br /&gt;
--------&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import tartanpy&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; tartanpy.call_scotty_demo(&amp;quot;Andrew Carnegie&amp;quot;)&lt;br /&gt;
-----------------------&lt;br /&gt;
| Hi Andrew Carnegie! |&lt;br /&gt;
|   -------------------&lt;br /&gt;
| /&lt;br /&gt;
|/  |\_/|&lt;br /&gt;
|   |q p|   /}&lt;br /&gt;
|   ( 0 )&amp;quot;&amp;quot;&amp;quot;\&lt;br /&gt;
 \  |&amp;quot;-&amp;quot;`    |&lt;br /&gt;
    || /=\\  |&lt;br /&gt;
    &amp;quot;&#039;&amp;quot;  &#039;&amp;quot;&amp;quot;&amp;quot;&#039;&lt;br /&gt;
File:      ..../tartanpy/src/tartanpy/communicate.py&lt;br /&gt;
Type:      function&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==== Towards &amp;quot;readthedocs&amp;quot;-style html documentation ====&lt;br /&gt;
&lt;br /&gt;
py-pkgs and poetry also provide a quick way to transform your documentation into a local html website so you can quickly look through your documentation or load it to readthedocs later, with information on how to here: [https://py-pkgs.org/06-documentation py-pkgs/06-documentation].&lt;br /&gt;
&lt;br /&gt;
Generally speaking you have to&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; install some additional packages to the development side of your package with&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;poetry add --dev sphinx nbsphinx ipykernel&amp;lt;/syntaxhighlight&amp;gt; &amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;and then go to your docs folder and make the website locally (the &amp;lt;code&amp;gt;--dev&amp;lt;/code&amp;gt; parameter makes these packages not tracked for those just wanted to use your package, but required as you continue to develop the package locally).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;cd docs&lt;br /&gt;
poetry run make html&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
and this will create a local webpage (just open &amp;lt;code&amp;gt;docs/index.html&amp;lt;/code&amp;gt;) that contains your documentation. If you find the docs website useful maybe bookmark the local file?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Step 5: Testing ===&lt;br /&gt;
&lt;br /&gt;
Testing is critical to making sure your functions do what you expect. There are few ways to write unit tests in python (e.g. &amp;lt;code&amp;gt;unittest&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;pytest&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;nose&amp;lt;/code&amp;gt;). We recommend using &amp;lt;code&amp;gt;pytest&amp;lt;/code&amp;gt; as it requires the least amount of overhead and provides the most details write off the bat.&lt;br /&gt;
&lt;br /&gt;
To use &amp;lt;code&amp;gt;pytest&amp;lt;/code&amp;gt; we first to tell &amp;lt;code&amp;gt;poetry&amp;lt;/code&amp;gt; that we’ll use &amp;lt;code&amp;gt;pytest&amp;lt;/code&amp;gt; in our development with&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;poetry add --dev pytest&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==== What’s the philosophy behind &amp;lt;code&amp;gt;pytest&amp;lt;/code&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&#039;&#039;&#039;Assertions&#039;&#039;&#039;: &amp;lt;code&amp;gt;pytest&amp;lt;/code&amp;gt;’s foundation is defined around checking basic assertion statements like&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;In [1]: assert 1 == 1, &amp;quot;a true statement shouldn&#039;t have errored...&amp;quot;&lt;br /&gt;
   ...: assert .3 - .2 == .1, &amp;quot;but sometimes floating points are bad...&amp;quot;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
that return:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;---------------------------------------------------------------------------&lt;br /&gt;
AssertionError                            Traceback (most recent call last)&lt;br /&gt;
&amp;lt;ipython-input-3-0daf5f7e9b9c&amp;gt; in &amp;lt;module&amp;gt;&lt;br /&gt;
      1 assert 1 == 1, &amp;quot;a true statement shouldn&#039;t have errored...&amp;quot;&lt;br /&gt;
----&amp;gt; 2 assert .3 - .2 == .1, &amp;quot;but sometimes floating points are bad...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
AssertionError: but sometimes floating points are bad...&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
as the second line actual fails (due to some floating point silliness). This simple structure can be combined with standard logical &amp;lt;code&amp;gt;and&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;or&amp;lt;/code&amp;gt; as well as other tools like &amp;lt;code&amp;gt;numpy&amp;lt;/code&amp;gt; logic (.e.g &amp;lt;code&amp;gt;np.all()&amp;lt;/code&amp;gt;). Notice that following a logical statement with a string nicely associated a statement to be returned if the assertion is not true.&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&#039;&#039;&#039;Grouping Assertions&#039;&#039;&#039;: We can imagine wishing to combine a set of assertions, and we can do this easily with a function wrapper. For example&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;import tartanpy&lt;br /&gt;
import pytest # only for warning&lt;br /&gt;
&lt;br /&gt;
def test_call_scotty_demo():&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    test the basics of call_scotty_demo&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    assert tartanpy.call_scotty_demo(&amp;quot;Oski Bear&amp;quot;) is None, \&lt;br /&gt;
        &amp;quot;the output of call_scotty_demo should be None&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # test warning&lt;br /&gt;
    with pytest.warns(UserWarning) as record:&lt;br /&gt;
        tartanpy.call_scotty_demo(&amp;quot;Oski Bear, your a wonderful, but slightly creepy Berkeley Bear&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    assert len(record) &amp;gt; 0, \&lt;br /&gt;
        &amp;quot;expect a warning for name_string longer than 30 for call_scotty_demo&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    assert .3 - .2 == .1, &amp;quot;but sometimes floating points are bad...&amp;quot;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;To actually leverage &amp;lt;code&amp;gt;pytest&amp;lt;/code&amp;gt; we can put &#039;&#039;&#039;A set of grouped tests&#039;&#039;&#039; in single file. When building a package your functions will likelyl live in different &amp;lt;code&amp;gt;.py&amp;lt;/code&amp;gt; files in the &amp;lt;code&amp;gt;src/&amp;lt;packagename&amp;gt;&amp;lt;/code&amp;gt; folder. To mirror this structure we put of our tests associated with a single &amp;lt;code&amp;gt;.py&amp;lt;/code&amp;gt; file into 1 test file. These files sit in the &amp;lt;code&amp;gt;tests/&amp;lt;/code&amp;gt; folder and must start with &amp;lt;code&amp;gt;test&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In these larger files (relative to group functions) need to make sure our functions are brought in, for example at the head we need to put &amp;lt;code&amp;gt;import tartanpy&amp;lt;/code&amp;gt; as see in the code block above.&lt;br /&gt;
&lt;br /&gt;
To run these tests you can either do&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;pytest&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
or (making sure you have all the correct packages)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;poetry run pytest&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&#039;&#039;Note: we actually have some printouts in &amp;lt;code&amp;gt;call_scotty_demo&amp;lt;/code&amp;gt;, which are not desirable, so we actually follow a suggestion from [https://stackoverflow.com/questions/8391411/how-to-block-calls-to-print stackoverflow] to suppress the printing (doesn’t mess with the testing), and is seen in the code block below:&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;import tartanpy&lt;br /&gt;
import pytest # only for warning&lt;br /&gt;
&lt;br /&gt;
def test_call_scotty_demo():&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    test the basics of call_scotty_demo&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    with open(os.devnull, &amp;quot;w&amp;quot;) as f, contextlib.redirect_stdout(f):&lt;br /&gt;
        assert tartanpy.call_scotty_demo(&amp;quot;Oski Bear&amp;quot;) is None, \&lt;br /&gt;
            &amp;quot;the output of call_scotty_demo should be None&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        # test warning&lt;br /&gt;
        with pytest.warns(UserWarning) as record:&lt;br /&gt;
            tartanpy.call_scotty_demo(&amp;quot;Oski Bear, your a wonderful, but slightly creepy Berkeley Bear&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
        assert len(record) &amp;gt; 0, \&lt;br /&gt;
            &amp;quot;expect a warning for name_string longer than 30 for call_scotty_demo&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        assert .3 - .2 == .1, &amp;quot;but sometimes floating points are bad...&amp;quot;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
If we remove the silly floating point error assession we get the following:&lt;br /&gt;
&lt;br /&gt;
[[File:1200px-Pytest example.png|300px|frame|left|output of pytest]]&lt;br /&gt;
&lt;br /&gt;
And if there are errors &amp;lt;code&amp;gt;pytest&amp;lt;/code&amp;gt; tries to be very clear about where in your tests you had an error.&lt;br /&gt;
&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== More comments on testing ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&#039;&#039;&#039;Hidden and/or not exported functions&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In our example we have a hidden function &amp;lt;code&amp;gt;_top_and_bottom&amp;lt;/code&amp;gt;. Different thoughts exist on whether or not one should test hidden functions, but to do so we have to be a bit tricker since the function isn’t loaded by the package. We can still test it by using the full path to the function, that is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;import tartanpy&lt;br /&gt;
import numpy as np&lt;br /&gt;
&lt;br /&gt;
def test__top_and_bottom():&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    test for hidden function _top_and_bottom&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    option4 = tartanpy.utils._top_and_bottom(len(&amp;quot;test&amp;quot;))&lt;br /&gt;
    option17 = tartanpy.utils._top_and_bottom(len(&amp;quot;test_a_longer_one&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
    assert np.all(option17 - option4 == 17-4), \&lt;br /&gt;
        &amp;quot;expect _top_and_bottom values to only differ by length of input&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    assert np.all(option17 - 17 == np.array([8,4])), \&lt;br /&gt;
        &amp;quot;expect that _top_and_bottom adds 8 and 4 to length of input&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Additionally, since we started the name off with a &amp;lt;code&amp;gt;_&amp;lt;/code&amp;gt;, we could also find that if we did&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;from tartanpy.utils import *&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
which should import everything from the &amp;lt;code&amp;gt;util.py&amp;lt;/code&amp;gt; file we won’t actually have access to it, whereas&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;from tartanpy.communicate import *&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
would get access to &amp;lt;code&amp;gt;call_scotty_demo&amp;lt;/code&amp;gt; even if it wasn’t in the &amp;lt;code&amp;gt;__init__.py&amp;lt;/code&amp;gt; file.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&#039;&#039;&#039;Numerical instablity&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
We included an example where floating point differnces made &amp;lt;code&amp;gt;.3-.2&amp;lt;/code&amp;gt; not equal to &amp;lt;code&amp;gt;.1&amp;lt;/code&amp;gt;. To avoid such errors we recommend using tools like&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;np.allclose&amp;lt;/code&amp;gt; (which allows user to provide relative and absolute tolerance between vectors)&lt;br /&gt;
* or do something like &amp;lt;code&amp;gt;np.abs(a-b)&amp;lt;1e-08&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;np.abs(a-b)/np.abs(b) &amp;lt; 1e-08&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Step 6. Sharing / using on other computers ===&lt;br /&gt;
&lt;br /&gt;
You could publish your package to pypi (documented here: [https://py-pkgs.org/07-releasing-versioning py-pkg/07-releasing-versioning]) but if you’re still actively working on a developer version another easy way is to make sure you have a clean copy on github, have the user clone the repo and then run either (when in the top directory of the cloned repo)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;pip install .&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
or&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;pip install -e .&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
where the first installs the package 1 time, and the second actually installs the package and updates the package if that user was to do more pulls / updates the the package.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Step 7. And beyond! ===&lt;br /&gt;
&lt;br /&gt;
In the above example, we still didn’t cover a lot of things, including:&lt;br /&gt;
&lt;br /&gt;
*publishing the package &lt;br /&gt;
*publishing the docs &lt;br /&gt;
*including data &lt;br /&gt;
*CI/CD (which will be provided in another wiki) &lt;br /&gt;
&lt;br /&gt;
See [https://py-pkgs.org py-pkgs] for some good starting blocks for most of these.&lt;/div&gt;</summary>
		<author><name>Skipper</name></author>
	</entry>
	<entry>
		<id>https://info.stat.cmu.edu/index.php?title=Developing_python_packages&amp;diff=69</id>
		<title>Developing python packages</title>
		<link rel="alternate" type="text/html" href="https://info.stat.cmu.edu/index.php?title=Developing_python_packages&amp;diff=69"/>
		<updated>2024-05-24T01:59:05Z</updated>

		<summary type="html">&lt;p&gt;Skipper: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This wiki presents a motivational example of a lot of properties of python packages and how to use them. Please see [[packages motivation]] for motivation about why you should utilize the package framework while doing research. This material captures the basics presented by [https://py-pkgs.org/ py-pkgs], (recently) developed by UBC professors. As such you’ll find that python packages online may have different structures. Still, &amp;lt;code&amp;gt;py-pkgs&amp;lt;/code&amp;gt; provides a lot of helpful tools to automate python package development. The &amp;lt;code&amp;gt;py-pkgs&amp;lt;/code&amp;gt; project was actually started to mirror the helpful [[Developing_R_packages|package development tools in &amp;lt;code&amp;gt;R&amp;lt;/code&amp;gt;]]. Note that this wiki page does provide additional commentary but the process proposed is very similar to &amp;lt;code&amp;gt;py-pkgs&amp;lt;/code&amp;gt;’s approach.&lt;br /&gt;
&lt;br /&gt;
== Foundations (what tools will be used) ==&lt;br /&gt;
&lt;br /&gt;
In the package development pipeline that is proposed by &amp;lt;code&amp;gt;py-pkgs&amp;lt;/code&amp;gt; we have a few very power packages to help you develop an &amp;lt;code&amp;gt;python&amp;lt;/code&amp;gt; package as painlessly as possible.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;poetry&amp;lt;/code&amp;gt; help build a python package&lt;br /&gt;
* &amp;lt;code&amp;gt;cookiecutter&amp;lt;/code&amp;gt; helps utilize pre-made templates (for our package’s files)&lt;br /&gt;
* &amp;lt;code&amp;gt;pytest&amp;lt;/code&amp;gt; provides clean and standardized tools for testing&lt;br /&gt;
* (numpy style code) provides rubrics for documentation&lt;br /&gt;
&lt;br /&gt;
== Building an python package ==&lt;br /&gt;
&lt;br /&gt;
This process is slightly different than the one we demonstrated in the [[Developing_R_packages]] wiki (we set up the structure of the package and then link to github).&lt;br /&gt;
&lt;br /&gt;
=== Step 1: Creating a minimal source package ===&lt;br /&gt;
&lt;br /&gt;
A python (&#039;&#039;source&#039;&#039;) package just files in a directory, formatted in a specific way.&lt;br /&gt;
&lt;br /&gt;
To create the bare bones python package, we will be using the packages &amp;lt;code&amp;gt;poetry&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;cookiecutter&amp;lt;/code&amp;gt;, so if you haven’t already done so, install those two packages (we’ll be using &amp;lt;code&amp;gt;conda&amp;lt;/code&amp;gt;) by typing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;conda install -c conda-forge poetry cookiecutter&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&#039;&#039;Note that this line is taken directly from [https://py-pkgs.org/02-setup py-pkgs/02-setup], and it is possible that some day these packages can be installed wit ha simple &amp;lt;code&amp;gt;conda install poetry cookiecutter&amp;lt;/code&amp;gt;.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Now&#039;&#039;&#039;, to actually start setting up your python package we will first use &amp;lt;code&amp;gt;cookiecutter&amp;lt;/code&amp;gt; to copy a package structure provided by &amp;lt;code&amp;gt;py-pkgs&amp;lt;/code&amp;gt; by running the following in our terminal:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;cookiecutter https://github.com/UBC-MDS/cookiecutter-ubc-mds.git&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
This will prompt you to answer a set of questions including &lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; the author name (can include caps and spaces) &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; github username &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; package name (can include caps and spaces) &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; package slug name (can included underscores but no spaces) &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; a short package description (can include caps and spaces) &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; version number (we recommend either 0.0.1 or 0.1.0) &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; python version 8. open source license (they list the options) &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; if the package should include github actions (we suggest no for now, and plan to have wikis help with this later) &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note: our package for this example will be named &amp;lt;code&amp;gt;tartanpy&amp;lt;/code&amp;gt;&#039;&#039; (an a copy of the &amp;quot;final&amp;quot; product can be found on [https://github.com/benjaminleroy/tartanpy|github].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note: the cookiecutter template from &amp;lt;code&amp;gt;py-pkg&amp;lt;/code&amp;gt;s (aka the one above) is still under construction - so it might look slightly different in the future.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This will create a &amp;lt;code&amp;gt;tartanpy&amp;lt;/code&amp;gt; folder with the following items:&lt;br /&gt;
&lt;br /&gt;
# Directory &amp;lt;code&amp;gt;src/&amp;lt;/code&amp;gt; (where all the function source code goes)&lt;br /&gt;
# Directory &amp;lt;code&amp;gt;docs/&amp;lt;/code&amp;gt; (where all the pretty looking documentation goes &#039;&#039;&#039;- auto generated&#039;&#039;&#039;)&lt;br /&gt;
# Directory &amp;lt;code&amp;gt;tests/&amp;lt;/code&amp;gt; (where you’ll store your test, with a placeholder test file)&lt;br /&gt;
# &amp;lt;code&amp;gt;pyproject.toml&amp;lt;/code&amp;gt; file (a description file about your package, which includes the things you entered when you ran the &amp;lt;code&amp;gt;cookiecutter&amp;lt;/code&amp;gt; call)&lt;br /&gt;
# &amp;lt;code&amp;gt;LICENSE&amp;lt;/code&amp;gt; (booler plate License - don’t really need to deal with this)&lt;br /&gt;
# A set of &amp;lt;code&amp;gt;.md&amp;lt;/code&amp;gt; files for document things like general info for viewers (&amp;lt;code&amp;gt;README.md&amp;lt;/code&amp;gt;), info for contributors and their conduct (&amp;lt;code&amp;gt;CONTRIBUTING.md&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;CONDUCT.md&amp;lt;/code&amp;gt;) and a file to include information on changes you’ve made &amp;lt;code&amp;gt;CHANGELOG.md&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
[[File:1200px-Tartanpy folder.png|600px|frame|left|initial directory items]]&lt;br /&gt;
&lt;br /&gt;
==== pyproject.toml file meta-data ====&lt;br /&gt;
&lt;br /&gt;
There are few ways for packages to store their meta-data, and &amp;lt;code&amp;gt;py-pkgs&amp;lt;/code&amp;gt;’s path is through the &amp;lt;code&amp;gt;pyproject.toml&amp;lt;/code&amp;gt;. Other options include things like &amp;lt;code&amp;gt;setup.py&amp;lt;/code&amp;gt; files. If you made a mistake when answering questions via your cookiecutter prompts you can change them by opening up the &amp;lt;code&amp;gt;pyproject.toml&amp;lt;/code&amp;gt; file. Our example package’s &amp;lt;code&amp;gt;pyproject.toml&amp;lt;/code&amp;gt; file looks like the image below&lt;br /&gt;
&lt;br /&gt;
[[File:1200px-Tartanpy pyproject description.png|600px|frame|left|initialized description file]]&lt;br /&gt;
&lt;br /&gt;
In a &amp;lt;code&amp;gt;pyproject.toml&amp;lt;/code&amp;gt; file you’ll notice that each section is headed by a &amp;lt;code&amp;gt;[info]&amp;lt;/code&amp;gt; heading. Notice that three of the sections in the image above have &amp;lt;code&amp;gt;tool.poetry&amp;lt;/code&amp;gt; headers. This means that the package &amp;lt;code&amp;gt;poetry&amp;lt;/code&amp;gt; can update these sections. As we showcase the power of this package you may find that using poetry to update a lot of these fields is more desirable than manually doing it yourself.&lt;br /&gt;
&lt;br /&gt;
=== Step 2: Setting up a Github repo ===&lt;br /&gt;
&lt;br /&gt;
Version control (and discussed in Stat Computing) is a very useful tool to help streamline file management and provide piece of mind. Oftentimes, you will want to have a copy of the repository not just on your personal computer but online (to help with sharing, just in case your computer dies, it’s cool, etc.). As such these steps will walk you through how to set up a github repo for your new package and how to connect that repo to a new python package. This step will mirror thoughts in [https://py-pkgs.org/03-how-to-package-a-python#set-up-remote-version-control py-pkgs/03-how-to-package-a-python].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: decimal;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;&#039;&#039;&#039;In &amp;lt;code&amp;gt;Github&amp;lt;/code&amp;gt;&#039;&#039;&#039;, do the following&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;go to the top-level directory (i.e., &amp;lt;code&amp;gt;github.com/&amp;lt;your user name&amp;gt;&amp;lt;/code&amp;gt;)&amp;lt;/p&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;click on “+” at top right, and select “New repository”&amp;lt;/p&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;name the repository (e.g., “tartan_python”). Note that if you’d like to share your package with others via pypi you’ll need to make your package name unique!&amp;lt;/p&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;provide a short description of the repository (don’t leave completely blank!)&amp;lt;/p&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;keep the repository public (as students you have access to free private repos https://education.github.com/pack, but for purposes of this example we will keep the repo public)&amp;lt;/p&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;&#039;&#039;&#039;do not&#039;&#039;&#039; initalize with a README, .gitignore, or license (It even says “Skip this step if you’re importing an exisiting repo”!!!)&amp;lt;/p&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;click on “Create Repository”&amp;lt;/p&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;&#039;&#039;&#039;…then in your terminal, do the following&#039;&#039;&#039;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;First, initialize your repository with&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;git init&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;then add all &amp;lt;code&amp;gt;cookiecutter&amp;lt;/code&amp;gt; files and create your initial commit with &amp;lt;code&amp;gt;bash  git add .  git commit -m &amp;quot;initial package setup&amp;quot;&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;setup connection to github by adding a a remote, your main branch and pushing your first commit with&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;git remote add origin https://github.com/benjaminleroy/tartanpy.git&lt;br /&gt;
git branch -M main&lt;br /&gt;
git push -u origin main&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&#039;&#039;Note that github provides you with walk throughs that mirror what was recommended above and showcases 2 approaches if you want to use the command line (&amp;lt;code&amp;gt;https&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;) as well as how you might do it with github desktop. So helpful - thanks github!&#039;&#039;&amp;lt;/p&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Step 3: Writing a function ===&lt;br /&gt;
&lt;br /&gt;
All of your python code needs to go in &amp;lt;code&amp;gt;.py&amp;lt;/code&amp;gt; files in the &amp;lt;code&amp;gt;src/tartanpy/&amp;lt;/code&amp;gt; directory. Suppose our first set of functions deal with communicating to the user - then we might make a &amp;lt;code&amp;gt;communicate.py&amp;lt;/code&amp;gt; file in &amp;lt;code&amp;gt;src/tartanpy/&amp;lt;/code&amp;gt; folder. &amp;lt;br&amp;gt; Inside this file, let’s image we add the following function&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;def call_scotty_demo(your_name):&lt;br /&gt;
&lt;br /&gt;
    name_length = len(your_name)&lt;br /&gt;
&lt;br /&gt;
    # say Hiiiiii&lt;br /&gt;
    hi_string = &amp;quot;\n&amp;quot; +\&lt;br /&gt;
        &amp;quot;-&amp;quot; * (name_length + 8) + &amp;quot;\n&amp;quot; +\&lt;br /&gt;
        &amp;quot;| Hi &amp;quot; + your_name + &amp;quot;! | \n&amp;quot; +\&lt;br /&gt;
        &amp;quot;|   &amp;quot; + &amp;quot;-&amp;quot; * (name_length + 4) + &amp;quot;\n&amp;quot; +\&lt;br /&gt;
        &amp;quot;| /\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    scotty_string = &amp;quot;&amp;quot;+\&lt;br /&gt;
        &amp;quot; |/  |\\_/|          \n&amp;quot; +\&lt;br /&gt;
        &amp;quot; |   |q p|   /}      \n&amp;quot; +\&lt;br /&gt;
        &amp;quot; |   ( 0 )\&amp;quot;\&amp;quot;\&amp;quot;\\   \n&amp;quot; +\&lt;br /&gt;
        &amp;quot;  \\  |\&amp;quot;-\&amp;quot;`    |    \n&amp;quot; +\&lt;br /&gt;
        &amp;quot;     || /=\\\\  |     \n&amp;quot; +\&lt;br /&gt;
        &amp;quot;     \&amp;quot;&#039;\&amp;quot;  &#039;\&amp;quot;\&amp;quot;\&amp;quot;&#039;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    print(hi_string + scotty_string)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
To get access to this function we can use &amp;lt;code&amp;gt;poetry&amp;lt;/code&amp;gt; to locally install our package with the bash command below (that needs to be run in the top folder of our package)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;poetry install&amp;lt;/pre&amp;gt;&lt;br /&gt;
&#039;&#039;Note that without poetry this could be done with a &amp;lt;code&amp;gt;pip install -e .&amp;lt;/code&amp;gt; in the same directory and this would actually not require running this line of code every time we update the package. On the other hand - we’ll show the versatility of &amp;lt;code&amp;gt;poetry&amp;lt;/code&amp;gt; in the rest of the article.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To utilize our function we can then open up a interactive python instance (e.g. &amp;lt;code&amp;gt;ipython&amp;lt;/code&amp;gt; in your terminal) and then run&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;In [1]: from tartanpy import communicate&lt;br /&gt;
&lt;br /&gt;
In [2]: communicate.call_scotty_demo(&amp;quot;Andrew Carnegie&amp;quot;)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
which will return:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;-----------------------&lt;br /&gt;
| Hi Andrew Carnegie! |&lt;br /&gt;
|   -------------------&lt;br /&gt;
| /&lt;br /&gt;
 |/  |\_/|&lt;br /&gt;
 |   |q p|   /}&lt;br /&gt;
 |   ( 0 )&amp;quot;&amp;quot;&amp;quot;\&lt;br /&gt;
  \  |&amp;quot;-&amp;quot;`    |&lt;br /&gt;
     || /=\\  |&lt;br /&gt;
     &amp;quot;&#039;&amp;quot;  &#039;&amp;quot;&amp;quot;&amp;quot;&#039;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Note that &amp;lt;code&amp;gt;poetry install&amp;lt;/code&amp;gt; can be called over and over if you keep updating your function files and will re-load the newest verion of all your functions.&lt;br /&gt;
&lt;br /&gt;
==== Additional notes: ====&lt;br /&gt;
&lt;br /&gt;
===== Understanding &amp;lt;code&amp;gt;__init__.py&amp;lt;/code&amp;gt; =====&lt;br /&gt;
&lt;br /&gt;
For &amp;lt;code&amp;gt;python&amp;lt;/code&amp;gt; packages you’ll always have an &amp;lt;code&amp;gt;__init__.py&amp;lt;/code&amp;gt; file in this directory. We currently have to import the &amp;lt;code&amp;gt;communicate&amp;lt;/code&amp;gt; file from &amp;lt;code&amp;gt;tartanpy&amp;lt;/code&amp;gt; in order to get access to our amazing function. To make this function come directly with the package, in the &amp;lt;code&amp;gt;__init__.py&amp;lt;/code&amp;gt; file we can write&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;from .communicate import call_scotty_demo&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&#039;&#039;Note the dot in &amp;lt;code&amp;gt;.communicate&amp;lt;/code&amp;gt; says “in this same directory as this current file”, and we don’t have to include the &amp;lt;code&amp;gt;.py&amp;lt;/code&amp;gt; file link at the end.&#039;&#039; Additionally This approach &#039;&#039;&#039;only&#039;&#039;&#039; imports call_scotty_demo to the global package, we could use &amp;lt;code&amp;gt;... import *&amp;lt;/code&amp;gt; to import all functions (but this approach is smart if we had helper functions we didn’t really need to share with the end user).*&lt;br /&gt;
&lt;br /&gt;
With the above change, we can then do (the &amp;lt;code&amp;gt;poetry&amp;lt;/code&amp;gt; part still needs to be at the top directory):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;poetry install&lt;br /&gt;
ipython&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
and then in the ipython shell:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;In [1]: import tartanpy&lt;br /&gt;
&lt;br /&gt;
In [2]: tartanpy.call_scotty_demo(&amp;quot;Andrew Mellon&amp;quot;)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
which will return:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;---------------------&lt;br /&gt;
| Hi Andrew Mellon! |&lt;br /&gt;
|   -----------------&lt;br /&gt;
| /&lt;br /&gt;
 |/  |\_/|&lt;br /&gt;
 |   |q p|   /}&lt;br /&gt;
 |   ( 0 )&amp;quot;&amp;quot;&amp;quot;\&lt;br /&gt;
  \  |&amp;quot;-&amp;quot;`    |&lt;br /&gt;
     || /=\\  |&lt;br /&gt;
     &amp;quot;&#039;&amp;quot;  &#039;&amp;quot;&amp;quot;&amp;quot;&#039;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===== Using external packages =====&lt;br /&gt;
&lt;br /&gt;
[You&#039;ll want to read the next section as well for a full understanding of dealing with external packages.]&lt;br /&gt;
&lt;br /&gt;
Suppose I wished to truncate really long names I’m greeting but also give the user a warning that I’m going to do so. I’d need to use the &amp;lt;code&amp;gt;warnings&amp;lt;/code&amp;gt; package. To use this in our package I’d need to change our &amp;lt;code&amp;gt;communicate.py&amp;lt;/code&amp;gt; file to&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;import warnings&lt;br /&gt;
&lt;br /&gt;
def call_scotty_demo(your_name):&lt;br /&gt;
    if len(your_name) &amp;gt; 30:&lt;br /&gt;
        warnings.warn(&amp;quot;your name is beyond 30 characters, &amp;quot;+\&lt;br /&gt;
                        &amp;quot;has been truncated&amp;quot;)&lt;br /&gt;
        your_name = your_name[:30]&lt;br /&gt;
&lt;br /&gt;
    name_length = len(your_name)&lt;br /&gt;
&lt;br /&gt;
    # say Hiiiiii&lt;br /&gt;
    hi_string = &amp;quot;\n&amp;quot; +\&lt;br /&gt;
        &amp;quot;-&amp;quot; * (name_length + 8) + &amp;quot;\n&amp;quot; +\&lt;br /&gt;
        &amp;quot;| Hi &amp;quot; + your_name + &amp;quot;! | \n&amp;quot; +\&lt;br /&gt;
        &amp;quot;|   &amp;quot; + &amp;quot;-&amp;quot; * (name_length + 4) + &amp;quot;\n&amp;quot; +\&lt;br /&gt;
        &amp;quot;| /\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    scotty_string = &amp;quot;&amp;quot;+\&lt;br /&gt;
        &amp;quot; |/  |\\_/|          \n&amp;quot; +\&lt;br /&gt;
        &amp;quot; |   |q p|   /}      \n&amp;quot; +\&lt;br /&gt;
        &amp;quot; |   ( 0 )\&amp;quot;\&amp;quot;\&amp;quot;\\   \n&amp;quot; +\&lt;br /&gt;
        &amp;quot;  \\  |\&amp;quot;-\&amp;quot;`    |    \n&amp;quot; +\&lt;br /&gt;
        &amp;quot;     || /=\\\\  |     \n&amp;quot; +\&lt;br /&gt;
        &amp;quot;     \&amp;quot;&#039;\&amp;quot;  &#039;\&amp;quot;\&amp;quot;\&amp;quot;&#039;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    print(hi_string + scotty_string)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Notice that we have to impot the &amp;lt;code&amp;gt;warnings&amp;lt;/code&amp;gt; package at the top of our function file.&lt;br /&gt;
&lt;br /&gt;
Now we have the additional funcitonality (after reloading with &amp;lt;code&amp;gt;poetry&amp;lt;/code&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;In [1]: import tartanpy&lt;br /&gt;
&lt;br /&gt;
In [2]: tartanpy.call_scotty_demo(&amp;quot;Oski Bear, your a wonderful, but slightly creepy Berkeley Bear&amp;quot;)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
which returns&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;.../tartanpy/src/tartanpy/communicate.py:6: UserWarning: your name is beyond 30 characters, has been truncated&lt;br /&gt;
  warnings.warn(&amp;quot;your name is beyond 30 characters, &amp;quot;+\&lt;br /&gt;
&lt;br /&gt;
--------------------------------------&lt;br /&gt;
| Hi Oski Bear, your a wonderful, b! |&lt;br /&gt;
|   ----------------------------------&lt;br /&gt;
| /&lt;br /&gt;
 |/  |\_/|&lt;br /&gt;
 |   |q p|   /}&lt;br /&gt;
 |   ( 0 )&amp;quot;&amp;quot;&amp;quot;\&lt;br /&gt;
  \  |&amp;quot;-&amp;quot;`    |&lt;br /&gt;
     || /=\\  |&lt;br /&gt;
     &amp;quot;&#039;&amp;quot;  &#039;&amp;quot;&amp;quot;&amp;quot;&#039;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==== Using external packages: declaring dependences &amp;amp; Using local functions in other files ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type: decimal;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;&#039;&#039;&#039;Declaring dependencies&#039;&#039;&#039;: The &amp;lt;code&amp;gt;warnings&amp;lt;/code&amp;gt; module is actually a built in python package, but suppose we also needed to use &amp;lt;code&amp;gt;numpy&amp;lt;/code&amp;gt; in our package. For example, suppose we created another &amp;lt;code&amp;gt;.py&amp;lt;/code&amp;gt; file called &amp;lt;code&amp;gt;utils.py&amp;lt;/code&amp;gt;, in it we had&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;import numpy as np&lt;br /&gt;
&lt;br /&gt;
def _top_and_bottom(name_length):&lt;br /&gt;
    length_vec = np.array([8,4]) + name_length&lt;br /&gt;
    return(length_vec)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;The first thing we’d need to do (so the code works for others) is to tell the package we require the installation of &amp;lt;code&amp;gt;numpy&amp;lt;/code&amp;gt; for anyone using our package. We do so by running&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;poetry add numpy&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;This will update our &amp;lt;code&amp;gt;pyproject.toml&amp;lt;/code&amp;gt; and add asssociated dependences (there are none for &amp;lt;code&amp;gt;numpy&amp;lt;/code&amp;gt;), and will put that note under &amp;lt;code&amp;gt;[tool.poetry.dependencies]&amp;lt;/code&amp;gt;.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&#039;&#039;Note: as of 8/20/21 this also required restricting my python version (in the &amp;lt;code&amp;gt;pyproject.toml&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;python = &amp;quot;?=3.8,&amp;lt;3.11&amp;quot;&amp;lt;/code&amp;gt;)&amp;lt;/p&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;&#039;&#039;&#039;Internal Functions&#039;&#039;&#039;: To use our interal function &amp;lt;code&amp;gt;_top_and_bottom&amp;lt;/code&amp;gt; we might change the &amp;lt;code&amp;gt;communicate.py&amp;lt;/code&amp;gt; file to:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;import warnings&lt;br /&gt;
from .utils import _top_and_bottom&lt;br /&gt;
&lt;br /&gt;
def call_scotty_demo(your_name):&lt;br /&gt;
    # import warnings&lt;br /&gt;
    if len(your_name) &amp;gt; 30:&lt;br /&gt;
        warnings.warn(&amp;quot;your name is beyond 30 characters, &amp;quot;+\&lt;br /&gt;
                        &amp;quot;has been truncated&amp;quot;)&lt;br /&gt;
        your_name = your_name[:30]&lt;br /&gt;
&lt;br /&gt;
    name_length = len(your_name)&lt;br /&gt;
&lt;br /&gt;
    tb_info = _top_and_bottom(name_length)&lt;br /&gt;
&lt;br /&gt;
    # say Hiiiiii&lt;br /&gt;
    hi_string = &amp;quot;\n&amp;quot; +\&lt;br /&gt;
        &amp;quot;-&amp;quot; * tb_info[0] + &amp;quot;\n&amp;quot; +\&lt;br /&gt;
        &amp;quot;| Hi &amp;quot; + your_name + &amp;quot;! | \n&amp;quot; +\&lt;br /&gt;
        &amp;quot;|   &amp;quot; + &amp;quot;-&amp;quot; * tb_info[1] + &amp;quot;\n&amp;quot; +\&lt;br /&gt;
        &amp;quot;| /\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    ...&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Notice that to give &amp;lt;code&amp;gt;call_scotty_demo&amp;lt;/code&amp;gt; and all functions in the &amp;lt;code&amp;gt;communicate.py&amp;lt;/code&amp;gt; file access to &amp;lt;code&amp;gt;_top_and_bottom&amp;lt;/code&amp;gt; we had to import it using &amp;lt;code&amp;gt;from .utils import _top_and_bottom&amp;lt;/code&amp;gt;. Additionally, it’s best practice to use add a &amp;lt;code&amp;gt;_&amp;lt;/code&amp;gt; at the beginning of a function name if you plan to keep it internal.&amp;lt;/p&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Step 4: Documenting your functions ===&lt;br /&gt;
&lt;br /&gt;
Python documentation is simplier than R documentation as when you look at the documentation of a python function you just get show a docstring at the head of function. In this section we’ll discuss a bit about the extra support poetry can do so that you can generate a localized website for your documentation (that you could upload to [https:://readthedocs.org readthedocs] later).&lt;br /&gt;
&lt;br /&gt;
For documentation to be easily publishable at a later date we recommend that your docstrings follow the &amp;lt;code&amp;gt;numpydoc&amp;lt;/code&amp;gt; format (more details can be found at [https://numpydoc.readthedocs.io/en/latest/format.html#docstring-standard numpydoc.readthedocs]). Using this guideline we can document &amp;lt;code&amp;gt;call_scotty_demo&amp;lt;/code&amp;gt; as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;def call_scotty_demo(your_name):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    Greet Scotty, the Scottie Dog&lt;br /&gt;
&lt;br /&gt;
    Scotty, the Scottie Dog greets your by name!&lt;br /&gt;
&lt;br /&gt;
    Parameters&lt;br /&gt;
    ----------&lt;br /&gt;
    your_name: str&lt;br /&gt;
        string of your name (max length 30 characters)&lt;br /&gt;
&lt;br /&gt;
    Returns&lt;br /&gt;
    -------&lt;br /&gt;
    None&lt;br /&gt;
        Though scotty appears on your screen and says Hi to you.&lt;br /&gt;
&lt;br /&gt;
    Examples&lt;br /&gt;
    --------&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; import tartanpy&lt;br /&gt;
    &amp;gt;&amp;gt;&amp;gt; tartanpy.call_scotty_demo(&amp;quot;Andrew Carnegie&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    -----------------------&lt;br /&gt;
    | Hi Andrew Carnegie! |&lt;br /&gt;
    |   -------------------&lt;br /&gt;
    | /&lt;br /&gt;
    |/  |\_/|&lt;br /&gt;
    |   |q p|   /}&lt;br /&gt;
    |   ( 0 )\&amp;quot;\&amp;quot;\&amp;quot;\\&lt;br /&gt;
     \\  |\&amp;quot;-\&amp;quot;`    |&lt;br /&gt;
        || /=\\\\  |&lt;br /&gt;
        \&amp;quot;&#039;\&amp;quot;  &#039;\&amp;quot;\&amp;quot;\&amp;quot;&#039;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    ...&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The basic structure of the documention is decently straight forward with the title / description of your function first, followed by (1) Parameters header with the parameter name, the type, and the description in the format above (2) Returns header followed by similar structure as Parameters. Adding (3) examples with standard python lines can be helpful as well.&lt;br /&gt;
&lt;br /&gt;
After reloading the package you could see that&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;In [1]: import tartanpy&lt;br /&gt;
&lt;br /&gt;
In [2]: ?tartanpy.call_scotty_demo&lt;br /&gt;
Signature: tartanpy.call_scotty_demo(your_name)&lt;br /&gt;
Docstring:&lt;br /&gt;
Greet Scotty, the Scottie Dog&lt;br /&gt;
&lt;br /&gt;
Scotty, the Scottie Dog greets your by name!&lt;br /&gt;
&lt;br /&gt;
Parameters&lt;br /&gt;
----------&lt;br /&gt;
your_name: str&lt;br /&gt;
    string of your name (max length 30 characters)&lt;br /&gt;
&lt;br /&gt;
Returns&lt;br /&gt;
-------&lt;br /&gt;
None&lt;br /&gt;
    Though scotty appears on your screen and says Hi to you.&lt;br /&gt;
&lt;br /&gt;
Examples&lt;br /&gt;
--------&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import tartanpy&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; tartanpy.call_scotty_demo(&amp;quot;Andrew Carnegie&amp;quot;)&lt;br /&gt;
-----------------------&lt;br /&gt;
| Hi Andrew Carnegie! |&lt;br /&gt;
|   -------------------&lt;br /&gt;
| /&lt;br /&gt;
|/  |\_/|&lt;br /&gt;
|   |q p|   /}&lt;br /&gt;
|   ( 0 )&amp;quot;&amp;quot;&amp;quot;\&lt;br /&gt;
 \  |&amp;quot;-&amp;quot;`    |&lt;br /&gt;
    || /=\\  |&lt;br /&gt;
    &amp;quot;&#039;&amp;quot;  &#039;&amp;quot;&amp;quot;&amp;quot;&#039;&lt;br /&gt;
File:      ..../tartanpy/src/tartanpy/communicate.py&lt;br /&gt;
Type:      function&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==== Towards &amp;quot;readthedocs&amp;quot;-style html documentation ====&lt;br /&gt;
&lt;br /&gt;
py-pkgs and poetry also provide a quick way to transform your documentation into a local html website so you can quickly look through your documentation or load it to readthedocs later, with information on how to here: [https://py-pkgs.org/06-documentation py-pkgs/06-documentation].&lt;br /&gt;
&lt;br /&gt;
Generally speaking you have to&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; install some additional packages to the development side of your package with&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;poetry add --dev sphinx nbsphinx ipykernel&amp;lt;/syntaxhighlight&amp;gt; &amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;and then go to your docs folder and make the website locally (the &amp;lt;code&amp;gt;--dev&amp;lt;/code&amp;gt; parameter makes these packages not tracked for those just wanted to use your package, but required as you continue to develop the package locally).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;cd docs&lt;br /&gt;
poetry run make html&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
and this will create a local webpage (just open &amp;lt;code&amp;gt;docs/index.html&amp;lt;/code&amp;gt;) that contains your documentation. If you find the docs website useful maybe bookmark the local file?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Step 5: Testing ===&lt;br /&gt;
&lt;br /&gt;
Testing is critical to making sure your functions do what you expect. There are few ways to write unit tests in python (e.g. &amp;lt;code&amp;gt;unittest&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;pytest&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;nose&amp;lt;/code&amp;gt;). We recommend using &amp;lt;code&amp;gt;pytest&amp;lt;/code&amp;gt; as it requires the least amount of overhead and provides the most details write off the bat.&lt;br /&gt;
&lt;br /&gt;
To use &amp;lt;code&amp;gt;pytest&amp;lt;/code&amp;gt; we first to tell &amp;lt;code&amp;gt;poetry&amp;lt;/code&amp;gt; that we’ll use &amp;lt;code&amp;gt;pytest&amp;lt;/code&amp;gt; in our development with&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;poetry add --dev pytest&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==== What’s the philosophy behind &amp;lt;code&amp;gt;pytest&amp;lt;/code&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&#039;&#039;&#039;Assertions&#039;&#039;&#039;: &amp;lt;code&amp;gt;pytest&amp;lt;/code&amp;gt;’s foundation is defined around checking basic assertion statements like&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;In [1]: assert 1 == 1, &amp;quot;a true statement shouldn&#039;t have errored...&amp;quot;&lt;br /&gt;
   ...: assert .3 - .2 == .1, &amp;quot;but sometimes floating points are bad...&amp;quot;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
that return:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;---------------------------------------------------------------------------&lt;br /&gt;
AssertionError                            Traceback (most recent call last)&lt;br /&gt;
&amp;lt;ipython-input-3-0daf5f7e9b9c&amp;gt; in &amp;lt;module&amp;gt;&lt;br /&gt;
      1 assert 1 == 1, &amp;quot;a true statement shouldn&#039;t have errored...&amp;quot;&lt;br /&gt;
----&amp;gt; 2 assert .3 - .2 == .1, &amp;quot;but sometimes floating points are bad...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
AssertionError: but sometimes floating points are bad...&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
as the second line actual fails (due to some floating point silliness). This simple structure can be combined with standard logical &amp;lt;code&amp;gt;and&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;or&amp;lt;/code&amp;gt; as well as other tools like &amp;lt;code&amp;gt;numpy&amp;lt;/code&amp;gt; logic (.e.g &amp;lt;code&amp;gt;np.all()&amp;lt;/code&amp;gt;). Notice that following a logical statement with a string nicely associated a statement to be returned if the assertion is not true.&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&#039;&#039;&#039;Grouping Assertions&#039;&#039;&#039;: We can imagine wishing to combine a set of assertions, and we can do this easily with a function wrapper. For example&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;import tartanpy&lt;br /&gt;
import pytest # only for warning&lt;br /&gt;
&lt;br /&gt;
def test_call_scotty_demo():&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    test the basics of call_scotty_demo&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    assert tartanpy.call_scotty_demo(&amp;quot;Oski Bear&amp;quot;) is None, \&lt;br /&gt;
        &amp;quot;the output of call_scotty_demo should be None&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # test warning&lt;br /&gt;
    with pytest.warns(UserWarning) as record:&lt;br /&gt;
        tartanpy.call_scotty_demo(&amp;quot;Oski Bear, your a wonderful, but slightly creepy Berkeley Bear&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    assert len(record) &amp;gt; 0, \&lt;br /&gt;
        &amp;quot;expect a warning for name_string longer than 30 for call_scotty_demo&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    assert .3 - .2 == .1, &amp;quot;but sometimes floating points are bad...&amp;quot;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;To actually leverage &amp;lt;code&amp;gt;pytest&amp;lt;/code&amp;gt; we can put &#039;&#039;&#039;A set of grouped tests&#039;&#039;&#039; in single file. When building a package your functions will likelyl live in different &amp;lt;code&amp;gt;.py&amp;lt;/code&amp;gt; files in the &amp;lt;code&amp;gt;src/&amp;lt;packagename&amp;gt;&amp;lt;/code&amp;gt; folder. To mirror this structure we put of our tests associated with a single &amp;lt;code&amp;gt;.py&amp;lt;/code&amp;gt; file into 1 test file. These files sit in the &amp;lt;code&amp;gt;tests/&amp;lt;/code&amp;gt; folder and must start with &amp;lt;code&amp;gt;test&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In these larger files (relative to group functions) need to make sure our functions are brought in, for example at the head we need to put &amp;lt;code&amp;gt;import tartanpy&amp;lt;/code&amp;gt; as see in the code block above.&lt;br /&gt;
&lt;br /&gt;
To run these tests you can either do&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;pytest&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
or (making sure you have all the correct packages)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;poetry run pytest&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&#039;&#039;Note: we actually have some printouts in &amp;lt;code&amp;gt;call_scotty_demo&amp;lt;/code&amp;gt;, which are not desirable, so we actually follow a suggestion from [https://stackoverflow.com/questions/8391411/how-to-block-calls-to-print stackoverflow] to suppress the printing (doesn’t mess with the testing), and is seen in the code block below:&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;import tartanpy&lt;br /&gt;
import pytest # only for warning&lt;br /&gt;
&lt;br /&gt;
def test_call_scotty_demo():&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    test the basics of call_scotty_demo&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    with open(os.devnull, &amp;quot;w&amp;quot;) as f, contextlib.redirect_stdout(f):&lt;br /&gt;
        assert tartanpy.call_scotty_demo(&amp;quot;Oski Bear&amp;quot;) is None, \&lt;br /&gt;
            &amp;quot;the output of call_scotty_demo should be None&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        # test warning&lt;br /&gt;
        with pytest.warns(UserWarning) as record:&lt;br /&gt;
            tartanpy.call_scotty_demo(&amp;quot;Oski Bear, your a wonderful, but slightly creepy Berkeley Bear&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
        assert len(record) &amp;gt; 0, \&lt;br /&gt;
            &amp;quot;expect a warning for name_string longer than 30 for call_scotty_demo&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        assert .3 - .2 == .1, &amp;quot;but sometimes floating points are bad...&amp;quot;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
If we remove the silly floating point error assession we get the following:&lt;br /&gt;
&lt;br /&gt;
[[File:1200px-Pytest example.png|600px|frame|left|output of pytest]]&lt;br /&gt;
&lt;br /&gt;
And if there are errors &amp;lt;code&amp;gt;pytest&amp;lt;/code&amp;gt; tries to be very clear about where in your tests you had an error.&lt;br /&gt;
&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== More comments on testing ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&#039;&#039;&#039;Hidden and/or not exported functions&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In our example we have a hidden function &amp;lt;code&amp;gt;_top_and_bottom&amp;lt;/code&amp;gt;. Different thoughts exist on whether or not one should test hidden functions, but to do so we have to be a bit tricker since the function isn’t loaded by the package. We can still test it by using the full path to the function, that is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;import tartanpy&lt;br /&gt;
import numpy as np&lt;br /&gt;
&lt;br /&gt;
def test__top_and_bottom():&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    test for hidden function _top_and_bottom&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    option4 = tartanpy.utils._top_and_bottom(len(&amp;quot;test&amp;quot;))&lt;br /&gt;
    option17 = tartanpy.utils._top_and_bottom(len(&amp;quot;test_a_longer_one&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
    assert np.all(option17 - option4 == 17-4), \&lt;br /&gt;
        &amp;quot;expect _top_and_bottom values to only differ by length of input&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    assert np.all(option17 - 17 == np.array([8,4])), \&lt;br /&gt;
        &amp;quot;expect that _top_and_bottom adds 8 and 4 to length of input&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Additionally, since we started the name off with a &amp;lt;code&amp;gt;_&amp;lt;/code&amp;gt;, we could also find that if we did&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;from tartanpy.utils import *&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
which should import everything from the &amp;lt;code&amp;gt;util.py&amp;lt;/code&amp;gt; file we won’t actually have access to it, whereas&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;from tartanpy.communicate import *&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
would get access to &amp;lt;code&amp;gt;call_scotty_demo&amp;lt;/code&amp;gt; even if it wasn’t in the &amp;lt;code&amp;gt;__init__.py&amp;lt;/code&amp;gt; file.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&#039;&#039;&#039;Numerical instablity&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
We included an example where floating point differnces made &amp;lt;code&amp;gt;.3-.2&amp;lt;/code&amp;gt; not equal to &amp;lt;code&amp;gt;.1&amp;lt;/code&amp;gt;. To avoid such errors we recommend using tools like&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;np.allclose&amp;lt;/code&amp;gt; (which allows user to provide relative and absolute tolerance between vectors)&lt;br /&gt;
* or do something like &amp;lt;code&amp;gt;np.abs(a-b)&amp;lt;1e-08&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;np.abs(a-b)/np.abs(b) &amp;lt; 1e-08&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Step 6. Sharing / using on other computers ===&lt;br /&gt;
&lt;br /&gt;
You could publish your package to pypi (documented here: [https://py-pkgs.org/07-releasing-versioning py-pkg/07-releasing-versioning]) but if you’re still actively working on a developer version another easy way is to make sure you have a clean copy on github, have the user clone the repo and then run either (when in the top directory of the cloned repo)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;pip install .&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
or&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;pip install -e .&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
where the first installs the package 1 time, and the second actually installs the package and updates the package if that user was to do more pulls / updates the the package.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Step 7. And beyond! ===&lt;br /&gt;
&lt;br /&gt;
In the above example, we still didn’t cover a lot of things, including:&lt;br /&gt;
&lt;br /&gt;
*publishing the package &lt;br /&gt;
*publishing the docs &lt;br /&gt;
*including data &lt;br /&gt;
*CI/CD (which will be provided in another wiki) &lt;br /&gt;
&lt;br /&gt;
See [https://py-pkgs.org py-pkgs] for some good starting blocks for most of these.&lt;/div&gt;</summary>
		<author><name>Skipper</name></author>
	</entry>
	<entry>
		<id>https://info.stat.cmu.edu/index.php?title=File:1200px-Pytest_example.png&amp;diff=68</id>
		<title>File:1200px-Pytest example.png</title>
		<link rel="alternate" type="text/html" href="https://info.stat.cmu.edu/index.php?title=File:1200px-Pytest_example.png&amp;diff=68"/>
		<updated>2024-05-24T01:58:39Z</updated>

		<summary type="html">&lt;p&gt;Skipper: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;output of pytest&lt;/div&gt;</summary>
		<author><name>Skipper</name></author>
	</entry>
	<entry>
		<id>https://info.stat.cmu.edu/index.php?title=File:1200px-Tartanpy_pyproject_description.png&amp;diff=67</id>
		<title>File:1200px-Tartanpy pyproject description.png</title>
		<link rel="alternate" type="text/html" href="https://info.stat.cmu.edu/index.php?title=File:1200px-Tartanpy_pyproject_description.png&amp;diff=67"/>
		<updated>2024-05-24T01:54:09Z</updated>

		<summary type="html">&lt;p&gt;Skipper: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;initialized description file&lt;/div&gt;</summary>
		<author><name>Skipper</name></author>
	</entry>
	<entry>
		<id>https://info.stat.cmu.edu/index.php?title=File:1200px-Tartanpy_folder.png&amp;diff=66</id>
		<title>File:1200px-Tartanpy folder.png</title>
		<link rel="alternate" type="text/html" href="https://info.stat.cmu.edu/index.php?title=File:1200px-Tartanpy_folder.png&amp;diff=66"/>
		<updated>2024-05-24T01:53:18Z</updated>

		<summary type="html">&lt;p&gt;Skipper: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;initial directory items&lt;/div&gt;</summary>
		<author><name>Skipper</name></author>
	</entry>
	<entry>
		<id>https://info.stat.cmu.edu/index.php?title=Developing_R_packages&amp;diff=65</id>
		<title>Developing R packages</title>
		<link rel="alternate" type="text/html" href="https://info.stat.cmu.edu/index.php?title=Developing_R_packages&amp;diff=65"/>
		<updated>2024-05-24T01:49:42Z</updated>

		<summary type="html">&lt;p&gt;Skipper: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki presents a motivational example of a lot of properties of R packages and how to use them. Please see [[packages motivation]] for motivation about why you should utilize the package framework while doing research. The material in this page captures thoughts from lots of people and is a rewriting of a lecture Ben LeRoy presented while teaching 36-350 in the summer of 2019. Additionally, there are a lot of useful resources on the web to help you make an &amp;lt;code&amp;gt;R&amp;lt;/code&amp;gt; package including:&lt;br /&gt;
&lt;br /&gt;
* [http://r-pkgs.had.co.nz R Packages]. ~Hadley Wickham&lt;br /&gt;
* [https://link.springer.com/book/10.1007/978-0-387-75936-4 Software for Data Analysis: Programming with R.] ~John Chambers&lt;br /&gt;
* [https://cran.r-project.org/doc/manuals/r-release/R-exts.html Writing R Extensions] (the official documentation)&lt;br /&gt;
&lt;br /&gt;
What’s nice about the &amp;lt;code&amp;gt;R&amp;lt;/code&amp;gt; programming language how many easy-to-use resources there are to help you develop your own package. The following quote captures a notation that if you’re going to be working with R for long enough, package-driven development is going to happen - so why don’t you start now?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;“… from user to programmer to contributor, in the gradual progress that R encourages.” ~ John Chambers (Software for Data Analysis: Programming with R)&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Foundations (what tools will be used) ==&lt;br /&gt;
&lt;br /&gt;
Currently, there are few very powerful packages to help you develop an &amp;lt;code&amp;gt;R&amp;lt;/code&amp;gt; package as painlessly as possible.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;devtools&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;usethis&amp;lt;/code&amp;gt; packages provide a set of functions to automate higher level package details and repeative package development demands&lt;br /&gt;
* &amp;lt;code&amp;gt;Roxygen2&amp;lt;/code&amp;gt; helps rapid and standardized documentation for your package&lt;br /&gt;
* &amp;lt;code&amp;gt;testthat&amp;lt;/code&amp;gt; provides clean and standardized tools for testing&lt;br /&gt;
&lt;br /&gt;
== Building an R package ==&lt;br /&gt;
&lt;br /&gt;
=== Step 0: Setting up a Github repo and a Rstudio project directory ===&lt;br /&gt;
&lt;br /&gt;
Version control (and discussed in Stat Computing) is a very useful tool to help streamline file management and provide piece of mind. Oftentimes, you will want to have a copy of the repository not just on your personal computer but online (to help with sharing, just in case your computer dies, it’s cool, etc.). As such these steps will walk you through how to set up a github repo for your new package and how to connect that repo to a new project in R studio.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&#039;&#039;&#039;In &amp;lt;code&amp;gt;GitHub&amp;lt;/code&amp;gt;&#039;&#039;&#039;, do the following:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;go to the top-level directory (i.e., &amp;lt;code&amp;gt;github.com/&amp;lt;your user name&amp;gt;&amp;lt;/code&amp;gt;) &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;click on “+” at top right, and select “New repository” &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;name the repository (e.g., “tartan”) &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;provide a short description of the repository (don’t leave completely blank!) &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;keep the repository public (as students you have access to free private repos https://education.github.com/pack, but for purposes of this example we will keep the repo public) &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;click on “Initialize this repository with a README” and select the R option in “Add .gitignore”… there is no need to “Add a license” &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;click on “Create Repository” &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&#039;&#039;&#039;…then in RStudio&#039;&#039;&#039;, do the following:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;click on &amp;lt;code&amp;gt;File &amp;gt; New Project...&amp;lt;/code&amp;gt; &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;click on “Version Control”, then on “Git” &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;provide the &#039;&#039;full&#039;&#039; address for the “Repository URL” (including the &amp;lt;code&amp;gt;https&amp;lt;/code&amp;gt;, etc.; by default, this will provide the name of your local repository)  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;make sure “Create project as subdirectory of:” points to where you want to point it &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;click on “Create Project” (in this example we will be calling our package &amp;lt;code&amp;gt;tartan&amp;lt;/code&amp;gt;) &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Step 1: Creating a minimal source package ===&lt;br /&gt;
&lt;br /&gt;
An R (&#039;&#039;source&#039;&#039;) package just files in a directory, formatted in a specific way.&lt;br /&gt;
&lt;br /&gt;
To create the bare bones R package, just type in your Rstudio console:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;r&amp;quot;&amp;gt;usethis::create_package(&amp;quot;tartan&amp;quot;)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;r&amp;quot;&amp;gt;# output of the above command&lt;br /&gt;
&amp;gt; usethis::create_package(&amp;quot;tartan&amp;quot;)&lt;br /&gt;
✔ Setting active project to &#039;./tartan&#039;&lt;br /&gt;
✔ Creating &#039;R/&#039;&lt;br /&gt;
✔ Creating &#039;man/&#039;&lt;br /&gt;
✔ Writing &#039;DESCRIPTION&#039;&lt;br /&gt;
✔ Writing &#039;NAMESPACE&#039;&lt;br /&gt;
✔ Changing working directory to &#039;./tartan&#039;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* if in the &amp;lt;code&amp;gt;tartan&amp;lt;/code&amp;gt; project, may need to do &amp;lt;code&amp;gt;setwd(&amp;amp;quot;../&amp;amp;quot;)&amp;lt;/code&amp;gt;, run the above line and then do &amp;lt;code&amp;gt;setwd(&amp;amp;quot;tartan&amp;amp;quot;)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This will create a &amp;lt;code&amp;gt;tartan&amp;lt;/code&amp;gt; folder with the following items:&lt;br /&gt;
&lt;br /&gt;
# Directory &amp;lt;code&amp;gt;R/&amp;lt;/code&amp;gt; (where all the function source code goes)&lt;br /&gt;
# Directory &amp;lt;code&amp;gt;man/&amp;lt;/code&amp;gt; (where all the &amp;lt;code&amp;gt;Roxygen&amp;lt;/code&amp;gt; created documentation goes &#039;&#039;&#039;- auto generated&#039;&#039;&#039;)&lt;br /&gt;
# &amp;lt;code&amp;gt;NAMESPACE&amp;lt;/code&amp;gt; file (information about what functions you’re providing the user &#039;&#039;&#039;- auto generated&#039;&#039;&#039;)&lt;br /&gt;
# &amp;lt;code&amp;gt;DESCRIPTION&amp;lt;/code&amp;gt; file (information about your package)&lt;br /&gt;
# &amp;lt;code&amp;gt;tartan.Rproj&amp;lt;/code&amp;gt; file (if using RStudio - just R project information &#039;&#039;&#039;- auto generated&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
and anything else you included from intializing your git repo (&amp;lt;code&amp;gt;.gitignore&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;LICENSE&amp;lt;/code&amp;gt;, etc)&lt;br /&gt;
&lt;br /&gt;
[[File:1200px-Tartan folder.png|600px|frameless|left|initial directory items]]&lt;br /&gt;
&lt;br /&gt;
==== Description file meta-data ====&lt;br /&gt;
&lt;br /&gt;
The first thing you should do is update a little bit of the meta-data in the &amp;lt;code&amp;gt;DESCRIPTION&amp;lt;/code&amp;gt; file, an example of which is seen below. You don’t need to add lots, but you’ll probably want to at least add your name and a title.&lt;br /&gt;
&lt;br /&gt;
[[File:Tartan description.png|600px|frameless|left|initialized description file]]&lt;br /&gt;
&lt;br /&gt;
=== Step 2: Writing a function ===&lt;br /&gt;
&lt;br /&gt;
All of your R code needs to go in &amp;lt;code&amp;gt;.R&amp;lt;/code&amp;gt; files in the &amp;lt;code&amp;gt;R/&amp;lt;/code&amp;gt; directory. You can create these files yourself, but you can also automate this with&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;r&amp;quot;&amp;gt;usethis::use_r(&amp;quot;welcome&amp;quot;) # opens up file (creates if need be)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
With the previous line of code creating an empty &amp;lt;code&amp;gt;R/welcome.R&amp;lt;/code&amp;gt; file. &amp;lt;br&amp;gt; Inside this file, let’s image we add the following function&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;r&amp;quot;&amp;gt;call_scotty_demo &amp;lt;- function(your_name) {&lt;br /&gt;
  if (nchar(your_name) &amp;gt; 30){&lt;br /&gt;
    warning(&amp;quot;your name is beyond 30 characters, and has been truncated&amp;quot;)&lt;br /&gt;
    your_name &amp;lt;- substr(your_name, 1, 30)&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  name_length &amp;lt;- nchar(your_name)&lt;br /&gt;
&lt;br /&gt;
  # Hiiiii&lt;br /&gt;
  cat(paste(&amp;quot;\n&amp;quot;,&lt;br /&gt;
    paste0(c(&amp;quot;&amp;quot;, rep(&amp;quot;-&amp;quot;, name_length + 8), &amp;quot;\n&amp;quot;), collapse = &amp;quot;&amp;quot;),&lt;br /&gt;
    paste0(c(&amp;quot;| Hi &amp;quot;, your_name, &amp;quot;! | \n&amp;quot;), collapse=&amp;quot;&amp;quot;),&lt;br /&gt;
    paste0(c(&amp;quot;|   &amp;quot;, rep(&amp;quot;-&amp;quot;, name_length + 4), &amp;quot;\n&amp;quot;), collapse = &amp;quot;&amp;quot;),&lt;br /&gt;
    paste0(c(&amp;quot;| /\n&amp;quot;)))&lt;br /&gt;
  )&lt;br /&gt;
&lt;br /&gt;
  # from Scotty.&lt;br /&gt;
  cat(paste0(&lt;br /&gt;
      &amp;quot; |/  |\\_/|          \n&amp;quot;,&lt;br /&gt;
      &amp;quot; |   |q p|   /}      \n&amp;quot;,&lt;br /&gt;
      &amp;quot; |   ( 0 )\&amp;quot;\&amp;quot;\&amp;quot;\\   \n&amp;quot;,&lt;br /&gt;
      &amp;quot;  \\  |\&amp;quot;-\&amp;quot;`    |    \n&amp;quot;,&lt;br /&gt;
      &amp;quot;     || /=\\\\  |     \n&amp;quot;,&lt;br /&gt;
      &amp;quot;     \&amp;quot;&#039;\&amp;quot;  &#039;\&amp;quot;\&amp;quot;\&amp;quot;&#039;&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
To get access to this function we can locally load the package into memory (a weaker install than calling &amp;lt;code&amp;gt;library()&amp;lt;/code&amp;gt;) by running:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;r&amp;quot;&amp;gt;devtools::load_all()&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Note that &amp;lt;code&amp;gt;load_all()&amp;lt;/code&amp;gt; can be called over and over if you keep updating your function files and will re-load the newest verion of all your functions.&lt;br /&gt;
&lt;br /&gt;
==== Additional notes ====&lt;br /&gt;
&lt;br /&gt;
Unlike writing code in an &amp;lt;code&amp;gt;.Rmd&amp;lt;/code&amp;gt; or a &amp;lt;code&amp;gt;.R&amp;lt;/code&amp;gt; file, we deal with library dependencies slightly differently. If you know functions need tools from a certain library we put that library in the &amp;lt;code&amp;gt;Imports:&amp;lt;/code&amp;gt; section of your &amp;lt;code&amp;gt;DESCRIPTION&amp;lt;/code&amp;gt; file. Additional to use functions from outside libraries in our functions we have to write them like &amp;lt;code&amp;gt;package_name::function_name&amp;lt;/code&amp;gt;. For example in our function &amp;lt;code&amp;gt;call_scotty_demo&amp;lt;/code&amp;gt; if we wanted to use &amp;lt;code&amp;gt;stringr&amp;lt;/code&amp;gt;’s &amp;lt;code&amp;gt;str_sub&amp;lt;/code&amp;gt; function we’d have to have our code look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;r&amp;quot;&amp;gt;call_scotty_demo &amp;lt;- function(your_name) {&lt;br /&gt;
  if (nchar(your_name) &amp;gt; 30){&lt;br /&gt;
    warning(&amp;quot;your name is beyond 30 characters, and has been truncated&amp;quot;)&lt;br /&gt;
    your_name &amp;lt;- stringr::str_sub(your_name, 1, 30)&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  name_length &amp;lt;- nchar(your_name)&lt;br /&gt;
&lt;br /&gt;
  # Hiiiii&lt;br /&gt;
  cat(paste(&amp;quot;\n&amp;quot;,&lt;br /&gt;
    paste0(c(&amp;quot;&amp;quot;, rep(&amp;quot;-&amp;quot;, name_length + 8), &amp;quot;\n&amp;quot;), collapse = &amp;quot;&amp;quot;),&lt;br /&gt;
    paste0(c(&amp;quot;| Hi &amp;quot;, your_name, &amp;quot;! | \n&amp;quot;), collapse=&amp;quot;&amp;quot;),&lt;br /&gt;
    paste0(c(&amp;quot;|   &amp;quot;, rep(&amp;quot;-&amp;quot;, name_length + 4), &amp;quot;\n&amp;quot;), collapse = &amp;quot;&amp;quot;),&lt;br /&gt;
    paste0(c(&amp;quot;| /\n&amp;quot;)))&lt;br /&gt;
  )&lt;br /&gt;
&lt;br /&gt;
  # from Scotty.&lt;br /&gt;
  cat(paste0(&lt;br /&gt;
      &amp;quot; |/  |\\_/|          \n&amp;quot;,&lt;br /&gt;
      &amp;quot; |   |q p|   /}      \n&amp;quot;,&lt;br /&gt;
      &amp;quot; |   ( 0 )\&amp;quot;\&amp;quot;\&amp;quot;\\   \n&amp;quot;,&lt;br /&gt;
      &amp;quot;  \\  |\&amp;quot;-\&amp;quot;`    |    \n&amp;quot;,&lt;br /&gt;
      &amp;quot;     || /=\\\\  |     \n&amp;quot;,&lt;br /&gt;
      &amp;quot;     \&amp;quot;&#039;\&amp;quot;  &#039;\&amp;quot;\&amp;quot;\&amp;quot;&#039;&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
and our &amp;lt;code&amp;gt;DESCRIPTION&amp;lt;/code&amp;gt; file would need lines like&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;r&amp;quot;&amp;gt;Imports:&lt;br /&gt;
    stringr&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Step 3: Documenting your functions ===&lt;br /&gt;
&lt;br /&gt;
With &amp;lt;code&amp;gt;devtools&amp;lt;/code&amp;gt; and a package it’s actually really easy to create local documentation for your own functions so that &amp;lt;code&amp;gt;?function_name&amp;lt;/code&amp;gt; pops up documentation in the same way &amp;lt;code&amp;gt;?sum&amp;lt;/code&amp;gt; does in Rstudio.&lt;br /&gt;
&lt;br /&gt;
The easiest way to document your code is using &amp;lt;code&amp;gt;Roxygen2&amp;lt;/code&amp;gt;’s helper tools. To start, make sure you’ve downloaded the package:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;r&amp;quot;&amp;gt;install.packages(&amp;quot;roxygen2&amp;quot;)&lt;br /&gt;
library(roxygen2)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Then at the first line of a function you’ve written (when you’re in Rstudio) use the short-cut &amp;lt;code&amp;gt;Command + Option + Shift + R&amp;lt;/code&amp;gt; (Mac) or &amp;lt;code&amp;gt;Ctrl+ Alt + Shift + R&amp;lt;/code&amp;gt; (Windows), this will auto-generate a documentation structure to fill in.&lt;br /&gt;
&lt;br /&gt;
For example, if we had the function from above used the shortcut, we would then have:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;r&amp;quot;&amp;gt;#&#039; Title&lt;br /&gt;
#&#039;&lt;br /&gt;
#&#039; @param your_name&lt;br /&gt;
#&#039;&lt;br /&gt;
#&#039; @return&lt;br /&gt;
#&#039; @export&lt;br /&gt;
#&#039;&lt;br /&gt;
#&#039; @examples&lt;br /&gt;
call_scotty_demo &amp;lt;- function(your_name) {&lt;br /&gt;
  ...&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
which we could fill in with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;r&amp;quot;&amp;gt;#&#039; Meet Scotty, the Scottie Dog&lt;br /&gt;
#&#039;&lt;br /&gt;
#&#039; @param your_name string of your name (max length 30 characters)&lt;br /&gt;
#&#039;&lt;br /&gt;
#&#039; @return NULL. Though scotty appears on your screen and says Hi to you.&lt;br /&gt;
#&#039; @export&lt;br /&gt;
#&#039;&lt;br /&gt;
#&#039; @examples&lt;br /&gt;
#&#039; call_scotty_demo(&amp;quot;Andrew Carnegie&amp;quot;)&lt;br /&gt;
call_scotty_demo &amp;lt;- function(your_name) {&lt;br /&gt;
  ...&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The basic structure of the documentation is decently straightforward (you can remove &amp;lt;code&amp;gt;@export&amp;lt;/code&amp;gt; if you don’t want the function to export, and you can remove &amp;lt;code&amp;gt;@examples&amp;lt;/code&amp;gt; if you don’t have any examples), but detailed guidance, documentation [https://r-pkgs.org/man.html?q=roxygen#man here] can be super helpful (with information on linking functions and other packages, adding math equations, code text, etc.)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Now&#039;&#039;&#039; to actually create a documentation file, we run&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;r&amp;quot;&amp;gt;devtools::document()&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The first time we do this we’ll create &amp;lt;code&amp;gt;man/&amp;lt;/code&amp;gt; folder if one doesn’t always exist and also create / update a corresponding file named &amp;lt;code&amp;gt;man/call_scotty_demo.Rd&amp;lt;/code&amp;gt; file that R uses to generate documentation. Additionally, the &amp;lt;code&amp;gt;document()&amp;lt;/code&amp;gt; function also updates the &amp;lt;code&amp;gt;NAMESPACE&amp;lt;/code&amp;gt; file so when you load your functions you get the desired documenation (need to have &amp;lt;code&amp;gt;@export&amp;lt;/code&amp;gt; in the docstring).&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;man/call_scotty_demo.Rd&amp;lt;/code&amp;gt; document file looks like the following. Notice how it says “do not edit by hand”.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;{r eval=F} % Generated by roxygen2: do not edit by hand % Please edit documentation in R/welcome.R \name{call_scotty_demo} \alias{call_scotty_demo} \title{Meet Scotty, the Scottie Dog} \usage{ call_scotty_demo(your_name) } \arguments{ \item{your_name}{string of your name (max length 30 characters)} } \value{ \code{NULL}. Though scotty appears on your screen and says Hi to you. } \description{ Meet Scotty, the Scottie Dog } \examples{ call_scotty_demo(&amp;amp;quot;Andrew Carnegie&amp;amp;quot;) }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To actually view your documentation files we need to re-load the package and then use the standard &amp;lt;code&amp;gt;?&amp;lt;/code&amp;gt; to get the help file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;r&amp;quot;&amp;gt;devtools::load_all()&lt;br /&gt;
?call_scotty_demo&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[File:Call scotty demo doc.png|600px|frameless|left|example of help file]]&lt;br /&gt;
&lt;br /&gt;
=== Step 4: Testing ===&lt;br /&gt;
&lt;br /&gt;
Testing is critical to making sure your functions do what you expect. The easiest way to get started with testing is the &amp;lt;code&amp;gt;testthat&amp;lt;/code&amp;gt; package, which also integrates with &amp;lt;code&amp;gt;devtools&amp;lt;/code&amp;gt;. To start testing using &amp;lt;code&amp;gt;testthat&amp;lt;/code&amp;gt; in your new R package do the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;{r eval = F} install.packages(&amp;amp;quot;testthat&amp;amp;quot;) usethis::use_testthat()&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will set up the &amp;lt;code&amp;gt;tests/testthat&amp;lt;/code&amp;gt; directory where we can store tests.&lt;br /&gt;
&lt;br /&gt;
==== What’s the philosophy behind &amp;lt;code&amp;gt;testthat&amp;lt;/code&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;testthat&amp;lt;/code&amp;gt; functionality can be see as tools to do a range of needs, from low level testing all the way up to overall testing of all functions in a package.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;On the low level, &amp;lt;code&amp;gt;testthat&amp;lt;/code&amp;gt; provides functions to test your &#039;&#039;&#039;expectations&#039;&#039;&#039;. The most fundamental unit of testing is this low level. &amp;lt;code&amp;gt;testthat&amp;lt;/code&amp;gt;’s &amp;lt;code&amp;gt;expect_...&amp;lt;/code&amp;gt; functions provide the building blocks for testing. They describe what result is expected for your various computations and we can use these to make sure our functions are giving the expected output. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;r&amp;quot;&amp;gt;library(testthat)&lt;br /&gt;
expect_equal(1, 1)&lt;br /&gt;
expect_equal(1, 2)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Returns:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;r&amp;quot;&amp;gt;## Error: 1 not equal to 2.&lt;br /&gt;
## 1/1 mismatches&lt;br /&gt;
## [1] 1 - 2 == -1&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&#039;&#039;&#039;Grouping expectations&#039;&#039;&#039; is the next level. We can group a set of expectations to examine more complex functionality with the wrapper &amp;lt;code&amp;gt;test_that&amp;lt;/code&amp;gt; which takes in a string describing what you’re examining, and then a set of &amp;lt;code&amp;gt;expect_...&amp;lt;/code&amp;gt;s that are wrapping in &amp;lt;code&amp;gt;{}&amp;lt;/code&amp;gt;. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;r&amp;quot;&amp;gt;test_that(paste(&amp;quot;calling scotty works well (returns null&amp;quot;,&lt;br /&gt;
                 &amp;quot;and provides warning nchar &amp;gt; 30)&amp;quot;), {&lt;br /&gt;
  expect_equal(call_scotty_demo(&amp;quot;Oski Bear&amp;quot;), NULL)&lt;br /&gt;
  expect_warning(call_scotty_demo(&amp;quot;Oski Bear, your a wonderful, but slightly creepy Berkeley Bear&amp;quot;))&lt;br /&gt;
  expect_equal(1, 2)&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Returns:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;r&amp;quot;&amp;gt;##&lt;br /&gt;
##  -----------------&lt;br /&gt;
##  | Hi Oski Bear! |&lt;br /&gt;
##  |   -------------&lt;br /&gt;
##  | /&lt;br /&gt;
##  |/  |\_/|&lt;br /&gt;
##  |   |q p|   /}&lt;br /&gt;
##  |   ( 0 )&amp;quot;&amp;quot;&amp;quot;\&lt;br /&gt;
##   \  |&amp;quot;-&amp;quot;`    |&lt;br /&gt;
##      || /=\\  |&lt;br /&gt;
##      &amp;quot;&#039;&amp;quot;  &#039;&amp;quot;&amp;quot;&amp;quot;&#039;&lt;br /&gt;
##  --------------------------------------&lt;br /&gt;
##  | Hi Oski Bear, your a wonderful, b! |&lt;br /&gt;
##  |   ----------------------------------&lt;br /&gt;
##  | /&lt;br /&gt;
##  |/  |\_/|&lt;br /&gt;
##  |   |q p|   /}&lt;br /&gt;
##  |   ( 0 )&amp;quot;&amp;quot;&amp;quot;\&lt;br /&gt;
##   \  |&amp;quot;-&amp;quot;`    |&lt;br /&gt;
##      || /=\\  |&lt;br /&gt;
##      &amp;quot;&#039;&amp;quot;  &#039;&amp;quot;&amp;quot;&amp;quot;&#039;&lt;br /&gt;
&lt;br /&gt;
## Error: Test failed: &#039;calling scotty works well (returns null and provides warning nchar &amp;gt; 30)&#039;&lt;br /&gt;
## * 1 not equal to 2.&lt;br /&gt;
## 1/1 mismatches&lt;br /&gt;
## [1] 1 - 2 == -1&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&#039;&#039;&#039;A set of grouped tests&#039;&#039;&#039; in single file. When building a package your functions will likely like in different &amp;lt;code&amp;gt;.R&amp;lt;/code&amp;gt; files in the &amp;lt;code&amp;gt;R/&amp;lt;/code&amp;gt; folder. To mirror this structure we put of our tests associated with a single &amp;lt;code&amp;gt;.R&amp;lt;/code&amp;gt; file into 1 test file. These files sit in the &amp;lt;code&amp;gt;tests/testthat/&amp;lt;/code&amp;gt; folder and must start with &amp;lt;code&amp;gt;test&amp;lt;/code&amp;gt;. &amp;lt;code&amp;gt;devtools&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;usethis&amp;lt;/code&amp;gt; provide a way to create these test in an automated fashion. For example, if we wanted to create a file &amp;lt;code&amp;gt;tests/testthat/test-welcome.R&amp;lt;/code&amp;gt;, we could call&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;r&amp;quot;&amp;gt;usethis::use_test(&amp;quot;welcome&amp;quot;)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
which provides the message:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;r&amp;quot;&amp;gt;✔ Setting active project to &#039;./tartan&#039;&lt;br /&gt;
✔ Adding &#039;testthat&#039; to Suggests field in DESCRIPTION&lt;br /&gt;
✔ Creating &#039;tests/testthat/&#039;&lt;br /&gt;
✔ Writing &#039;tests/testthat.R&#039;&lt;br /&gt;
✔ Writing &#039;tests/testthat/test-welcome.R&#039;&lt;br /&gt;
● Modify &#039;tests/testthat/test-welcome.R&#039;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
In these larger files (relative to group functions) we include group expectations as well as context information for the overall file using the &amp;lt;code&amp;gt;context()&amp;lt;/code&amp;gt; function. And example can be see below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;r&amp;quot;&amp;gt;context(&amp;quot;test welcome from scotty&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
test_that(paste(&amp;quot;calling scotty works well (returns null&amp;quot;,&lt;br /&gt;
                 &amp;quot;and provides warning nchar &amp;gt; 30)&amp;quot;), {&lt;br /&gt;
  expect_equal(call_scotty_demo(&amp;quot;Oski Bear&amp;quot;), NULL)&lt;br /&gt;
  expect_warning(call_scotty_demo(&amp;quot;Oski Bear, your a wonderful, but slightly creepy Berkeley Bear&amp;quot;))&lt;br /&gt;
  expect_equal(1, 2)&lt;br /&gt;
})&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Once you have a test file in your package all you need to do is run&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;r&amp;quot;&amp;gt;devtools::test()&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
and R will run all your associated test, and will return output like seen in the following image:&lt;br /&gt;
&lt;br /&gt;
[[File:Devtool test example.png|600px|frame|left|output of testthat]]&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Step 5. Checking the full package ===&lt;br /&gt;
&lt;br /&gt;
To understanding if your overall package is clean and able to be shared we can run&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;devtools::check()&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This checks all your dependencies, syntax, and more that may have slipped through the cracks. Often times this is only necessary when you’re looking to share your package with others, but is a good step to include so you don’t have to change a lot of things right before sharing.&lt;br /&gt;
&lt;br /&gt;
=== Step 6: Syncronizing with Github ===&lt;br /&gt;
&lt;br /&gt;
As always, once you’ve completed a clean block of code you should push it to Github. When your code is on github other folks can download the package in a similar fashion to the standard &amp;lt;code&amp;gt;install.packages(...)&amp;lt;/code&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
For example, to install the R package we just made we could use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;{r eval = T, message=F, warning=F} devtools::install_github(repo = &amp;amp;quot;benjaminleroy/tartan&amp;amp;quot;,                          force = F) # so making the sides does do it a ton of times library(tartan) #?call_scotty_demo call_scotty_demo(&amp;amp;quot;Big Bird&amp;amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Step 7: And beyond! ===&lt;br /&gt;
&lt;br /&gt;
In the above example we still didn’t cover a lot of things, including:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Including data in your package (that can be [http://r-pkgs.had.co.nz/data.html documented] too)&lt;br /&gt;
&amp;lt;code&amp;gt;r     # suppose that I have a tarans dataset that I created - than I can save it this way     usethis::use_data(tartans)     # and document at     usethis::use_r(&amp;amp;quot;data&amp;amp;quot;)&amp;lt;/code&amp;gt; &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Vignettes (long form documentation, knitr) &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Compiled code (C, C++, Fortran…) &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Creating a CRAN ready package &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; See [https://usethis.r-lib.org/reference/index.html &amp;lt;code&amp;gt;usethis&amp;lt;/code&amp;gt;] to see all the package development steps that &amp;lt;code&amp;gt;usethis&amp;lt;/code&amp;gt; automates. &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;/div&gt;</summary>
		<author><name>Skipper</name></author>
	</entry>
	<entry>
		<id>https://info.stat.cmu.edu/index.php?title=File:Devtool_test_example.png&amp;diff=64</id>
		<title>File:Devtool test example.png</title>
		<link rel="alternate" type="text/html" href="https://info.stat.cmu.edu/index.php?title=File:Devtool_test_example.png&amp;diff=64"/>
		<updated>2024-05-24T01:49:27Z</updated>

		<summary type="html">&lt;p&gt;Skipper: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;output of testthat&lt;/div&gt;</summary>
		<author><name>Skipper</name></author>
	</entry>
	<entry>
		<id>https://info.stat.cmu.edu/index.php?title=Developing_R_packages&amp;diff=63</id>
		<title>Developing R packages</title>
		<link rel="alternate" type="text/html" href="https://info.stat.cmu.edu/index.php?title=Developing_R_packages&amp;diff=63"/>
		<updated>2024-05-24T01:48:06Z</updated>

		<summary type="html">&lt;p&gt;Skipper: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki presents a motivational example of a lot of properties of R packages and how to use them. Please see [[packages motivation]] for motivation about why you should utilize the package framework while doing research. The material in this page captures thoughts from lots of people and is a rewriting of a lecture Ben LeRoy presented while teaching 36-350 in the summer of 2019. Additionally, there are a lot of useful resources on the web to help you make an &amp;lt;code&amp;gt;R&amp;lt;/code&amp;gt; package including:&lt;br /&gt;
&lt;br /&gt;
* [http://r-pkgs.had.co.nz R Packages]. ~Hadley Wickham&lt;br /&gt;
* [https://link.springer.com/book/10.1007/978-0-387-75936-4 Software for Data Analysis: Programming with R.] ~John Chambers&lt;br /&gt;
* [https://cran.r-project.org/doc/manuals/r-release/R-exts.html Writing R Extensions] (the official documentation)&lt;br /&gt;
&lt;br /&gt;
What’s nice about the &amp;lt;code&amp;gt;R&amp;lt;/code&amp;gt; programming language how many easy-to-use resources there are to help you develop your own package. The following quote captures a notation that if you’re going to be working with R for long enough, package-driven development is going to happen - so why don’t you start now?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;“… from user to programmer to contributor, in the gradual progress that R encourages.” ~ John Chambers (Software for Data Analysis: Programming with R)&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Foundations (what tools will be used) ==&lt;br /&gt;
&lt;br /&gt;
Currently, there are few very powerful packages to help you develop an &amp;lt;code&amp;gt;R&amp;lt;/code&amp;gt; package as painlessly as possible.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;devtools&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;usethis&amp;lt;/code&amp;gt; packages provide a set of functions to automate higher level package details and repeative package development demands&lt;br /&gt;
* &amp;lt;code&amp;gt;Roxygen2&amp;lt;/code&amp;gt; helps rapid and standardized documentation for your package&lt;br /&gt;
* &amp;lt;code&amp;gt;testthat&amp;lt;/code&amp;gt; provides clean and standardized tools for testing&lt;br /&gt;
&lt;br /&gt;
== Building an R package ==&lt;br /&gt;
&lt;br /&gt;
=== Step 0: Setting up a Github repo and a Rstudio project directory ===&lt;br /&gt;
&lt;br /&gt;
Version control (and discussed in Stat Computing) is a very useful tool to help streamline file management and provide piece of mind. Oftentimes, you will want to have a copy of the repository not just on your personal computer but online (to help with sharing, just in case your computer dies, it’s cool, etc.). As such these steps will walk you through how to set up a github repo for your new package and how to connect that repo to a new project in R studio.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&#039;&#039;&#039;In &amp;lt;code&amp;gt;GitHub&amp;lt;/code&amp;gt;&#039;&#039;&#039;, do the following:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;go to the top-level directory (i.e., &amp;lt;code&amp;gt;github.com/&amp;lt;your user name&amp;gt;&amp;lt;/code&amp;gt;) &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;click on “+” at top right, and select “New repository” &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;name the repository (e.g., “tartan”) &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;provide a short description of the repository (don’t leave completely blank!) &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;keep the repository public (as students you have access to free private repos https://education.github.com/pack, but for purposes of this example we will keep the repo public) &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;click on “Initialize this repository with a README” and select the R option in “Add .gitignore”… there is no need to “Add a license” &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;click on “Create Repository” &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&#039;&#039;&#039;…then in RStudio&#039;&#039;&#039;, do the following:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;click on &amp;lt;code&amp;gt;File &amp;gt; New Project...&amp;lt;/code&amp;gt; &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;click on “Version Control”, then on “Git” &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;provide the &#039;&#039;full&#039;&#039; address for the “Repository URL” (including the &amp;lt;code&amp;gt;https&amp;lt;/code&amp;gt;, etc.; by default, this will provide the name of your local repository)  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;make sure “Create project as subdirectory of:” points to where you want to point it &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;click on “Create Project” (in this example we will be calling our package &amp;lt;code&amp;gt;tartan&amp;lt;/code&amp;gt;) &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Step 1: Creating a minimal source package ===&lt;br /&gt;
&lt;br /&gt;
An R (&#039;&#039;source&#039;&#039;) package just files in a directory, formatted in a specific way.&lt;br /&gt;
&lt;br /&gt;
To create the bare bones R package, just type in your Rstudio console:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;r&amp;quot;&amp;gt;usethis::create_package(&amp;quot;tartan&amp;quot;)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;r&amp;quot;&amp;gt;# output of the above command&lt;br /&gt;
&amp;gt; usethis::create_package(&amp;quot;tartan&amp;quot;)&lt;br /&gt;
✔ Setting active project to &#039;./tartan&#039;&lt;br /&gt;
✔ Creating &#039;R/&#039;&lt;br /&gt;
✔ Creating &#039;man/&#039;&lt;br /&gt;
✔ Writing &#039;DESCRIPTION&#039;&lt;br /&gt;
✔ Writing &#039;NAMESPACE&#039;&lt;br /&gt;
✔ Changing working directory to &#039;./tartan&#039;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* if in the &amp;lt;code&amp;gt;tartan&amp;lt;/code&amp;gt; project, may need to do &amp;lt;code&amp;gt;setwd(&amp;amp;quot;../&amp;amp;quot;)&amp;lt;/code&amp;gt;, run the above line and then do &amp;lt;code&amp;gt;setwd(&amp;amp;quot;tartan&amp;amp;quot;)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This will create a &amp;lt;code&amp;gt;tartan&amp;lt;/code&amp;gt; folder with the following items:&lt;br /&gt;
&lt;br /&gt;
# Directory &amp;lt;code&amp;gt;R/&amp;lt;/code&amp;gt; (where all the function source code goes)&lt;br /&gt;
# Directory &amp;lt;code&amp;gt;man/&amp;lt;/code&amp;gt; (where all the &amp;lt;code&amp;gt;Roxygen&amp;lt;/code&amp;gt; created documentation goes &#039;&#039;&#039;- auto generated&#039;&#039;&#039;)&lt;br /&gt;
# &amp;lt;code&amp;gt;NAMESPACE&amp;lt;/code&amp;gt; file (information about what functions you’re providing the user &#039;&#039;&#039;- auto generated&#039;&#039;&#039;)&lt;br /&gt;
# &amp;lt;code&amp;gt;DESCRIPTION&amp;lt;/code&amp;gt; file (information about your package)&lt;br /&gt;
# &amp;lt;code&amp;gt;tartan.Rproj&amp;lt;/code&amp;gt; file (if using RStudio - just R project information &#039;&#039;&#039;- auto generated&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
and anything else you included from intializing your git repo (&amp;lt;code&amp;gt;.gitignore&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;LICENSE&amp;lt;/code&amp;gt;, etc)&lt;br /&gt;
&lt;br /&gt;
[[File:1200px-Tartan folder.png|600px|frameless|left|initial directory items]]&lt;br /&gt;
&lt;br /&gt;
==== Description file meta-data ====&lt;br /&gt;
&lt;br /&gt;
The first thing you should do is update a little bit of the meta-data in the &amp;lt;code&amp;gt;DESCRIPTION&amp;lt;/code&amp;gt; file, an example of which is seen below. You don’t need to add lots, but you’ll probably want to at least add your name and a title.&lt;br /&gt;
&lt;br /&gt;
[[File:Tartan description.png|600px|frameless|left|initialized description file]]&lt;br /&gt;
&lt;br /&gt;
=== Step 2: Writing a function ===&lt;br /&gt;
&lt;br /&gt;
All of your R code needs to go in &amp;lt;code&amp;gt;.R&amp;lt;/code&amp;gt; files in the &amp;lt;code&amp;gt;R/&amp;lt;/code&amp;gt; directory. You can create these files yourself, but you can also automate this with&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;r&amp;quot;&amp;gt;usethis::use_r(&amp;quot;welcome&amp;quot;) # opens up file (creates if need be)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
With the previous line of code creating an empty &amp;lt;code&amp;gt;R/welcome.R&amp;lt;/code&amp;gt; file. &amp;lt;br&amp;gt; Inside this file, let’s image we add the following function&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;r&amp;quot;&amp;gt;call_scotty_demo &amp;lt;- function(your_name) {&lt;br /&gt;
  if (nchar(your_name) &amp;gt; 30){&lt;br /&gt;
    warning(&amp;quot;your name is beyond 30 characters, and has been truncated&amp;quot;)&lt;br /&gt;
    your_name &amp;lt;- substr(your_name, 1, 30)&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  name_length &amp;lt;- nchar(your_name)&lt;br /&gt;
&lt;br /&gt;
  # Hiiiii&lt;br /&gt;
  cat(paste(&amp;quot;\n&amp;quot;,&lt;br /&gt;
    paste0(c(&amp;quot;&amp;quot;, rep(&amp;quot;-&amp;quot;, name_length + 8), &amp;quot;\n&amp;quot;), collapse = &amp;quot;&amp;quot;),&lt;br /&gt;
    paste0(c(&amp;quot;| Hi &amp;quot;, your_name, &amp;quot;! | \n&amp;quot;), collapse=&amp;quot;&amp;quot;),&lt;br /&gt;
    paste0(c(&amp;quot;|   &amp;quot;, rep(&amp;quot;-&amp;quot;, name_length + 4), &amp;quot;\n&amp;quot;), collapse = &amp;quot;&amp;quot;),&lt;br /&gt;
    paste0(c(&amp;quot;| /\n&amp;quot;)))&lt;br /&gt;
  )&lt;br /&gt;
&lt;br /&gt;
  # from Scotty.&lt;br /&gt;
  cat(paste0(&lt;br /&gt;
      &amp;quot; |/  |\\_/|          \n&amp;quot;,&lt;br /&gt;
      &amp;quot; |   |q p|   /}      \n&amp;quot;,&lt;br /&gt;
      &amp;quot; |   ( 0 )\&amp;quot;\&amp;quot;\&amp;quot;\\   \n&amp;quot;,&lt;br /&gt;
      &amp;quot;  \\  |\&amp;quot;-\&amp;quot;`    |    \n&amp;quot;,&lt;br /&gt;
      &amp;quot;     || /=\\\\  |     \n&amp;quot;,&lt;br /&gt;
      &amp;quot;     \&amp;quot;&#039;\&amp;quot;  &#039;\&amp;quot;\&amp;quot;\&amp;quot;&#039;&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
To get access to this function we can locally load the package into memory (a weaker install than calling &amp;lt;code&amp;gt;library()&amp;lt;/code&amp;gt;) by running:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;r&amp;quot;&amp;gt;devtools::load_all()&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Note that &amp;lt;code&amp;gt;load_all()&amp;lt;/code&amp;gt; can be called over and over if you keep updating your function files and will re-load the newest verion of all your functions.&lt;br /&gt;
&lt;br /&gt;
==== Additional notes ====&lt;br /&gt;
&lt;br /&gt;
Unlike writing code in an &amp;lt;code&amp;gt;.Rmd&amp;lt;/code&amp;gt; or a &amp;lt;code&amp;gt;.R&amp;lt;/code&amp;gt; file, we deal with library dependencies slightly differently. If you know functions need tools from a certain library we put that library in the &amp;lt;code&amp;gt;Imports:&amp;lt;/code&amp;gt; section of your &amp;lt;code&amp;gt;DESCRIPTION&amp;lt;/code&amp;gt; file. Additional to use functions from outside libraries in our functions we have to write them like &amp;lt;code&amp;gt;package_name::function_name&amp;lt;/code&amp;gt;. For example in our function &amp;lt;code&amp;gt;call_scotty_demo&amp;lt;/code&amp;gt; if we wanted to use &amp;lt;code&amp;gt;stringr&amp;lt;/code&amp;gt;’s &amp;lt;code&amp;gt;str_sub&amp;lt;/code&amp;gt; function we’d have to have our code look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;r&amp;quot;&amp;gt;call_scotty_demo &amp;lt;- function(your_name) {&lt;br /&gt;
  if (nchar(your_name) &amp;gt; 30){&lt;br /&gt;
    warning(&amp;quot;your name is beyond 30 characters, and has been truncated&amp;quot;)&lt;br /&gt;
    your_name &amp;lt;- stringr::str_sub(your_name, 1, 30)&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  name_length &amp;lt;- nchar(your_name)&lt;br /&gt;
&lt;br /&gt;
  # Hiiiii&lt;br /&gt;
  cat(paste(&amp;quot;\n&amp;quot;,&lt;br /&gt;
    paste0(c(&amp;quot;&amp;quot;, rep(&amp;quot;-&amp;quot;, name_length + 8), &amp;quot;\n&amp;quot;), collapse = &amp;quot;&amp;quot;),&lt;br /&gt;
    paste0(c(&amp;quot;| Hi &amp;quot;, your_name, &amp;quot;! | \n&amp;quot;), collapse=&amp;quot;&amp;quot;),&lt;br /&gt;
    paste0(c(&amp;quot;|   &amp;quot;, rep(&amp;quot;-&amp;quot;, name_length + 4), &amp;quot;\n&amp;quot;), collapse = &amp;quot;&amp;quot;),&lt;br /&gt;
    paste0(c(&amp;quot;| /\n&amp;quot;)))&lt;br /&gt;
  )&lt;br /&gt;
&lt;br /&gt;
  # from Scotty.&lt;br /&gt;
  cat(paste0(&lt;br /&gt;
      &amp;quot; |/  |\\_/|          \n&amp;quot;,&lt;br /&gt;
      &amp;quot; |   |q p|   /}      \n&amp;quot;,&lt;br /&gt;
      &amp;quot; |   ( 0 )\&amp;quot;\&amp;quot;\&amp;quot;\\   \n&amp;quot;,&lt;br /&gt;
      &amp;quot;  \\  |\&amp;quot;-\&amp;quot;`    |    \n&amp;quot;,&lt;br /&gt;
      &amp;quot;     || /=\\\\  |     \n&amp;quot;,&lt;br /&gt;
      &amp;quot;     \&amp;quot;&#039;\&amp;quot;  &#039;\&amp;quot;\&amp;quot;\&amp;quot;&#039;&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
and our &amp;lt;code&amp;gt;DESCRIPTION&amp;lt;/code&amp;gt; file would need lines like&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;r&amp;quot;&amp;gt;Imports:&lt;br /&gt;
    stringr&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Step 3: Documenting your functions ===&lt;br /&gt;
&lt;br /&gt;
With &amp;lt;code&amp;gt;devtools&amp;lt;/code&amp;gt; and a package it’s actually really easy to create local documentation for your own functions so that &amp;lt;code&amp;gt;?function_name&amp;lt;/code&amp;gt; pops up documentation in the same way &amp;lt;code&amp;gt;?sum&amp;lt;/code&amp;gt; does in Rstudio.&lt;br /&gt;
&lt;br /&gt;
The easiest way to document your code is using &amp;lt;code&amp;gt;Roxygen2&amp;lt;/code&amp;gt;’s helper tools. To start, make sure you’ve downloaded the package:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;r&amp;quot;&amp;gt;install.packages(&amp;quot;roxygen2&amp;quot;)&lt;br /&gt;
library(roxygen2)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Then at the first line of a function you’ve written (when you’re in Rstudio) use the short-cut &amp;lt;code&amp;gt;Command + Option + Shift + R&amp;lt;/code&amp;gt; (Mac) or &amp;lt;code&amp;gt;Ctrl+ Alt + Shift + R&amp;lt;/code&amp;gt; (Windows), this will auto-generate a documentation structure to fill in.&lt;br /&gt;
&lt;br /&gt;
For example, if we had the function from above used the shortcut, we would then have:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;r&amp;quot;&amp;gt;#&#039; Title&lt;br /&gt;
#&#039;&lt;br /&gt;
#&#039; @param your_name&lt;br /&gt;
#&#039;&lt;br /&gt;
#&#039; @return&lt;br /&gt;
#&#039; @export&lt;br /&gt;
#&#039;&lt;br /&gt;
#&#039; @examples&lt;br /&gt;
call_scotty_demo &amp;lt;- function(your_name) {&lt;br /&gt;
  ...&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
which we could fill in with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;r&amp;quot;&amp;gt;#&#039; Meet Scotty, the Scottie Dog&lt;br /&gt;
#&#039;&lt;br /&gt;
#&#039; @param your_name string of your name (max length 30 characters)&lt;br /&gt;
#&#039;&lt;br /&gt;
#&#039; @return NULL. Though scotty appears on your screen and says Hi to you.&lt;br /&gt;
#&#039; @export&lt;br /&gt;
#&#039;&lt;br /&gt;
#&#039; @examples&lt;br /&gt;
#&#039; call_scotty_demo(&amp;quot;Andrew Carnegie&amp;quot;)&lt;br /&gt;
call_scotty_demo &amp;lt;- function(your_name) {&lt;br /&gt;
  ...&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The basic structure of the documentation is decently straightforward (you can remove &amp;lt;code&amp;gt;@export&amp;lt;/code&amp;gt; if you don’t want the function to export, and you can remove &amp;lt;code&amp;gt;@examples&amp;lt;/code&amp;gt; if you don’t have any examples), but detailed guidance, documentation [https://r-pkgs.org/man.html?q=roxygen#man here] can be super helpful (with information on linking functions and other packages, adding math equations, code text, etc.)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Now&#039;&#039;&#039; to actually create a documentation file, we run&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;r&amp;quot;&amp;gt;devtools::document()&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The first time we do this we’ll create &amp;lt;code&amp;gt;man/&amp;lt;/code&amp;gt; folder if one doesn’t always exist and also create / update a corresponding file named &amp;lt;code&amp;gt;man/call_scotty_demo.Rd&amp;lt;/code&amp;gt; file that R uses to generate documentation. Additionally, the &amp;lt;code&amp;gt;document()&amp;lt;/code&amp;gt; function also updates the &amp;lt;code&amp;gt;NAMESPACE&amp;lt;/code&amp;gt; file so when you load your functions you get the desired documenation (need to have &amp;lt;code&amp;gt;@export&amp;lt;/code&amp;gt; in the docstring).&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;man/call_scotty_demo.Rd&amp;lt;/code&amp;gt; document file looks like the following. Notice how it says “do not edit by hand”.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;{r eval=F} % Generated by roxygen2: do not edit by hand % Please edit documentation in R/welcome.R \name{call_scotty_demo} \alias{call_scotty_demo} \title{Meet Scotty, the Scottie Dog} \usage{ call_scotty_demo(your_name) } \arguments{ \item{your_name}{string of your name (max length 30 characters)} } \value{ \code{NULL}. Though scotty appears on your screen and says Hi to you. } \description{ Meet Scotty, the Scottie Dog } \examples{ call_scotty_demo(&amp;amp;quot;Andrew Carnegie&amp;amp;quot;) }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To actually view your documentation files we need to re-load the package and then use the standard &amp;lt;code&amp;gt;?&amp;lt;/code&amp;gt; to get the help file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;r&amp;quot;&amp;gt;devtools::load_all()&lt;br /&gt;
?call_scotty_demo&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[File:Call scotty demo doc.png|600px|frameless|left|example of help file]]&lt;br /&gt;
&lt;br /&gt;
=== Step 4: Testing ===&lt;br /&gt;
&lt;br /&gt;
Testing is critical to making sure your functions do what you expect. The easiest way to get started with testing is the &amp;lt;code&amp;gt;testthat&amp;lt;/code&amp;gt; package, which also integrates with &amp;lt;code&amp;gt;devtools&amp;lt;/code&amp;gt;. To start testing using &amp;lt;code&amp;gt;testthat&amp;lt;/code&amp;gt; in your new R package do the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;{r eval = F} install.packages(&amp;amp;quot;testthat&amp;amp;quot;) usethis::use_testthat()&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will set up the &amp;lt;code&amp;gt;tests/testthat&amp;lt;/code&amp;gt; directory where we can store tests.&lt;br /&gt;
&lt;br /&gt;
==== What’s the philosophy behind &amp;lt;code&amp;gt;testthat&amp;lt;/code&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;testthat&amp;lt;/code&amp;gt; functionality can be see as tools to do a range of needs, from low level testing all the way up to overall testing of all functions in a package.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;On the low level, &amp;lt;code&amp;gt;testthat&amp;lt;/code&amp;gt; provides functions to test your &#039;&#039;&#039;expectations&#039;&#039;&#039;. The most fundamental unit of testing is this low level. &amp;lt;code&amp;gt;testthat&amp;lt;/code&amp;gt;’s &amp;lt;code&amp;gt;expect_...&amp;lt;/code&amp;gt; functions provide the building blocks for testing. They describe what result is expected for your various computations and we can use these to make sure our functions are giving the expected output. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;r&amp;quot;&amp;gt;library(testthat)&lt;br /&gt;
expect_equal(1, 1)&lt;br /&gt;
expect_equal(1, 2)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Returns:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;r&amp;quot;&amp;gt;## Error: 1 not equal to 2.&lt;br /&gt;
## 1/1 mismatches&lt;br /&gt;
## [1] 1 - 2 == -1&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&#039;&#039;&#039;Grouping expectations&#039;&#039;&#039; is the next level. We can group a set of expectations to examine more complex functionality with the wrapper &amp;lt;code&amp;gt;test_that&amp;lt;/code&amp;gt; which takes in a string describing what you’re examining, and then a set of &amp;lt;code&amp;gt;expect_...&amp;lt;/code&amp;gt;s that are wrapping in &amp;lt;code&amp;gt;{}&amp;lt;/code&amp;gt;. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;r&amp;quot;&amp;gt;test_that(paste(&amp;quot;calling scotty works well (returns null&amp;quot;,&lt;br /&gt;
                 &amp;quot;and provides warning nchar &amp;gt; 30)&amp;quot;), {&lt;br /&gt;
  expect_equal(call_scotty_demo(&amp;quot;Oski Bear&amp;quot;), NULL)&lt;br /&gt;
  expect_warning(call_scotty_demo(&amp;quot;Oski Bear, your a wonderful, but slightly creepy Berkeley Bear&amp;quot;))&lt;br /&gt;
  expect_equal(1, 2)&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Returns:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;r&amp;quot;&amp;gt;##&lt;br /&gt;
##  -----------------&lt;br /&gt;
##  | Hi Oski Bear! |&lt;br /&gt;
##  |   -------------&lt;br /&gt;
##  | /&lt;br /&gt;
##  |/  |\_/|&lt;br /&gt;
##  |   |q p|   /}&lt;br /&gt;
##  |   ( 0 )&amp;quot;&amp;quot;&amp;quot;\&lt;br /&gt;
##   \  |&amp;quot;-&amp;quot;`    |&lt;br /&gt;
##      || /=\\  |&lt;br /&gt;
##      &amp;quot;&#039;&amp;quot;  &#039;&amp;quot;&amp;quot;&amp;quot;&#039;&lt;br /&gt;
##  --------------------------------------&lt;br /&gt;
##  | Hi Oski Bear, your a wonderful, b! |&lt;br /&gt;
##  |   ----------------------------------&lt;br /&gt;
##  | /&lt;br /&gt;
##  |/  |\_/|&lt;br /&gt;
##  |   |q p|   /}&lt;br /&gt;
##  |   ( 0 )&amp;quot;&amp;quot;&amp;quot;\&lt;br /&gt;
##   \  |&amp;quot;-&amp;quot;`    |&lt;br /&gt;
##      || /=\\  |&lt;br /&gt;
##      &amp;quot;&#039;&amp;quot;  &#039;&amp;quot;&amp;quot;&amp;quot;&#039;&lt;br /&gt;
&lt;br /&gt;
## Error: Test failed: &#039;calling scotty works well (returns null and provides warning nchar &amp;gt; 30)&#039;&lt;br /&gt;
## * 1 not equal to 2.&lt;br /&gt;
## 1/1 mismatches&lt;br /&gt;
## [1] 1 - 2 == -1&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&#039;&#039;&#039;A set of grouped tests&#039;&#039;&#039; in single file. When building a package your functions will likely like in different &amp;lt;code&amp;gt;.R&amp;lt;/code&amp;gt; files in the &amp;lt;code&amp;gt;R/&amp;lt;/code&amp;gt; folder. To mirror this structure we put of our tests associated with a single &amp;lt;code&amp;gt;.R&amp;lt;/code&amp;gt; file into 1 test file. These files sit in the &amp;lt;code&amp;gt;tests/testthat/&amp;lt;/code&amp;gt; folder and must start with &amp;lt;code&amp;gt;test&amp;lt;/code&amp;gt;. &amp;lt;code&amp;gt;devtools&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;usethis&amp;lt;/code&amp;gt; provide a way to create these test in an automated fashion. For example, if we wanted to create a file &amp;lt;code&amp;gt;tests/testthat/test-welcome.R&amp;lt;/code&amp;gt;, we could call&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;r&amp;quot;&amp;gt;usethis::use_test(&amp;quot;welcome&amp;quot;)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
which provides the message:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;r&amp;quot;&amp;gt;✔ Setting active project to &#039;./tartan&#039;&lt;br /&gt;
✔ Adding &#039;testthat&#039; to Suggests field in DESCRIPTION&lt;br /&gt;
✔ Creating &#039;tests/testthat/&#039;&lt;br /&gt;
✔ Writing &#039;tests/testthat.R&#039;&lt;br /&gt;
✔ Writing &#039;tests/testthat/test-welcome.R&#039;&lt;br /&gt;
● Modify &#039;tests/testthat/test-welcome.R&#039;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
In these larger files (relative to group functions) we include group expectations as well as context information for the overall file using the &amp;lt;code&amp;gt;context()&amp;lt;/code&amp;gt; function. And example can be see below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;r&amp;quot;&amp;gt;context(&amp;quot;test welcome from scotty&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
test_that(paste(&amp;quot;calling scotty works well (returns null&amp;quot;,&lt;br /&gt;
                 &amp;quot;and provides warning nchar &amp;gt; 30)&amp;quot;), {&lt;br /&gt;
  expect_equal(call_scotty_demo(&amp;quot;Oski Bear&amp;quot;), NULL)&lt;br /&gt;
  expect_warning(call_scotty_demo(&amp;quot;Oski Bear, your a wonderful, but slightly creepy Berkeley Bear&amp;quot;))&lt;br /&gt;
  expect_equal(1, 2)&lt;br /&gt;
})&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Once you have a test file in your package all you need to do is run&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;r&amp;quot;&amp;gt;devtools::test()&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
and R will run all your associated test, and will return output like seen in the following image:&lt;br /&gt;
&lt;br /&gt;
[[File:devtool_test_example.png|frameless|600px|alt=output of testthat|output of testthat]]&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Step 5. Checking the full package ===&lt;br /&gt;
&lt;br /&gt;
To understanding if your overall package is clean and able to be shared we can run&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;devtools::check()&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This checks all your dependencies, syntax, and more that may have slipped through the cracks. Often times this is only necessary when you’re looking to share your package with others, but is a good step to include so you don’t have to change a lot of things right before sharing.&lt;br /&gt;
&lt;br /&gt;
=== Step 6: Syncronizing with Github ===&lt;br /&gt;
&lt;br /&gt;
As always, once you’ve completed a clean block of code you should push it to Github. When your code is on github other folks can download the package in a similar fashion to the standard &amp;lt;code&amp;gt;install.packages(...)&amp;lt;/code&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
For example, to install the R package we just made we could use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;{r eval = T, message=F, warning=F} devtools::install_github(repo = &amp;amp;quot;benjaminleroy/tartan&amp;amp;quot;,                          force = F) # so making the sides does do it a ton of times library(tartan) #?call_scotty_demo call_scotty_demo(&amp;amp;quot;Big Bird&amp;amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Step 7: And beyond! ===&lt;br /&gt;
&lt;br /&gt;
In the above example we still didn’t cover a lot of things, including:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Including data in your package (that can be [http://r-pkgs.had.co.nz/data.html documented] too)&lt;br /&gt;
&amp;lt;code&amp;gt;r     # suppose that I have a tarans dataset that I created - than I can save it this way     usethis::use_data(tartans)     # and document at     usethis::use_r(&amp;amp;quot;data&amp;amp;quot;)&amp;lt;/code&amp;gt; &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Vignettes (long form documentation, knitr) &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Compiled code (C, C++, Fortran…) &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Creating a CRAN ready package &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; See [https://usethis.r-lib.org/reference/index.html &amp;lt;code&amp;gt;usethis&amp;lt;/code&amp;gt;] to see all the package development steps that &amp;lt;code&amp;gt;usethis&amp;lt;/code&amp;gt; automates. &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;/div&gt;</summary>
		<author><name>Skipper</name></author>
	</entry>
	<entry>
		<id>https://info.stat.cmu.edu/index.php?title=File:Call_scotty_demo_doc.png&amp;diff=62</id>
		<title>File:Call scotty demo doc.png</title>
		<link rel="alternate" type="text/html" href="https://info.stat.cmu.edu/index.php?title=File:Call_scotty_demo_doc.png&amp;diff=62"/>
		<updated>2024-05-24T01:46:38Z</updated>

		<summary type="html">&lt;p&gt;Skipper: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;example of help file&lt;/div&gt;</summary>
		<author><name>Skipper</name></author>
	</entry>
	<entry>
		<id>https://info.stat.cmu.edu/index.php?title=File:Tartan_description.png&amp;diff=61</id>
		<title>File:Tartan description.png</title>
		<link rel="alternate" type="text/html" href="https://info.stat.cmu.edu/index.php?title=File:Tartan_description.png&amp;diff=61"/>
		<updated>2024-05-24T01:45:18Z</updated>

		<summary type="html">&lt;p&gt;Skipper: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;initialized description file&lt;/div&gt;</summary>
		<author><name>Skipper</name></author>
	</entry>
	<entry>
		<id>https://info.stat.cmu.edu/index.php?title=File:1200px-Tartan_folder.png&amp;diff=60</id>
		<title>File:1200px-Tartan folder.png</title>
		<link rel="alternate" type="text/html" href="https://info.stat.cmu.edu/index.php?title=File:1200px-Tartan_folder.png&amp;diff=60"/>
		<updated>2024-05-24T01:44:10Z</updated>

		<summary type="html">&lt;p&gt;Skipper: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;initial directory items&lt;/div&gt;</summary>
		<author><name>Skipper</name></author>
	</entry>
	<entry>
		<id>https://info.stat.cmu.edu/index.php?title=Parallel_computing&amp;diff=59</id>
		<title>Parallel computing</title>
		<link rel="alternate" type="text/html" href="https://info.stat.cmu.edu/index.php?title=Parallel_computing&amp;diff=59"/>
		<updated>2024-05-24T01:34:47Z</updated>

		<summary type="html">&lt;p&gt;Skipper: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= When and why of parallel computing =&lt;br /&gt;
&lt;br /&gt;
Parallel computing is a “hot” topic in computing and data science, but in many Statisticians’ daily lives it’s not too commonplace. This wiki article attempts to discuss some examples that might lead you to leveraging parallel computing as a statistician (often in the form of task-parallelization) and the trade-offs and potential power of parallel computing.&lt;br /&gt;
&lt;br /&gt;
= General: Why parallel computing =&lt;br /&gt;
&lt;br /&gt;
Some classic examples (expanded base on a list from [https://people.duke.edu/~ccc14/sta-663-2018/notebooks/S14A_Parallel_Programming_Introduction.html duke] for parallelization in statistics include &lt;br /&gt;
&lt;br /&gt;
# simulations&lt;br /&gt;
## sensitivity testing&lt;br /&gt;
## parameter tuning&lt;br /&gt;
## Monte Carlo integration &lt;br /&gt;
# bootstrapping /other resampling&lt;br /&gt;
# Multiple MCMC chains&lt;br /&gt;
&lt;br /&gt;
A lot of &amp;lt;code&amp;gt;R&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;python&amp;lt;/code&amp;gt; code runs fast enough on a single processor. But at times, computations can be:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;cpu-bound&#039;&#039;&#039;: Take too much cpu time&lt;br /&gt;
* &#039;&#039;&#039;memory-bound&#039;&#039;&#039;: Take too much memory&lt;br /&gt;
* &#039;&#039;&#039;I/O-bound&#039;&#039;&#039;: Take too much time to read/write from disk&lt;br /&gt;
* &#039;&#039;&#039;network-bound&#039;&#039;&#039;: Take too much time to transfer&lt;br /&gt;
&lt;br /&gt;
Parallelization directly helps with &#039;&#039;&#039;cpu-bound&#039;&#039;&#039; computations and can allow the user to leverage modern processor architectures that provide multiple cores on a single processor.&lt;br /&gt;
&lt;br /&gt;
= General: When to parallelize (and when not to) =&lt;br /&gt;
Supposing you’re in a situation where your analysis’s computation is &#039;&#039;&#039;cpu-bound&#039;&#039;&#039;, a secondary question is “can parallelization help speed this up?”. This question should capture &lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;the amount of time you need to parallelize the process &amp;amp; combine the data,&amp;lt;/li&amp;gt; &lt;br /&gt;
&amp;lt;li&amp;gt;how much increased overhead (in RAM &amp;amp; memory and cpu processing) is required to run and&amp;lt;/li&amp;gt; &lt;br /&gt;
&amp;lt;li&amp;gt;if the process can even be parallelized.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Potential to parallelize ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&#039;&#039;&#039;Amdahl’s Law&#039;&#039;&#039;: trade-oof between cores and parallelizable proportion of analysis In the computing community some of these trade-offs are captured by &#039;&#039;&#039;Amdahl’s Law&#039;&#039;&#039; which relates the increased speedup of your computation (y-axis) as a function of the number of cores (x-axis) and the proportion of computation that can be parallelized (see the colored lines). The image below visualizes this idea:&lt;br /&gt;
&lt;br /&gt;
[[File:1200px-Parallelization.png|600px|frameless|thumb|center]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, suppose you have to process a lot of early steps before running something that can be parallelized, and these early steps can’t be saved as they are too memory intensive (e.g. having more RAM than actually solid-state memory available), This might make the amount of computation that can be parallelized smalled (say 50%). In certain cases, this should discourage you to parallelize your process completely. This could lead your to do language-specific parallelization ([[parallelization_in_r|R parallel computing]] or [[parallelization_in_python|Python parallel computing]]) instead of higher-level parallelization (through [[Slurm]] or [[Bash_files|Bash files]] + [[Terminal_multiplexers|Terminal multiplexers]]).&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Memory Constraints&lt;br /&gt;
&lt;br /&gt;
Outside considerations of Amdahl’s Law, the amount of RAM (especially on your personal computer), may give you pause. Often, when trying to alleviate cpu-bound constraints using parallelization one can run into memory-bound constraints. Specifically, running multiple processes intrinsically increases the amount of RAM memory used. this can actually make language-specific parallelization ([[parallelization_in_r|R parallel computing]]  or [[parallelization_in_python|Python parallel computing]]) on personal computers &#039;&#039;&#039;unworkable&#039;&#039;&#039;, and encourage utilizing resources with more RAM which can lead to using ([[Slurm]] or [[Bash files]] + [[Terminal_multiplexers]])-style parallelization.&lt;br /&gt;
&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Additional Reading =&lt;br /&gt;
&lt;br /&gt;
As you can guess, there are more specific articles to help you get started/know some of what is available to actually do parallelization.&lt;br /&gt;
&lt;br /&gt;
* Language-specific parallelization&lt;br /&gt;
** [[Parallelization_in_r|paralleliation with R]]&lt;br /&gt;
** [[Parallelization_in_python|parallelization with python]]&lt;br /&gt;
* Parallelization on Department servers&lt;br /&gt;
** You can use language-specific parallelization or combine [[Terminal multiplexers]] and [[Bash files]] to speed up the process&lt;br /&gt;
* [[Pittsburgh Super computer|PSC]]&lt;br /&gt;
** you’re best off learning the [[Slurm|Slurm workload manager]]&lt;/div&gt;</summary>
		<author><name>Skipper</name></author>
	</entry>
	<entry>
		<id>https://info.stat.cmu.edu/index.php?title=Parallel_computing&amp;diff=58</id>
		<title>Parallel computing</title>
		<link rel="alternate" type="text/html" href="https://info.stat.cmu.edu/index.php?title=Parallel_computing&amp;diff=58"/>
		<updated>2024-05-24T01:33:57Z</updated>

		<summary type="html">&lt;p&gt;Skipper: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= When and why of parallel computing =&lt;br /&gt;
&lt;br /&gt;
Parallel computing is a “hot” topic in computing and data science, but in many Statisticians’ daily lives it’s not too commonplace. This wiki article attempts to discuss some examples that might lead you to leveraging parallel computing as a statistician (often in the form of task-parallelization) and the trade-offs and potential power of parallel computing.&lt;br /&gt;
&lt;br /&gt;
= General: Why parallel computing =&lt;br /&gt;
&lt;br /&gt;
Some classic examples (expanded base on a list from [https://people.duke.edu/~ccc14/sta-663-2018/notebooks/S14A_Parallel_Programming_Introduction.html duke] for parallelization in statistics include &lt;br /&gt;
&lt;br /&gt;
# simulations&lt;br /&gt;
## sensitivity testing&lt;br /&gt;
## parameter tuning&lt;br /&gt;
## Monte Carlo integration &lt;br /&gt;
# bootstrapping /other resampling&lt;br /&gt;
# Multiple MCMC chains&lt;br /&gt;
&lt;br /&gt;
A lot of &amp;lt;code&amp;gt;R&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;python&amp;lt;/code&amp;gt; code runs fast enough on a single processor. But at times, computations can be:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;cpu-bound&#039;&#039;&#039;: Take too much cpu time&lt;br /&gt;
* &#039;&#039;&#039;memory-bound&#039;&#039;&#039;: Take too much memory&lt;br /&gt;
* &#039;&#039;&#039;I/O-bound&#039;&#039;&#039;: Take too much time to read/write from disk&lt;br /&gt;
* &#039;&#039;&#039;network-bound&#039;&#039;&#039;: Take too much time to transfer&lt;br /&gt;
&lt;br /&gt;
Parallelization directly helps with &#039;&#039;&#039;cpu-bound&#039;&#039;&#039; computations and can allow the user to leverage modern processor architectures that provide multiple cores on a single processor.&lt;br /&gt;
&lt;br /&gt;
= General: When to parallelize (and when not to) =&lt;br /&gt;
[[File:1200px-Parallelization.png|600px|thumb|center]]&lt;br /&gt;
Supposing you’re in a situation where your analysis’s computation is &#039;&#039;&#039;cpu-bound&#039;&#039;&#039;, a secondary question is “can parallelization help speed this up?”. This question should capture &lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;the amount of time you need to parallelize the process &amp;amp; combine the data,&amp;lt;/li&amp;gt; &lt;br /&gt;
&amp;lt;li&amp;gt;how much increased overhead (in RAM &amp;amp; memory and cpu processing) is required to run and&amp;lt;/li&amp;gt; &lt;br /&gt;
&amp;lt;li&amp;gt;if the process can even be parallelized.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Potential to parallelize ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&#039;&#039;&#039;Amdahl’s Law&#039;&#039;&#039;: trade-oof between cores and parallelizable proportion of analysis In the computing community some of these trade-offs are captured by &#039;&#039;&#039;Amdahl’s Law&#039;&#039;&#039; which relates the increased speedup of your computation (y-axis) as a function of the number of cores (x-axis) and the proportion of computation that can be parallelized (see the colored lines). The image below visualizes this idea:&lt;br /&gt;
&lt;br /&gt;
[[File:Parallelization.png|frameless|600px|alt=amdahls law|amdahls law]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, suppose you have to process a lot of early steps before running something that can be parallelized, and these early steps can’t be saved as they are too memory intensive (e.g. having more RAM than actually solid-state memory available), This might make the amount of computation that can be parallelized smalled (say 50%). In certain cases, this should discourage you to parallelize your process completely. This could lead your to do language-specific parallelization ([[parallelization_in_r|R parallel computing]] or [[parallelization_in_python|Python parallel computing]]) instead of higher-level parallelization (through [[Slurm]] or [[Bash_files|Bash files]] + [[Terminal_multiplexers|Terminal multiplexers]]).&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Memory Constraints&lt;br /&gt;
&lt;br /&gt;
Outside considerations of Amdahl’s Law, the amount of RAM (especially on your personal computer), may give you pause. Often, when trying to alleviate cpu-bound constraints using parallelization one can run into memory-bound constraints. Specifically, running multiple processes intrinsically increases the amount of RAM memory used. this can actually make language-specific parallelization ([[parallelization_in_r|R parallel computing]]  or [[parallelization_in_python|Python parallel computing]]) on personal computers &#039;&#039;&#039;unworkable&#039;&#039;&#039;, and encourage utilizing resources with more RAM which can lead to using ([[Slurm]] or [[Bash files]] + [[Terminal_multiplexers]])-style parallelization.&lt;br /&gt;
&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Additional Reading =&lt;br /&gt;
&lt;br /&gt;
As you can guess, there are more specific articles to help you get started/know some of what is available to actually do parallelization.&lt;br /&gt;
&lt;br /&gt;
* Language-specific parallelization&lt;br /&gt;
** [[Parallelization_in_r|paralleliation with R]]&lt;br /&gt;
** [[Parallelization_in_python|parallelization with python]]&lt;br /&gt;
* Parallelization on Department servers&lt;br /&gt;
** You can use language-specific parallelization or combine [[Terminal multiplexers]] and [[Bash files]] to speed up the process&lt;br /&gt;
* [[Pittsburgh Super computer|PSC]]&lt;br /&gt;
** you’re best off learning the [[Slurm|Slurm workload manager]]&lt;/div&gt;</summary>
		<author><name>Skipper</name></author>
	</entry>
	<entry>
		<id>https://info.stat.cmu.edu/index.php?title=File:1200px-Parallelization.png&amp;diff=57</id>
		<title>File:1200px-Parallelization.png</title>
		<link rel="alternate" type="text/html" href="https://info.stat.cmu.edu/index.php?title=File:1200px-Parallelization.png&amp;diff=57"/>
		<updated>2024-05-24T01:33:10Z</updated>

		<summary type="html">&lt;p&gt;Skipper: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;amdahls law&lt;/div&gt;</summary>
		<author><name>Skipper</name></author>
	</entry>
</feed>