├── LICENSE
├── README.md
├── agenda-master.md
├── exercises.md
├── lola-club
├── agenda-g1s1-with-notes.md
├── agenda-g1s2-with-notes.md
├── agenda-g1s3-with-notes.md
├── agenda-g1s4-with-notes.md
├── agenda-g2s1-with-notes.md
├── agenda-g2s2-with-notes.md
├── agenda-g3s1-with-notes.md
├── agenda-s1.md
├── agenda-s2.md
├── agenda-s3.md
├── agenda-s4.md
├── agenda-s5.md
├── code-s1.pdf
├── code-s2.pdf
├── code-s2.txt
├── code-s3-scribbled.jpg
├── code-s3.pdf
├── code-s3.txt
├── code-s4.pdf
├── code-s4.txt
├── code-s5.pdf
├── code-s6.pdf
├── code-s7-notes.md
├── code-s7.pdf
├── code-s7.rkt
├── code-s8-notes.md
├── code-s8.lua
├── code-s8.pdf
└── code-s8.tic
└── neontribe-club
├── retrospective
├── exercises.md
├── reflections.md
└── wash-ups.md
├── session1
├── agenda-s1.md
├── code-sample-ARCVService-Note.pdf
├── code-sample-gbptm-UI-LooListItem.pdf
├── completedExercises
│ ├── colouring-example.jpg
│ └── what-for-example.txt
└── what-happened-s1.md
├── session11
├── agenda.md
├── marked-up-code.jpg
└── notes.md
├── session2
├── agenda-s2.md
├── completedExercises
│ ├── colouring-example.jpg
│ └── what-for-example.txt
├── python_file_1.pdf
├── python_file_1_test.pdf
├── python_file_2-tests.py
├── python_file_2.pdf
├── short-code-option-1-code-format.pdf
└── what-happened-s2.md
├── session3
├── agenda-s3.md
├── completedExercises
│ └── doctest-example-coloured.jpg
├── doctest-example.py
└── doctest-example.py.stdout
├── session4
├── Signal-iOS-PhoneNumberValidator.swift
├── agenda-s4.md
├── neontribe_code_reading_club_session_4_notes.pdf
└── neontribe_code_reading_club_session_4_notes.txt
├── session5
├── agenda-s5.md
├── completedExercises
│ ├── code-club-5-marked.jpg
│ └── code-club-5-marked2.jpg
└── ssh_key.py
├── session6
├── agenda-s6.md
├── completedExercises
│ ├── code-sample-marked-1.jpg
│ └── code-sample-marked-2.jpg
├── example_code.html.haml
└── washup
├── session7
├── Example.cs
└── agenda-s7.md
├── session8
├── Example.rs
├── Notes.md
├── agenda-s8.md
├── example_code.pdf
└── example_code.png
└── sessionX
├── agenda-s10.md
├── agenda_s10.pdf
├── code_sample.pdf
└── example.rb
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Neontribe
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Code reading club
2 |
3 | This is an experiment inspired by research and teaching excercises designed by [Felienne Hermans](https://www.felienne.com). At its core is the idea that the paradigm we use to teach programming is flawed. One of the most obvious ommissions is the ability to read code, both phoneticlly and analytically. We aren't suitably equiping ourselves with these building blocks.
4 |
5 | ## The Plan
6 | We run the club initially for 6-8 weeks. Hopefully we find it so useful that we don't want to stop. We meet for 1 hour every other week. Sometimes there is optional prep in the form of reading, that participants can choose to do as homework outside that time.
7 |
8 | ## The Collaboration
9 | Neontribe run the club and feed back to Felienne on a regular basis about what works and what doesn't. She comes up with potential exercises. We come up with potential exercises. We experiment and try to make the sessions useful and enlightening.
10 |
11 | ## The Expectation
12 | Participants should have some professional coding experience. Apart from that, the sessions should work for a diverse group (in terms of cognitive, formal training, experience, skills, style etc). The sessions use a variety of languages and styles of code. The key benefit should be increased ability to understand code when reading and a more sympathetic style of writing code to be read by others.
13 |
14 | ## The Stuff
15 | The directories in this repo contain the resources and wash-up notes from each session.
16 |
--------------------------------------------------------------------------------
/agenda-master.md:
--------------------------------------------------------------------------------
1 | # Code Reading Club agenda
2 |
3 | ## Reflection (5 mins)
4 | - Note a time the past 2 weeks when you used one of the techniques from the club in your work
5 | - Note a time the past 2 weeks when you used information learned about code in your work
6 |
7 | ## Exercises
8 | At the start everyone should look at the same code, but as the club evolves you can tackle a bigger bit of code by splitting into sections. These exercises are best carried out when the code can fit on one or two pages but with it being the norm to split in many ways - we hope to invent and discover different exercises.
9 |
10 | You will need:
11 | - two printed copies of the code for today's club
12 | - some graph paper - or coloured paper and scissors - or acetate and something to write on it with
13 | - coloured pens, crayons or pencils
14 |
15 | ### Interaction with code (10 mins)
16 | 1. Colour1 the variables - circle and draw links between instatiation and all uses
17 | 1. Colour2 the method/ function calls - circle and draw links between declarations and calls
18 | 1. Colour3 the classes - circle and draw links between classes and their instances
19 | 1. Draw the indentaiton patterns - There are a few ways to do this. Fill over with black sharpie. Trace on graph paper. Trace on acetate. etc?
20 |
21 | #### Discuss the results (10 mins)
22 | 1. What patterns are visible from the colors and indentations only?
23 | 1. What parts of the code warrant more attention based on the colors and indentation?
24 |
25 | ### Content
26 |
27 | #### Identify (10 mins)
28 | 1. Define what it means to be important and independently identify the 5 lines you consider most important
29 | 1. Discuss in the group:
30 | - lines covered by many people?
31 | - lines named but not by a lot of people
32 | - Agree less than 10 of the most important lines
33 |
34 | #### Discuss (10 mins)
35 | Take turns in the group, and let every member talk about the code for 30 seconds (or less/more, could also be one sentence each). Try to add new information and not repeat things that have been said, and repeat until people do not know new things anymore.
36 | [Save the last word for me protocol](https://lead.nwp.org/knowledgebase/save-the-last-word-for-me-protocol/)
37 |
38 | #### Summarize in less than 10 sentences (10 mins)
39 | 1. Independently write down the essence of the code in a few sentences
40 | 1. Discuss in the group
41 | - topics covered by many vs few
42 | - strategies used to create the summary (e.g. method names, documentation, variable names, prior knowledge of system)
43 | 1. Create a summary together
44 | 1. Compare the summary with the available documentation (inside and outside the code)
45 | - identify differences and similarities between the groups findings and the existing
46 |
47 |
48 | ## Wash up (5 mins)
49 | - What worked well
50 | - What worked badly
51 |
52 | ## Follow up (2 weeks of elapsed time)
53 | - Identify code for next session, keaping in mind Wash up and Reflection information
54 |
55 |
56 |
--------------------------------------------------------------------------------
/exercises.md:
--------------------------------------------------------------------------------
1 | This page contains a set of exercises which can be used in Code Reading Clubs. Of course, your club does not need to use all exercises, they are meant as a starting point. If you are trying out variants, do let us know!
2 | For now we have divided them into basic and advanced. Advanced exercises can be used in clube that have been running for a while, or when doing a second seccion on the same code snippet.
3 |
4 | ## Basic Exercises
5 |
6 | You will need:
7 |
8 | - two printed copies of the code for today's club
9 | - coloured paper and scissors
10 | - acetate and something to write on it with
11 | - coloured pens, crayons or pencils
12 | - or: a tablet and tablet pen with a PDF of the code
13 |
14 | ### First glance
15 |
16 | The goal of this exercise is to practice to get a first impression of code and to act upon that.
17 |
18 | #### Look at the code (1 min)
19 |
20 | Look at the code at a glance, really not more than 1 minute. Then try to answer these questions:
21 |
22 | * What is the first thing that catches your eye? Why is that?
23 |
24 | * What is the *second* think that you see? Why?
25 |
26 | * Are these two things (variables, classes, prorgramming concepts) related?
27 |
28 |
29 | #### Discuss the results (10 mins)
30 |
31 | Discuss the results as a group. What lines of facts or concepts were chosen by everyone versus by only a few people?
32 |
33 | Reflect also on what kind of knowledge did you use in this exercise? Knowledge of the domain, of the progamming language? Of a framework? What knowledge do you think might be needed to better understand this code?
34 |
35 | ### Code structure
36 |
37 | #### Examine structure (10 mins)
38 | The goal of this exercise is to be a concrete thing to *do* when looking at new code for the first time. New code can be scary, doing something will help!
39 |
40 | Color variables
41 | * Go through the code and circle all variables in red
42 | * Then draw a link between variables and their uses
43 |
44 | Color method/function calls
45 | * Go through the code and circle all methods in blue
46 | * Then draw a link between methods and their invocations
47 |
48 | Instantiation
49 | * Go through the code and circle all instances of classes in green
50 | * Then draw a link between classes and their instances
51 |
52 | #### Discuss the results (10 mins)
53 | 1. What patterns are visible from the colors and links only?
54 | 1. What parts of the code warrant more attention based on the colors?
55 |
56 | ### Content
57 |
58 | #### All variable/class/method names (5 mins)
59 |
60 | Go through the code mechanically and create a list of all identifier names in the snippet. Of you have done the "examine structure" exercise before, this should be relatively quick and easy.
61 |
62 | #### Discussion (10 mins)
63 |
64 | Discuss in the group:
65 |
66 | * What can we learn from these names?
67 | * Which names are related to each other, from the names only?
68 | * Are there names that are ambiguous when looked at without context?
69 |
70 | #### A random line (5 mins)
71 |
72 | Select a random line from the code in whatever way you like. Examine this line individually. What is the main idea of this line? What lines does it relate to and why?
73 |
74 | #### Discussion (10 mins)
75 |
76 | Discuss in the group:
77 |
78 | * What is the 'scope' of the random line? What part of the code was seen as related?
79 | * How does the line fit into the rest of the code base?
80 |
81 | #### Identify most important lines (10 mins)
82 | Define what it means to be important as a group, and then independently identify the 5 lines you consider most important.
83 |
84 | #### Discussion (10 mins)
85 | Discuss in the group:
86 |
87 | - lines covered by many people?
88 | - lines named but not by a lot of people
89 | - Agree less than 10 of the most important lines
90 |
91 | Take turns in the group, and let every member talk about the code for 30 seconds (or less/more, could also be one sentence each). Try to add new information and not repeat things that have been said, and repeat until people do not know new things anymore.
92 | [Save the last word for me protocol](https://lead.nwp.org/knowledgebase/save-the-last-word-for-me-protocol/)
93 |
94 | #### Summarize in less than 10 sentences individually (10 mins)
95 | 1. Independently write down the essence of the code in a few sentences
96 |
97 | #### Discussion (10 mins)
98 | - topics covered by many vs few
99 | - strategies used to create the summary (e.g. method names, documentation, variable names, prior knowledge of system)
100 |
101 | #### Summarize in less than 10 sentences (10 mins)
102 | 1. Create a summary together
103 | 1. Compare the summary with the available documentation (inside and outside the code)
104 | - identify differences and similarities between the groups findings and the existing
105 |
106 | ## Advanced Exercises
107 |
108 | These exercises are more advanced, in the sense that you might need a bit more understanding of the code for these to make sense. This might be because the group is familiar with the code before the session, or because you are doing a second club on the same code snippet.
109 |
110 | ### Code structure
111 |
112 | #### Examine structure (5 mins)
113 |
114 | Use one of the basic exercises to examine the structure of the code (such as circle variables and link them), or reuse the notes from the previous club. Individuallt study the patterns and think about what they tell you. What direction does the code 'flow' in? What parts stand out for lack of, or access of links?
115 |
116 | #### Discussion (10 mins)
117 |
118 | - Parts of the code covered by many vs few
119 | - Strategies used to decide
120 |
121 | ### Content
122 |
123 | #### Central thematic concepts (5 mins)
124 |
125 | Each participant gets 5 minutes to individually name the 5 most central concepts of the code. These could be names, themes, classes, or information found in comments.
126 |
127 | #### Discussion (10 mins)
128 |
129 | - Topics covered by many vs few
130 | - Strategies used to decide (e.g. method names, documentation, variable names, prior knowledge of system)
131 |
132 | #### Central programming concepts (5 mins)
133 |
134 | Each participant gets 5 minutes to individually name the 5 most central computer science concepts of the code. These could be algorithms, data structures, assumptions or techniques.
135 |
136 | #### Discussion (10 mins)
137 |
138 | - Topics covered by many vs few
139 | - Strategies used to decide (e.g. method names, documentation, variable names, prior knowledge of system)
140 |
141 | ### The 'why' of the code
142 |
143 | Reexamine the code snippet and list decisions and intentions of the creator(s) of the code. For example a decision to use a certain design pattern ir use a certain library or API?
144 |
145 | * What decisions were made in the creation of this code?
146 | * What assumptions do these decisions rely on?
147 |
148 | #### Discussion (10 mins)
149 |
150 | Gather all decisions people made individually and discuss:
151 |
152 | - Pros of these decisions
153 | - Possible cons of these decisions
154 | - Alternative solutions
155 |
--------------------------------------------------------------------------------
/lola-club/agenda-g1s1-with-notes.md:
--------------------------------------------------------------------------------
1 | # Code Reading Club agenda
2 |
3 | ## Club goals and expectations (14:05)
4 | - Intro code reading club concept
5 | - Intro people in the group including experience & types of programming
6 | - JS, python, done before, extent to which other people read code in the way that I do, from humanities background, words rather than structures
7 | - JS, php, bash, reading code is one of most importnt skills you can have as a programmer, most of our days spent writing and reading.
8 | - JS 4 years, no cs background, read similar on Dan Abrimov, reviewing and debugging
9 | - No tech education, humanities, not reading code as other people, dev ops not reading full time or as main activity but would like to, least experienced in group, reading documention, tutorial, not being able to tye everything together, and flow, being able to wrap my mind around it all and how the components fit together. Bash, python
10 | - CS bg. wroked in IT mich of adult life. bash, python, perl, bit JS. Reading more code than I write these days, not sure if I like that not. Better understanding of code I get exposed to. Read code blind sounded good to me.
11 | - Set sessions. Frequency and length.
12 | - Discuss with Rupert not sure if 1 per week will be better to get it moving more quickly
13 | - Discuss goals and expectations of group members
14 | - Done in intros
15 |
16 | ### Interaction with code (10 mins) (14:20)
17 | 1. Colour1 the variables - circle and draw links between instatiation and all uses
18 | 1. Colour2 the method/ function calls - circle and draw links between declarations and calls
19 | 1. Colour3 the classes - circle and draw links between classes and their instances
20 |
21 | #### Discuss the results (10 mins) (14:30)
22 | 1. What patterns are visible from the colors and indentations only?
23 | 1. What parts of the code warrant more attention based on the colors and indentation?
24 |
25 | - Know nothing abour redux react, modern, funky js. Curious about the useDispath - can't figure out what it's doing.
26 | - Interested in import (5-10) reliying on prefix to determine what sort of thing it was
27 | - diff between var and function in react / js. doing word names vs.
28 | - Looks similar to code I see every day
29 | - Asking what sort of tool for static typing were they using there are types written down all over the place.
30 | - consentrated on variables in the inside of the component itself
31 | - Took me a while, but interested in how the imports were effecting
32 | - What is this thing returning? And then work backwards
33 | - colouring starting from line 1 high density at the top. Not sure if that means it's more important or just where I started
34 |
35 | ### Content
36 |
37 | #### Identify (10 mins) (14:40)
38 | 1. As a group breifly define what it means to be important and what constitues a line
39 | 1. Independently identify the 5 lines you consider most important
40 |
41 | #### Discuss (10 mins)
42 | Take turns in the group, and let every member talk about the code for 30 seconds (or less/more, could also be one sentence each). Try to add new information and not repeat things that have been said, and repeat until people do not know new things anymore.
43 | [Save the last word for me protocol](https://lead.nwp.org/knowledgebase/save-the-last-word-for-me-protocol/)
44 | Discuss in the group:
45 | - lines covered by many people?
46 | - lines named but not by a lot of people
47 | - Agree less than 10 of the most important lines
48 |
49 | - Votes:
50 | - ONE: 5,7,8,9,10,11,12,14,27,31,33,52,67
51 | - TWO: 6,35,35,50,68,75
52 | - THREE: 19,24
53 | - FOUR: 47
54 | - Group agreed 10 lines: 6,19,24,27,33,34,35,47,50,75
55 | - In the initial "vote" one person admitted they could not choose only 5 an had ended up with 10 (all of the imports (5-12) plus the const declaration for component (14) and the export declaration (75)) which led to great discussion
56 | - Interesting note that when we ran this with another club 47 also got the most votes.
57 | - Which lines lead you to understanding more?
58 | - Conversation about important for experienced react/redux dev vs others "It's readable only because I know this pattern of use" vs. "I sense there is some magic"
59 | - Highlight at the end when we realised there was an early return which all but one had ignored.
60 |
61 |
62 | ## Wash up (5 mins)
63 | - What worked well
64 | - I love importance of lines. Natural inclinations of people - different for everyone
65 | - I've leart an awful lot by looking at code I've never seen before for the 1st time and mostly understanding (beginner)
66 | - First time I've scribbled on code since 20 years ago at uni. Enjoyable.
67 | - Discussion of importance was interesting
68 | - What worked badly
69 | - Forgot to mention the reflection reminder
70 | - Code snippet for next session? We forgot to talk about in Goals.
71 | - Yes please different languages / frameworks
72 | - Neutral comment
73 | - Is there value in recording. Yes, for an example / guide to facilitation (a one off). No, nit generally, agreed the value is in the participation, rather than observation
74 |
75 | ## Reminder to note for reflection next session (next time!)
76 | - Between sessions, note times when you notice that code reading club has helped you in your other projects or conversations.
77 |
--------------------------------------------------------------------------------
/lola-club/agenda-g1s2-with-notes.md:
--------------------------------------------------------------------------------
1 | # Code Reading Club agenda
2 |
3 | ## Reflections
4 | - Mentioned to my partner (also a developer) & she thinks it's a great idea.
5 | - I have to read and analyse 2 unfamiliar codebases in Java (not a language I use). I would have been apprehensive about this, but now I'm looking forward to it instead because of experience in code reading club. It'll be like a private code reading session.
6 |
7 | ### Interaction with code (10 mins) 14:08
8 | #### Discuss the results (10 mins) 14:15
9 | - I focused on finding things the things
10 | - Noticed varibles used but not declared
11 | - I had to re-map my idesa of what constitues and variable and a function
12 | - I noted external programs (like `node`) and bash commands (like `test`) as functions
13 | - Things seem to exist simply by referring to them. No imports.
14 |
15 |
16 |
17 | ### Content
18 |
19 | #### Identify (10 mins) 14:25
20 | One vote: 5,7,11,15,30,33,70,73
21 | Two votes: 18,53,82,84
22 | Three votes: 10,63,81
23 |
24 | #### Discuss (10 mins) 14:35
25 | Nine lines agreed: 10,18,34,53,63,73,81,82,84
26 |
27 | Agreed - purpose was to run `VS Code` application with electron. The branching was necessary for compatibility and configs for iOS, linux and Linux in Windows. As a group, we belatedly noticed early return (line 35) because it was pointed out by 1 group memeber.
28 |
29 |
30 | ## Wash up (5 mins)
31 | - Adds excitement to read something in a language I'm not familiar with
32 | - There were no philosophical conversations around what constitutes important, maybe due to language or nature of the code in execution
33 | - Looking at code different languages makes me question my mental model of what code really is and how it interacts with the machine (what really is the difference between a command and a function). No matter how we imagine it, it boils down to instructions for the hardware.
34 |
--------------------------------------------------------------------------------
/lola-club/agenda-g1s3-with-notes.md:
--------------------------------------------------------------------------------
1 | # Code Reading Club agenda (14:05)
2 | Code source: https://github.com/moment/moment/blob/develop/src/lib/create/from-anything.js
3 |
4 | ## Reminder to note for reflection next session (14:10)
5 | - Between sessions, note times when you notice that code reading club has helped you in your other projects or conversations.
6 |
7 | - Practice! New project read completely new code bases never seen before. Directly applicable.
8 | - Google alternate sulutions for client - I found myself underlining
9 | - Spent last week unfamiliar codebases jvm. groovy grails java. Also project is in french - an extra layer of amusement. Reflection that acrynyms CMS is not a CMS in french.
10 | - You tube video of someone doing work to be able to code without typing due to RSI - voice transcription for writing software. There is crossover here.
11 |
12 | ### Interaction with code (10 mins) (14:20)
13 | 1. Colour1 the variables - circle and draw links between instatiation and all uses
14 | 1. Colour2 the method/ function calls - circle and draw links between declarations and calls
15 | 1. Colour3 the classes - circle and draw links between classes and their instances
16 |
17 | - First time arrows going up.
18 | - Adds to the clutter if I arrow from imports
19 | - Marking 89 as constructor
20 | - What is a class?
21 | - Started marking returns as well as variables etc in the colouring stage. Moticated by conversaion last week about early returns. Could this be another 'pattern' we scan look for in this section?
22 |
23 | #### Discuss the results (10 mins) (14:30)
24 | 1. What patterns are visible from the colors and connections only?
25 | 1. What parts of the code warrant more attention based on the colors and connections
26 |
27 |
28 | ### Content
29 |
30 | #### Identify (10 mins) (14:40)
31 | 1. If necessary, define / remind in group a meaning of importance
32 | 1. Independently identify the 5 lines you consider most important
33 | 1. Note down which line numbers people selected individually
34 |
35 | This time there was virtually no consensus but as a group we agreed 22,47,88 as being important.
36 | - We talked a lot about why that might be including:
37 | - Eveolved oever a long time
38 | - Backward compatibility
39 | - Not really doing one thing (exports 2 completely different types of function)
40 | - Returns vs mutations
41 | -
42 |
43 | #### Discuss (10 mins) (14:50)
44 | Take turns in the group, and let every member talk about the code for 30 seconds (or less/more, could also be one sentence each). Try to add new information and not repeat things that have been said, and repeat until people do not know new things anymore.
45 | [Save the last word for me protocol](https://lead.nwp.org/knowledgebase/save-the-last-word-for-me-protocol/)
46 | 1. Discuss in the group:
47 | - lines covered by many people?
48 | - lines named but not by a lot of people
49 | - Agree less than 10 of the most important lines
50 |
51 | #### Summarize in less than 10 sentences (10 mins) (15:00)
52 | 1. Independently write down the essence of the code in a few sentences
53 | 1. Discuss in the group
54 | - topics covered by many vs few
55 | - strategies used to create the summary (e.g. method names, documentation, variable names, prior knowledge of system)
56 |
57 | WE DID NOT GET THIS FAR - but getting closer.
58 | 1. Create a summary together
59 | 1. Compare the summary with the available documentation (inside and outside the code)
60 | - identify differences and similarities between the groups findings and the existing
61 |
62 | ## Wash up (5 mins)
63 | - What worked well
64 | - Excitement: At the end of the session one member of the group grabbed a plastic box full of pens and held it up to the camera "This is my box of colours!"
65 |
66 | - What we want to do better next time
67 | - Try with a Miro board
68 | - discuss our stragtegies as well as the summarise the code and the important bits
69 | - try some Elm
70 |
--------------------------------------------------------------------------------
/lola-club/agenda-g1s4-with-notes.md:
--------------------------------------------------------------------------------
1 | # Code Reading Club agenda
2 | https://github.com/carwow/elm-slider/tree/master/examples
3 |
4 |
5 | ## Reflection (14:02)
6 | - Between sessions, note times when you notice that code reading club has helped you in your other projects or conversations.
7 | -
8 | - Continuing to work on project to make changes in code. So this is extremely appliable. The logic in determining user lang preference is not terrible obvious - and there were no test cases. It was not clear which input preferences would result in which files being read from the server. So I did actually take a pdf of main controller & highlighted with a cup of tea. I could have just tried loads of different inputs and checked what happened, but instead, I made the effot to not just fiddle and look at output. Keen to apply this
9 | - I've only been writing code last week - so I didn't get the opportunity.
10 |
11 | ### Code structure
12 |
13 | #### Examine structure (14:08)
14 | The goal of this exercise is to be a concrete thing to *do* when looking at new code for the first time. New code can be scary, doing something will help!
15 |
16 | Color variables
17 | * Go through the code and circle all variables in red
18 | * Then draw a link between variables and their uses
19 |
20 | Color method/function calls
21 | * Go through the code and circle all methods in blue
22 | * Then draw a link between methods and their invocations
23 |
24 | Instantiation
25 | * Go through the code and circle all instances of classes in green
26 | * Then draw a link between classes and their instances
27 |
28 | #### Discuss the results (14:18 mins)
29 | 1. What patterns are visible from the colors and links only?
30 | 1. What parts of the code warrant more attention based on the colors?
31 | 1. What strategy did you use to identify the different types of element?
32 |
33 | - Confused. Not know what is a declaration etc. Drew nothing.
34 | - Model, View, Update (is the update like a controller?)
35 | - weird syntax - the part with in confused me
36 | - what is the return
37 | - Oh - that's a type declaration
38 | - Started trying to colour variables, types, functions but got stuck and tried a new strategy of figuring out what was imports so I could see what was defined in this file vs. defined elsewhere
39 | - Cmd seems to be a global
40 |
41 | ### Content
42 |
43 | #### Identify most important lines (14:31)
44 | Independently identify the 5 lines you consider most important.
45 |
46 | #### Discussion (14:41)
47 | Discuss in the group:
48 |
49 | - lines covered by many people?
50 | - lines named but not by a lot of people
51 | - What strategy did you use to identify importance?
52 | - Agree less than 10 of the most important lines
53 |
54 | Take turns in the group, and let every member talk about the code for 30 seconds (or less/more, could also be one sentence each). Try to add new information and not repeat things that have been said, and repeat until people do not know new things anymore.
55 |
56 |
57 | | votes | lines |
58 | |---|---|
59 | | 1 | 11,26,31,36,72,73,74,83,104,107,114 |
60 | | 2 | 65,105 |
61 | | 4 | 12 |
62 | | 5 | 20 |
63 |
64 | 8 agreed lines - 12,20,31,36,65,73,83,105 basically the function declarations for init, update, view, the defiition of main (the export) and the definition of the Model record.
65 |
66 |
67 |
68 | #### Summarize in less than 10 sentences individually (15:01)
69 | 1. Independently write down the essence of the code in a few sentences
70 |
71 | #### Discussion (10 mins)
72 | - topics covered by many vs few
73 | - strategies used to create the summary (e.g. method names, documentation, variable names, prior knowledge of system)
74 |
75 | #### Summarize in less than 10 sentences (10 mins)
76 | 1. Create a summary together
77 | 1. Compare the summary with the available documentation (inside and outside the code)
78 | - identify differences and similarities between the groups findings and the existing
79 |
80 | ## Wash up (5 mins)
81 | - What worked well
82 | - Doesn't make me anxious that I don't understand because it's an academic exercise.I'm not trying to debug it or work on it.
83 | - The more I stay with the code the more readable it seems. If you know the syntax, it looks much easier than any other language I've used. That's just an instinct
84 | - It looks really clean if you know what you are reading. Not too many semicolons and keywords and curly braces
85 | - It's nice looking at languages I don't use
86 |
87 | - What worked badly
88 | - That was the most confusing code I've read
89 | - I've looked at elm before because I heard it has nice error messages, but when I read a blog post I'm like whoa, no way that looks hard
90 |
91 | ## Next time
92 | - Prolog? https://meet.google.com/linkredirect?authuser=0&dest=https%3A%2F%2Fyarnpkg.com%2Ffeatures%2Fconstraints
93 | - Would have been better to explain syntax first? In real world, you'd probably look up the basics before reading if the language was totally unfamiliar
94 |
--------------------------------------------------------------------------------
/lola-club/agenda-g2s1-with-notes.md:
--------------------------------------------------------------------------------
1 | # Code Reading Club agenda
2 |
3 | ## Club goals and expectations
4 |
5 | Motivations
6 | * atttracted by fun, learning GQL
7 | * interested and curious recent tangles with legacy
8 | * curious problem solving
9 | * it all life, not engaged with code
10 | * had touble reading someone else's code
11 | * make the bridge to a humanities-style reading approach
12 |
13 | Wished-for Gains
14 | - encounter new languages
15 | - improve skills at reading code
16 | - engaging with software from a non-project persepctive
17 |
18 |
19 | ### Interaction with code (10 mins)
20 |
21 |
22 | * comforting to draw the connections
23 | * interesting to see the imports being used
24 | * the use of imports led me to an important line
25 | Some participants were drawn directly into a consideration of the code's functioning.
26 | Discussing the shapes in abstract was not easy. Perhaps harder because we lacked visual reference.
27 |
28 | ### Content
29 |
30 | #### Identify (10 mins)
31 | * importance is not crashing
32 | * importance is the core funtions
33 |
34 | #### Discuss (10 mins)
35 | Take turns in the group, and let every member talk about the code for 30 seconds (or less/more, could also be one sentence each). Try to add new information and not repeat things that have been said, and repeat until people do not know new things anymore.
36 | [Save the last word for me protocol](https://lead.nwp.org/knowledgebase/save-the-last-word-for-me-protocol/)
37 | 1. Discuss in the group:
38 | - lines covered by many people?
39 | - lines named but not by a lot of people
40 | - Agree less than 10 of the most important lines
41 |
42 | Discussion around outliers was especially productive
43 |
44 | #### Summarize in less than 10 sentences (10 mins)
45 | We didn't get this far...
46 |
47 | ## Wash up (5 mins)
48 | - What worked well
49 | - What worked badly
50 |
51 | * the code was blurry at the start later it was clear
52 | * taking time and identifying was different from my normal approach to open a new file
53 | * interesting to see how different perspectives on importance
54 | * seeing similar apporaches to problems we face
55 |
56 | - it might be nice to see the code in advance for some
57 |
58 | ## Reminder to note for reflection next session
59 | - Between sessions, note times when you notice that code reading club has helped you in your other projects or conversations.
60 |
--------------------------------------------------------------------------------
/lola-club/agenda-g2s2-with-notes.md:
--------------------------------------------------------------------------------
1 | # Code Reading Club agenda
2 |
3 | ## Reminder to note for reflection next session
4 | - Between sessions, note times when you notice that code reading club has helped you in your other projects or conversations.
5 |
6 | * Some folk report it is making them reflect consciously when reading code
7 | * One had tried marking up, when reading a difficult piece. Not sure it helped
8 | * Others simply that they enjoyed the first session and were looking forward to another
9 |
10 | ### Interaction with code
11 |
12 | * in this case the locus is in the centre
13 | * indentation supports this
14 | * as does the upflow from the hoisted private functions
15 |
16 | ### Content
17 |
18 | #### Identify (10 mins)
19 |
20 | * We talked about trying to to this with blocks not loc, but it seemed to be cheating in the end
21 |
22 | #### Discuss (10 mins)
23 |
24 |
25 | #### Summarize in less than 10 sentences (10 mins)
26 | Interesting and lengthy discussion in which we discovered that we were still split about the core purpose of the code. We had become enmeshed in some of the edge cases, and had mostly ignored a main case.
27 |
28 | ## Wash up (5 mins)
29 | - What worked well
30 | - What worked badly
31 |
32 |
33 |
34 | This applies validation rules to phone numbers, ensuring they have a country code, and using stricter rules for Brazilian and US numbers than for the rest of the world.
--------------------------------------------------------------------------------
/lola-club/agenda-g3s1-with-notes.md:
--------------------------------------------------------------------------------
1 | # Code Reading Club agenda
2 |
3 | ## Club goals and expectations
4 |
5 | * need to read different languages - already has an idea for us to read some C# - general knowlege about programming
6 | * get comfortable reading someone else's code - understand faster - exposure to concepts - diminish fear
7 | * reading code makes you better - make one's mind more flexible
8 | * didn't learn many languiages in school - interested to find if I can understand code in an unfamiliar language - how can I apply my general knowlege - gain a view of other languages to explore possible change
9 | * curiosity - compare a book club with a code club - see pateterns and particularites
10 | * like a puzzle game - fun - understand other patterns
11 |
12 | ### Interaction with code
13 |
14 | * i didn't start from the top and missed stuff - I use phpstorm for this normally - it is harder on paper
15 | * it feels necessary to tread from top to bottom
16 | * declaration then use - inline definitions buck the trend
17 | * I tried to be the interpreter/compiler
18 | * I threaded the word patients through the code
19 |
20 | ### Content
21 |
22 | #### Identify (10 mins)
23 | 1. As a group breifly define what it means to be important and what constitues a line
24 | 1. Independently identify the 5 lines you consider most important
25 |
26 | * inverse importance - what can you take out
27 | * locus - many things pointing to it
28 | * correctness - will it break
29 | * function - relies on an understanding of the purpose of the code
30 |
31 | #### Discuss (10 mins)
32 |
33 |
34 | ## Wash up (5 mins)
35 | * even if excerscises don't "work" for everyone they all have value because they articulate different approaches
36 |
37 |
38 |
--------------------------------------------------------------------------------
/lola-club/agenda-s1.md:
--------------------------------------------------------------------------------
1 | # Code Reading Club agenda
2 |
3 | ## Club goals and expectations
4 | - Intro code reading club concept
5 | - Intro people in the group including experience & types of programming
6 | - Set sessions. Frequency and length.
7 | - Discuss goals and expectations of group members
8 |
9 | ### Interaction with code (10 mins)
10 | 1. Colour1 the variables - circle and draw links between instatiation and all uses
11 | 1. Colour2 the method/ function calls - circle and draw links between declarations and calls
12 | 1. Colour3 the classes - circle and draw links between classes and their instances
13 |
14 | #### Discuss the results (10 mins)
15 | 1. What patterns are visible from the colors and indentations only?
16 | 1. What parts of the code warrant more attention based on the colors and indentation?
17 |
18 | ### Content
19 |
20 | #### Identify (10 mins)
21 | 1. As a group breifly define what it means to be important and what constitues a line
22 | 1. Independently identify the 5 lines you consider most important
23 |
24 | #### Discuss (10 mins)
25 | Take turns in the group, and let every member talk about the code for 30 seconds (or less/more, could also be one sentence each). Try to add new information and not repeat things that have been said, and repeat until people do not know new things anymore.
26 | [Save the last word for me protocol](https://lead.nwp.org/knowledgebase/save-the-last-word-for-me-protocol/)
27 | 1. Discuss in the group:
28 | - lines covered by many people?
29 | - lines named but not by a lot of people
30 | - Agree less than 10 of the most important lines
31 |
32 | #### Summarize in less than 10 sentences (10 mins)
33 | 1. Independently write down the essence of the code in a few sentences
34 | 1. Discuss in the group
35 | - topics covered by many vs few
36 | - strategies used to create the summary (e.g. method names, documentation, variable names, prior knowledge of system)
37 | 1. Create a summary together
38 | 1. Compare the summary with the available documentation (inside and outside the code)
39 | - identify differences and similarities between the groups findings and the existing
40 |
41 | ## Wash up (5 mins)
42 | - What worked well
43 | - What worked badly
44 |
45 | ## Reminder to note for reflection next session
46 | - Between sessions, note times when you notice that code reading club has helped you in your other projects or conversations.
47 |
--------------------------------------------------------------------------------
/lola-club/agenda-s2.md:
--------------------------------------------------------------------------------
1 | # Code Reading Club agenda
2 |
3 | ## Reminder to note for reflection next session
4 | - Between sessions, note times when you notice that code reading club has helped you in your other projects or conversations.
5 |
6 | ### Interaction with code (10 mins)
7 | 1. Colour1 the variables - circle and draw links between instatiation and all uses
8 | 1. Colour2 the method/ function calls - circle and draw links between declarations and calls
9 | 1. Colour3 the classes - circle and draw links between classes and their instances
10 |
11 | #### Discuss the results (10 mins)
12 | 1. What patterns are visible from the colors and indentations only?
13 | 1. What parts of the code warrant more attention based on the colors and indentation?
14 |
15 | ### Content
16 |
17 | #### Identify (10 mins)
18 | 1. As a group breifly define what it means to be important and what constitues a line
19 | 1. Independently identify the 5 lines you consider most important
20 |
21 | #### Discuss (10 mins)
22 | Take turns in the group, and let every member talk about the code for 30 seconds (or less/more, could also be one sentence each). Try to add new information and not repeat things that have been said, and repeat until people do not know new things anymore.
23 | [Save the last word for me protocol](https://lead.nwp.org/knowledgebase/save-the-last-word-for-me-protocol/)
24 | 1. Discuss in the group:
25 | - lines covered by many people?
26 | - lines named but not by a lot of people
27 | - Agree less than 10 of the most important lines
28 |
29 | #### Summarize in less than 10 sentences (10 mins)
30 | 1. Independently write down the essence of the code in a few sentences
31 | 1. Discuss in the group
32 | - topics covered by many vs few
33 | - strategies used to create the summary (e.g. method names, documentation, variable names, prior knowledge of system)
34 | 1. Create a summary together
35 | 1. Compare the summary with the available documentation (inside and outside the code)
36 | - identify differences and similarities between the groups findings and the existing
37 |
38 | ## Wash up (5 mins)
39 | - What worked well
40 | - What worked badly
41 |
--------------------------------------------------------------------------------
/lola-club/agenda-s3.md:
--------------------------------------------------------------------------------
1 | # Code Reading Club agenda
2 |
3 | ## Reflection (5 mins)
4 | - Between sessions, note times when you notice that code reading club has helped you in your other projects or conversations.
5 |
6 | ### Interaction with code (10 mins)
7 | 1. Colour1 the variables - circle and draw links between instatiation and all uses
8 | 1. Colour2 the method/ function calls - circle and draw links between declarations and calls
9 | 1. Colour3 the classes - circle and draw links between classes and their instances
10 |
11 | #### Discuss the results (10 mins)
12 | 1. What patterns are visible from the colors and connections?
13 | 1. What parts of the code warrant more attention based on the colors and connections?
14 |
15 | ### Content
16 |
17 | #### Identify (10 mins)
18 | 1. If necessary, define / remind in group a meaning of importance
19 | 1. Independently identify the 5 lines you consider most important
20 | 1. Note down which line numbers people selected individually
21 |
22 | #### Discuss (15 mins)
23 | Take turns in the group, and let every member talk about the code for 30 seconds (or less/more, could also be one sentence each). Try to add new information and not repeat things that have been said, and repeat until people do not know new things anymore.
24 | [Save the last word for me protocol](https://lead.nwp.org/knowledgebase/save-the-last-word-for-me-protocol/)
25 | 1. Discuss in the group:
26 | - lines covered by many people?
27 | - lines named but not by a lot of people
28 | - Agree less than 10 of the most important lines
29 |
30 | #### Summarize in less than 10 sentences (10 mins)
31 | 1. Independently write down the essence of the code in a few sentences
32 | 1. Discuss in the group
33 | - topics covered by many vs few
34 | - strategies used to create the summary (e.g. method names, documentation, variable names, prior knowledge of system)
35 | 1. Create a summary together
36 | 1. Compare the summary with the available documentation (inside and outside the code)
37 | - identify differences and similarities between the groups findings and the existing
38 |
39 | ## Wash up (5 mins)
40 | - What worked well
41 | - What worked badly
42 |
--------------------------------------------------------------------------------
/lola-club/agenda-s4.md:
--------------------------------------------------------------------------------
1 | # Code Reading Club agenda
2 |
3 | ## Reflection (5 mins)
4 | - Between sessions, note times when you notice that code reading club has helped you in your other projects or conversations.
5 |
6 | ### Code structure
7 |
8 | #### Examine structure (10 mins)
9 | The goal of this exercise is to be a concrete thing to *do* when looking at new code for the first time. New code can be scary, doing something will help!
10 |
11 | Color variables
12 | * Go through the code and circle all variables in red
13 | * Then draw a link between variables and their uses
14 |
15 | Color method/function calls
16 | * Go through the code and circle all methods in blue
17 | * Then draw a link between methods and their invocations
18 |
19 | Instantiation
20 | * Go through the code and circle all instances of classes in green
21 | * Then draw a link between classes and their instances
22 |
23 | #### Discuss the results (10 mins)
24 | 1. What patterns are visible from the colors and links only?
25 | 1. What parts of the code warrant more attention based on the colors?
26 | 1. What strategy did you use to identify the different types of element?
27 |
28 | ### Content
29 |
30 | #### Identify most important lines (10 mins)
31 | Independently identify the 5 lines you consider most important.
32 |
33 | #### Discussion (10 mins)
34 | Discuss in the group:
35 |
36 | - lines covered by many people?
37 | - lines named but not by a lot of people
38 | - What strategy did you use to identify importance?
39 | - Agree less than 10 of the most important lines
40 |
41 | Take turns in the group, and let every member talk about the code for 30 seconds (or less/more, could also be one sentence each). Try to add new information and not repeat things that have been said, and repeat until people do not know new things anymore.
42 |
43 | #### Summarize in less than 10 sentences individually (10 mins)
44 | 1. Independently write down the essence of the code in a few sentences
45 |
46 | #### Discussion (10 mins)
47 | - topics covered by many vs few
48 | - strategies used to create the summary (e.g. method names, documentation, variable names, prior knowledge of system)
49 |
50 | #### Summarize in less than 10 sentences (10 mins)
51 | 1. Create a summary together
52 | 1. Compare the summary with the available documentation (inside and outside the code)
53 | - identify differences and similarities between the groups findings and the existing
54 |
55 | ## Wash up (5 mins)
56 | - What worked well
57 | - What worked badly
58 |
--------------------------------------------------------------------------------
/lola-club/agenda-s5.md:
--------------------------------------------------------------------------------
1 | # Code Reading Club agenda
2 |
3 | ## Reflection (5 mins)
4 | - Between sessions, note times when you notice that code reading club has helped you in your other projects or conversations.
5 |
6 | ### Code structure
7 |
8 | #### Examine structure (10 mins)
9 | The goal of this exercise is to be a concrete thing to *do* when looking at new code for the first time. New code can be scary, doing something will help!
10 |
11 | Color variables
12 | * Go through the code and circle all variables in red
13 | * Then draw a link between variables and their uses
14 |
15 | Color method/function calls
16 | * Go through the code and circle all methods in blue
17 | * Then draw a link between methods and their invocations
18 |
19 | Instantiation
20 | * Go through the code and circle all instances of classes in green
21 | * Then draw a link between classes and their instances
22 |
23 | #### Discuss the results (10 mins)
24 | 1. What patterns are visible from the colors and links only?
25 | 1. What parts of the code warrant more attention based on the colors?
26 | 1. What strategy did you use to identify the different types of element?
27 |
28 | ### Content
29 |
30 | #### Identify most important lines (10 mins)
31 | Independently identify the 5 lines you consider most important.
32 |
33 | #### Discussion (10 mins)
34 | Discuss in the group:
35 |
36 | - lines covered by many people?
37 | - lines named but not by a lot of people
38 | - What strategy did you use to identify importance?
39 | - Agree less than 10 of the most important lines
40 |
41 | Take turns in the group, and let every member talk about the code for 30 seconds (or less/more, could also be one sentence each). Try to add new information and not repeat things that have been said, and repeat until people do not know new things anymore.
42 |
43 | #### Summarize in less than 10 sentences individually (10 mins)
44 | 1. Independently write down the essence of the code in a few sentences
45 |
46 | #### Discussion (10 mins)
47 | - topics covered by many vs few
48 | - strategies used to create the summary (e.g. method names, documentation, variable names, prior knowledge of system)
49 |
50 | #### Summarize in less than 10 sentences (10 mins)
51 | 1. Create a summary together
52 | 1. Compare the summary with the available documentation (inside and outside the code)
53 | - identify differences and similarities between the groups findings and the existing
54 |
55 | ## Wash up (5 mins)
56 | - What worked well
57 | - What worked badly
58 |
--------------------------------------------------------------------------------
/lola-club/code-s1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neontribe/code-reading-club/c3baf98c0d517ec7c7b9f09addee7f0cd3cca71f/lola-club/code-s1.pdf
--------------------------------------------------------------------------------
/lola-club/code-s2.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neontribe/code-reading-club/c3baf98c0d517ec7c7b9f09addee7f0cd3cca71f/lola-club/code-s2.pdf
--------------------------------------------------------------------------------
/lola-club/code-s2.txt:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -e
4 |
5 | if [[ "$OSTYPE" == "darwin"* ]]; then
6 | realpath() { [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"; }
7 | ROOT=$(dirname "$(dirname "$(realpath "$0")")")
8 | else
9 | ROOT=$(dirname "$(dirname "$(readlink -f $0)")")
10 | if grep -qi Microsoft /proc/version; then
11 | IN_WSL=true
12 | fi
13 | fi
14 |
15 | function code() {
16 | cd "$ROOT"
17 |
18 | if [[ "$OSTYPE" == "darwin"* ]]; then
19 | NAME=`node -p "require('./product.json').nameLong"`
20 | CODE="./.build/electron/$NAME.app/Contents/MacOS/Electron"
21 | else
22 | NAME=`node -p "require('./product.json').applicationName"`
23 | CODE=".build/electron/$NAME"
24 | fi
25 |
26 | # Node modules
27 | test -d node_modules || yarn
28 |
29 | # Get electron
30 | yarn electron
31 |
32 | # Manage built-in extensions
33 | if [[ "$1" == "--builtin" ]]; then
34 | exec "$CODE" build/builtin
35 | return
36 | fi
37 |
38 | # Sync built-in extensions
39 | node build/lib/builtInExtensions.js
40 |
41 | # Build
42 | test -d out || yarn compile
43 |
44 | # Configuration
45 | export NODE_ENV=development
46 | export VSCODE_DEV=1
47 | export VSCODE_CLI=1
48 | export ELECTRON_ENABLE_STACK_DUMPING=1
49 | export ELECTRON_ENABLE_LOGGING=1
50 | export VSCODE_LOGS=
51 |
52 | # Launch Code
53 | exec "$CODE" . --no-sandbox "$@"
54 | }
55 |
56 | function code-wsl()
57 | {
58 | HOST_IP=$(powershell.exe -Command "& {(Get-NetIPAddress | Where-Object {\$_.InterfaceAlias -like '*WSL*' -and \$_.AddressFamily -eq 'IPv4'}).IPAddress | Write-Host -NoNewline}")
59 | export DISPLAY="$HOST_IP:0"
60 |
61 | # in a wsl shell
62 | ELECTRON="$ROOT/.build/electron/Code - OSS.exe"
63 | if [ -f "$ELECTRON" ]; then
64 | local CWD=$(pwd)
65 | cd $ROOT
66 | export WSLENV=ELECTRON_RUN_AS_NODE/w:$WSLENV
67 | local WSL_EXT_ID="ms-vscode-remote.remote-wsl"
68 | local WSL_EXT_WLOC=$(ELECTRON_RUN_AS_NODE=1 "$ROOT/.build/electron/Code - OSS.exe" "out/cli.js" --locate-extension $WSL_EXT_ID)
69 | cd $CWD
70 | if [ -n "$WSL_EXT_WLOC" ]; then
71 | # replace \r\n with \n in WSL_EXT_WLOC
72 | local WSL_CODE=$(wslpath -u "${WSL_EXT_WLOC%%[[:cntrl:]]}")/scripts/wslCode-dev.sh
73 | $WSL_CODE "$ROOT" "$@"
74 | exit $?
75 | else
76 | echo "Remote WSL not installed, trying to run VSCode in WSL."
77 | fi
78 | fi
79 | }
80 |
81 | if ! [ -z ${IN_WSL+x} ]; then
82 | code-wsl "$@"
83 | fi
84 | code "$@"
85 |
--------------------------------------------------------------------------------
/lola-club/code-s3-scribbled.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neontribe/code-reading-club/c3baf98c0d517ec7c7b9f09addee7f0cd3cca71f/lola-club/code-s3-scribbled.jpg
--------------------------------------------------------------------------------
/lola-club/code-s3.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neontribe/code-reading-club/c3baf98c0d517ec7c7b9f09addee7f0cd3cca71f/lola-club/code-s3.pdf
--------------------------------------------------------------------------------
/lola-club/code-s3.txt:
--------------------------------------------------------------------------------
1 | import isArray from '../utils/is-array';
2 | import isObject from '../utils/is-object';
3 | import isObjectEmpty from '../utils/is-object-empty';
4 | import isUndefined from '../utils/is-undefined';
5 | import isNumber from '../utils/is-number';
6 | import isDate from '../utils/is-date';
7 | import map from '../utils/map';
8 | import { createInvalid } from './valid';
9 | import { Moment, isMoment } from '../moment/constructor';
10 | import { getLocale } from '../locale/locales';
11 | import { hooks } from '../utils/hooks';
12 | import checkOverflow from './check-overflow';
13 | import { isValid } from './valid';
14 |
15 | import { configFromStringAndArray } from './from-string-and-array';
16 | import { configFromStringAndFormat } from './from-string-and-format';
17 | import { configFromString } from './from-string';
18 | import { configFromArray } from './from-array';
19 | import { configFromObject } from './from-object';
20 |
21 | function createFromConfig(config) {
22 | var res = new Moment(checkOverflow(prepareConfig(config)));
23 | if (res._nextDay) {
24 | // Adding is smart enough around DST
25 | res.add(1, 'd');
26 | res._nextDay = undefined;
27 | }
28 |
29 | return res;
30 | }
31 |
32 | export function prepareConfig(config) {
33 | var input = config._i,
34 | format = config._f;
35 |
36 | config._locale = config._locale || getLocale(config._l);
37 |
38 | if (input === null || (format === undefined && input === '')) {
39 | return createInvalid({ nullInput: true });
40 | }
41 |
42 | if (typeof input === 'string') {
43 | config._i = input = config._locale.preparse(input);
44 | }
45 |
46 | if (isMoment(input)) {
47 | return new Moment(checkOverflow(input));
48 | } else if (isDate(input)) {
49 | config._d = input;
50 | } else if (isArray(format)) {
51 | configFromStringAndArray(config);
52 | } else if (format) {
53 | configFromStringAndFormat(config);
54 | } else {
55 | configFromInput(config);
56 | }
57 |
58 | if (!isValid(config)) {
59 | config._d = null;
60 | }
61 |
62 | return config;
63 | }
64 |
65 | function configFromInput(config) {
66 | var input = config._i;
67 | if (isUndefined(input)) {
68 | config._d = new Date(hooks.now());
69 | } else if (isDate(input)) {
70 | config._d = new Date(input.valueOf());
71 | } else if (typeof input === 'string') {
72 | configFromString(config);
73 | } else if (isArray(input)) {
74 | config._a = map(input.slice(0), function (obj) {
75 | return parseInt(obj, 10);
76 | });
77 | configFromArray(config);
78 | } else if (isObject(input)) {
79 | configFromObject(config);
80 | } else if (isNumber(input)) {
81 | // from milliseconds
82 | config._d = new Date(input);
83 | } else {
84 | hooks.createFromInputFallback(config);
85 | }
86 | }
87 |
88 | export function createLocalOrUTC(input, format, locale, strict, isUTC) {
89 | var c = {};
90 |
91 | if (format === true || format === false) {
92 | strict = format;
93 | format = undefined;
94 | }
95 |
96 | if (locale === true || locale === false) {
97 | strict = locale;
98 | locale = undefined;
99 | }
100 |
101 | if (
102 | (isObject(input) && isObjectEmpty(input)) ||
103 | (isArray(input) && input.length === 0)
104 | ) {
105 | input = undefined;
106 | }
107 | // object construction must be done this way.
108 | // https://github.com/moment/moment/issues/1423
109 | c._isAMomentObject = true;
110 | c._useUTC = c._isUTC = isUTC;
111 | c._l = locale;
112 | c._i = input;
113 | c._f = format;
114 | c._strict = strict;
115 |
116 | return createFromConfig(c);
117 | }
118 |
--------------------------------------------------------------------------------
/lola-club/code-s4.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neontribe/code-reading-club/c3baf98c0d517ec7c7b9f09addee7f0cd3cca71f/lola-club/code-s4.pdf
--------------------------------------------------------------------------------
/lola-club/code-s4.txt:
--------------------------------------------------------------------------------
1 | 1 module Main exposing (main)
2 | 2
3 | 3 import Browser
4 | 4 import DoubleSlider as DoubleSlider exposing (..)
5 | 5 import Html exposing (Html, button, div, text)
6 | 6 import Html.Events exposing (onClick)
7 | 7 import RangeSlider as RangeSlider exposing (..)
8 | 8 import SingleSlider exposing (..)
9 | 9
10 | 10
11 | 11 main : Program Flags Model Msg
12 | 12 main =
13 | 13 Browser.element { init = init, update = update, view = view, subscriptions = subscriptions }
14 | 14
15 | 15
16 | 16
17 | 17 -- MODEL
18 | 18
19 | 19
20 | 20 type alias Model =
21 | 21 { singleSlider : SingleSlider.SingleSlider Msg
22 | 22 , doubleSlider : DoubleSlider.DoubleSlider Msg
23 | 23 }
24 | 24
25 | 25
26 | 26 type alias Flags =
27 | 27 {}
28 | 28
29 | 29
30 | 30 init : Flags -> ( Model, Cmd Msg )
31 | 31 init flags =
32 | 32 let
33 | 33 minFormatter =
34 | 34 \value -> String.fromFloat value
35 | 35
36 | 36 model =
37 | 37 { singleSlider =
38 | 38 SingleSlider.init
39 | 39 { min = 0
40 | 40 , max = 1000
41 | 41 , value = 500
42 | 42 , step = 50
43 | 43 , onChange = SingleSliderChange
44 | 44 }
45 | 45 |> SingleSlider.withMinFormatter minFormatter
46 | 46 , doubleSlider =
47 | 47 DoubleSlider.init
48 | 48 { min = 0
49 | 49 , max = 1000
50 | 50 , lowValue = 500
51 | 51 , highValue = 750
52 | 52 , step = 50
53 | 53 , onLowChange = DoubleSliderLowChange
54 | 54 , onHighChange = DoubleSliderHighChange
55 | 55 }
56 | 56 }
57 | 57 in
58 | 58 ( model, Cmd.none )
59 | 59
60 | 60
61 | 61
62 | 62 -- UPDATE
63 | 63
64 | 64
65 | 65 type Msg
66 | 66 = NoOp
67 | 67 | DoubleSliderLowChange Float
68 | 68 | DoubleSliderHighChange Float
69 | 69 | SingleSliderChange Float
70 | 70
71 | 71
72 | 72 update : Msg -> Model -> ( Model, Cmd Msg )
73 | 73 update msg model =
74 | 74 case msg of
75 | 75 NoOp ->
76 | 76 ( model, Cmd.none )
77 | 77
78 | 78 DoubleSliderLowChange str ->
79 | 79 let
80 | 80 newSlider =
81 | 81 DoubleSlider.updateLowValue str model.doubleSlider
82 | 82 in
83 | 83 ( { model | doubleSlider = newSlider }, Cmd.none )
84 | 84
85 | 85 DoubleSliderHighChange str ->
86 | 86 let
87 | 87 newSlider =
88 | 88 DoubleSlider.updateHighValue str model.doubleSlider
89 | 89 in
90 | 90 ( { model | doubleSlider = newSlider }, Cmd.none )
91 | 91
92 | 92 SingleSliderChange str ->
93 | 93 let
94 | 94 newSlider =
95 | 95 SingleSlider.update str model.singleSlider
96 | 96 in
97 | 97 ( { model | singleSlider = newSlider }, Cmd.none )
98 | 98
99 | 99
100 | 100
101 | 101 -- VIEW
102 | 102
103 | 103
104 | 104 view : Model -> Html Msg
105 | 105 view model =
106 | 106 div []
107 | 107 [ div [] [ DoubleSlider.view model.doubleSlider ]
108 | 108 , div [] [ SingleSlider.view model.singleSlider ]
109 | 109 ]
110 | 110
111 | 111
112 | 112 subscriptions : Model -> Sub msg
113 | 113 subscriptions model =
114 | 114 Sub.none
115 |
--------------------------------------------------------------------------------
/lola-club/code-s5.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neontribe/code-reading-club/c3baf98c0d517ec7c7b9f09addee7f0cd3cca71f/lola-club/code-s5.pdf
--------------------------------------------------------------------------------
/lola-club/code-s6.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neontribe/code-reading-club/c3baf98c0d517ec7c7b9f09addee7f0cd3cca71f/lola-club/code-s6.pdf
--------------------------------------------------------------------------------
/lola-club/code-s7-notes.md:
--------------------------------------------------------------------------------
1 | # Lola session 7 host notes
2 |
3 | Sample lightly adapted from [Racket's example "Memory" card game](https://github.com/racket/games/tree/master/memory).
4 |
5 | Trimmed down a bit for easier reading (mostly just removed the game timer).
6 |
7 | `code-s7.rkt` can be executed as-is in DrRacket and it will show the game GUI, but it assumes you have a full Racket install with the game assets in `share/games/...` etc. However, if you just want to run the pre-compiled version (with the timer) it is included in [the default Racket bundle](https://download.racket-lang.org) (run the "PLT Games" executable in the download and select "Memory").
8 |
9 |
10 | ## Hints
11 |
12 | - The `#t` and `#f` values on lines 26, 34, 35 etc. are booleans
13 | - `(+ 1 HEIGHT)` is calling the `(+)` function and passing in 1 and HEIGHT
14 | - `(car)` is a standard function that returns the first element in a list (should really be named `(first)`)
15 | - `(cdr)` returns the remaining elements as a list (should really be named `(rest)`)
16 | - the reasons for these function names are quite literally lost in the mists of time
17 | - lists are recursively defined: they're either `null` or a pair of elements; the first element being the head of the list, the second being either `null` (if it's a single-element list) or a list of the remaining elements
18 | - `(cond)` is a convenience function used to chain **cond**itionals as a series of tests
19 | - square brackets `[]` are interchangeable with parens `()`
20 | - by _convention_ they're used for `(cond)` clauses (along with indentation) to make things a bit more readable
21 | - `(send t stack-cards deck)`
22 | - sending `deck` to the `stack-cards` function in the `t` object (ish)
23 | - The exclamation in `(set!)` [is significant](https://docs.racket-lang.org/guide/set_.html)
24 |
25 |
--------------------------------------------------------------------------------
/lola-club/code-s7.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neontribe/code-reading-club/c3baf98c0d517ec7c7b9f09addee7f0cd3cca71f/lola-club/code-s7.pdf
--------------------------------------------------------------------------------
/lola-club/code-s7.rkt:
--------------------------------------------------------------------------------
1 | #lang racket
2 | (require games/cards racket/gui racket/class racket/unit)
3 |
4 | ;; Layout width and height:
5 | (define WIDTH 5)
6 | (define HEIGHT 4)
7 | (define MAX-MATCHES (/ (* WIDTH HEIGHT) 2))
8 |
9 | ;; Randomize
10 | (random-seed (modulo (current-milliseconds) 10000))
11 |
12 | ;; Set up the table
13 | (define t (make-table "Memory" (+ 2 WIDTH) (+ 1 HEIGHT)))
14 | (send t show #t)
15 | (send t set-double-click-action #f)
16 |
17 | ;; Get table width & height
18 | (define w (send t table-width))
19 | (define h (send t table-height))
20 |
21 | ;; Set up the cards
22 | (define deck
23 | (let ([cards (map (lambda (name value)
24 | (let ([bm (make-object
25 | bitmap%
26 | (build-path
27 | (collection-path "games" "memory" "images")
28 | (format "~a.png" name)))])
29 | (make-card bm #f 0 value)))
30 | '("club" "heart" "spade" "diamond"
31 | "happy" "unhappy" "fish" "two-fish" "jack" "star")
32 | '(1 2 3 4 5 6 7 8 9 10))])
33 | (append cards (map (lambda (c) (send c copy)) cards))))
34 | (for-each (lambda (card)
35 | (send card user-can-move #f)
36 | (send card user-can-flip #t))
37 | deck)
38 |
39 | ;; Card width & height
40 | (define cw (send (car deck) card-width))
41 | (define ch (send (car deck) card-height))
42 |
43 | (define dx (/ cw (+ 2 WIDTH)))
44 | (define dy (/ ch (+ 1 HEIGHT)))
45 |
46 | (define match-x (- w cw dx))
47 | (define match-y dy)
48 |
49 | ;; Put the cards on the table
50 | (send t add-cards deck match-x match-y)
51 |
52 | ;; Setup
53 | (define (setup)
54 | (set! deck (shuffle-list deck 7))
55 | (send t stack-cards deck)
56 | (send t move-cards deck 0 0
57 | (lambda (pos)
58 | (let ([i (modulo pos WIDTH)]
59 | [j (quotient pos WIDTH)])
60 | (values (+ dx (* i (+ cw dx)))
61 | (+ dy (* j (+ ch dy))))))))
62 |
63 | ;; Number of matches found so far:
64 | (define matches 0)
65 |
66 | ;; First card flipped, or #f if non flipped, yet
67 | (define card-1 #f)
68 |
69 | (define (flip-and-match c)
70 | (cond [(eq? c card-1)
71 | ;; Cancel first card
72 | (send t flip-card c)
73 | (set! card-1 #f)]
74 | [(not (send c face-down?))
75 | ;; Can't click a matched card, unless the game is over,
76 | ;; in which case we reset the game
77 | (when (= matches MAX-MATCHES)
78 | (send t flip-cards deck)
79 | (set! matches 0)
80 | (setup))]
81 | [else
82 | ;; Flip over a card...
83 | (send t flip-card c)
84 | (send t card-to-front c)
85 | (cond [(not card-1)
86 | ;; That was the first card
87 | (set! card-1 c)]
88 | [(and (equal? (send card-1 get-value) (send c get-value))
89 | (equal? (send card-1 get-suit) (send c get-suit)))
90 | ;; Match
91 | (send t move-cards (list card-1 c) match-x match-y)
92 | (set! card-1 #f)
93 | (set! matches (add1 matches))]
94 | [else
95 | ;; Not a match
96 | (send t pause 0.5)
97 | (send t flip-cards (list card-1 c))
98 | (set! card-1 #f)])]))
99 |
100 | (send t set-single-click-action flip-and-match)
101 |
102 | ;; Start the game:
103 | (setup)
104 |
--------------------------------------------------------------------------------
/lola-club/code-s8-notes.md:
--------------------------------------------------------------------------------
1 | # Lola session 8 host notes
2 |
3 | Snake game — written in Lua for the TIC-80 — made following [this tutorial at infinitelimit.net](https://www.infinitelimit.net/article/tic-80-snake).
4 |
5 | This session is suitable for beginners as the program presented is complete, simple and easily understood. The context of the TIC-80 provides some interesting discussion points for more experienced folks.
6 |
7 | The `code-s8.tic` "cartridge" can be loaded and run as-is in the [TIC-80](https://tic80.com/create). I'd recommend downloading the TIC-80 binary and running it locally, rather than typing everything into the HTML5 version on their site (can't copy/paste into the web version due to browser security restrictions on clipboard access).
8 |
9 |
10 | ## Notes/hints
11 |
12 | (All line numbers refer to `code-s8.pdf`)
13 |
14 | - The `TIC()` function on line 51 is the magic "main" function which is called by the TIC-80 60 times per second
15 | - Lua uses [tables](https://www.lua.org/manual/5.1/manual.html#2.5.7) for its arrays, associative arrays and more…
16 | >Tables are the sole data structuring mechanism in Lua; they can be used to represent ordinary arrays, symbol tables, sets, records, graphs, trees, etc. To represent records, Lua uses the field name as an index. The language supports this representation by providing a.name as syntactic sugar for a["name"].
17 | - Lua's `#foo` "hashtag" (e.g. line 53) is its [length operator](https://www.lua.org/manual/5.1/manual.html#2.5.5), so `#body` gives you the length of the `body` table
18 | - The `pairs()` function (e.g. line 27) iterates over key/value pairs in a table
19 | - The [trace](https://github.com/nesbox/TIC-80/wiki/trace), [btn](https://github.com/nesbox/TIC-80/wiki/btn), [cls](https://github.com/nesbox/TIC-80/wiki/cls) and [rect](https://github.com/nesbox/TIC-80/wiki/rect) functions are all TIC-80 built-ins
20 | - If you have time, I'd definitely recommend screen sharing and showing the program running in the TIC-80
21 | - Our group enjoyed seeing the instant modify/run behaviour
22 | - You can load another demo cartridge like `quest.tic` to show the sprite and map editor
23 | - The body of the snake (and the food) is drawn with 8x8 blocks
24 | - Changing `*8` to `*4` in the `draw()` function will "double the resolution"
25 | - You'll also need to update the modulo operations on lines 64 and 65 so that the snake still wraps at the screen boundary
26 | - Game speed is controlled on line 21
27 | - The last parameter passed to `rect()` (and the only param to `cls()`) is a colour reference (integer index of the 16-colour palette)
--------------------------------------------------------------------------------
/lola-club/code-s8.lua:
--------------------------------------------------------------------------------
1 | -- Created by IntelliJ IDEA.
2 | -- User: henry
3 | -- Date: 12/11/2020
4 | -- Time: 19:57
5 | -- To change this template use File | Settings | File Templates.
6 | -- Made by following this tutorial https://www.infinitelimit.net/article/tic-80-snake
7 | -- script: lua
8 | -- title: Snakey
9 | -- author: @trelemar
10 | -- palette: 1516184424340059ff4e4a4e854c30346524d9213f7571613898ecd27d2c8595a16daa2cd2aa996dc2cadad45edeeed6
11 |
12 | dirs={
13 | [0]={x= 0,y=-1},
14 | [1]={x= 0,y= 1},
15 | [2]={x=-1,y= 0},
16 | [3]={x= 1,y= 0}
17 | }
18 |
19 | function init()
20 | time=0
21 | count=0
22 | body={
23 | {x=15,y=8},
24 | {x=14,y=8},
25 | {x=13,y=8}
26 | }
27 | target={x=0,y=0}
28 | dir=dirs[0]
29 | end
30 |
31 | function update()
32 | return time%5==0
33 | end
34 |
35 | function setTarget()
36 | target.x=math.random(0,29)
37 | target.y=math.random(0,16)
38 | for i,v in pairs(body) do
39 | if v.x==target.x and v.y==target.y then
40 | setTarget()
41 | end
42 | end
43 | end
44 |
45 | function hitTarget()
46 | if head.x==target.x and head.y==target.y then
47 | return true
48 | end
49 | end
50 |
51 | function draw()
52 | cls(2)
53 | for i,v in pairs(body) do
54 | rect(v.x*8,v.y*8,8,8,15)
55 | end
56 | rect(target.x*8,target.y*8,8,8,6)
57 | end
58 |
59 | init()
60 | setTarget()
61 |
62 | function TIC()
63 | time=time+1
64 | head = body[#body]
65 | join = body[#body-1]
66 | tail = body[1]
67 | if update() then
68 | for i,v in pairs(body) do
69 | if i~=#body and v.x==head.x and v.y==head.y then
70 | trace("Total: "..count)
71 | exit()
72 | end
73 | end
74 | table.insert(body, #body+1, {
75 | x=(head.x+dir.x) % 30,
76 | y=(head.y+dir.y) % 17
77 | })
78 | if not hitTarget() then
79 | table.remove(body,1)
80 | else
81 | setTarget()
82 | count=count+1
83 | end
84 | end
85 | local last_dir=dir
86 | if btn(0) then dir=dirs[0]
87 | elseif btn(1) then dir=dirs[1]
88 | elseif btn(2) then dir=dirs[2]
89 | elseif btn(3) then dir=dirs[3]
90 | end
91 |
92 | if head.x+dir.x==join.x and head.y+dir.y==join.y then
93 | dir=last_dir
94 | end
95 | draw()
96 | end
--------------------------------------------------------------------------------
/lola-club/code-s8.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neontribe/code-reading-club/c3baf98c0d517ec7c7b9f09addee7f0cd3cca71f/lola-club/code-s8.pdf
--------------------------------------------------------------------------------
/lola-club/code-s8.tic:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neontribe/code-reading-club/c3baf98c0d517ec7c7b9f09addee7f0cd3cca71f/lola-club/code-s8.tic
--------------------------------------------------------------------------------
/neontribe-club/retrospective/exercises.md:
--------------------------------------------------------------------------------
1 | ## Exercises
2 |
3 | ### Read and dicuss large code sample (20 mins)
4 | #### Read (Independent)
5 | #### Discuss (Group)
6 | Todo add structure if we think this is worthwhile exercise.
7 |
8 | ### Interaction with code
9 | #### Identify pieces (Independent)
10 | Use 3 different colours to circle and draw links between instantiation/declaration and uses of/calls to variables, methods/functions and classes
11 |
12 | #### Discuss patterns (Group)
13 | What patterns are visible from the colors? What parts of the code warrant more attention based on the colors?
14 |
15 | ### Content
16 | #### Identify 5 most important lines (Independent)
17 |
18 | #### Discuss (Group)
19 | lines covered by many people & lines named but not by a lot of people
20 | Agree less than 10 of the most important lines
21 |
22 | ### Summarize
23 | #### Essence of the code in a few sentences (Independent)
24 | #### Discuss (Group)
25 | topics covered by many vs few
26 | strategies used to create the summary (e.g. method names, documentation, variable names, prior knowledge of system)
27 |
28 | #### Create a summary (Group)
29 | Compare the summary with the available documentation (inside and outside the code)
30 | identify differences and similarities between the groups findings and the existing
31 |
--------------------------------------------------------------------------------
/neontribe-club/retrospective/reflections.md:
--------------------------------------------------------------------------------
1 | ## Reflections
2 |
3 | - Note a time the past 2 weeks when you used one of the techniques from the club in your work
4 | - Note a time the past 2 weeks when you used information learned about code in your work
5 |
6 | -------------
7 |
8 | - Helping people improve interview technique - by using the code club reading technique instead of white board for shared code reading exercise.
9 | - Decisions about order of items - in writing code.
10 | - Telling people it is amazing
11 | - Beginner thinks more about features and less about keywords whereas I think about keywords, not what they are doing.
12 | - Makes me think about comments more.
13 | - Crazy that we used to learn by reading lines Increased my confidence of reading python (beginner)
14 | - not just learning concepts only.
15 | - I'm here to see if there is anything I'm missing
16 | - some of the techniques second nature In terms of teaching me how to code. I don't follow instructions.
17 | - not in work, but talking about/promoting the idea of reading code to other developers who acknowledged that is a great initiative
18 | - making my comments less noisy - not new but a visual reminder of what that can do to a codebase\
19 | - thinking about a problem I was facing - and I found myself thinking if navigating the whole code base not just a snippet could be useful (e.g. a small application, regardless of the language)\
20 | - doing refactoring by looking at the core functionality - similar to the exercise where we identif
21 |
--------------------------------------------------------------------------------
/neontribe-club/retrospective/wash-ups.md:
--------------------------------------------------------------------------------
1 | ## Wash ups
2 |
3 | ### Worked well
4 |
5 | - line numbers!
6 | - the club and conversations
7 | - This is a sufficiently sized example to have a crack at in the time we have
8 | - Amazing that we had an interesting conversation about simpole bit of code
9 | - Conversation is more about what it is doing and the structure rather than talking about the code syntax line by line (outputs/ comments/ it's messy/ it's noisy not this is a class and how we write it, etc.)
10 | - python which is what I am learaning anyway
11 | - good, clean piece of code, as every week we look at different code (language wise)
12 | - seemingly simple lines of code but more challenging than thought
13 | - reflection brought up quite a few uses about the information/techniques learned from previous sessions
14 | - Interesting code choice, challenged more experienced developers!
15 |
16 |
17 | ### Worked badly
18 |
19 | - ran out of time
20 | - taking notes and facilitating at the same time
21 | - experienced developers were doing most of the talking
22 | - The second bit of code (test output) wasn't looked at
23 | - Is as important and as hard to read as the comments
24 | - We talked about the wrong part of the code, not the interesting part
25 | - we didn't talk about method, class, variable this time
26 | - Not prepared for today - in a sprint week
27 | - didn't stick to the agenda and we tend to spend more time on certain parts (perhaps this tells us something about the group dynamic and maybe the agenda should be tailored to meet the group's needs?)
28 | - for beginners, some technical chat between more experienced developers was confusing/difficult to follow especially when not indicating the number of the code line in reference
29 | - time :-( we always overrun
30 | - no printer! need to have a section on digital marking and colouring code
31 | - prepare feedback comments before session we always struggle to remember
32 | - different formats when printed, maybe provide code samples as pdf with line numbers
33 |
--------------------------------------------------------------------------------
/neontribe-club/session1/agenda-s1.md:
--------------------------------------------------------------------------------
1 | # Code Reading Club agenda
2 |
3 | ## Reflection (5 mins) - usually that but first session ARC sample exercise - ID the purpose of each file
4 | - Note a time the past 2 weeks when you used one of the techniques from the club in your work
5 | - Note a time the past 2 weeks when you used information learned about code in your work
6 |
7 | ## Exercises
8 | At the start everyone should look at the same code, but as the club evolves you can tackle a bigger bit of code by splitting into sections. These exercises are best carried out when the code can fit on one or two pages but with it being the norm to split in many ways - we hope to invent and discover different exercises.
9 |
10 | You will need:
11 | - two printed copies of the code for today's club
12 | - some graph paper - or coloured paper and scissors - or acetate and something to write on it with
13 | - coloured pens, crayons or pencils
14 |
15 | ### Interaction with code (10 mins)
16 | 1. Colour1 the variables - circle and draw links between instatiation and all uses
17 | 1. Colour2 the method/ function calls - circle and draw links between declarations and calls
18 | 1. Colour3 the classes - circle and draw links between classes and their instances
19 | 1. Draw the indentaiton patterns - There are a few ways to do this. Fill over with black sharpie. Trace on graph paper. Trace on acetate. etc?
20 |
21 | #### Discuss the results (10 mins)
22 | 1. What patterns are visible from the colors and indentations only?
23 | 1. What parts of the code warrant more attention based on the colors and indentation?
24 |
25 | ### Content
26 |
27 | #### Identify (10 mins)
28 | 1. Define what it means to be important and independently identify the 5 lines you consider most important
29 | 1. Discuss in the group:
30 | - lines covered by many people?
31 | - lines named but not by a lot of people
32 | - Agree less than 10 of the most important lines
33 |
34 | #### Discuss (10 mins)
35 | Take turns in the group, and let every member talk about the code for 30 seconds (or less/more, could also be one sentence each). Try to add new information and not repeat things that have been said, and repeat until people do not know new things anymore.
36 | [Save the last word for me protocol](https://lead.nwp.org/knowledgebase/save-the-last-word-for-me-protocol/)
37 |
38 | #### Summarize in less than 10 sentences (10 mins)
39 | 1. Independently write down the essence of the code in a few sentences
40 | 1. Discuss in the group
41 | - topics covered by many vs few
42 | - strategies used to create the summary (e.g. method names, documentation, variable names, prior knowledge of system)
43 | 1. Create a summary together
44 | 1. Compare the summary with the available documentation (inside and outside the code)
45 | - identify differences and similarities between the groups findings and the existing
46 |
47 |
48 | ## Wash up (5 mins)
49 | - What worked well
50 | - What worked badly
51 |
52 | ## Follow up (2 weeks of elapsed time)
53 | - Identify code for next session, keaping in mind Wash up and Reflection information
54 |
55 |
56 |
--------------------------------------------------------------------------------
/neontribe-club/session1/code-sample-ARCVService-Note.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neontribe/code-reading-club/c3baf98c0d517ec7c7b9f09addee7f0cd3cca71f/neontribe-club/session1/code-sample-ARCVService-Note.pdf
--------------------------------------------------------------------------------
/neontribe-club/session1/code-sample-gbptm-UI-LooListItem.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neontribe/code-reading-club/c3baf98c0d517ec7c7b9f09addee7f0cd3cca71f/neontribe-club/session1/code-sample-gbptm-UI-LooListItem.pdf
--------------------------------------------------------------------------------
/neontribe-club/session1/completedExercises/colouring-example.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neontribe/code-reading-club/c3baf98c0d517ec7c7b9f09addee7f0cd3cca71f/neontribe-club/session1/completedExercises/colouring-example.jpg
--------------------------------------------------------------------------------
/neontribe-club/session1/completedExercises/what-for-example.txt:
--------------------------------------------------------------------------------
1 | Note model/ object
2 | CentreUser model that can have notes.
3 | Family model that can have notes.
4 | Creates the data store for the Note
5 | Tests for the CentreUser-Note relationship. No tests for Family.
6 |
7 | Curiously - the Note is never used in the app.
8 |
--------------------------------------------------------------------------------
/neontribe-club/session1/what-happened-s1.md:
--------------------------------------------------------------------------------
1 | # Code Reading Club agenda
2 |
3 | ## Reflection (5 mins) - usually that but first session ARC sample exercise - ID the purpose of each file
4 | - Note a time the past 2 weeks when you used one of the techniques from the club in your work
5 | - Note a time the past 2 weeks when you used information learned about code in your work
6 |
7 | ## Exercises
8 | At the start everyone should look at the same code, but as the club evolves you can tackle a bigger bit of code by splitting into sections. These exercises are best carried out when the code can fit on one or two pages but with it being the norm to split in many ways - we hope to invent and discover different exercises.
9 |
10 | You will need:
11 | - two printed copies of the code for today's club
12 | - some graph paper - or coloured paper and scissors - or acetate and something to write on it with
13 | - coloured pens, crayons or pencils
14 |
15 | ### Interaction with code (10 mins)
16 | 1. Colour1 the variables - circle and draw links between instatiation and all uses
17 | 1. Colour2 the method/ function calls - circle and draw links between declarations and calls
18 | 1. Colour3 the classes - circle and draw links between classes and their instances
19 | 1. Draw the indentaiton patterns - There are a few ways to do this. Fill over with black sharpie. Trace on graph paper. Trace on acetate. etc?
20 |
21 | #### Discuss the results (10 mins)
22 | 1. What patterns are visible from the colors and indentations only?
23 | 1. What parts of the code warrant more attention based on the colors and indentation?
24 |
25 | ### Content
26 |
27 | #### Identify (10 mins)
28 | 1. Define what it means to be important and independently identify the 5 lines you consider most important
29 | 1. Discuss in the group:
30 | - lines covered by many people?
31 | - lines named but not by a lot of people
32 | - Agree less than 10 of the most important lines
33 |
34 | #### Discuss (10 mins)
35 | Take turns in the group, and let every member talk about the code for 30 seconds (or less/more, could also be one sentence each). Try to add new information and not repeat things that have been said, and repeat until people do not know new things anymore.
36 | [Save the last word for me protocol](https://lead.nwp.org/knowledgebase/save-the-last-word-for-me-protocol/)
37 |
38 | #### Summarize in less than 10 sentences (10 mins)
39 | 1. Independently write down the essence of the code in a few sentences
40 | 1. Discuss in the group
41 | - topics covered by many vs few
42 | - strategies used to create the summary (e.g. method names, documentation, variable names, prior knowledge of system)
43 | 1. Create a summary together
44 | 1. Compare the summary with the available documentation (inside and outside the code)
45 | - identify differences and similarities between the groups findings and the existing
46 |
47 |
48 | ## Wash up (5 mins)
49 | - What worked well
50 | - What worked badly
51 |
52 | ## Follow up (2 weeks of elapsed time)
53 | - Identify code for next session, keaping in mind Wash up and Reflection information
54 |
55 |
56 |
--------------------------------------------------------------------------------
/neontribe-club/session11/agenda.md:
--------------------------------------------------------------------------------
1 | ## Advanced Exercises
2 |
3 | These exercises are more advanced, in the sense that you might need a bit more understanding of the code for these to make sense. This might be because the group is familiar with the code before the session, or because you are doing a second club on the same code snippet.
4 |
5 | ### Code structure
6 |
7 | #### Examine structure (5 mins)
8 |
9 | Use one of the basic exercises to examine the structure of the code (such as circle variables and link them), or reuse the notes from the previous club. Individuallt study the patterns and think about what they tell you. What direction does the code 'flow' in? What parts stand out for lack of, or access of links?
10 |
11 | #### Discussion (10 mins)
12 |
13 | - Parts of the code covered by many vs few
14 | - Strategies used to decide
15 |
16 | ### Content
17 |
18 | #### Central thematic concepts (5 mins)
19 |
20 | Each participant gets 5 minutes to individually name the 5 most central concepts of the code. These could be names, themes, classes, or information found in comments.
21 |
22 | #### Discussion (10 mins)
23 |
24 | - Topics covered by many vs few
25 | - Strategies used to decide (e.g. method names, documentation, variable names, prior knowledge of system)
26 |
27 | #### Central programming concepts (5 mins)
28 |
29 | Each participant gets 5 minutes to individually name the 5 most central computer science concepts of the code. These could be algorithms, data structures, assumptions or techniques.
30 |
31 | #### Discussion (10 mins)
32 |
33 | - Topics covered by many vs few
34 | - Strategies used to decide (e.g. method names, documentation, variable names, prior knowledge of system)
35 |
36 | ### The 'why' of the code
37 |
38 | Reexamine the code snippet and list decisions and intentions of the creator(s) of the code. For example a decision to use a certain design pattern ir use a certain library or API?
39 |
40 | * What decisions were made in the creation of this code?
41 | * What assumptions do these decisions rely on?
42 |
43 | #### Discussion (10 mins)
44 |
45 | Gather all decisions people made individually and discuss:
46 |
47 | - Pros of these decisions
48 | - Possible cons of these decisions
49 | - Alternative solutions
50 |
--------------------------------------------------------------------------------
/neontribe-club/session11/marked-up-code.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neontribe/code-reading-club/c3baf98c0d517ec7c7b9f09addee7f0cd3cca71f/neontribe-club/session11/marked-up-code.jpg
--------------------------------------------------------------------------------
/neontribe-club/session11/notes.md:
--------------------------------------------------------------------------------
1 | Central Thematic Concepts
2 |
3 | - const list generate markup for list of patients
4 | - load patients
5 | - search to filter patients
6 | -
7 |
8 |
9 | -looks highly finctional
10 | - bunch of functions
11 | - whole pile of const
12 |
13 |
14 | - component framework of react
15 | - also own made components
16 | - relying on whole load of other stuff
17 | - recent react useEffect
18 | - breaks out complicated UI
19 | - uses REDUx
20 |
21 |
22 | Discussion
23 | - 3 of us picked out structural things about code being built of fuctions
24 | - 2 peolpe talked framework - prior knowledge
25 | - Had not seen before, not idea what does, structure
26 | - WHy is hte code layed out this way, not guess what it does.
27 | - noticable lack of documentation
28 | - used method & variable names
29 |
30 |
31 | Cebtral programming
32 |
33 | - do not repeat yourself, highly modular
34 | - transpolation - virtual language (react)
35 | - type enforcement
36 | - async procedures
37 | - templating
38 |
39 | - declarative - extracts the doing for you (react) e.g. virtual dom
40 | - component driven way of buidling. expect components to have exportable blobs of markup, styles and functions
41 |
42 | - funcitonal programming
43 | - higher order functions
44 | - types
45 |
46 | -react core methods
47 | - events
48 | - async
49 | - html
50 | - html form submit
51 | - mapping
52 | - fetch - wait state - render
53 | - translate key -> string
54 | - state management in objects
55 |
56 |
57 | Discussion
58 | - you 3 went high level 1 went lower
59 | - only crossover was types and componet-y nature
60 | - backed out of code and looked for blocks that were implementing lang features
61 | - got DRY from all the imports
62 | - react - we know is transpiles
63 | - async obvious
64 | - triggered by earlier discusion on functions
65 | - previous stuff not reading now
66 | - looked blocks of code to identify what atterns they used on a low level
67 | - is a .tsx file
68 | - used types to id what htings were maybe that is why not as much docs?)
69 |
70 |
71 | The why of the code
72 |
73 | - React (get state management for free)
74 | - Types
75 | - tsx (html really)
76 | - Components with props to customise
77 | - const for functions to reuse and state info
78 | - translation system to keep copy out
79 | - classes in html
80 |
81 | - offline first (literally says that)
82 | - web tool hybrid development (not native)
83 | - included more libraries because their choice of react was was limiting (e.g. wanted types0
84 | - most modern tecniques they could find
85 |
86 | - Use react!
87 | - To show patients
88 | - No useful comments
89 | - use spinners to make the ui seems more responsive
90 | - reuse components, maybe not v accessible way
91 |
92 | - functional components
93 | - loading spinner for better UI (good idea!)
94 |
95 |
96 | Discussion
97 | - offline first means hybrid
98 | - like assigning functions to const could be less invasive to use named
99 | - prefer named functions directly
100 |
101 | Pros and Cons
102 | - cons of js is library management - need to touch every month at least
103 | - offline choice makes it hard
104 | - where data lives? data management
105 | - developing world aware they need to sync , not expect constant connection
106 |
107 | Wash up:
108 |
109 | Well
110 | - revist used bit of code already marked
111 | - straight into conversatoin
112 | - made us thing more about the architechtue and concepts more
113 | - more about planning and think about why they code is like that vs figuring out what the code does (in easrlier sessoins)
114 | - fun
115 |
116 | Badly
117 | - Questioning is wide, more specific
118 | - Why of the code needs warning that beginners might listen
119 | - Why of the code needs more context maybe more explain
120 | (not why they made decisions, but what they get for free and what rods they have created for backs)
121 | - Programming concepts (for beginners prompy with 'like a for loop')
122 |
123 | Amend resources:
124 | - couple typos
125 | - add 5 mins independant to why of code section
126 | - Central theme needs more clear task
127 | - Examine structure section same as before?
128 |
129 |
--------------------------------------------------------------------------------
/neontribe-club/session2/agenda-s2.md:
--------------------------------------------------------------------------------
1 | # Code Reading Club agenda
2 |
3 | ## Reflection (5 mins)
4 | - Note a time the past 2 weeks when you used one of the techniques from the club in your work
5 | - Note a time the past 2 weeks when you used information learned about code in your work
6 |
7 | ## Exercises
8 | At the start everyone should look at the same code, but as the club evolves you can tackle a bigger bit of code by splitting into sections. These exercises are best carried out when the code can fit on one or two pages but with it being the norm to split in many ways - we hope to invent and discover different exercises.
9 |
10 | You will need:
11 | - two printed copies of the code for today's club
12 | - some graph paper - or coloured paper and scissors - or acetate and something to write on it with
13 | - coloured pens, crayons or pencils
14 |
15 | ### Interaction with code (10 mins)
16 | 1. Colour1 the variables - circle and draw links between instatiation and all uses
17 | 1. Colour2 the method/ function calls - circle and draw links between declarations and calls
18 | 1. Colour3 the classes - circle and draw links between classes and their instances
19 | 1. Draw the indentaiton patterns - There are a few ways to do this. Fill over with black sharpie. Trace on graph paper. Trace on acetate. etc?
20 |
21 | #### Discuss the results (10 mins)
22 | 1. What patterns are visible from the colors and indentations only?
23 | 1. What parts of the code warrant more attention based on the colors and indentation?
24 |
25 | ### Content
26 |
27 | #### Identify (10 mins)
28 | 1. Define what it means to be important and independently identify the 5 lines you consider most important
29 | 1. Discuss in the group:
30 | - lines covered by many people?
31 | - lines named but not by a lot of people
32 | - Agree less than 10 of the most important lines
33 |
34 | #### Discuss (10 mins)
35 | Take turns in the group, and let every member talk about the code for 30 seconds (or less/more, could also be one sentence each). Try to add new information and not repeat things that have been said, and repeat until people do not know new things anymore.
36 | [Save the last word for me protocol](https://lead.nwp.org/knowledgebase/save-the-last-word-for-me-protocol/)
37 |
38 | #### Summarize in less than 10 sentences (10 mins)
39 | 1. Independently write down the essence of the code in a few sentences
40 | 1. Discuss in the group
41 | - topics covered by many vs few
42 | - strategies used to create the summary (e.g. method names, documentation, variable names, prior knowledge of system)
43 | 1. Create a summary together
44 | 1. Compare the summary with the available documentation (inside and outside the code)
45 | - identify differences and similarities between the groups findings and the existing
46 |
47 |
48 | ## Wash up (5 mins)
49 | - What worked well
50 | - What worked badly
51 |
52 | ## Follow up (2 weeks of elapsed time)
53 | - Identify code for next session, keaping in mind Wash up and Reflection information
54 |
55 |
56 |
--------------------------------------------------------------------------------
/neontribe-club/session2/completedExercises/colouring-example.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neontribe/code-reading-club/c3baf98c0d517ec7c7b9f09addee7f0cd3cca71f/neontribe-club/session2/completedExercises/colouring-example.jpg
--------------------------------------------------------------------------------
/neontribe-club/session2/completedExercises/what-for-example.txt:
--------------------------------------------------------------------------------
1 | Base utility classes for google app engine API email functions with specific rules
2 | Functions for sending mail using mailgun in bulk
3 | Tests for the gae services
4 | Tests for the mailgun services
5 |
6 |
7 |
--------------------------------------------------------------------------------
/neontribe-club/session2/python_file_1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neontribe/code-reading-club/c3baf98c0d517ec7c7b9f09addee7f0cd3cca71f/neontribe-club/session2/python_file_1.pdf
--------------------------------------------------------------------------------
/neontribe-club/session2/python_file_1_test.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neontribe/code-reading-club/c3baf98c0d517ec7c7b9f09addee7f0cd3cca71f/neontribe-club/session2/python_file_1_test.pdf
--------------------------------------------------------------------------------
/neontribe-club/session2/python_file_2-tests.py:
--------------------------------------------------------------------------------
1 | # Source: Oppia - https://github.com/oppia/oppia - an online learning tool that enables anyone to easily create and share interactive activities
2 |
3 | """Tests for the Mailgun API wrapper."""
4 |
5 | from __future__ import absolute_import # pylint: disable=import-only-modules
6 | from __future__ import unicode_literals # pylint: disable=import-only-modules
7 |
8 | from core.platform.email import mailgun_email_services
9 | from core.tests import test_utils
10 | import feconf
11 | import python_utils
12 |
13 |
14 | class EmailTests(test_utils.GenericTestBase):
15 | """Tests for sending emails."""
16 |
17 | def test_post_to_mailgun(self):
18 | """Test for sending HTTP POST request."""
19 | swapped_urlopen = lambda x: x
20 | swapped_request = lambda *args: args
21 | swap_urlopen_context = self.swap(
22 | python_utils, 'url_open', swapped_urlopen)
23 | swap_request_context = self.swap(
24 | python_utils, 'url_request', swapped_request)
25 | swap_api = self.swap(feconf, 'MAILGUN_API_KEY', 'key')
26 | swap_domain = self.swap(feconf, 'MAILGUN_DOMAIN_NAME', 'domain')
27 | with swap_urlopen_context, swap_request_context, swap_api, swap_domain:
28 | result = mailgun_email_services.post_to_mailgun({
29 | 'from': 'a@a.com',
30 | 'to': 'b@b.com',
31 | 'subject': 'Hola 😂 - invitation to collaborate'.encode(
32 | encoding='utf-8'),
33 | 'text': 'plaintext_body 😂'.encode(encoding='utf-8'),
34 | 'html': 'Hi abc,
😂'.encode(encoding='utf-8')
35 | })
36 | expected = (
37 | 'https://api.mailgun.net/v3/domain/messages',
38 | ('to=b%40b.com&text=plaintext_body+%F0%9F%98%82&html=Hi+abc'
39 | '%2C%3Cbr%3E+%F0%9F%98%82&from=a%40a.com&subject=Hola+%F0'
40 | '%9F%98%82+-+invitation+to+collaborate'),
41 | {'Authorization': 'Basic YXBpOmtleQ=='})
42 | self.assertEqual(result, expected)
43 |
44 | def test_send_mail_raises_exception_for_missing_api_key(self):
45 | """Tests the missing Mailgun API key exception."""
46 | mailgun_api_exception = (
47 | self.assertRaisesRegexp(
48 | Exception, 'Mailgun API key is not available.'))
49 |
50 | allow_emailing = self.swap(feconf, 'CAN_SEND_EMAILS', True)
51 | with mailgun_api_exception, allow_emailing:
52 | mailgun_email_services.send_mail(
53 | feconf.SYSTEM_EMAIL_ADDRESS, feconf.ADMIN_EMAIL_ADDRESS,
54 | 'subject', 'body', 'html', bcc_admin=False)
55 |
56 | def test_send_mail_raises_exception_for_missing_domain_name(self):
57 | """Tests the missing Mailgun domain name exception."""
58 | mailgun_api = self.swap(feconf, 'MAILGUN_API_KEY', 'api')
59 | mailgun_domain_name_exception = (
60 | self.assertRaisesRegexp(
61 | Exception, 'Mailgun domain name is not set.'))
62 | allow_emailing = self.swap(feconf, 'CAN_SEND_EMAILS', True)
63 | with mailgun_api, mailgun_domain_name_exception, allow_emailing:
64 | mailgun_email_services.send_mail(
65 | feconf.SYSTEM_EMAIL_ADDRESS, feconf.ADMIN_EMAIL_ADDRESS,
66 | 'subject', 'body', 'html', bcc_admin=False)
67 |
68 | def test_send_mail_raises_exception_for_invalid_permissions(self):
69 | """Tests the send_mail exception raised for invalid user permissions."""
70 | send_email_exception = (
71 | self.assertRaisesRegexp(
72 | Exception, 'This app cannot send emails to users.'))
73 | mailgun_api = self.swap(feconf, 'MAILGUN_API_KEY', 'api')
74 | mailgun_domain = self.swap(feconf, 'MAILGUN_DOMAIN_NAME', 'domain')
75 | with mailgun_api, mailgun_domain, send_email_exception:
76 | mailgun_email_services.send_mail(
77 | feconf.SYSTEM_EMAIL_ADDRESS, feconf.ADMIN_EMAIL_ADDRESS,
78 | 'subject', 'body', 'html', bcc_admin=False)
79 |
80 | def test_send_mail_data_properly_sent(self):
81 | """Verifies that the data sent in send_mail is correct."""
82 | mailgun_api = self.swap(feconf, 'MAILGUN_API_KEY', 'api')
83 | mailgun_domain = self.swap(feconf, 'MAILGUN_DOMAIN_NAME', 'domain')
84 | allow_emailing = self.swap(feconf, 'CAN_SEND_EMAILS', True)
85 |
86 | # Data we expect to have been sent in the
87 | # mailgun_email_services.post_to_mailgun().
88 | expected = {'from': feconf.SYSTEM_EMAIL_ADDRESS,
89 | 'to': feconf.ADMIN_EMAIL_ADDRESS,
90 | 'subject': 'subject',
91 | 'text': 'body',
92 | 'html': 'html'}
93 |
94 | # Lambda function, will replace post_to_mailgun().
95 | req_post_lambda = (lambda data=None:
96 | self.assertDictContainsSubset(expected, data))
97 | post_request = self.swap(
98 | mailgun_email_services, 'post_to_mailgun', req_post_lambda)
99 |
100 | with mailgun_api, mailgun_domain, post_request, allow_emailing:
101 | mailgun_email_services.send_mail(
102 | feconf.SYSTEM_EMAIL_ADDRESS, feconf.ADMIN_EMAIL_ADDRESS,
103 | 'subject', 'body', 'html', bcc_admin=False)
104 |
105 | def test_bcc_admin_flag(self):
106 | """Verifies that the bcc admin flag is working properly in send_mail.
107 | Note that we replace the mailgun_email_services.post_to_mailgun()
108 | function in send_mail with an alternate lambda that asserts the correct
109 | values were placed in the data dictionary that is then passed to the
110 | mailgun api.
111 | """
112 | mailgun_api = self.swap(feconf, 'MAILGUN_API_KEY', 'api')
113 | mailgun_domain = self.swap(feconf, 'MAILGUN_DOMAIN_NAME', 'domain')
114 | allow_emailing = self.swap(feconf, 'CAN_SEND_EMAILS', True)
115 |
116 | # Lambda function, will replace post_to_mailgun().
117 | req_post_lambda = (lambda data=None:
118 | self.assertEqual(
119 | data['bcc'], feconf.ADMIN_EMAIL_ADDRESS))
120 | post_request = self.swap(
121 | mailgun_email_services, 'post_to_mailgun', req_post_lambda)
122 |
123 | with mailgun_api, mailgun_domain, post_request, allow_emailing:
124 | mailgun_email_services.send_mail(
125 | feconf.SYSTEM_EMAIL_ADDRESS, feconf.ADMIN_EMAIL_ADDRESS,
126 | 'subject', 'body', 'html', bcc_admin=True)
127 |
128 | def test_reply_to_id_flag(self):
129 | """Verifies that the reply_to_id flag is working properly."""
130 | mailgun_api = self.swap(feconf, 'MAILGUN_API_KEY', 'api')
131 | mailgun_domain = self.swap(feconf, 'MAILGUN_DOMAIN_NAME', 'domain')
132 | allow_emailing = self.swap(feconf, 'CAN_SEND_EMAILS', True)
133 | reply_id = 123
134 |
135 | # Lambda function, will replace post_to_mailgun().
136 | req_post_lambda = (
137 | lambda data=None:
138 | self.assertEqual(
139 | data['h:Reply-To'],
140 | 'reply+' + python_utils.UNICODE(reply_id) + '@' +
141 | feconf.INCOMING_EMAILS_DOMAIN_NAME))
142 | post_request = self.swap(
143 | mailgun_email_services, 'post_to_mailgun', req_post_lambda)
144 |
145 | with mailgun_api, mailgun_domain, post_request, allow_emailing:
146 | mailgun_email_services.send_mail(
147 | feconf.SYSTEM_EMAIL_ADDRESS, feconf.ADMIN_EMAIL_ADDRESS,
148 | 'subject', 'body', 'html',
149 | bcc_admin=False, reply_to_id=reply_id)
150 |
151 | def test_send_bulk_mail_raises_exception_for_missing_api_key(self):
152 | """Test that send_bulk_mail raises exception for missing
153 | mailgun api key.
154 | """
155 | mailgun_api_exception = (
156 | self.assertRaisesRegexp(
157 | Exception, 'Mailgun API key is not available.'))
158 | allow_emailing = self.swap(feconf, 'CAN_SEND_EMAILS', True)
159 | with mailgun_api_exception, allow_emailing:
160 | mailgun_email_services.send_bulk_mail(
161 | feconf.SYSTEM_EMAIL_ADDRESS, [feconf.ADMIN_EMAIL_ADDRESS],
162 | 'subject', 'body', 'html')
163 |
164 | def test_send_bulk_mail_raises_exception_for_missing_domain_name(self):
165 | """Tests the missing Mailgun domain name exception for
166 | send_bulk_mail.
167 | """
168 | mailgun_api = self.swap(feconf, 'MAILGUN_API_KEY', 'api')
169 | allow_emailing = self.swap(feconf, 'CAN_SEND_EMAILS', True)
170 | mailgun_domain_name_exception = (
171 | self.assertRaisesRegexp(
172 | Exception, 'Mailgun domain name is not set.'))
173 | with mailgun_api, mailgun_domain_name_exception, allow_emailing:
174 | mailgun_email_services.send_bulk_mail(
175 | feconf.SYSTEM_EMAIL_ADDRESS, [feconf.ADMIN_EMAIL_ADDRESS],
176 | 'subject', 'body', 'html')
177 |
178 | def test_send_bulk_mail_exception_for_invalid_permissions(self):
179 | """Tests the send_bulk_mail exception raised for invalid user
180 | permissions.
181 | """
182 | send_email_exception = (
183 | self.assertRaisesRegexp(
184 | Exception, 'This app cannot send emails to users.'))
185 | mailgun_api = self.swap(feconf, 'MAILGUN_API_KEY', 'api')
186 | mailgun_domain = self.swap(feconf, 'MAILGUN_DOMAIN_NAME', 'domain')
187 | with mailgun_api, mailgun_domain, send_email_exception:
188 | mailgun_email_services.send_bulk_mail(
189 | feconf.SYSTEM_EMAIL_ADDRESS, [feconf.ADMIN_EMAIL_ADDRESS],
190 | 'subject', 'body', 'html')
191 |
192 | def test_send_bulk_mail_data_properly_sent(self):
193 | """Verifies that the data sent in send_bulk_mail is correct
194 | for each user in the recipient list.
195 | """
196 | mailgun_api = self.swap(feconf, 'MAILGUN_API_KEY', 'api')
197 | mailgun_domain = self.swap(feconf, 'MAILGUN_DOMAIN_NAME', 'domain')
198 | allow_emailing = self.swap(feconf, 'CAN_SEND_EMAILS', True)
199 | recipients = [feconf.ADMIN_EMAIL_ADDRESS]
200 |
201 | # Data that we expect to have been sent in the post_to_mailgun().
202 | expected = ({'from': feconf.SYSTEM_EMAIL_ADDRESS, 'to': recipients,
203 | 'subject': 'subject', 'text': 'body', 'html': 'html',
204 | 'recipient-variables': '{}'})
205 |
206 | # Lambda function, will replace post_to_mailgun().
207 | req_post_lambda = (lambda data=None:
208 | self.assertDictContainsSubset(expected, data))
209 | post_request = self.swap(
210 | mailgun_email_services, 'post_to_mailgun', req_post_lambda)
211 |
212 | with mailgun_api, mailgun_domain, post_request, allow_emailing:
213 | mailgun_email_services.send_bulk_mail(
214 | feconf.SYSTEM_EMAIL_ADDRESS, recipients,
215 | 'subject', 'body', 'html')
216 |
--------------------------------------------------------------------------------
/neontribe-club/session2/python_file_2.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neontribe/code-reading-club/c3baf98c0d517ec7c7b9f09addee7f0cd3cca71f/neontribe-club/session2/python_file_2.pdf
--------------------------------------------------------------------------------
/neontribe-club/session2/short-code-option-1-code-format.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neontribe/code-reading-club/c3baf98c0d517ec7c7b9f09addee7f0cd3cca71f/neontribe-club/session2/short-code-option-1-code-format.pdf
--------------------------------------------------------------------------------
/neontribe-club/session2/what-happened-s2.md:
--------------------------------------------------------------------------------
1 | # Code Reading Club agenda
2 |
3 | ## Reflection (10 mins)
4 | - Note a time the past 2 weeks when you used one of the techniques from the club in your work
5 | - Note a time the past 2 weeks when you used information learned about code in your work
6 |
7 | Helping people improve interview technique - by using the code club reading technique instead of whote board for shared code reading exercise.
8 | order of items- in writing code.
9 |
10 | ## Exercises
11 | At the start everyone should look at the same code, but as the club evolves you can tackle a bigger bit of code by splitting into sections. These exercises are best carried out when the code can fit on one or two pages but with it being the norm to split in many ways - we hope to invent and discover different exercises.
12 |
13 | You will need:
14 | - two printed copies of the code for today's club
15 | - some graph paper - or coloured paper and scissors - or acetate and something to write on it with
16 | - coloured pens, crayons or pencils
17 |
18 | ### Read code files (8mins)
19 | This week we had 4 files
20 |
21 | ### Discuss code files (12mins)
22 | Comments helpful and informative - is that right to look at them?
23 | Testing a hypothesis - will the tests tell me what the code is supposed to do
24 | There were a lot of tests - seems like they were tesing the API not only their own
25 | function doc comments are in the functions (can be in there for the ast) - so they ship with code
26 | extra thought - you can use your comments as test
27 | lookslike it is in the way but you get used to it
28 | multiline comments and strings use same syntax - not a problem because of indenting
29 | mailgun vs appengine - do they build on each other
30 |
31 | ### Exercise Interaction with code (10 mins)
32 | 1. Colour1 the variables - circle and draw links between instatiation and all uses
33 | 1. Colour2 the method/ function calls - circle and draw links between declarations and calls
34 | 1. Colour3 the classes - circle and draw links between classes and their instances
35 |
36 | #### Discuss the results (10 mins)
37 | 1. What patterns are visible from the colors?
38 | 1. What parts of the code warrant more attention based on the colors?
39 | - Confused me more than last week
40 | - was expecting to be procedureal but ended up looking like circles
41 | - wanted to visualise output but didn't have time
42 | - variables/ constants turned out to be functions
43 | - we couldn't find any classes but sometimes under the hood some might be intantiated as objects
44 | - traditional CSc model of oop but this code feels more aiming for pure functional
45 | - using typescript but not types
46 | - uses known and understood conventions (like use- and set-) but this is by practice/ convention and not obvious to new people to write this way
47 | - found myself drawing flux / redux cycles on the page
48 |
49 | ### Content
50 |
51 | #### Identify (10 mins)
52 | 1. Define what it means to be important and independently identify the 5 lines you consider most important
53 | 1. Discuss in the group:
54 | - lines covered by many people?
55 | - lines named but not by a lot of people
56 | - Agree less than 10 of the most important lines
57 |
58 | Votes by line number: count
59 | 7, 17, 18, 28, 41, 45, 50, : 1
60 | 11, 19, 23: 2
61 | 47: 3
62 | 34, 75: 4
63 |
64 | #### Some notes in conversation
65 | - history wasn't history of patients, but browser history - this is an example of convention we take for granted
66 | - where are side effects
67 | - using the patients string in 2 places near each other looks like var but was a translation string
68 | - dispatch event important
69 | - people who write react a lot took export for granted
70 | - people not as familiar with react went there first
71 | - agree that the core markup generator of patient list item and the side effects most important to understand
72 | - thoughts around what is important when reading vs writing the code
73 |
74 | ## Wash up (independent after session)
75 | ### What worked well
76 | - line numbers!
77 | - the club and conversations
78 |
79 | ### What worked badly
80 | - ran out of time
81 | - taking notes and facilitating at the same time
82 | - experienced developers were doing most of the talking
83 |
84 | ## Follow up (2 weeks of elapsed time)
85 | - Identify code for next session, keeping in mind Wash up and Reflection information
86 | - Rob to id some code with comments as tests
87 | - Try to get to the section about independent summary
88 |
--------------------------------------------------------------------------------
/neontribe-club/session3/agenda-s3.md:
--------------------------------------------------------------------------------
1 | # Code Reading Club agenda
2 | katja, charlie, alin, amanda, nick, rob
3 |
4 | ## Reflection (5 mins) 12:37
5 | - Note a time the past 2 weeks when you used one of the techniques from the club in your work
6 | - Note a time the past 2 weeks when you used information learned about code in your work
7 | Telling people it is amazing
8 | Not actual evidence of how it helps but - observations
9 | Beginner things more about features and less about keywords whereas I think about keywords, not what they are doing. Makes me think about comments more.
10 | Crazy that we used to learn by reading lines
11 | Increased my confidence of reading python (beginner) - not just learning concepts only.
12 | Here to see if there is anything I'm missing -some of the techniques second nature
13 | In terms of teaching me how to code. I don't follow instructions.
14 |
15 | ## Exercises
16 | At the start everyone should look at the same code, but as the club evolves you can tackle a bigger bit of code by splitting into sections. These exercises are best carried out when the code can fit on one or two pages but with it being the norm to split in many ways - we hope to invent and discover different exercises.
17 |
18 | You will need:
19 | - two printed copies of the code for today's club
20 | - some graph paper - or coloured paper and scissors - or acetate and something to write on it with
21 | - coloured pens, crayons or pencils
22 |
23 | ### Interaction with code (10 mins) 12:42
24 | 1. Colour1 the variables - circle and draw links between instatiation and all uses
25 | 1. Colour2 the method/ function calls - circle and draw links between declarations and calls
26 | 1. Colour3 the classes - circle and draw links between classes and their instances
27 | 1. Draw the indentaiton patterns - There are a few ways to do this. Fill over with black sharpie. Trace on graph paper. Trace on acetate. etc?
28 |
29 | #### Discuss the results (10 mins) 12:52
30 | 1. What patterns are visible from the colors and indentations only?
31 | 1. What parts of the code warrant more attention based on the colors and indentation?
32 |
33 | - Identation shows that import inside of the function. I'm used to languages where imports happen at top of file.
34 | - Import works wherever you use it in python. Like require in js.
35 | - Indentation level scopes stuff the block of code
36 | - Comment very noisy compared to the code
37 | - Looks like it's inside a REPL
38 | - Doc test library needs the syntax for parsing
39 | - Confused me at first - thought it was the code
40 |
41 | ### Content
42 |
43 | #### Identify (10 mins) 13:00
44 | 1. Define what it means to be important and independently identify the 3 lines you consider most important
45 | 1. Discuss in the group:
46 | - lines covered by many people?
47 | 46 (4 people) and 47 (3 people)
48 | - lines named but not by a lot of people
49 | 10, 37, 48, 49 (2 people) and 52,53 (1 person)
50 | - Agree less than 7 of the most important lines
51 | - 46, 47, 38, 40, 42 - interestingly when we only had 3 lines to choose independently, no one chose 38,40,42
52 |
53 | #### Discuss (10 mins) 13:20
54 | Take turns in the group, and let every member talk about the code for 30 seconds (or less/more, could also be one sentence each). Try to add new information and not repeat things that have been said, and repeat until people do not know new things anymore.
55 | [Save the last word for me protocol](https://lead.nwp.org/knowledgebase/save-the-last-word-for-me-protocol/)
56 |
57 | - Form is confusing because I don't know python
58 | - I'm a beginner and it doesn't match what I know about python. Is a mess.
59 | - If it didn't have the if block for floats, would not need to import all of `math`
60 | - I like lots of code examples in file don't always see that
61 | - Big numbers in python 300 zeros behind one number
62 | - Python is lovely for big numbers
63 | - You can have too much tests in your comments
64 | -Impression that formatting of comments is not consistant with the """ on same line at start and new line at end.
65 | - There's only one inline comment (catch the big number by using n+1 ==n)
66 | - Now I understand why we have colour coding in our IDEs
67 |
68 | #### Summarize in less than 10 sentences (10 mins) SKIPPED
69 | 1. Independently write down the essence of the code in a few sentences
70 | 1. Discuss in the group
71 | - topics covered by many vs few
72 | - strategies used to create the summary (e.g. method names, documentation, variable names, prior knowledge of system)
73 | 1. Create a summary together
74 | 1. Compare the summary with the available documentation (inside and outside the code)
75 | - identify differences and similarities between the groups findings and the existing
76 |
77 |
78 | ## Wash up (5 mins) 13:27
79 | ### What worked well
80 | - This is a sufficiently sized example to have a crack at in the time we have
81 | - Amazing that we had an interesting conversation about simpole bit of code
82 | - Conversation is more about what it is doing and the structure rather than talking about the code syntax line by line (outputs/ comments/ it's messy/ it's noisy not this is a class and how we write it, etc.)
83 | - python which is what I am learaning anyway
84 |
85 | ### What worked badly
86 | - The second bit of code (test output) wasn't looked at
87 | - Is as important and as hard to read as the comments
88 | - We talked about the wrong part of the code, not the interesting part
89 | - we didn't talk about method, class, variable this time
90 | - Not prepared for today - in a sprint week
91 |
92 | Finish 13:35
93 |
94 | ## Follow up (2 weeks of elapsed time)
95 | - Identify code for next session, keeping in mind Wash up and Reflection information
96 |
97 |
98 |
--------------------------------------------------------------------------------
/neontribe-club/session3/completedExercises/doctest-example-coloured.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neontribe/code-reading-club/c3baf98c0d517ec7c7b9f09addee7f0cd3cca71f/neontribe-club/session3/completedExercises/doctest-example-coloured.jpg
--------------------------------------------------------------------------------
/neontribe-club/session3/doctest-example.py:
--------------------------------------------------------------------------------
1 | """
2 | This is the "example" module.
3 |
4 | The example module supplies one function, factorial(). For example,
5 |
6 | >>> factorial(5)
7 | 120
8 | """
9 |
10 | def factorial(n):
11 | """Return the factorial of n, an exact integer >= 0.
12 |
13 | >>> [factorial(n) for n in range(6)]
14 | [1, 1, 2, 6, 24, 120]
15 | >>> factorial(30)
16 | 265252859812191058636308480000000
17 | >>> factorial(-1)
18 | Traceback (most recent call last):
19 | ...
20 | ValueError: n must be >= 0
21 |
22 | Factorials of floats are OK, but the float must be an exact integer:
23 | >>> factorial(30.1)
24 | Traceback (most recent call last):
25 | ...
26 | ValueError: n must be exact integer
27 | >>> factorial(30.0)
28 | 265252859812191058636308480000000
29 |
30 | It must also not be ridiculously large:
31 | >>> factorial(1e100)
32 | Traceback (most recent call last):
33 | ...
34 | OverflowError: n too large
35 | """
36 |
37 | import math
38 | if not n >= 0:
39 | raise ValueError("n must be >= 0")
40 | if math.floor(n) != n:
41 | raise ValueError("n must be exact integer")
42 | if n+1 == n: # catch a value like 1e300
43 | raise OverflowError("n too large")
44 | result = 1
45 | factor = 2
46 | while factor <= n:
47 | result *= factor
48 | factor += 1
49 | return result
50 |
51 |
52 | if __name__ == "__main__":
53 | import doctest
54 | doctest.testmod()
--------------------------------------------------------------------------------
/neontribe-club/session3/doctest-example.py.stdout:
--------------------------------------------------------------------------------
1 | $ python doctest-example.py -v
2 | Trying:
3 | factorial(5)
4 | Expecting:
5 | 120
6 | ok
7 | Trying:
8 | [factorial(n) for n in range(6)]
9 | Expecting:
10 | [1, 1, 2, 6, 24, 120]
11 | ok
12 | Trying:
13 | factorial(30)
14 | Expecting:
15 | 265252859812191058636308480000000
16 | **********************************************************************
17 | File "doctest-example.py", line 15, in __main__.factorial
18 | Failed example:
19 | factorial(30)
20 | Expected:
21 | 265252859812191058636308480000000
22 | Got:
23 | 265252859812191058636308480000000L
24 | Trying:
25 | factorial(-1)
26 | Expecting:
27 | Traceback (most recent call last):
28 | ...
29 | ValueError: n must be >= 0
30 | ok
31 | Trying:
32 | factorial(30.1)
33 | Expecting:
34 | Traceback (most recent call last):
35 | ...
36 | ValueError: n must be exact integer
37 | ok
38 | Trying:
39 | factorial(30.0)
40 | Expecting:
41 | 265252859812191058636308480000000
42 | **********************************************************************
43 | File "doctest-example.py", line 27, in __main__.factorial
44 | Failed example:
45 | factorial(30.0)
46 | Expected:
47 | 265252859812191058636308480000000
48 | Got:
49 | 265252859812191058636308480000000L
50 | Trying:
51 | factorial(1e100)
52 | Expecting:
53 | Traceback (most recent call last):
54 | ...
55 | OverflowError: n too large
56 | ok
57 | 1 items passed all tests:
58 | 1 tests in __main__
59 | **********************************************************************
60 | 1 items had failures:
61 | 2 of 6 in __main__.factorial
62 | 7 tests in 2 items.
63 | 5 passed and 2 failed.
64 | ***Test Failed*** 2 failures.
65 |
--------------------------------------------------------------------------------
/neontribe-club/session4/Signal-iOS-PhoneNumberValidator.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2019 Open Whisper Systems. All rights reserved.
3 | //
4 | import Foundation
5 | import SignalServiceKit
6 |
7 | @objc
8 | public enum ValidatedPhoneCountryCodes: UInt {
9 | case unitedStates = 1
10 | case brazil = 55
11 | }
12 |
13 | @objc
14 | public class PhoneNumberValidator: NSObject {
15 |
16 | @objc
17 | public func isValidForRegistration(phoneNumber: PhoneNumber) -> Bool {
18 | guard let countryCode = phoneNumber.getCountryCode() else {
19 | return false
20 | }
21 |
22 | guard let validatedCountryCode = ValidatedPhoneCountryCodes(rawValue: countryCode.uintValue) else {
23 | // no extra validation for this country
24 | return true
25 | }
26 |
27 | switch validatedCountryCode {
28 | case .brazil:
29 | return isValidForBrazilRegistration(phoneNumber: phoneNumber)
30 | case .unitedStates:
31 | return isValidForUnitedStatesRegistration(phoneNumber: phoneNumber)
32 | }
33 | }
34 |
35 | let validBrazilPhoneNumberRegex = try! NSRegularExpression(pattern: "^\\+55\\d{2}9?\\d{8}$", options: [])
36 | private func isValidForBrazilRegistration(phoneNumber: PhoneNumber) -> Bool {
37 | let e164 = phoneNumber.toE164()
38 | return validBrazilPhoneNumberRegex.hasMatch(input: e164)
39 | }
40 |
41 | let validUnitedStatesPhoneNumberRegex = try! NSRegularExpression(pattern: "^\\+1\\d{10}$", options: [])
42 | private func isValidForUnitedStatesRegistration(phoneNumber: PhoneNumber) -> Bool {
43 | let e164 = phoneNumber.toE164()
44 | return validUnitedStatesPhoneNumberRegex.hasMatch(input: e164)
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/neontribe-club/session4/agenda-s4.md:
--------------------------------------------------------------------------------
1 | # Code Reading Club agenda
2 |
3 | - Try to find someone else to take notes. Karl?
4 | - Split into 2 groups for 1st half (either geographical or by coding experience)
5 | - Discuss the independent findings
6 |
7 | ## Reflection (5 mins)
8 | - Note a time the past 2 weeks when you used one of the techniques from the club in your work
9 | - Note a time the past 2 weeks when you used information learned about code in your work
10 |
11 | ## Exercises
12 | At the start everyone should look at the same code, but as the club evolves you can tackle a bigger bit of code by splitting into sections. These exercises are best carried out when the code can fit on one or two pages but with it being the norm to split in many ways - we hope to invent and discover different exercises.
13 |
14 | You will need:
15 | - two printed copies of the code for today's club
16 | - some graph paper - or coloured paper and scissors - or acetate and something to write on it with
17 | - coloured pens, crayons or pencils
18 |
19 | ### Interaction with code (10 mins)
20 | 1. Colour1 the variables - circle and draw links between instatiation and all uses
21 | 1. Colour2 the method/ function calls - circle and draw links between declarations and calls
22 | 1. Colour3 the classes - circle and draw links between classes and their instances
23 | 1. Draw the indentaiton patterns - There are a few ways to do this. Fill over with black sharpie. Trace on graph paper. Trace on acetate. etc?
24 |
25 | #### Discuss the results (10 mins)
26 | 1. What patterns are visible from the colors and indentations only?
27 | 1. What parts of the code warrant more attention based on the colors and indentation?
28 |
29 | ### Content
30 |
31 | #### Identify (10 mins)
32 | 1. Define what it means to be important and independently identify the 5 lines you consider most important
33 | 1. Discuss in the group:
34 | - lines covered by many people?
35 | - lines named but not by a lot of people
36 | - Agree less than 10 of the most important lines
37 |
38 | #### Discuss (10 mins)
39 | Take turns in the group, and let every member talk about the code for 30 seconds (or less/more, could also be one sentence each). Try to add new information and not repeat things that have been said, and repeat until people do not know new things anymore.
40 | [Save the last word for me protocol](https://lead.nwp.org/knowledgebase/save-the-last-word-for-me-protocol/)
41 |
42 | #### Summarize in less than 10 sentences (10 mins)
43 | 1. Independently write down the essence of the code in a few sentences
44 | 1. Discuss in the group
45 | - topics covered by many vs few
46 | - strategies used to create the summary (e.g. method names, documentation, variable names, prior knowledge of system)
47 | 1. Create a summary together
48 | 1. Compare the summary with the available documentation (inside and outside the code)
49 | - identify differences and similarities between the groups findings and the existing
50 |
51 |
52 | ## Wash up (5 mins)
53 | - What worked well
54 | - What worked badly
55 |
56 | ## Follow up (2 weeks of elapsed time)
57 | - Identify code for next session, keaping in mind Wash up and Reflection information
58 |
59 |
60 |
--------------------------------------------------------------------------------
/neontribe-club/session4/neontribe_code_reading_club_session_4_notes.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neontribe/code-reading-club/c3baf98c0d517ec7c7b9f09addee7f0cd3cca71f/neontribe-club/session4/neontribe_code_reading_club_session_4_notes.pdf
--------------------------------------------------------------------------------
/neontribe-club/session4/neontribe_code_reading_club_session_4_notes.txt:
--------------------------------------------------------------------------------
1 | {\rtf1\ansi\ansicpg1252\cocoartf2511
2 | \cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fswiss\fcharset0 Helvetica-Bold;\f1\fswiss\fcharset0 Helvetica;}
3 | {\colortbl;\red255\green255\blue255;\red5\green61\blue204;\red251\green2\blue255;\red0\green0\blue0;
4 | \red102\green0\blue141;}
5 | {\*\expandedcolortbl;;\cssrgb\c0\c33896\c83855;\cssrgb\c100000\c25279\c100000;\cssrgb\c0\c0\c0;
6 | \cssrgb\c48169\c12809\c62212;}
7 | {\*\listtable{\list\listtemplateid1\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid1\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{hyphen\}}{\leveltext\leveltemplateid2\'01\uc0\u8259 ;}{\levelnumbers;}\fi-360\li1440\lin1440 }{\listname ;}\listid1}
8 | {\list\listtemplateid2\listhybrid{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{decimal\}.}{\leveltext\leveltemplateid101\'02\'00.;}{\levelnumbers\'01;}\fi-360\li720\lin720 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{hyphen\}}{\leveltext\leveltemplateid102\'01\uc0\u8259 ;}{\levelnumbers;}\fi-360\li1440\lin1440 }{\listname ;}\listid2}}
9 | {\*\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}{\listoverride\listid2\listoverridecount0\ls2}}
10 | \paperw11900\paperh16840\margl1440\margr1440\vieww21120\viewh21300\viewkind0
11 | \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0
12 |
13 | \f0\b\fs32 \cf0 Session 4
14 | \f1\b0\fs24 \
15 |
16 | \fs28 \ul Number of participants: 8\
17 | Code sample language: Swift\
18 |
19 | \fs24 \ulnone \
20 |
21 | \fs26 \ul Reflection
22 | \fs24 \ulnone \
23 | -> not in work, but talking about/promoting the idea of reading code to other developers who acknowledged that is a great initiative\
24 | -> making my comments less noisy - not new but a visual reminder of what that can do to a codebase\
25 | -> thinking about a problem I was facing - and I found myself thinking if navigating the whole code base not just a snippet could be useful (e.g. a small application, regardless of the language)\
26 | -> doing refactoring by looking at the core functionality - similar to the exercise where we identify the the most important lines of code\
27 | \
28 |
29 | \fs26 \ul Interaction with code
30 | \fs24 \ulnone \
31 | - interaction with code - the more experienced devs recognised what this file is about\
32 | - colouring - some people are not that invested \
33 | - colouring for others helps clarify the code, make it less fuzzy and draw connections\
34 | - difference between function and method -> code that warrants more attention\
35 | - helpful if we can discuss what this code does first before we delve into dissecting it\
36 | \
37 |
38 | \fs26 \ul Content
39 | \fs24 \ulnone \
40 | - lines covered by many people (line - number of people who selected that): \
41 | \pard\tx940\tx1440\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li1440\fi-1440\pardirnatural\partightenfactor0
42 | \ls1\ilvl1\cf0 {\listtext \uc0\u8259 }8 - 4\
43 | {\listtext \uc0\u8259 }17 - 4\
44 | {\listtext \uc0\u8259 }18 - 4\
45 | {\listtext \uc0\u8259 }
46 | \f0\b\fs28 \cf2 22 - 5
47 | \f1\b0\fs24 \cf0 \
48 | {\listtext \uc0\u8259 }27 - 4\
49 | {\listtext \uc0\u8259 }
50 | \f0\b\fs28 \cf3 5 - 1
51 | \fs24 \
52 | \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0
53 | \cf4 The most important lines: agreed that those covered by many people - 22, 8, 17, 18, and 27 - are the most important ones. \
54 | \
55 | \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0
56 |
57 | \f1\b0\fs26 \cf0 \ul \ulc0 Content discussion
58 | \fs24 \ulnone \
59 | \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0
60 | \cf0 - line 24 - any case that is not Brazil or US - (why are these so special and why are other countries phone number not validated)?\
61 | - this is code from he Signal messenger app - {\field{\*\fldinst{HYPERLINK "https://signal.org"}}{\fldrslt https://signal.org}} - and that fact that is so well encrypted makes it widely used by those attending public protests\
62 | - so it might be that these lines are meant to filter out phone numbers from US and Brazil for further encryption/protection against tracking? \
63 | \
64 | - line 18 elicits a discussion - what it does, construct -
65 | \f0\b \cf5 \expnd0\expndtw0\kerning0
66 | \outl0\strokewidth0 \strokec4 guard let countryCode = phoneNumber.getCountryCode() else \{return false\}
67 | \f1\b0 \cf0 \kerning1\expnd0\expndtw0 \outl0\strokewidth0 \
68 | - enums are very useful - analogy with code in games\
69 | \
70 |
71 | \fs26 \ul Summary\
72 |
73 | \fs24 \ulnone - skipped to save time \
74 | - Uint - data type declaration (unsigned integer)\
75 | \
76 |
77 | \fs26 \ul Wash up
78 | \fs24 \ulnone \
79 | \pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural\partightenfactor0
80 | \ls2\ilvl0\cf0 {\listtext 1. }What worked well \
81 | \pard\tx940\tx1440\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li1440\fi-1440\pardirnatural\partightenfactor0
82 | \ls2\ilvl1\cf0 {\listtext \uc0\u8259 }good, clean piece of code, as every week we look at different code (language wise) \
83 | {\listtext \uc0\u8259 }seemingly simple lines of code but more challenging than thought\
84 | {\listtext \uc0\u8259 }reflection brought up quite a few uses about the information/techniques learned from previous sessions\
85 | \pard\tx220\tx720\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li720\fi-720\pardirnatural\partightenfactor0
86 | \ls2\ilvl0\cf0 {\listtext 2. }What worked badly\
87 | \pard\tx940\tx1440\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li1440\fi-1440\pardirnatural\partightenfactor0
88 | \ls2\ilvl1\cf0 {\listtext \uc0\u8259 }didn\'92t stick to the agenda and we tend to spend more time on certain parts (perhaps this tells us something about the group dynamic and maybe the agenda should be tailored to meet the group\'92s needs?); \
89 | {\listtext \uc0\u8259 }for beginners, some technical chat between more experienced developers was confusing/difficult to follow especially when not indicating the number of the code line in reference\
90 | \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0
91 | \cf0 \
92 |
93 | \fs26 \ul Follow up\
94 | \ulnone - Charlie volunteered to supply next session\'92s code samples}
--------------------------------------------------------------------------------
/neontribe-club/session5/agenda-s5.md:
--------------------------------------------------------------------------------
1 | # Code Reading Club agenda
2 |
3 | - Try to find someone else to take notes. Karl?
4 | - Split into 2 groups for 1st half (either geographical or by coding experience)
5 | - Discuss the independent findings
6 |
7 | ## Reflection (5 mins)
8 | - Note a time the past 2 weeks when you used one of the techniques from the club in your work
9 | - Note a time the past 2 weeks when you used information learned about code in your work
10 |
11 | ## Exercises
12 | At the start everyone should look at the same code, but as the club evolves you can tackle a bigger bit of code by splitting into sections. These exercises are best carried out when the code can fit on one or two pages but with it being the norm to split in many ways - we hope to invent and discover different exercises.
13 |
14 | You will need:
15 | - two printed copies of the code for today's club
16 | - some graph paper - or coloured paper and scissors - or acetate and something to write on it with
17 | - coloured pens, crayons or pencils
18 |
19 | ### Interaction with code (10 mins)
20 | 1. Colour1 the variables - circle and draw links between instatiation and all uses
21 | 1. Colour2 the method/ function calls - circle and draw links between declarations and calls
22 | 1. Colour3 the classes - circle and draw links between classes and their instances
23 | 1. Draw the indentaiton patterns - There are a few ways to do this. Fill over with black sharpie. Trace on graph paper. Trace on acetate. etc?
24 |
25 | #### Discuss the results (10 mins)
26 | 1. What patterns are visible from the colors and indentations only?
27 | 1. What parts of the code warrant more attention based on the colors and indentation?
28 |
29 | ### Content
30 |
31 | #### Identify (10 mins)
32 | 1. Define what it means to be important and independently identify the 5 lines you consider most important
33 | 1. Discuss in the group:
34 | - lines covered by many people?
35 | - lines named but not by a lot of people
36 | - Agree less than 10 of the most important lines
37 |
38 | #### Discuss (10 mins)
39 | Take turns in the group, and let every member talk about the code for 30 seconds (or less/more, could also be one sentence each). Try to add new information and not repeat things that have been said, and repeat until people do not know new things anymore.
40 | [Save the last word for me protocol](https://lead.nwp.org/knowledgebase/save-the-last-word-for-me-protocol/)
41 |
42 | #### Summarize in less than 10 sentences (10 mins)
43 | 1. Independently write down the essence of the code in a few sentences
44 | 1. Discuss in the group
45 | - topics covered by many vs few
46 | - strategies used to create the summary (e.g. method names, documentation, variable names, prior knowledge of system)
47 | 1. Create a summary together
48 | 1. Compare the summary with the available documentation (inside and outside the code)
49 | - identify differences and similarities between the groups findings and the existing
50 |
51 |
52 | ## Wash up (5 mins)
53 | - What worked well
54 | - What worked badly
55 |
56 | ## Follow up (2 weeks of elapsed time)
57 | - Identify code for next session, keaping in mind Wash up and Reflection information
58 |
59 |
60 |
--------------------------------------------------------------------------------
/neontribe-club/session5/completedExercises/code-club-5-marked.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neontribe/code-reading-club/c3baf98c0d517ec7c7b9f09addee7f0cd3cca71f/neontribe-club/session5/completedExercises/code-club-5-marked.jpg
--------------------------------------------------------------------------------
/neontribe-club/session5/completedExercises/code-club-5-marked2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neontribe/code-reading-club/c3baf98c0d517ec7c7b9f09addee7f0cd3cca71f/neontribe-club/session5/completedExercises/code-club-5-marked2.jpg
--------------------------------------------------------------------------------
/neontribe-club/session5/ssh_key.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | # This Source Code Form is subject to the terms of the Mozilla Public
4 | # License, v. 2.0. If a copy of the MPL was not distributed with this
5 | # file, You can obtain one at https://mozilla.org/MPL/2.0/.
6 | # Copyright (c) 2017 Mozilla Corporation
7 |
8 | from lib.alerttask import AlertTask
9 | from mozdef_util.query_models import SearchQuery, TermMatch
10 | import re
11 | import os
12 |
13 | # This alert consumes data produced by the MIG sshkey module and mig-runner.
14 | # ssh key related events are compared against a whitelist which is the
15 | # alerts configuration file (sshkey.conf). The format of this whitelist
16 | # is as follows:
17 | #
18 | #
19 | #
20 | # If a host matches the regex, and the detected key matches the path, the
21 | # alert will not generate an alert event. If the detected key is not in
22 | # the whitelist, an alert will be created.
23 |
24 |
25 | class SSHKey(AlertTask):
26 | def __init__(self):
27 | # _whitelist contains all whitelisted key paths, loaded from the
28 | # configuration file for the alert plugin
29 | self._whitelist = []
30 |
31 | AlertTask.__init__(self)
32 | self._parse_whitelist('ssh_key.conf')
33 |
34 | def main(self):
35 | search_query = SearchQuery(minutes=30)
36 |
37 | search_query.add_must([
38 | TermMatch('category', 'event'),
39 | TermMatch('tags', 'mig-runner-sshkey')
40 | ])
41 |
42 | self.filtersManual(search_query)
43 |
44 | self.searchEventsSimple()
45 | self.walkEvents()
46 |
47 | # Load whitelist from file system and store in object, path specifies the
48 | # path to load the whitelist from
49 | def _parse_whitelist(self, path):
50 | full_config_filename = os.path.join(os.path.dirname(__file__), path)
51 | with open(full_config_filename) as fd:
52 | lns = [x.strip() for x in fd.readlines()]
53 | for entry in lns:
54 | try:
55 | pindex = entry.index(' ')
56 | except ValueError:
57 | continue
58 | self._whitelist.append({
59 | 'hostre': entry[:pindex],
60 | 'path': entry[pindex + 1:]
61 | })
62 |
63 | # Return false if the key path is present in the whitelist, otherwise return
64 | # true
65 | def _whitelist_check(self, hostname, privkey):
66 | for went in self._whitelist:
67 | try:
68 | rem = re.compile(went['hostre'])
69 | except:
70 | continue
71 | if rem.match(hostname) is None:
72 | continue
73 | if privkey['path'] == went['path']:
74 | return False
75 | return True
76 |
77 | def onEvent(self, event):
78 | # Each event could potentially contain a number of identified private keys, since
79 | # mig-runner will send an event per host. Compare the private keys in the event
80 | # to the keys in the whitelist, if any are missing from the whitelist we will include
81 | # the paths in an alert and return the alert, otherwise no alert is returned.
82 | ev = event['_source']
83 |
84 | if 'details' not in ev:
85 | return None
86 | if 'private' not in ev['details'] or 'agent' not in ev['details']:
87 | return None
88 | hostname = ev['details']['agent']
89 | alertkeys = [x for x in ev['details']['private'] if self._whitelist_check(hostname, x)]
90 | if len(alertkeys) == 0:
91 | return None
92 |
93 | category = 'sshkey'
94 | tags = ['sshkey']
95 | severity = 'WARNING'
96 | summary = 'Private keys detected on {} missing from whitelist'.format(hostname)
97 | ret = self.createAlertDict(summary, category, tags, [event], severity)
98 | ret['details'] = {
99 | 'private': alertkeys
100 | }
101 | return ret
--------------------------------------------------------------------------------
/neontribe-club/session6/agenda-s6.md:
--------------------------------------------------------------------------------
1 | # Code Reading Club agenda
2 |
3 | - Try to find someone else to take notes. Karl?
4 | - Split into 2 groups for 1st half (either geographical or by coding experience)
5 | - Discuss the independent findings
6 |
7 | ## Reflection (5 mins)
8 | - Note a time the past 2 weeks when you used one of the techniques from the club in your work
9 | - Note a time the past 2 weeks when you used information learned about code in your work
10 |
11 | ## Exercises
12 | At the start everyone should look at the same code, but as the club evolves you can tackle a bigger bit of code by splitting into sections. These exercises are best carried out when the code can fit on one or two pages but with it being the norm to split in many ways - we hope to invent and discover different exercises.
13 |
14 | You will need:
15 | - two printed copies of the code for today's club
16 | - some graph paper - or coloured paper and scissors - or acetate and something to write on it with
17 | - coloured pens, crayons or pencils
18 |
19 | ### Interaction with code (10 mins)
20 | 1. Colour1 the variables - circle and draw links between instatiation and all uses
21 | 1. Colour2 the method/ function calls - circle and draw links between declarations and calls
22 | 1. Colour3 the classes - circle and draw links between classes and their instances
23 | 1. Draw the indentaiton patterns - There are a few ways to do this. Fill over with black sharpie. Trace on graph paper. Trace on acetate. etc?
24 |
25 | #### Discuss the results (10 mins)
26 | 1. What patterns are visible from the colors and indentations only?
27 | 1. What parts of the code warrant more attention based on the colors and indentation?
28 |
29 | ### Content
30 |
31 | #### Identify (10 mins)
32 | 1. Define what it means to be important and independently identify the 5 lines you consider most important
33 | 1. Discuss in the group:
34 | - lines covered by many people?
35 | - lines named but not by a lot of people
36 | - Agree less than 10 of the most important lines
37 |
38 | #### Discuss (10 mins)
39 | Take turns in the group, and let every member talk about the code for 30 seconds (or less/more, could also be one sentence each). Try to add new information and not repeat things that have been said, and repeat until people do not know new things anymore.
40 | [Save the last word for me protocol](https://lead.nwp.org/knowledgebase/save-the-last-word-for-me-protocol/)
41 |
42 | #### Summarize in less than 10 sentences (10 mins)
43 | 1. Independently write down the essence of the code in a few sentences
44 | 1. Discuss in the group
45 | - topics covered by many vs few
46 | - strategies used to create the summary (e.g. method names, documentation, variable names, prior knowledge of system)
47 | 1. Create a summary together
48 | 1. Compare the summary with the available documentation (inside and outside the code)
49 | - identify differences and similarities between the groups findings and the existing
50 |
51 |
52 | ## Wash up (5 mins)
53 | - What worked well
54 | - What worked badly
55 |
56 | ## Follow up (2 weeks of elapsed time)
57 | - Identify code for next session, keaping in mind Wash up and Reflection information
58 |
--------------------------------------------------------------------------------
/neontribe-club/session6/completedExercises/code-sample-marked-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neontribe/code-reading-club/c3baf98c0d517ec7c7b9f09addee7f0cd3cca71f/neontribe-club/session6/completedExercises/code-sample-marked-1.jpg
--------------------------------------------------------------------------------
/neontribe-club/session6/completedExercises/code-sample-marked-2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neontribe/code-reading-club/c3baf98c0d517ec7c7b9f09addee7f0cd3cca71f/neontribe-club/session6/completedExercises/code-sample-marked-2.jpg
--------------------------------------------------------------------------------
/neontribe-club/session6/example_code.html.haml:
--------------------------------------------------------------------------------
1 | .icon-bar.seven-up
2 | = link_to edit_admin_workshop_path(@workshop), class: 'item' do
3 | %i.fa.fa-pencil
4 | %label Edit
5 | - if !@workshop.date_and_time.future?
6 | = link_to '#', class: 'item disabled', title: 'The event has already taken place' do
7 | %i.fa.fa-send-o
8 | %label Invite
9 | - elsif (@workshop.has_valid_host? || @workshop.virtual?) and @workshop.invitable?
10 | = link_to admin_workshop_send_invites_path(@workshop), class: 'item' do
11 | %i.fa.fa-send-o
12 | %label Invite
13 | - else
14 | = link_to '#', class: 'item disabled', title: t('admin.workshop.not_invitable.') do
15 | %i.fa.fa-send-o
16 | %label Invite
17 | = link_to admin_workshop_path(format: 'csv'), class: 'item', title: 'CSV for pairing' do
18 | %i.fa.fa-users
19 | %label Pairing CSV
20 | = link_to admin_workshop_path(type: 'labels', format: 'csv'), class: 'item', title: 'CSV for labels' do
21 | %i.fa.fa-users
22 | %label Labels
23 | = link_to admin_workshop_attendees_checklist_path(@workshop, format: 'text'), title: 'Attendee checklist', class: 'item' do
24 | %i.fa.fa-list-ul
25 | %label Attendees
26 | = link_to admin_workshop_attendees_emails_path(@workshop, format: 'text'), title: 'Attendee emails', class: 'item' do
27 | %i.fa.fa-at
28 | %label Emails
29 | = link_to admin_workshop_path(@workshop), method: :delete, data: { confirm: 'Are you sure you want to delete this workshop?' }, title: 'Destroy workshop', class: 'item' do
30 | %i.fa.fa-remove
31 | %label Destroy
32 |
33 |
34 | %section
35 | .stripe.reverse
36 | .row
37 | .medium-12.columns
38 | %h2
39 | = @workshop.to_s
40 | = link_to [:admin, @workshop.chapter] do
41 | %small=@workshop.chapter.name
42 | %h3
43 | %small #{l(@workshop.date_and_time, format: :dashboard)} #{@workshop.start_and_end_time}
44 | - if @workshop.rsvp_opens_at
45 | RSVPs will open at
46 | = @workshop.rsvp_opens_at.strftime('%H:%M on %d/%m/%Y.')
47 | %br
48 | %br
49 | - if @workshop.venue.present? || @workshop.virtual?
50 | %strong.label.round.primary #{@workshop.student_spaces} student spots, #{@workshop.coach_spaces} coach spots
51 | - unless @workshop.spaces?
52 | %label.label.round.warning Full
53 | - if !@workshop.invitable?
54 | %br
55 | %p
56 | %label.label.info= t('admin.workshop.not_invitable')
57 | %p.description
58 | %br
59 | = sanitize(@workshop.description)
60 | - if @workshop.virtual?
61 | .row
62 | .large-12.small-6.columns#slack-details
63 | .panel.callout
64 | %h5= t('admin.workshop.virtual.details.title')
65 | %p
66 | %strong="#{t('admin.workshop.virtual.details.slack')}:"
67 | #{link_to("##{@workshop.slack_channel}", @workshop.slack_channel_link)}
68 | %br
69 | %strong="#{t('admin.workshop.virtual.details.discord')}:"
70 | #{link_to(t('social_media_links.discord_invitation'), t('social_media_links.discord_invitation'))}
71 | %br
72 | %br
73 | #{t('admin.workshop.virtual.details.more_html', slack_channel: link_to('#organisers', 'https://codebar.slack.com/archives/G08CQ5KFD'))}
74 |
75 | %br
76 | .row
77 | .large-3.small-6.columns#host
78 | - if @workshop.venue.present?
79 | %h4 Venue
80 | %strong= @workshop.venue.name
81 | %br
82 | %small= @workshop.address.to_html
83 | .large-3.small-6.columns#sponsors
84 | - if (@workshop.sponsors - [@workshop.host]).any?
85 | %h4 Sponsors
86 | %ul.no-bullet
87 | - (@workshop.sponsors - [@workshop.host]).each do |sponsor|
88 | %li
89 | %span
90 | = link_to sponsor.name, [:admin, sponsor]
91 | .large-6.small-12.columns
92 | %h4 Team
93 | - @workshop.organisers.each do |organiser|
94 | %span.has-tip{ 'data-tooltip': '', 'aria-haspopup': 'true', title: organiser.full_name }
95 | = image_tag(organiser.avatar(40), alt: organiser.full_name)
96 |
97 | .stripe.reverse#invitations
98 | = render partial: 'invitation_management'
99 |
--------------------------------------------------------------------------------
/neontribe-club/session6/washup:
--------------------------------------------------------------------------------
1 | ## Good
2 | - Interesting code choice, challenged more experienced developers!
3 |
4 | ## Bad
5 | - time :-( we always overrun
6 |
7 | ## Ugly
8 | - no printer! need to have a section on diigtal marking and colouring code
9 |
--------------------------------------------------------------------------------
/neontribe-club/session7/Example.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using UnityEngine;
3 | using UnityStandardAssets.CrossPlatformInput;
4 |
5 | namespace UnityStandardAssets.Characters.ThirdPerson
6 | {
7 | [RequireComponent(typeof (ThirdPersonCharacter))]
8 | public class ThirdPersonUserControl : MonoBehaviour
9 | {
10 | private ThirdPersonCharacter m_Character; // A reference to the ThirdPersonCharacter on the object
11 | private Transform m_Cam; // A reference to the main camera in the scenes transform
12 | private Vector3 m_CamForward; // The current forward direction of the camera
13 | private Vector3 m_Move;
14 | private bool m_Jump; // the world-relative desired move direction, calculated from the camForward and user input.
15 |
16 |
17 | private void Start()
18 | {
19 | // get the transform of the main camera
20 | if (Camera.main != null)
21 | {
22 | m_Cam = Camera.main.transform;
23 | }
24 | else
25 | {
26 | Debug.LogWarning(
27 | "Warning: no main camera found. Third person character needs a Camera tagged \"MainCamera\", for camera-relative controls.", gameObject);
28 | // we use self-relative controls in this case, which probably isn't what the user wants, but hey, we warned them!
29 | }
30 |
31 | // get the third person character ( this should never be null due to require component )
32 | m_Character = GetComponent();
33 | }
34 |
35 |
36 | private void Update()
37 | {
38 | if (!m_Jump)
39 | {
40 | m_Jump = CrossPlatformInputManager.GetButtonDown("Jump");
41 | }
42 | }
43 |
44 |
45 | // Fixed update is called in sync with physics
46 | private void FixedUpdate()
47 | {
48 | // read inputs
49 | float h = CrossPlatformInputManager.GetAxis("Horizontal");
50 | float v = CrossPlatformInputManager.GetAxis("Vertical");
51 | bool crouch = Input.GetKey(KeyCode.C);
52 |
53 | // calculate move direction to pass to character
54 | if (m_Cam != null)
55 | {
56 | // calculate camera relative direction to move:
57 | m_CamForward = Vector3.Scale(m_Cam.forward, new Vector3(1, 0, 1)).normalized;
58 | m_Move = v*m_CamForward + h*m_Cam.right;
59 | }
60 | else
61 | {
62 | // we use world-relative directions in the case of no main camera
63 | m_Move = v*Vector3.forward + h*Vector3.right;
64 | }
65 | #if !MOBILE_INPUT
66 | // walk speed multiplier
67 | if (Input.GetKey(KeyCode.LeftShift)) m_Move *= 0.5f;
68 | #endif
69 |
70 | // pass all parameters to the character control script
71 | m_Character.Move(m_Move, crouch, m_Jump);
72 | m_Jump = false;
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/neontribe-club/session7/agenda-s7.md:
--------------------------------------------------------------------------------
1 | # Code Reading Club agenda
2 |
3 | ### Reflection (5 mins)
4 |
5 | - Between sessions, note times when you notice that code reading club has helped you in your other projects or conversations.
6 |
7 | ## Code structure
8 |
9 | ### First glance
10 |
11 | The goal of this exercise is to practice to get a first impression of code and to act upon that.
12 |
13 | #### Look at the code (1 min)
14 |
15 | Look at the code at a glance, really not more than 1 minute. Then try to answer these questions:
16 |
17 | - What is the first thing that catches your eye? Why is that?
18 |
19 | - What is the *second* think that you see? Why?
20 |
21 | - Are these two things (variables, classes, programming concepts) related?
22 |
23 | #### Discuss the results (5 mins)
24 |
25 | Discuss the results as a group. What lines of facts or concepts were chosen by everyone versus by only a few people?
26 |
27 | Reflect also on what kind of knowledge did you use in this exercise? Knowledge of the domain, of the programming language? Of a framework? What knowledge do you think might be needed to better understand this code?
28 |
29 |
30 | ### Examine structure (10 mins)
31 | The goal of this exercise is to be a concrete thing to *do* when looking at new code for the first time. New code can be scary, doing something will help!
32 |
33 | Color variables
34 |
35 | * Go through the code and circle all variables in red
36 | * Then draw a link between variables and their uses
37 |
38 | Color method/function calls
39 |
40 | * Go through the code and circle all methods in blue
41 | * Then draw a link between methods and their invocations
42 |
43 | Instantiation
44 |
45 | * Go through the code and circle all instances of classes in green
46 | * Then draw a link between classes and their instances
47 |
48 | #### Discuss the results (10 mins)
49 | 1. What patterns are visible from the colors and links only?
50 | 1. What parts of the code warrant more attention based on the colors?
51 | 1. What strategy did you use to identify the different types of element?
52 |
53 | ## Content
54 |
55 | ### All variable/class/method names (5 mins)
56 |
57 | Go through the code mechanically and create a list of all identifier names in the snippet. Of you have done the "examine structure" exercise before, this should be relatively quick and easy.
58 |
59 | #### Discussion (5 mins)
60 |
61 | Discuss in the group:
62 |
63 | - What can we learn from these names?
64 | - Which names are related to each other, from the names only?
65 | - Are there names that are ambiguous when looked at without context?
66 |
67 | ### Identify most important lines (5 mins)
68 | Independently identify the 5 lines you consider most important.
69 |
70 | #### Discussion (10 mins)
71 | Discuss in the group:
72 |
73 | - lines covered by many people?
74 | - lines named but not by a lot of people
75 | - What strategy did you use to identify importance?
76 | - Agree less than 10 of the most important lines
77 |
78 | Take turns in the group, and let every member talk about the code for 30 seconds (or less/more, could also be one sentence each). Try to add new information and not repeat things that have been said, and repeat until people do not know new things anymore.
79 |
80 | #### Summarize in less than 10 sentences individually (5 mins)
81 |
82 | 1. Independently write down the essence of the code in a few sentences
83 |
84 | #### Discussion (10 mins)
85 |
86 | - topics covered by many vs few
87 | - strategies used to create the summary (e.g. method names, documentation, variable names, prior knowledge of system)
88 |
89 | #### Summarize in less than 10 sentences (5 mins)
90 |
91 | 1. Create a summary together
92 | 1. Compare the summary with the available documentation (inside and outside the code)
93 |
94 | - identify differences and similarities between the groups findings and the existing
95 |
96 | ## Wash up (5 mins)
97 |
98 | - What worked well
99 | - What worked badly
100 |
--------------------------------------------------------------------------------
/neontribe-club/session8/Example.rs:
--------------------------------------------------------------------------------
1 | //! # Bump frame allocator
2 | //! Some code was borrowed from [Phil Opp's Blog](http://os.phil-opp.com/allocating-frames.html)
3 |
4 | use crate::paging::PhysicalAddress;
5 |
6 | use super::{Frame, FrameAllocator, MemoryArea, MemoryAreaIter};
7 |
8 |
9 | pub struct BumpAllocator {
10 | next_free_frame: Frame,
11 | current_area: Option<&'static MemoryArea>,
12 | areas: MemoryAreaIter,
13 | kernel_start: Frame,
14 | kernel_end: Frame
15 | }
16 |
17 | impl BumpAllocator {
18 | pub fn new(kernel_start: usize, kernel_end: usize, memory_areas: MemoryAreaIter) -> Self {
19 | let mut allocator = Self {
20 | next_free_frame: Frame::containing_address(PhysicalAddress::new(0)),
21 | current_area: None,
22 | areas: memory_areas,
23 | kernel_start: Frame::containing_address(PhysicalAddress::new(kernel_start)),
24 | kernel_end: Frame::containing_address(PhysicalAddress::new(kernel_end))
25 | };
26 | allocator.choose_next_area();
27 | allocator
28 | }
29 |
30 | fn choose_next_area(&mut self) {
31 | self.current_area = self.areas.clone().filter(|area| {
32 | let address = area.base_addr + area.length - 1;
33 | Frame::containing_address(PhysicalAddress::new(address as usize)) >= self.next_free_frame
34 | }).min_by_key(|area| area.base_addr);
35 |
36 | if let Some(area) = self.current_area {
37 | let start_frame = Frame::containing_address(PhysicalAddress::new(area.base_addr as usize));
38 | if self.next_free_frame < start_frame {
39 | self.next_free_frame = start_frame;
40 | }
41 | }
42 | }
43 | }
44 |
45 | impl FrameAllocator for BumpAllocator {
46 | #[allow(unused)]
47 | fn set_noncore(&mut self, noncore: bool) {}
48 |
49 | fn free_frames(&self) -> usize {
50 | let mut count = 0;
51 |
52 | for area in self.areas.clone() {
53 | let start_frame = Frame::containing_address(PhysicalAddress::new(area.base_addr as usize));
54 | let end_frame = Frame::containing_address(PhysicalAddress::new((area.base_addr + area.length - 1) as usize));
55 | for frame in Frame::range_inclusive(start_frame, end_frame) {
56 | if frame >= self.kernel_start && frame <= self.kernel_end {
57 | // Inside of kernel range
58 | } else if frame >= self.next_free_frame {
59 | // Frame is in free range
60 | count += 1;
61 | } else {
62 | // Inside of used range
63 | }
64 | }
65 | }
66 |
67 | count
68 | }
69 |
70 | fn used_frames(&self) -> usize {
71 | let mut count = 0;
72 |
73 | for area in self.areas.clone() {
74 | let start_frame = Frame::containing_address(PhysicalAddress::new(area.base_addr as usize));
75 | let end_frame = Frame::containing_address(PhysicalAddress::new((area.base_addr + area.length - 1) as usize));
76 | for frame in Frame::range_inclusive(start_frame, end_frame) {
77 | if frame >= self.kernel_start && frame <= self.kernel_end {
78 | // Inside of kernel range
79 | count += 1
80 | } else if frame >= self.next_free_frame {
81 | // Frame is in free range
82 | } else {
83 | count += 1;
84 | }
85 | }
86 | }
87 |
88 | count
89 | }
90 |
91 | fn allocate_frames(&mut self, count: usize) -> Option {
92 | if count == 0 {
93 | None
94 | } else if let Some(area) = self.current_area {
95 | // "Clone" the frame to return it if it's free. Frame doesn't
96 | // implement Clone, but we can construct an identical frame.
97 | let start_frame = Frame{ number: self.next_free_frame.number };
98 | let end_frame = Frame { number: self.next_free_frame.number + (count - 1) };
99 |
100 | // the last frame of the current area
101 | let current_area_last_frame = {
102 | let address = area.base_addr + area.length - 1;
103 | Frame::containing_address(PhysicalAddress::new(address as usize))
104 | };
105 |
106 | if end_frame > current_area_last_frame {
107 | // all frames of current area are used, switch to next area
108 | self.choose_next_area();
109 | } else if (start_frame >= self.kernel_start && start_frame <= self.kernel_end)
110 | || (end_frame >= self.kernel_start && end_frame <= self.kernel_end) {
111 | // `frame` is used by the kernel
112 | self.next_free_frame = Frame {
113 | number: self.kernel_end.number + 1
114 | };
115 | } else {
116 | // frame is unused, increment `next_free_frame` and return it
117 | self.next_free_frame.number += count;
118 | return Some(start_frame);
119 | }
120 | // `frame` was not valid, try it again with the updated `next_free_frame`
121 | self.allocate_frames(count)
122 | } else {
123 | None // no free frames left
124 | }
125 | }
126 |
127 | fn deallocate_frames(&mut self, _frame: Frame, _count: usize) {
128 | //panic!("BumpAllocator::deallocate_frame: not supported: {:?}", frame);
129 | }
130 | }
131 |
--------------------------------------------------------------------------------
/neontribe-club/session8/Notes.md:
--------------------------------------------------------------------------------
1 | # Code Reading Club Session Notes
2 |
3 | ## Intro: Reflection
4 | ### Has code reading club has helped you in your other projects or conversations?
5 | Not much except from suggesting to a colleague to join the Club due to his practise.
6 |
7 | ## Exercise 1: First glance
8 | ### Look at the code and discuss
9 |
10 | A piece of prep code.
11 | It looks like an object orientated code due to the existence of classes or objects, functions, constructors.
12 | Using familiarity, only one participant guessed it was Rust.
13 | One participant acknowledged that the bump was allocated twice (defined, implemented) which appeared to be important as the frame allocator was imported for the bump allocator.
14 |
15 | ## Exercise 2: Examine the structure
16 | ### Highlight the code and discuss
17 |
18 | - Due to the tool (Miro) some participants struggled to finish the exercise.
19 | - The code seems to consist only of 5 functions but each reference something.
20 | - It is a dynamically constructed object.
21 | - Lots of static things.
22 | - Some participants started the exercise by trying to find variables by looking for keywords.
23 | - It seems it contains a lot of variables.
24 | - Classes seem to be called similar way as PHP with double colon.
25 | - Functions are interesting due to the way they are being called which is inside of themselves.
26 | - For one participant there was not enough time to understand what the code was doing.
27 | - The code has been described by all as “very wordy”.
28 |
29 | ## Exercise 3: Most important lines
30 | ### Identify the most important lines of the code
31 |
32 | Easy agreement on the following lines:
33 | 9
34 | 18
35 | 45
36 | 56 (bounce check of line 55’s validity)
37 | 91
38 | 128 (Comment. If it were to be present in a parent it would mean don’t do anything if you are in panic)
39 |
40 | ### Summarize in less than 10 sentences the essence of the code
41 | Memory allocation. Bump allocator defines how to choose next physical memory area. Frame allocator has functions to help the bump allocator find & make areas it can use.
42 |
43 | ## Wash Up
44 | - Miro – Seems to be a good tool but still is a good tool if we know how to use it
45 | - Layout is good (i.e. each participant has its own frame with its own code sheet and agenda)
46 | - First exercise of glancing the code was pushed to 2min. For one participant it was too long, for another one it was enough.
47 | - For accessibility matter, PDF seems better than Jpeg.
48 | - Facilitator has removed the exercise “create a list of all identifier names in the snippet” due to not knowing how to make it work and ensuring there was time for a wash up.
49 |
50 | ## Code Source
51 | https://gitlab.redox-os.org/redox-os/kernel/-/commit/fe705d9b63173c8e8f31bd6b5bfde8349779df61
52 |
--------------------------------------------------------------------------------
/neontribe-club/session8/agenda-s8.md:
--------------------------------------------------------------------------------
1 | # Code Reading Club agenda
2 |
3 | ## Intro
4 | *{7 min}*
5 |
6 | ### Set up (Facilitator, 2 min)
7 | - Board
8 | - Agenda
9 |
10 | ### Reflection (Group, 5 mins)
11 | *[ 0'50 / 1'00 / 1'25 per person ]*
12 |
13 | - Has code reading club has helped you in your other projects or conversations?
14 |
15 | ## Code structure
16 | *{22 min}*
17 |
18 | ### Exercise 1: First glance (7 min)
19 |
20 | #### Look at the code (Solo, 2 min)
21 |
22 | Look at the code at a glance and try to answer these questions:
23 |
24 | - What is the **first thing** that catches your eye? Why?
25 | - What is the **second thing** that you see? Why?
26 | - Are these two things **related** (variables, classes, programming concepts)?
27 |
28 | #### Discuss the results (Group, 5 mins)
29 | *[ 0'50 / 1'00 / 1'25 per person ]*
30 |
31 | - Everyone vs a few: What lines of facts or concepts were chosen ?
32 |
33 | - What knowledge did you use in this exercise?
34 |
35 |
36 | *Domain, programming language? a framework? What knowledge do you think might be needed to better understand this code?*
37 |
38 |
39 | ### Exercise 2: Examine the structure (15 mins)
40 |
41 | #### Highlight the code (Solo, 5 min)
42 |
43 | * Red for Varibales: Circle and draw links between instatiation and all uses
44 |
45 | * Blue for Method/function calls: Circle and draw links between declarations and calls
46 |
47 | * Green for Classes: Circle and draw links between classes and their instances
48 |
49 |
50 |
51 | #### Discuss the results (Group, 10 mins)
52 | *[ 1'30 / 2'00 / 2'30 per person ]*
53 |
54 | 1. What patterns are visible from the colors and links only?
55 | 2. What parts of the code warrant more attention based on the colors?
56 | 3. What strategy did you use to identify the different types of element?
57 |
58 | ## Content
59 | *{30 min}*
60 |
61 | ### Exercise 3: Most important lines (30 mins)
62 |
63 | #### Identify the most important lines (Solo, 5 mins)
64 |
65 | Independently identify the 5 lines you consider most important.
66 |
67 | #### Discuss the results (Group, 10 mins)
68 | *[ 1'30 / 2'00 / 2'30 per person ]*
69 |
70 | - lines covered by many people?
71 | - lines named but not by a lot of people
72 | - What strategy did you use to identify importance?
73 | - Agree less than 10 of the most important lines
74 |
75 |
76 | #### Summarize in less than 10 sentences (Solo, 5 mins)
77 |
78 | Independently write down the essence of the code in a few sentences
79 |
80 | #### Discuss the results (Group, 10 mins)
81 | *[ 1'30 / 2'00 / 2'30 per person ]*
82 |
83 | - topics covered by many vs few
84 | - strategies used to create the summary (e.g. method names, documentation, variable names, prior knowledge of system)
85 |
86 | #### Summarize in less than 10 sentences (Group, 5 mins)
87 | *[ 0'50 / 1'00 / 1'25 per person ]*
88 |
89 | 1. Create a summary together
90 | 2. Compare the summary with the available documentation (inside and outside the code)
91 |
92 | 3. identify differences and similarities between the groups findings and the existing
93 |
94 | ## Wash up (16 mins)
95 |
96 | - What worked well
97 | - What worked badly
98 |
--------------------------------------------------------------------------------
/neontribe-club/session8/example_code.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neontribe/code-reading-club/c3baf98c0d517ec7c7b9f09addee7f0cd3cca71f/neontribe-club/session8/example_code.pdf
--------------------------------------------------------------------------------
/neontribe-club/session8/example_code.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neontribe/code-reading-club/c3baf98c0d517ec7c7b9f09addee7f0cd3cca71f/neontribe-club/session8/example_code.png
--------------------------------------------------------------------------------
/neontribe-club/sessionX/agenda-s10.md:
--------------------------------------------------------------------------------
1 | # Code Reading Club agenda
2 |
3 | ## Reflection (4 mins)
4 |
5 | - Between sessions, note times when you notice that code reading club has helped you in your other projects or conversations.
6 |
7 | ## First glance (6 minutes)
8 |
9 | The goal of this exercise is to practice to get a first impression of code and to act upon that.
10 |
11 | ### Look at the code (1 min)
12 |
13 | Look at the code at a glance, really not more than 1 minute. Then try to answer these questions:
14 |
15 | - What is the first thing that catches your eye? Why is that?
16 |
17 | - What is the *second* think that you see? Why?
18 |
19 | - Are these two things (variables, classes, programming concepts) related?
20 |
21 | ### Discuss the results (5 mins)
22 |
23 | Discuss the results as a group. What lines of facts or concepts were chosen by everyone versus by only a few people?
24 |
25 | Reflect also on what kind of knowledge did you use in this exercise? Knowledge of the domain, of the programming language? Of a framework? What knowledge do you think might be needed to better understand this code?
26 |
27 | ## Code structure (20 minutes)
28 |
29 | ### Examine structure (10 minutes)
30 | The goal of this exercise is to be a concrete thing to *do* when looking at new code for the first time. New code can be scary, doing something will help!
31 |
32 | Color variables
33 |
34 | * Go through the code and circle all variables in red
35 | * Then draw a link between variables and their uses
36 |
37 | Color method/function calls
38 |
39 | * Go through the code and circle all methods in blue
40 | * Then draw a link between methods and their invocations
41 |
42 | Instantiation
43 |
44 | * Go through the code and circle all instances of classes in green
45 | * Then draw a link between classes and their instances
46 |
47 | ### Discuss the results (10 mins)
48 | 1. What patterns are visible from the colors and links only?
49 | 1. What parts of the code warrant more attention based on the colors?
50 | 1. What strategy did you use to identify the different types of element?
51 |
52 | ## Content (30 minutes)
53 |
54 | ### A random line (5 mins)
55 |
56 | Select a random line from the code in whatever way you like. Examine this line individually. What is the main idea of this line? What lines does it relate to and why?
57 |
58 | ### Discussion (10 mins)
59 |
60 | Discuss in the group:
61 |
62 | * What is the 'scope' of the random line? What part of the code was seen as related?
63 | * How does the line fit into the rest of the code base?
64 |
65 | ### Identify most important lines (5 mins)
66 | Independently identify the 5 lines you consider most important.
67 |
68 | #### Discussion (10 mins)
69 | Discuss in the group:
70 |
71 | - lines covered by many people?
72 | - lines named but not by a lot of people
73 | - What strategy did you use to identify importance?
74 | - Agree less than 10 of the most important lines
75 |
76 | Take turns in the group, and let every member talk about the code for 30 seconds (or less/more, could also be one sentence each). Try to add new information and not repeat things that have been said, and repeat until people do not know new things anymore.
77 |
78 | ## Summary (15 minutes)
79 |
80 | ### Summarize in less than 10 sentences individually (5 mins)
81 |
82 | 1. Independently write down the essence of the code in a few sentences
83 |
84 | ### Discussion (10 mins)
85 |
86 | - topics covered by many vs few
87 | - strategies used to create the summary (e.g. method names, documentation, variable names, prior knowledge of system)
88 |
89 | ### Summarize in less than 10 sentences (5 mins)
90 |
91 | 1. Create a summary together
92 | 1. Compare the summary with the available documentation (inside and outside the code)
93 |
94 | - identify differences and similarities between the groups findings and the existing
95 |
96 | ## Wash up (5 mins)
97 |
98 | - What worked well
99 | - What worked badly
100 |
--------------------------------------------------------------------------------
/neontribe-club/sessionX/agenda_s10.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neontribe/code-reading-club/c3baf98c0d517ec7c7b9f09addee7f0cd3cca71f/neontribe-club/sessionX/agenda_s10.pdf
--------------------------------------------------------------------------------
/neontribe-club/sessionX/code_sample.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neontribe/code-reading-club/c3baf98c0d517ec7c7b9f09addee7f0cd3cca71f/neontribe-club/sessionX/code_sample.pdf
--------------------------------------------------------------------------------
/neontribe-club/sessionX/example.rb:
--------------------------------------------------------------------------------
1 |
2 | #
3 | # Copyright (C) 2011 - present Instructure, Inc.
4 | #
5 | # This file is part of Canvas.
6 | #
7 | # Canvas is free software: you can redistribute it and/or modify it under
8 | # the terms of the GNU Affero General Public License as published by the Free
9 | # Software Foundation, version 3 of the License.
10 | #
11 | # Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
12 | # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
13 | # A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
14 | # details.
15 | #
16 | # You should have received a copy of the GNU Affero General Public License along
17 | # with this program. If not, see .
18 | #
19 |
20 | class QuestionBanksController < ApplicationController
21 | before_action :require_context, :except => :bookmark
22 | add_crumb(proc { t('#crumbs.question_banks', "Question Banks") }, :except => :bookmark) { |c| c.send :named_context_url, c.instance_variable_get("@context"), :context_question_banks_url }
23 |
24 | include Api::V1::Outcome
25 |
26 | def index
27 | if @context == @current_user || authorized_action(@context, @current_user, :read_question_banks)
28 | @question_banks = @context.assessment_question_banks.active.except(:preload).to_a
29 | if params[:include_bookmarked] == '1'
30 | @question_banks += @current_user.assessment_question_banks.active
31 | end
32 | if params[:inherited] == '1' && @context != @current_user
33 | @question_banks += @context.inherited_assessment_question_banks.active
34 | end
35 | @question_banks = @question_banks.select{|b| b.grants_right?(@current_user, :manage) } if params[:managed] == '1'
36 | @question_banks = Canvas::ICU.collate_by(@question_banks.uniq) { |b| b.title || CanvasSort::Last }
37 | respond_to do |format|
38 | format.html
39 | format.json { render :json => @question_banks.map{ |b| b.as_json(methods: [:cached_context_short_name, :assessment_question_count]) }}
40 | end
41 | end
42 | end
43 |
44 | def questions
45 | find_bank(params[:question_bank_id], params[:inherited] == '1') do
46 | @questions = @bank.assessment_questions.active
47 | url = polymorphic_url([@context, :question_bank_questions], :question_bank_id => @bank)
48 | @questions = Api.paginate(@questions, self, url, default_per_page: 50)
49 | render :json => {:pages => @questions.total_pages, :questions => @questions}
50 | end
51 | end
52 |
53 | def reorder
54 | @bank = @context.assessment_question_banks.find(params[:question_bank_id])
55 | if authorized_action(@bank, @current_user, :update)
56 | @bank.assessment_questions.active.first.update_order(params[:order].split(','))
57 | render :json => {:reorder => true}
58 | end
59 | end
60 |
61 | def show
62 | @bank = @context.assessment_question_banks.find(params[:id])
63 | js_env({
64 | :CONTEXT_URL_ROOT => polymorphic_path([@context]),
65 | :ROOT_OUTCOME_GROUP => outcome_group_json(@context.root_outcome_group, @current_user, session)
66 | })
67 | rce_js_env
68 |
69 | add_crumb(@bank.title)
70 | if authorized_action(@bank, @current_user, :read)
71 | @alignments = Canvas::ICU.collate_by(@bank.learning_outcome_alignments) { |a| a.learning_outcome.short_description }
72 | @questions = @bank.assessment_questions.active.paginate(:per_page => 50, :page => 1)
73 | end
74 |
75 | js_bundle :quizzes_bundle, :question_bank
76 | css_bundle :quizzes, :learning_outcomes, :tinymce, :question_bank
77 | @page_title = @bank.title
78 | end
79 |
80 | def move_questions
81 | @bank = @context.assessment_question_banks.find(params[:question_bank_id])
82 | @new_bank = AssessmentQuestionBank.find(params[:assessment_question_bank_id])
83 | if authorized_action(@bank, @current_user, :update) && authorized_action(@new_bank, @current_user, :manage)
84 | ids = []
85 | params[:questions].each do |key, value|
86 | ids << key.to_i if value != '0' && key.to_i != 0
87 | end
88 | @questions = @bank.assessment_questions.where(:id => ids)
89 | if params[:move] != '1'
90 | attributes = @questions.columns.map(&:name) - %w{id created_at updated_at assessment_question_bank_id}
91 | connection = @questions.connection
92 | attributes = attributes.map { |attr| connection.quote_column_name(attr) }
93 | now = connection.quote(Time.now.utc)
94 | connection.insert(
95 | "INSERT INTO #{AssessmentQuestion.quoted_table_name} (#{(%w{assessment_question_bank_id created_at updated_at} + attributes).join(', ')})" +
96 | @questions.select(([@new_bank.id, now, now] + attributes).join(', ')).to_sql)
97 | else
98 | @questions.update_all(:assessment_question_bank_id => @new_bank.id)
99 | end
100 |
101 | [ @bank, @new_bank ].each(&:touch)
102 |
103 | render :json => {}
104 | end
105 | end
106 |
107 | def create
108 | if authorized_action(@context.assessment_question_banks.temp_record, @current_user, :create)
109 | @bank = @context.assessment_question_banks.build(bank_params)
110 | respond_to do |format|
111 | if @bank.save
112 | @bank.bookmark_for(@current_user)
113 | flash[:notice] = t :bank_success, "Question bank successfully created!"
114 | format.html { redirect_to named_context_url(@context, :context_question_banks_url) }
115 | format.json { render :json => @bank }
116 | else
117 | flash[:error] = t :bank_fail, "Question bank failed to create."
118 | format.html { redirect_to named_context_url(@context, :context_question_banks_url) }
119 | format.json { render :json => @bank.errors, :status => :bad_request }
120 | end
121 | end
122 | end
123 | end
124 |
125 | def bookmark
126 | @bank = AssessmentQuestionBank.find(params[:question_bank_id])
127 |
128 | if params[:unbookmark] == "1"
129 | render :json => @bank.bookmark_for(@current_user, false)
130 | elsif authorized_action(@bank, @current_user, :update)
131 | render :json => @bank.bookmark_for(@current_user)
132 | end
133 | end
134 |
135 | def update
136 | @bank = @context.assessment_question_banks.find(params[:id])
137 | if authorized_action(@bank, @current_user, :update)
138 | if @bank.update(bank_params)
139 | @bank.reload
140 | render :json => @bank.as_json(:include => {:learning_outcome_alignments => {:include => {:learning_outcome => {:include_root => false}}}})
141 | else
142 | render :json => @bank.errors, :status => :bad_request
143 | end
144 | end
145 | end
146 |
147 | def destroy
148 | @bank = @context.assessment_question_banks.find(params[:id])
149 | if authorized_action(@bank, @current_user, :delete)
150 | @bank.destroy
151 | render :json => @bank
152 | end
153 | end
154 |
155 | private
156 |
157 | def bank_params
158 | params.require(:assessment_question_bank).permit(:title, :alignments => strong_anything)
159 | end
160 | end
--------------------------------------------------------------------------------