summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--notebooks/python/python_3_8_to_3_11.ipynb2
-rw-r--r--notebooks/python/python_intro.ipynb2
-rw-r--r--notebooks/python/python_oo.ipynb2
-rw-r--r--notebooks/sqlalchemy/sqlalchemy.ipynb2
-rw-r--r--reveal.js/free_software.html219
-rwxr-xr-xreveal.js/git.html513
-rw-r--r--reveal.js/images/git/advance-master.pngbin0 -> 7140 bytes
-rw-r--r--reveal.js/images/git/advance-testing.pngbin0 -> 8146 bytes
-rw-r--r--reveal.js/images/git/basic-rebase-2.pngbin0 -> 8218 bytes
-rw-r--r--reveal.js/images/git/basic-rebase-3.pngbin0 -> 7741 bytes
-rw-r--r--reveal.js/images/git/branches.pngbin0 -> 22842 bytes
-rw-r--r--reveal.js/images/git/checkout-master.pngbin0 -> 7583 bytes
-rw-r--r--reveal.js/images/git/commit.pngbin0 -> 19774 bytes
-rw-r--r--reveal.js/images/git/head-to-master.pngbin0 -> 9977 bytes
-rw-r--r--reveal.js/images/git/head-to-testing.pngbin0 -> 9884 bytes
-rw-r--r--reveal.js/sqlalchemy.html285
16 files changed, 879 insertions, 146 deletions
diff --git a/notebooks/python/python_3_8_to_3_11.ipynb b/notebooks/python/python_3_8_to_3_11.ipynb
index e2a08e9..b8724e8 100644
--- a/notebooks/python/python_3_8_to_3_11.ipynb
+++ b/notebooks/python/python_3_8_to_3_11.ipynb
@@ -834,7 +834,7 @@
834 "name": "python", 834 "name": "python",
835 "nbconvert_exporter": "python", 835 "nbconvert_exporter": "python",
836 "pygments_lexer": "ipython3", 836 "pygments_lexer": "ipython3",
837 "version": "3.11.4" 837 "version": "3.11.7"
838 } 838 }
839 }, 839 },
840 "nbformat": 4, 840 "nbformat": 4,
diff --git a/notebooks/python/python_intro.ipynb b/notebooks/python/python_intro.ipynb
index 171b83c..f129ffe 100644
--- a/notebooks/python/python_intro.ipynb
+++ b/notebooks/python/python_intro.ipynb
@@ -1053,7 +1053,7 @@
1053 "name": "python", 1053 "name": "python",
1054 "nbconvert_exporter": "python", 1054 "nbconvert_exporter": "python",
1055 "pygments_lexer": "ipython3", 1055 "pygments_lexer": "ipython3",
1056 "version": "3.11.5" 1056 "version": "3.11.7"
1057 } 1057 }
1058 }, 1058 },
1059 "nbformat": 4, 1059 "nbformat": 4,
diff --git a/notebooks/python/python_oo.ipynb b/notebooks/python/python_oo.ipynb
index 0ab369b..e38d7f3 100644
--- a/notebooks/python/python_oo.ipynb
+++ b/notebooks/python/python_oo.ipynb
@@ -1418,7 +1418,7 @@
1418 "name": "python", 1418 "name": "python",
1419 "nbconvert_exporter": "python", 1419 "nbconvert_exporter": "python",
1420 "pygments_lexer": "ipython3", 1420 "pygments_lexer": "ipython3",
1421 "version": "3.11.3" 1421 "version": "3.11.7"
1422 } 1422 }
1423 }, 1423 },
1424 "nbformat": 4, 1424 "nbformat": 4,
diff --git a/notebooks/sqlalchemy/sqlalchemy.ipynb b/notebooks/sqlalchemy/sqlalchemy.ipynb
index 58a7eb9..0d2a966 100644
--- a/notebooks/sqlalchemy/sqlalchemy.ipynb
+++ b/notebooks/sqlalchemy/sqlalchemy.ipynb
@@ -991,7 +991,7 @@
991 "name": "python", 991 "name": "python",
992 "nbconvert_exporter": "python", 992 "nbconvert_exporter": "python",
993 "pygments_lexer": "ipython3", 993 "pygments_lexer": "ipython3",
994 "version": "3.11.5" 994 "version": "3.11.6"
995 } 995 }
996 }, 996 },
997 "nbformat": 4, 997 "nbformat": 4,
diff --git a/reveal.js/free_software.html b/reveal.js/free_software.html
new file mode 100644
index 0000000..71bea85
--- /dev/null
+++ b/reveal.js/free_software.html
@@ -0,0 +1,219 @@
1<!doctype html>
2<html lang="en">
3 <head>
4 <meta charset="utf-8">
5 <title>Free software in a nutshell</title>
6 <meta name="author" content="Simeon Simeonov">
7 <meta name="apple-mobile-web-app-capable" content="yes">
8 <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
9 <meta name="viewport" content="width=device-width, initial-scale=1.0">
10
11 <link rel="stylesheet" href="dist/reset.css">
12 <link rel="stylesheet" href="dist/reveal.css">
13
14 <link rel="stylesheet" href="dist/theme/statnett_compact.css" id="theme">
15
16 <!-- Theme used for syntax highlighting of code -->
17 <link rel="stylesheet" href="plugin/highlight/monokai.css" id="highlight-theme">
18 <!-- <link rel="stylesheet" href="plugin/highlight/zenburn.css" id="highlight-theme"> -->
19 </head>
20 <body>
21 <div class="reveal">
22
23 <!-- Any section element inside of this container is displayed as a slide -->
24 <div class="slides">
25
26 <section>
27 <h2>Free software in a nutshell</h2>
28 <h4>Free as in freedom</h4>
29 </br>
30 <p><small>Simeon Simeonov - TDE</small></p>
31 </section>
32
33 <section>
34
35 <section id="fragments">
36 <h2>Agenda</h2>
37 </br>
38 <ul>
39 <span class="fragment"><li>What is free software - historical context</li></span>
40 <span class="fragment"><li>Free software vs. "open source"</li></span>
41 <span class="fragment"><li>Free software licenses</li></span>
42 <span class="fragment"><li>Debunking some of the most common myths about free software</li></span>
43 <span class="fragment"><li>The main practical advantages of free software</li></span>
44 <span class="fragment"><li>What can Statnett and I do?</li></span>
45 <span class="fragment"><li>Q & A</li></span>
46 </ul>
47 </section>
48
49 </section>
50
51 <section>
52 <h3>Historical context</h3>
53 <ul>
54 <li><p>In the late 1970s while working as a programmer at MIT AI Laboratory, Richard Matthew Stallman (b. 1953), also known by his initials <em>rms</em>, became frustrated when most manufacturers stopped distributing <em>source code</em> and began using copyright and restrictive software licenses to limit or prohibit copying and redistribution. This was a consequence triggered by the US Copyright Act of 1976.</p></li>
55 <li><p>In September 1983 Stallman announced the plan for the <em>GNU operating system</em> - a free operating system "compatible with Unix so that it would be portable, and so that Unix users could easily switch to it". The name GNU is a recursive acronym for "GNU's Not Unix".</p></li>
56 <li><p>In February 1984, Stallman quit his job at MIT to work full-time on the GNU project. Since then, he had remained affiliated with MIT as an unpaid "visiting scientist" in the Computer Science and Artificial Intelligence Laboratory.</p></li>
57 <li><p>In 1985, Stallman published the GNU Manifesto, which outlined his motivation for creating a free operating system called GNU. Soon after, he started a nonprofit corporation called the <em>Free Software Foundation</em> (FSF) to employ free software programmers and provide a legal infrastructure for the free software movement. Stallman was the nonsalaried president of the FSF, which is a 501(c)(3) nonprofit organization founded in Massachusetts. Stallman popularized the concept of <em>copyleft</em>, a legal mechanism to protect the modification and redistribution rights for free software.</p></li>
58 </ul>
59 </section>
60
61 <section>
62 <h2>What is free software?</h2>
63 <p>A program is free software if the program's users have the four essential freedoms:</p>
64 <ul>
65 <li><p>Freedom 0 - The freedom to run the program as you wish, for any purpose</p></li>
66 <li><p>Freedom 1 - The freedom to study how the program works, and change it so it does your computing as you wish. Access to the source code is a precondition for this</p></li>
67 <li><p>Freedom 2 - The freedom to redistribute copies so you can help others</p></li>
68 <li><p>Freedom 3 - The freedom to distribute copies of your modified versions to others. By doing this you can give the whole community a chance to benefit from your changes. Access to the source code is a precondition for this</p></li>
69 </ul>
70 <p>"A program is free software if it gives users adequately all of these freedoms. Otherwise, it is nonfree. While we can distinguish various nonfree distribution schemes in terms of how far they fall short of being free, we consider them all equally unethical." - <a href="https://www.gnu.org/philosophy/free-sw.html">GNU (Philosophy)</a></p>
71 <p>The term "libre" has been used lately</p>
72 </section>
73
74 <section>
75 <h4>The GNU operating system</h4>
76 <ul>
77 <li><p>By June 1987, the project had accumulated and developed free software for an assembler, an almost finished portable optimizing C compiler - GCC, an editor - GNU Emacs, and various Unix utilities (such as ls, grep, awk, make and ld). They had an initial kernel that needed more updates.</p></li>
78 <li><p>By 1992, the GNU project had completed all of the major operating system utilities, but had not completed their proposed operating system kernel - <em>GNU Hurd</em>. With the release of the Linux kernel, started independently by Linus Torvalds in 1991, and released under the GPLv2 with version 0.12 in 1992, for the first time it was possible to run an operating system composed completely of free software. Though the Linux kernel is not part of the GNU project, it was developed using GCC and other GNU programming tools and was released as free software under the GNU General Public License. Most compilation of the Linux kernel is still done with GNU toolchains.</p></li>
79 <li><p>The GNU packages consist of numerous operating system tools and utilities (shell, coreutils, compilers, libraries, etc.) including a library implementation of all of the functions specified in POSIX System Application Program Interface (POSIX.1). The GCC compiler can generate machine-code for a large variety of computer-architectures.</p></li>
80 <li><p>Linux kernel – this implements program scheduling, multitasking, device drivers, memory management, etc. and allows the system to run on a large variety of computer-architectures.</p></li>
81 <li><p>The packaging of GNU tools, together with the Linux kernel and other programs, is usually called a Linux distribution (distro). The GNU Project calls the combination of GNU and the Linux kernel "GNU/Linux", and asks others to do the same, resulting in the GNU/Linux naming controversy.</p></li>
82 </ul>
83 <p>Visit <a href="https://www.gnu.org/software/">https://www.gnu.org/software/</a> for a complete list of the GNU packages</p>
84 </section>
85
86 <section>
87 <h2>Free software vs. "open source"</h2>
88 <ul>
89 <li><p>In February 1998 Bruce Perens and Eric S. Raymond (<em>esr</em>) founded the <em>Open Source Initiative</em></p></li>
90 <li><p>Stallman argues that software users should have the freedom to share with their neighbors and be able to study and make changes to the software that they use. He maintains that attempts by proprietary software vendors to prohibit these acts are antisocial and unethical. He argues that freedom is vital for the sake of users and society as a moral value, and not merely for pragmatic reasons such as possibly developing technically superior software.</p></li>
91 <li><p>Eric S. Raymond argues that moral arguments, rather than pragmatic ones, alienate potential allies and hurt the end goal of removing code secrecy.</p></li>
92 </ul>
93 <p>Most "open source" software is a free software, but there are exceptions (f.i. qmail, nmap, True crypt... )</p>
94 <p>The term <em>FOSS</em> - (Free and open-source software) is widely used to describe specific software.</p>
95 </section>
96
97 <section>
98 <h2>Other free software</h2>
99 <ul>
100 <li><p>The earliest distributions of Unix from Bell Labs in the 1970s included the source code to the operating system, allowing researchers at universities to modify and extend Unix</p></li>
101 <li><p>In 1974 the operating system arrived at University of California Berkeley, at the request of computer science professor Bob Fabry</p></li>
102 <li><p>The Berkeley Software Distribution - <em>BSD</em> just included some extra features, which were intertwined with code owned by AT&T</p></li>
103 <li><p>Extensive academic research during the 80s. 4.3BSD was released in June 1986</p></li>
104 <li><p>4.3BSD + TCP/IP stack was freely redistributable under the terms of the BSD license. It was released in June 1989</p></li>
105 <li><p>1993 - FreeBSD and NetBSD are first released</p></li>
106 <li><p>1995 - The last 4.4BSD is released. OpenBSD is released</p></li>
107 </ul>
108 <p>The permissive nature of the BSD license has allowed many other operating systems, both open-source and proprietary, to incorporate BSD source code. Microsoft Windows used BSD code in its implementation of TCP/IP and bundles recompiled versions of BSD's command-line networking tools since Windows 2000. Darwin, the basis for Apple's macOS and iOS, is based on 4.4BSD-Lite2 and FreeBSD. Plastation (3,4,5), Nintendo Switch...</p>
109 </section>
110
111 <section>
112 <h2>Free software licenses (GPL)</h2>
113 <p>The Free Software Foundations is behind several versions of the <em>GNU General Public License</em> (GNU GPL or simply GPL)</p>
114 <p><em>Copyleft</em> - any derivative work must be distributed under the same or equivalent license terms</p>
115 <ul>
116 <li><p>GPLv1 - Released in 1989 and no longer used</p></li>
117 <li><p>GPLv2 - Released in 1991 and still in use (f.i. the Linux kernel) - "strong copyleft" not even allowing integration of GPL licensed software components into non GPL software</p></li>
118 <li><p>GPLv3 - Released in 2007 - changes in regard to software patents, DRM and alike.</p></li>
119 <li><p>LGPL(2 and 3) - "weak copyleft" - making it possible to use and integrate a software component released under the LGPL into (even proprietary) software without being required by the terms of a strong copyleft license to release the source code of their own components</p></li>
120 </ul>
121 <p>GPLv2+ or GPLv3+ stands for "2 (or 3) or any later version" and is the default form of the license</p>
122 </section>
123
124 <section>
125 <h2>Free software licenses (BSD)</h2>
126 <p>3-clause BSD license ("BSD License 2.0", "Revised BSD License", "New BSD License", or "Modified BSD License") and 2-clause BSD license ("Simplified BSD License" or "FreeBSD License") are the most popular BSD licenses. No copyleft.</p>
127 <ul>
128 <li><p>Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer</p></li>
129 <li><p>Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution</p></li>
130 <li><p>Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission (3rd clause)</p></li>
131 </ul>
132 </section>
133
134 <section>
135 <h2>Free software licenses (Apache)</h2>
136 <p>A permissive free software license written by the Apache Software Foundation (ASF). No copyleft.</p>
137 <p>Requiring a patent license on contributions that necessarily infringe a contributor's own patents. This license requires preservation of the copyright notice and disclaimer.</p>
138 </section>
139
140 <section>
141 <h2>Free software licenses (MIT)</h2>
142 <p>A permissive free software license written by MIT. No copyleft. Does not mention patents.</p>
143 <p>"The above copyright notice and this permission notice shall be included in all
144copies or substantial portions of the Software."</p>
145 </section>
146
147 <section>
148 <section id="fragments">
149 <h2>Some of the most common myths about free software</h2>
150 <ul>
151 <span class="fragment"><li><p>If you use free software and modify it, you have to release your modifications (licensed under the GPL)</p></li></span>
152 <span class="fragment"><li><p>You will never get proper / commercial support if you use free software</p></li></span>
153 <span class="fragment"><li><p>Free software is free of charge</p></li></span>
154 <span class="fragment"><li><p>Free software is not / anti commercial</p></li></span>
155 </ul>
156 </section>
157 </section>
158
159 <section>
160 <h2>The main practical advantages of free software</h2>
161 <ul>
162 <li><p>Better personal control - avoiding vendor lock-in</p></li>
163 <li><p>Privacy and security - nothing happens behind your back, the security of a software is verified by the community and not by the company that made it</p></li>
164 <li><p>Quality over profit</p></li>
165 </ul>
166 </section>
167
168 <section>
169 <h2>What can Statnett do?</h2>
170 <ul>
171 <li><p>Using free software with commercial support</p></li>
172 <li><p>Developing and sharing free software</p></li>
173 <li><p>Modifying and sharing free software</p></li>
174 <li><p>Supporting free software projects - software that is already in use at Statnett</p></li>
175 <li><p>Influencing free software projects by purchasing / ordering new features</p></li>
176 </ul>
177 </section>
178
179 <section>
180 <h2>What can I do?</h2>
181 <ul>
182 <li><p>Consciousness raising</p></li>
183 <li><p>Developing and sharing free software</p></li>
184 <li><p>Donating (FSF, FSFE, or any other free software peoject) instead of "When are they going to implement / fix this?"</p></li>
185 </ul>
186 </section>
187
188 <section>
189 <h1>Q &amp; A</h1>
190 </section>
191
192 </div>
193 </div>
194
195 <script src="dist/reveal.js"></script>
196 <script src="plugin/zoom/zoom.js"></script>
197 <script src="plugin/notes/notes.js"></script>
198 <script src="plugin/search/search.js"></script>
199 <script src="plugin/markdown/markdown.js"></script>
200 <script src="plugin/highlight/highlight.js"></script>
201 <script>
202
203 // Also available as an ES module, see:
204 // https://revealjs.netlify.app/initialization/
205 Reveal.initialize({
206 controls: true,
207 progress: true,
208 center: true,
209 hash: true,
210
211 // Learn about plugins: https://revealjs.netlify.app/plugins/
212 plugins: [ RevealZoom, RevealNotes, RevealSearch, RevealMarkdown, RevealHighlight ]
213 });
214 Reveal.configure({ pdfSeparateFragments: false });
215
216 </script>
217
218 </body>
219</html>
diff --git a/reveal.js/git.html b/reveal.js/git.html
new file mode 100755
index 0000000..6ee3406
--- /dev/null
+++ b/reveal.js/git.html
@@ -0,0 +1,513 @@
1<!doctype html>
2<html lang="en">
3 <head>
4 <meta charset="utf-8">
5 <title>Introduction to git</title>
6 <meta name="author" content="Simeon Simeonov">
7 <meta name="apple-mobile-web-app-capable" content="yes">
8 <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
9 <meta name="viewport" content="width=device-width, initial-scale=1.0">
10
11 <link rel="stylesheet" href="dist/reset.css">
12 <link rel="stylesheet" href="dist/reveal.css">
13
14 <link rel="stylesheet" href="dist/theme/statnett.css" id="theme">
15
16 <!-- Theme used for syntax highlighting of code -->
17 <link rel="stylesheet" href="plugin/highlight/monokai.css" id="highlight-theme">
18 <!-- <link rel="stylesheet" href="plugin/highlight/zenburn.css" id="highlight-theme"> -->
19 </head>
20 <body>
21 <div class="reveal">
22
23 <!-- Any section element inside of this container is displayed as a slide -->
24 <div class="slides">
25
26 <section>
27 <h2>Introduction to Git</h2>
28 </br>
29 <p>Competence group (Faggruppe) Python</p>
30 <p><small>Simeon Simeonov - TDE</small></p>
31 </section>
32
33 <section>
34
35 <section id="fragments">
36 <h2>Agenda</h2>
37 </br>
38 <ul>
39 <span class="fragment"><li>What is Git? A brief history</li></span>
40 <span class="fragment"><li>Working locally. Dealing with commits and branches</li></span>
41 <span class="fragment"><li>Using remotes and GitLab</li></span>
42 <span class="fragment"><li>Walkthrough. Demonstrating some common Git flows</li></span>
43 </ul>
44 </section>
45
46 </section>
47
48
49 <section>
50 <h2>What is Git?</h2>
51 <p>Git is a <em>distributed version control</em> system that tracks changes in any set of computer files, usually used for coordinating work among programmers who are collaboratively developing source code during software development.</p>
52 <p><em>Distributed version control</em> is a form of version control in which the complete codebase, including its full history, is mirrored on every developer's computer.</p>
53 <ul>
54 <span><li>Git development was started by Linus Torvalds on 3. April 2005</li></span>
55 <span><li>Torvalds wanted a distributed system that he could use like <em>BitKeeper</em>, but none of the available free (as in freedom) systems met his needs</li></span>
56 <span><li>The main objectives were: performance, very strong safeguards against corruption, either accidental or malicious, distributed workflow</li></span>
57 <span><li>The name: <em>git</em> means "unpleasant person" in British English slang. "I'm an egotistical bastard, and I name all my projects after myself. First 'Linux', now 'git'.". The man page describes Git as "the stupid content tracker".</li></span>
58 <span><li>Torvalds achieved his performance goals on 29 April 2005</li></span>
59 <span><li>Torvalds turned over maintenance on 26 July 2005 to Junio Hamano, a major contributor to the project. Hamano was responsible for the 1.0 release on 21 December 2005</li></span>
60 <span><li>Current (23. February 2024) stable version: 2.44.0</li></span>
61 </ul>
62 </section>
63
64
65 <section>
66 <h2>Configuring Git</h2>
67 </br>
68 <p>We start be configuring Git for our needs</p>
69 <ul>
70 <span><li><em>git config</em> - gets and sets repository options</li></span>
71 <span><li><em>git config --global</em> - gets and sets global options</li></span>
72 </ul>
73
74 <p>Using WSL / devbox or Git for Windows (from <em>Software Center</em>):</p>
75 <pre data-id="code-animation">
76 <code class="bash" data-trim type="text/template">
77 # - this is a comment and the remainder of this line will be ignored by the shell
78 git config --global user.name "Simeon Simeonov"
79 git config --global user.email "simeon.simeonov@statnett.no"
80 git config --global init.defaultBranch master # sets 'master' as the default branch name
81 # git config --global init.defaultBranch main # sets 'main' as the default branch name
82 </code>
83 </pre>
84 <p><b>Note: </b>The recommended name for the default branch is 'main'</p>
85 </section>
86
87
88 <section>
89 <h2>The Git repository</h2>
90 </br>
91 <p>A Git repository is a virtual storage of your project. It allows you to save versions of your code, which you can access when needed.</p>
92 <ul>
93 <span><li><em>git init</em> - creates an empty Git repository or reinitializes an existing. A new .git subdirectory is created in your current working directory. This will also create a new <em>master</em> branch.</li></span>
94 <span><li><em>git add</em> - add file contents to the index - a file or directory (folder) contents are selected to be <em>tracked</em></li></span>
95 </ul>
96 <pre data-id="code-animation">
97 <code class="bash" data-trim type="text/template">
98 mkdir myproject # creates a new folder named 'myproject'
99 cd myproject # sets 'myproject' as current working directory
100 touch README.md pycode.py # creates the empty files 'README.md' and 'pycode.py' in the new folder
101 git init # creates an empty Git repository inside 'myproject' - a .git folder is added
102 git add README.md pycode.py # selects 'README.md' and 'pycode.py' for tracking
103 </code>
104 </pre>
105 </section>
106
107
108 <section>
109 <h2>Tracking content</h2>
110 </br>
111 <ul>
112 <span><li><em>git status</em> - shows the working tree status</li></span>
113 </ul>
114 <p>Each file in your working directory can be in one of two states:</p>
115 <ul>
116 <span><li><em>tracked</em> - the files Git knows and "cares" about - files that were in the last snapshot, as well as any newly staged files. They can be <em>unmodified</em>, <em>modified</em>, or <em>staged</em>.</li></span>
117 <span><li><em>untracked</em> - files that Git doesn't "care" about</li></span>
118 </ul>
119 <p>Often, you'll have a class of files that you don't want Git to automatically add or even show you as being untracked. These are generally automatically generated files such as log files or files produced by your build system. In such cases, you can create a file listing patterns to match them named <em>.gitignore</em>. Here is an example <em>.gitignore</em> file:</p>
120 <pre data-id="code-animation">
121 <code class="bash" data-trim type="text/template">
122 cat .gitignore
123 *.pyc
124 *~
125 </code>
126 </pre>
127 </section>
128
129
130 <section>
131 <h2>Committing changes</h2>
132 </br>
133 <p>A <em>commit</em> command captures a snapshot of the project's currently staged changes. Committed snapshots can be thought of as "safe" versions of a project. A snapshot can be seen as a "node" (with an unique id) related to the previous commit (unless initial commit)</p>
134 <ul>
135 <span><li><em>git commit</em> - records changes to the repository</li></span>
136 </ul>
137 <img src="images/git/commit.png"></img>
138 <p>Any files you have created or modified that you haven't run <em>git add</em> on since you edited them - won't go into this commit. They will stay as modified files on your disk.</p>
139 </section>
140
141
142 <section>
143 <h2>Committing changes (cont.)</h2>
144 </br>
145 <ul>
146 <span><li><em>git diff</em> - shows changes between commits, commit and working tree, etc</li></span>
147 <span><li><em>git log</em> - shows commit logs</li></span>
148 <span><li><em>git show</em> - shows various types of objects</li></span>
149 <span><li><em>git tag</em> - creates, lists, deletes or verifies a tag object</li></span>
150 </ul>
151 <pre data-id="code-animation">
152 <code class="bash" data-trim type="text/template">
153 cd myproject
154 echo "# My project documentation" > README.md # sets a basic content for the file README.md
155 echo "import os" >> pycode.py # appends a new content to the file pycode.py
156 git add README.md pycode.py # stages the changes
157 git commit -m "Initial commit" # creates a commit with commit message
158 # git commit -a -m "Initial commit" # automatically stages files that have been modified
159 git log # shows the existing commits (only one so far)
160 echo "import sys" >> pycode.py # appends a new line to 'pycode.py'
161 git status # shows that one file - 'pycode.py' has been modified since the last commit
162 git diff # shows that changes for this repository
163 git diff pycode.py # shows the changes for a particular file
164 git commit -a -m "Import the sys module" # stages and commits the last changes
165 git tag v0.1 # creates a lightweight tag 'v0.1'
166 git log # shows that a new commit has been added
167 git show &lt;commit id&gt; # shows the files and their changes that are part of a given commit
168 </code>
169 </pre>
170 </section>
171
172
173 <section>
174 <h2>Undoing things</h2>
175 </br>
176 <ul>
177 <span><li><em>git restore</em> - restores working tree files (Git version >= 2.23.0)</li></span>
178 </ul>
179 <pre data-id="code-animation">
180 <code class="bash" data-trim type="text/template">
181 cd myproject
182 touch newpycode.py # creates a new file
183 git add newpycode.py # sets the file as tracked (and stages it)
184 echo "import sys" >> pycode.py # appends yet another new line
185 echo "The new project documentation is here" >> README.md # appends yet another new line
186 git add README.md # stages README.md
187 git status # shows 'newpycode.py' (new file), 'pycode.py' (modified), 'README.md' (modified and staged)
188
189 git restore --staged newpycode.py # 'newpycode.py' now becomes untracked
190 # git reset HEAD newpycode.py # Git version < 2.23.0
191
192 git restore --staged README.md # unstages 'README.md' (modified)
193 # git reset HEAD README.md # Git version < 2.23.0
194
195 git restore pycode.py # reverts all modifications on 'pycode.py'
196 # git checkout -- pycode.py # Git version < 2.23.0
197 </code>
198 </pre>
199 </section>
200
201
202 <section>
203 <h2>Git branching</h2>
204 <p>Branching means you diverge from the main line of development and continue to do work without messing with that main line. Some people refer to the Git branching model as its "killer feature", and it certainly sets Git apart in the VCS community. The way Git branches is incredibly lightweight, making branching operations nearly instantaneous, and switching back and forth between branches generally just as fast. Unlike many other VCSs, Git encourages workflows that branch and merge often, even multiple times in a day. Understanding and mastering this feature gives you a powerful and unique tool and can entirely change the way that you develop.</p>
205 <img style="width: 40vw;" src="images/git/branches.png"></img>
206 </section>
207
208
209 <section>
210 <h2>Git branching (cont.)</h2>
211 </br>
212 <ul>
213 <span><li><em>git branch</em> - lists, creates, or deletes branches</li></span>
214 <span><li><em>git checkout</em> - switches branches or restores working tree files</li></span>
215 </ul>
216 <pre data-id="code-animation">
217 <code class="bash" data-trim type="text/template">
218 git branch testing # creates a new branch from 'master' called 'testing'
219 </code>
220 </pre>
221 <img style="width: 40vw;" src="images/git/head-to-master.png"></img>
222 </section>
223
224
225 <section>
226 <h2>Git branching (cont.)</h2>
227 </br>
228 <pre data-id="code-animation">
229 <code class="bash" data-trim type="text/template">
230 git checkout testing # makes 'testing' testing the current (active) branch
231 # git checkout -b testing # creates a new branch named 'testing' and makes it active
232 </code>
233 </pre>
234 <img style="width: 45vw;" src="images/git/head-to-testing.png"></img>
235 </section>
236
237
238 <section>
239 <h2>Git branching (cont.)</h2>
240 </br>
241 <pre data-id="code-animation">
242 <code class="bash" data-trim type="text/template">
243 echo "Extra content" >> README.md
244 git commit -a -m "Improve the documentation" # creates a new commit on the 'testing' branch
245 </code>
246 </pre>
247 <img style="width: 45vw;" src="images/git/advance-testing.png"></img>
248 </section>
249
250
251 <section>
252 <h2>Git branching (cont.)</h2>
253 </br>
254 <pre data-id="code-animation">
255 <code class="bash" data-trim type="text/template">
256 git checkout master # "switches" to 'master'
257 </code>
258 </pre>
259 <img style="width: 45vw;" src="images/git/checkout-master.png"></img>
260 </section>
261
262
263 <section>
264 <h2>Git branching (cont.)</h2>
265 </br>
266 <pre data-id="code-animation">
267 <code class="bash" data-trim type="text/template">
268 echo "# Extra comment" >> pycode.py
269 git commit -a -m "Add a very useful comment to the Python code" # creates a new commit on the 'master' branch
270 </code>
271 </pre>
272 <img style="width: 45vw;" src="images/git/advance-master.png"></img>
273 </section>
274
275
276 <section>
277 <h2>Merging</h2>
278 <p>In Git, there are two main ways to integrate changes from one branch into another: the <em>merge</em> and the <em>rebase</em></p>
279 <ul>
280 <span><li><em>git merge</em> - joins two or more development histories together</li></span>
281 </ul>
282 <p>There are three possible outcomes when attempting to merge two different branches:</p>
283 <ul>
284 <span><li><em>fast forward</em> - the last common node between the source and the target branch is also the last node on the target branch (no changes since the source branch branched out). The changes (the commits) on the source branch are simply appended to the target branch. No new commits are created.</li></span>
285 <span><li><em>merge commit</em> - both the source and the target branch have new commits after the last common node. A new commit node is created on the target branch</li></span>
286 <span><li><em>conflict</em> - both the source and the target branch have new commits after the last common node. At least one file has been edited differently on both branches. A three-way-merge is performed resulting in a new commit node is created on the target branch</li></span>
287 </ul>
288 </section>
289
290
291 <section>
292 <h2>Rebasing</h2>
293 <p>With the <em>rebase</em> command, you can take all the changes that were committed on one branch and replay them on a different branch.</p>
294 <ul>
295 <span><li><em>git rebase</em> - reapply commits on top of another base tip</li></span>
296 </ul>
297 <p>The following is a typical situation when dealing with two diverged branches. A new merge commit (C5) is created when using merge:</p>
298 <pre data-id="code-animation">
299 <code class="bash" data-trim type="text/template">
300 git checkout master
301 git merge experiment # merges 'experiment' into 'master'
302 </code>
303 </pre>
304 <img style="width: 45vw;" src="images/git/basic-rebase-2.png"></img>
305 </section>
306
307
308 <section>
309 <h2>Rebasing (cont.)</h2>
310 <pre data-id="code-animation">
311 <code class="bash" data-trim type="text/template">
312 git checkout experiment # Note!! (not master)
313 git rebase master
314 </code>
315 </pre>
316 <img style="width: 45vw;" src="images/git/basic-rebase-3.png"></img>
317 <p>...now the following operation will result in a fast-forward merge:</p>
318 <pre data-id="code-animation">
319 <code class="bash" data-trim type="text/template">
320 git checkout master
321 git merge experiment
322 </code>
323 </pre>
324 <p><b>N.B. Do not rebase commits that exist outside your repository and that people may have based work on!</b></p>
325 </section>
326
327
328 <section>
329 <h2>Remotes</h2>
330 </br>
331 <p>To be able to collaborate on any Git project, you need to know how to manage your remote repositories. Remote repositories are versions of your project that are hosted on the Internet or network somewhere. Locally a remote can be seen as a sort of bookmark.</p>
332 <ul>
333 <span><li><em>git remote</em> - manages set of tracked repositories (remotes)</li></span>
334 <span><li><em>git clone</em> - clones a repository into a new directory. A remote named "origin" will be automatically created</li></span>
335 <span><li><em>git fetch</em> - downloads objects and refs from another repository</li></span>
336 <span><li><em>git pull</em> - fetches from and integrates with another repository or a local branch</li></span>
337 <span><li><em>git push</em> - updates remote refs along with associated objects</li></span>
338 </ul>
339 <p>The two most popular protocols (schema) for interacting with remotes are <em>ssh</em> and <em>http(s)</em> (usually read-only)</p>
340 </section>
341
342
343 <section>
344 <h2>GitLab</h2>
345 </br>
346 <p><em>GitLab</em> is a developer platform that allows developers to create, store, manage and share their code. It uses Git, providing the distributed version control of Git plus access control, bug tracking, software feature requests, task management, continuous integration...</p>
347 <p>Statnett operates its own instance at <a href="https://gitlab.statnett.no">https://gitlab.statnett.no</a>. It is used for storing / managing Statnett's own Git repositories</p>
348 <p>Another popular and widely used platform is <a href="https://github.com">GitHub - https://github.com</a></p>
349 </section>
350
351
352 <section>
353 <h2>Walkthrough</h2>
354 </br>
355 <p>The following walkthrough illustrates some of the most common patterns when two or more parties are using Git and GitLab in a typical project at Statnett.</p>
356 <p><b>Note: </b>GitLab's CI/CD will not be included in this presentation.</p>
357 <p><b>Note: </b>This presentation should not be considered as a reference but merely as an introduction.</p>
358 </section>
359
360
361 <section>
362 <h2>Walkthrough - Accessing GitLab</h2>
363 </br>
364 <p>In order for a local repository to be able to interact with GitLab through the SSH protocol, a private / public SSH key pair has to be created</p>
365 <pre data-id="code-animation">
366 <code class="bash" data-trim type="text/template">
367 ssh-keygen -t ed25519 # interactively creates a key pair in ~/.ssh
368 cat ~/.ssh/id_ed25519.pub # displays the public key
369 </code>
370 </pre>
371 <p>The public key is then added (pasted) under <em>User settings -> SSH Keys -> Add new key</em></p>
372 </section>
373
374
375 <section>
376 <h2>Walkthrough - Initial code / repository</h2>
377 </br>
378 <p>When starting a new repository that is about to be shared using GitLab, a corresponding GitLab project is created first. Then there are two possible approaches.</p>
379 <ul>
380 <span><li>a new repository is created on GitLab and then cloned (<em>git clone</em>) by all other parties</li></span>
381 <span><li>the repository is initialized locally and then pushed (<em>git push</em>) to GitLab</li></span>
382 </ul>
383 <pre data-id="code-animation">
384 <code class="bash" data-trim type="text/template">
385 git clone &lt;url&gt; # clones (copies) the repository
386
387 git remote add origin &lt;url&gt; # adds a new remote in the local repository
388 git push origin main
389 </code>
390 </pre>
391 <p>All parties should have a local copy of the same repository. For this demonstration we can imagine two users, randomly called "Daniel" and "Simeon".</p>
392 </section>
393
394
395 <section>
396 <h2>Walkthrough - A very simple flow</h2>
397 </br>
398 <p>Usually changes should not be committed directly into the main branch. Daniel starts by creating a new branch from "main" called "feature1"</p>
399 <p>He commits his changes there and pushes them to the remote (origin) branch "feature1". He then creates a merge request (MR) (also known as a pull request on GitHub) to the main branch on the remote origin</p>
400 <pre data-id="code-animation">
401 <code class="bash" data-trim type="text/template">
402 git checkout main
403 git checkout -b feature1
404 # editing some code
405 git commit -a -m "Add a new function"
406 git push origin feature1
407 # MR is created and reviewed by Simeon. "feature1" is then merged into "main"
408 git checkout main
409 git pull origin main # done before the next time we want to branch out from "main"
410 </code>
411 </pre>
412 </section>
413
414
415 <section>
416 <h2>Walkthrough - A more complex flow using rebase</h2>
417 </br>
418 <p>Simeon starts by updating his local main branch. He then branches out from "main" to a branch called "interesting". He commits his changes there.</p>
419 <p>At the same time Daniel branches out to "moreinteresting" and commits changes (to a different file).Daniel pushes his changes to origin "moreinteresting" and then using MR to origin "main".</p>
420 <p>The next day Simeon rebases "main" onto his "interesting". Finally Simeon creates his own MR after pushing his "intersting" branch to origin interesting</p>
421 <pre data-id="code-animation">
422 <code class="bash" data-trim type="text/template">
423 git checkout main # both Simeon and Daniel
424 git checkout -b interesting # Simeon
425 git checkout -b moreinteresting # Daniel
426 # editing some code
427 git commit -a -m "Add a new interesting feature" # Simeon
428 git commit -a -m "Add a new even more interesting feature" # Daniel
429 git push origin moreinteresting # Daniel
430
431 # The next day (Simeon)
432 git fetch origin # the current branch is still "interesting"
433 git rebase origin/main
434 git push origin interesting
435 # creates a MR
436 git pull origin main # done before the next time we want to branch out from "main"
437 </code>
438 </pre>
439 </section>
440
441
442 <section>
443 <h2>Walkthrough - Squahing commits</h2>
444 </br>
445 <p>The act of "squashing" your commits means that you combine multiple existing commits into a single one. If you should do this or avoid it is - to some extent - a question of preference: in some teams, for example, squashing commits is the preferred way to merge a feature branch back into a long-running branch like "master" or "main".</p>
446 <p>Squashing can be performed either locally (before MR) or on GitLab (before or after MR)</p>
447 <pre data-id="code-animation">
448 <code class="bash" data-trim type="text/template">
449 # squashing locally
450
451 # squashing only a selected amount of commits...
452 # select the last 3 commits interactively,
453 # ordering them with the last at the bottom of the interactive file
454 git rebase -i HEAD~3
455 # We then mark the line at the top (chronologically the first commit) with "pick"
456 # and the rest of the lines with "squash" or "s".
457 # Finally we are also adding a proper commit message.
458
459 # Using "fixup" or "f" instead of "squash" will produce the same result,
460 # except it will not prompt for a new commit message and will use the commit
461 # message of the first commit.
462
463
464 # squashing everything...
465 git merge --squash &lt;branch-name&gt;
466 # will take all the commits from the branch, squash them,
467 # and stage all changes in the current branch
468 </code>
469 </pre>
470 </section>
471
472
473 <section>
474 <h2>Sources</h2>
475 </br>
476 <p><a href="https://en.wikipedia.org">https://en.wikipedia.org</a> - Wikipedia</p>
477 <p><a href="https://git-scm.com/book/en/v2/">https://git-scm.com/book/en/v2/</a> - Pro Git</p>
478 <p>The official man pages</p>
479 </section>
480
481
482 <section>
483 <h1>Q &amp; A</h1>
484 </section>
485
486 </div>
487 </div>
488
489 <script src="dist/reveal.js"></script>
490 <script src="plugin/zoom/zoom.js"></script>
491 <script src="plugin/notes/notes.js"></script>
492 <script src="plugin/search/search.js"></script>
493 <script src="plugin/markdown/markdown.js"></script>
494 <script src="plugin/highlight/highlight.js"></script>
495 <script>
496
497 // Also available as an ES module, see:
498 // https://revealjs.netlify.app/initialization/
499 Reveal.initialize({
500 controls: true,
501 progress: true,
502 center: true,
503 hash: true,
504
505 // Learn about plugins: https://revealjs.netlify.app/plugins/
506 plugins: [ RevealZoom, RevealNotes, RevealSearch, RevealMarkdown, RevealHighlight ]
507 });
508 Reveal.configure({ pdfSeparateFragments: false });
509
510 </script>
511
512 </body>
513</html>
diff --git a/reveal.js/images/git/advance-master.png b/reveal.js/images/git/advance-master.png
new file mode 100644
index 0000000..c3a7ebe
--- /dev/null
+++ b/reveal.js/images/git/advance-master.png
Binary files differ
diff --git a/reveal.js/images/git/advance-testing.png b/reveal.js/images/git/advance-testing.png
new file mode 100644
index 0000000..312e65e
--- /dev/null
+++ b/reveal.js/images/git/advance-testing.png
Binary files differ
diff --git a/reveal.js/images/git/basic-rebase-2.png b/reveal.js/images/git/basic-rebase-2.png
new file mode 100644
index 0000000..c82140c
--- /dev/null
+++ b/reveal.js/images/git/basic-rebase-2.png
Binary files differ
diff --git a/reveal.js/images/git/basic-rebase-3.png b/reveal.js/images/git/basic-rebase-3.png
new file mode 100644
index 0000000..a1afaef
--- /dev/null
+++ b/reveal.js/images/git/basic-rebase-3.png
Binary files differ
diff --git a/reveal.js/images/git/branches.png b/reveal.js/images/git/branches.png
new file mode 100644
index 0000000..3ddf1cd
--- /dev/null
+++ b/reveal.js/images/git/branches.png
Binary files differ
diff --git a/reveal.js/images/git/checkout-master.png b/reveal.js/images/git/checkout-master.png
new file mode 100644
index 0000000..06e9878
--- /dev/null
+++ b/reveal.js/images/git/checkout-master.png
Binary files differ
diff --git a/reveal.js/images/git/commit.png b/reveal.js/images/git/commit.png
new file mode 100644
index 0000000..d563972
--- /dev/null
+++ b/reveal.js/images/git/commit.png
Binary files differ
diff --git a/reveal.js/images/git/head-to-master.png b/reveal.js/images/git/head-to-master.png
new file mode 100644
index 0000000..86c7ae8
--- /dev/null
+++ b/reveal.js/images/git/head-to-master.png
Binary files differ
diff --git a/reveal.js/images/git/head-to-testing.png b/reveal.js/images/git/head-to-testing.png
new file mode 100644
index 0000000..08352d6
--- /dev/null
+++ b/reveal.js/images/git/head-to-testing.png
Binary files differ
diff --git a/reveal.js/sqlalchemy.html b/reveal.js/sqlalchemy.html
index bbcd1ca..a0d6617 100644
--- a/reveal.js/sqlalchemy.html
+++ b/reveal.js/sqlalchemy.html
@@ -98,29 +98,29 @@
98 metadata = MetaData() 98 metadata = MetaData()
99 99
100 production_types_table = Table( 100 production_types_table = Table(
101 "production_types", 101 "production_types",
102 metadata, 102 metadata,
103 Column("production_type_id", Integer, primary_key=True), 103 Column("production_type_id", Integer, primary_key=True),
104 Column("code", String(3), nullable=False, unique=True), 104 Column("code", String(3), nullable=False, unique=True),
105 Column("description", String), # Column("name", String(128)) is possible 105 Column("description", String), # Column("name", String(128)) is possible
106 ) 106 )
107 107
108 bidding_areas_table = Table( 108 bidding_areas_table = Table(
109 "bidding_areas", 109 "bidding_areas",
110 metadata, 110 metadata,
111 Column("bidding_area_id", Integer, primary_key=True), 111 Column("bidding_area_id", Integer, primary_key=True),
112 Column("code", String(3), nullable=False, unique=True), 112 Column("code", String(3), nullable=False, unique=True),
113 Column("name", String(32)), 113 Column("name", String(32)),
114 ) 114 )
115 115
116 production_plans_table = Table( 116 production_plans_table = Table(
117 "production_plans", 117 "production_plans",
118 metadata, 118 metadata,
119 Column("record_created_time", DateTime(timezone=False), primary_key=True), 119 Column("record_created_time", DateTime(timezone=False), primary_key=True),
120 Column("start_time", DateTime(timezone=False), primary_key=True), 120 Column("start_time", DateTime(timezone=False), primary_key=True),
121 Column("bidding_area_id", Integer, ForeignKey("bidding_areas.bidding_area_id"), primary_key=True), 121 Column("bidding_area_id", Integer, ForeignKey("bidding_areas.bidding_area_id"), primary_key=True),
122 Column("production_type_id", Integer, ForeignKey("production_types.production_type_id"), primary_key=True), 122 Column("production_type_id", Integer, ForeignKey("production_types.production_type_id"), primary_key=True),
123 Column("value", Numeric, nullable=False), 123 Column("value", Numeric, nullable=False),
124 ) 124 )
125 125
126 metadata.create_all(engine) # creates the tables 126 metadata.create_all(engine) # creates the tables
@@ -150,13 +150,13 @@
150 insert_stmt.execute(bidding_area_id=1, code="NO1", name="Elspot NO1") # insert a single entry 150 insert_stmt.execute(bidding_area_id=1, code="NO1", name="Elspot NO1") # insert a single entry
151 # ... or a list of entries 151 # ... or a list of entries
152 insert_stmt.execute( 152 insert_stmt.execute(
153 [ 153 [
154 {"bidding_area_id": 2, "code": "NO2", "name": "Elspot NO2"}, 154 {"bidding_area_id": 2, "code": "NO2", "name": "Elspot NO2"},
155 {"bidding_area_id": 3, "code": "NO3", "name": "Elspot NO3"}, 155 {"bidding_area_id": 3, "code": "NO3", "name": "Elspot NO3"},
156 {"bidding_area_id": 4, "code": "NO4", "name": "Elspot NO4"}, 156 {"bidding_area_id": 4, "code": "NO4", "name": "Elspot NO4"},
157 {"bidding_area_id": 5, "code": "NO5", "name": "Elspot NO5"}, 157 {"bidding_area_id": 5, "code": "NO5", "name": "Elspot NO5"},
158 {"bidding_area_id": 6, "code": "NO6", "name": "Elspot NO6"}, 158 {"bidding_area_id": 6, "code": "NO6", "name": "Elspot NO6"},
159 ] 159 ]
160 ) 160 )
161 161
162 metadata.bind = engine # no need to explicitly bind the engine from now on 162 metadata.bind = engine # no need to explicitly bind the engine from now on
@@ -182,21 +182,21 @@
182 from sqlalchemy.orm import mapper 182 from sqlalchemy.orm import mapper
183 183
184 class ProductionType: 184 class ProductionType:
185 def __init__(self, code, description): 185 def __init__(self, code, description):
186 self.code = code 186 self.code = code
187 self.description = description 187 self.description = description
188 188
189 def __str__(self): 189 def __str__(self):
190 return self.code 190 return self.code
191 191
192 192
193 class BiddingArea: 193 class BiddingArea:
194 def __init__(self, code, name): 194 def __init__(self, code, name):
195 self.code = code 195 self.code = code
196 self.name = name 196 self.name = name
197 197
198 def __str__(self): 198 def __str__(self):
199 return self.code 199 return self.code
200 200
201 mapper(ProductionType, production_types_table) 201 mapper(ProductionType, production_types_table)
202 mapper(BiddingArea, bidding_areas_table) 202 mapper(BiddingArea, bidding_areas_table)
@@ -212,27 +212,27 @@
212 from sqlalchemy.orm import relationship 212 from sqlalchemy.orm import relationship
213 213
214 class ProductionPlan: 214 class ProductionPlan:
215 def __init__(self, record_created_time, start_time, production_type, bidding_area, value): 215 def __init__(self, record_created_time, start_time, production_type, bidding_area, value):
216 self.record_created_time = record_created_time 216 self.record_created_time = record_created_time
217 self.start_time = start_time 217 self.start_time = start_time
218 self.production_type = production_type 218 self.production_type = production_type
219 self.bidding_area = bidding_area 219 self.bidding_area = bidding_area
220 self.value = value 220 self.value = value
221 221
222 def __str__(self): 222 def __str__(self):
223 return ( 223 return (
224 f"{self.record_created_time} {self.start_time} " 224 f"{self.record_created_time} {self.start_time} "
225 f"{self.production_type} {self.bidding_area} {self.value}" 225 f"{self.production_type} {self.bidding_area} {self.value}"
226 ) 226 )
227 227
228 228
229 mapper( 229 mapper(
230 ProductionPlan, 230 ProductionPlan,
231 production_plans_table, 231 production_plans_table,
232 properties = { 232 properties = {
233 "production_type": relationship(ProductionType, backref="production_plans"), 233 "production_type": relationship(ProductionType, backref="production_plans"),
234 "bidding_area": relationship(BiddingArea, backref="production_plans"), 234 "bidding_area": relationship(BiddingArea, backref="production_plans"),
235 }, 235 },
236 ) 236 )
237 </code> 237 </code>
238 </pre> 238 </pre>
@@ -249,32 +249,32 @@
249 Base = declarative_base() 249 Base = declarative_base()
250 250
251 class ProductionType(Base): 251 class ProductionType(Base):
252 __tablename__ = "production_types" 252 __tablename__ = "production_types"
253 253
254 production_type_id = Column(Integer, primary_key=True) 254 production_type_id = Column(Integer, primary_key=True)
255 code = Column(String(3), nullable=False, unique=True) 255 code = Column(String(3), nullable=False, unique=True)
256 description = Column(String) 256 description = Column(String)
257 257
258 def __init__(self, code, description): 258 def __init__(self, code, description):
259 self.code = code 259 self.code = code
260 self.description = description 260 self.description = description
261 261
262 def __str__(self): 262 def __str__(self):
263 return self.code 263 return self.code
264 264
265 class BiddingArea(Base): 265 class BiddingArea(Base):
266 __tablename__ = "bidding_areas" 266 __tablename__ = "bidding_areas"
267 267
268 bidding_area_id = Column(Integer, primary_key=True) 268 bidding_area_id = Column(Integer, primary_key=True)
269 code = Column(String(3), nullable=False, unique=True) 269 code = Column(String(3), nullable=False, unique=True)
270 name = Column(String(32)) 270 name = Column(String(32))
271 271
272 def __init__(self, code, name): 272 def __init__(self, code, name):
273 self.code = code 273 self.code = code
274 self.name = name 274 self.name = name
275 275
276 def __str__(self): 276 def __str__(self):
277 return self.code 277 return self.code
278 </code> 278 </code>
279 </pre> 279 </pre>
280 </section> 280 </section>
@@ -288,31 +288,31 @@
288 from sqlalchemy.orm import relationship, backref 288 from sqlalchemy.orm import relationship, backref
289 289
290 class ProductionPlan(Base): 290 class ProductionPlan(Base):
291 __tablename__ = "production_plans" 291 __tablename__ = "production_plans"
292 292
293 record_created_time = Column(DateTime(timezone=False), primary_key=True) 293 record_created_time = Column(DateTime(timezone=False), primary_key=True)
294 start_time = Column(DateTime(timezone=False), primary_key=True) 294 start_time = Column(DateTime(timezone=False), primary_key=True)
295 bidding_area_id = Column(Integer, ForeignKey("bidding_areas.bidding_area_id"), primary_key=True) 295 bidding_area_id = Column(Integer, ForeignKey("bidding_areas.bidding_area_id"), primary_key=True)
296 production_type_id = Column(Integer, ForeignKey("production_types.production_type_id"), primary_key=True) 296 production_type_id = Column(Integer, ForeignKey("production_types.production_type_id"), primary_key=True)
297 value = Column(Numeric, nullable=False) 297 value = Column(Numeric, nullable=False)
298 298
299 # defining relationships. 299 # defining relationships.
300 # the defined attributes will reference 'ProductionType' and 'BiddingArea' objects 300 # the defined attributes will reference 'ProductionType' and 'BiddingArea' objects
301 production_type = relationship(ProductionType, backref=backref("production_plans")) 301 production_type = relationship(ProductionType, backref=backref("production_plans"))
302 bidding_area = relationship(BiddingArea, backref=backref("production_plans")) 302 bidding_area = relationship(BiddingArea, backref=backref("production_plans"))
303 303
304 def __init__(self, record_created_time, start_time, production_type, bidding_area, value): 304 def __init__(self, record_created_time, start_time, production_type, bidding_area, value):
305 self.record_created_time = record_created_time 305 self.record_created_time = record_created_time
306 self.start_time = start_time 306 self.start_time = start_time
307 self.production_type = production_type # a 'ProductionType' object 307 self.production_type = production_type # a 'ProductionType' object
308 self.bidding_area = bidding_area # a 'BiddingArea' object 308 self.bidding_area = bidding_area # a 'BiddingArea' object
309 self.value = value 309 self.value = value
310 310
311 def __str__(self): 311 def __str__(self):
312 return ( 312 return (
313 f"{self.record_created_time} {self.start_time} " 313 f"{self.record_created_time} {self.start_time} "
314 f"{self.production_type} {self.bidding_area} {self.value}" 314 f"{self.production_type} {self.bidding_area} {self.value}"
315 ) 315 )
316 316
317 Base.metadata.create_all(engine) # create tables 317 Base.metadata.create_all(engine) # create tables
318 </code> 318 </code>
@@ -337,27 +337,27 @@
337 session.add(bidding_area1) 337 session.add(bidding_area1)
338 338
339 session.add_all( 339 session.add_all(
340 [ 340 [
341 BiddingArea("NO2", "Elspot NO2"), 341 BiddingArea("NO2", "Elspot NO2"),
342 BiddingArea("NO3", "Elspot NO3"), 342 BiddingArea("NO3", "Elspot NO3"),
343 BiddingArea("NO4", "Elspot NO4"), 343 BiddingArea("NO4", "Elspot NO4"),
344 BiddingArea("NO5", "Elspot NO5"), 344 BiddingArea("NO5", "Elspot NO5"),
345 ] 345 ]
346 ) 346 )
347 347
348 production_type_B37 = ProductionType("B37", "Thermal unspecified") 348 production_type_B37 = ProductionType("B37", "Thermal unspecified")
349 production_type_B30 = ProductionType("B30", "Wind unspecified") 349 production_type_B30 = ProductionType("B30", "Wind unspecified")
350 350
351 session.add_all( 351 session.add_all(
352 [ 352 [
353 ProductionType("B19", "Wind Onshore"), 353 ProductionType("B19", "Wind Onshore"),
354 ProductionType("B10", "Hydro-electric pure pumped storage head installation"), 354 ProductionType("B10", "Hydro-electric pure pumped storage head installation"),
355 ProductionType("B11", "Hydro Run-of-river head installation"), 355 ProductionType("B11", "Hydro Run-of-river head installation"),
356 ProductionType("B12", "Hydro-electric storage head installation"), 356 ProductionType("B12", "Hydro-electric storage head installation"),
357 ProductionType("A04", "Generation"), 357 ProductionType("A04", "Generation"),
358 production_type_B37, 358 production_type_B37,
359 production_type_B30, 359 production_type_B30,
360 ] 360 ]
361 ) 361 )
362 </code> 362 </code>
363 </pre> 363 </pre>
@@ -371,21 +371,21 @@
371 # adding some production plans... 371 # adding some production plans...
372 372
373 session.add( 373 session.add(
374 ProductionPlan( 374 ProductionPlan(
375 datetime.datetime.now(), 375 datetime.datetime.now(),
376 datetime.datetime(2022, 11, 2, 1, 0), 376 datetime.datetime(2022, 11, 2, 1, 0),
377 production_type_B37, 377 production_type_B37,
378 bidding_area1, 378 bidding_area1,
379 decimal.Decimal("80.5"), 379 decimal.Decimal("80.5"),
380 ) 380 )
381 ) 381 )
382 382
383 production_plan2 = ProductionPlan( 383 production_plan2 = ProductionPlan(
384 datetime.datetime.now(), 384 datetime.datetime.now(),
385 datetime.datetime(2022, 11, 2, 2, 0), 385 datetime.datetime(2022, 11, 2, 2, 0),
386 production_type_B37, 386 production_type_B37,
387 bidding_area1, 387 bidding_area1,
388 decimal.Decimal("90.5"), 388 decimal.Decimal("90.5"),
389 ) 389 )
390 390
391 session.add(production_plan2) 391 session.add(production_plan2)
@@ -427,17 +427,17 @@
427 427
428 # return production plans with production type 'B37' 428 # return production plans with production type 'B37'
429 session.query(ProductionPlan).filter( 429 session.query(ProductionPlan).filter(
430 ProductionPlan.production_type_id == ProductionType.production_type_id 430 ProductionPlan.production_type_id == ProductionType.production_type_id
431 ).filter(ProductionType.code == "B37").all() 431 ).filter(ProductionType.code == "B37").all()
432 session.query(ProductionPlan).join(ProductionType).filter(ProductionType.code == "B37").all() 432 session.query(ProductionPlan).join(ProductionType).filter(ProductionType.code == "B37").all()
433 session.query(ProductionPlan).filter(ProductionPlan.production_type == production_type_B37).all() 433 session.query(ProductionPlan).filter(ProductionPlan.production_type == production_type_B37).all()
434 session.query( 434 session.query(
435 ProductionPlan 435 ProductionPlan
436 ).from_statement( 436 ).from_statement(
437 text( 437 text(
438 "SELECT pp.* FROM production_plans pp, production_types pt " 438 "SELECT pp.* FROM production_plans pp, production_types pt "
439 "WHERE pp.production_type_id = pt.production_type_id AND pt.code=:code" 439 "WHERE pp.production_type_id = pt.production_type_id AND pt.code=:code"
440 ) 440 )
441 ).params(code="B37").all() 441 ).params(code="B37").all()
442 </code> 442 </code>
443 </pre> 443 </pre>
@@ -449,28 +449,29 @@
449 449
450 </div> 450 </div>
451 </div> 451 </div>
452
453 <script src="dist/reveal.js"></script>
454 <script src="plugin/zoom/zoom.js"></script>
455 <script src="plugin/notes/notes.js"></script>
456 <script src="plugin/search/search.js"></script>
457 <script src="plugin/markdown/markdown.js"></script>
458 <script src="plugin/highlight/highlight.js"></script>
459 <script>
452 460
453 <script src="dist/reveal.js"></script> 461 // Also available as an ES module, see:
454 <script src="plugin/zoom/zoom.js"></script> 462 // https://revealjs.netlify.app/initialization/
455 <script src="plugin/notes/notes.js"></script> 463 Reveal.initialize({
456 <script src="plugin/search/search.js"></script> 464 controls: true,
457 <script src="plugin/markdown/markdown.js"></script> 465 progress: true,
458 <script src="plugin/highlight/highlight.js"></script> 466 center: true,
459 <script> 467 hash: true,
460
461 // Also available as an ES module, see:
462 // https://revealjs.com/initialization/
463 Reveal.initialize({
464 controls: true,
465 progress: true,
466 center: true,
467 hash: true,
468 468
469 // Learn about plugins: https://revealjs.com/plugins/ 469 // Learn about plugins: https://revealjs.netlify.app/plugins/
470 plugins: [ RevealZoom, RevealNotes, RevealSearch, RevealMarkdown, RevealHighlight ] 470 plugins: [ RevealZoom, RevealNotes, RevealSearch, RevealMarkdown, RevealHighlight ]
471 }); 471 });
472 Reveal.configure({ pdfSeparateFragments: false });
472 473
473 </script> 474 </script>
474 475
475 </body> 476 </body>
476</html> 477</html>