├── .bin
└── spelling.sh
├── .circleci
└── config.yml
├── .github
└── dependabot.yml
├── .gitignore
├── .ruby-version
├── .spelling
├── .vscode
└── settings.json
├── CNAME
├── Gemfile
├── Gemfile.lock
├── LICENSE.md
├── Makefile
├── README.md
├── _config.yml
├── _data
└── tech-courses.yml
├── _includes
├── digital_element_container.html
├── digital_element_content.html
├── digital_element_header.html
├── digital_element_resources.html
├── footer.html
├── skill_header.html
├── skill_resources.html
├── tech_course_listing.html
└── tech_course_summary.html
├── _layouts
├── default.html
└── main.html
├── assets
├── css
│ ├── madetech-frontend.css
│ ├── madetech-frontend.css.map
│ ├── madetech-frontend.min.css
│ ├── madetech-frontend.min.css.map
│ └── style.scss
├── fonts
│ ├── neuzeit-gro-bold.eot
│ ├── neuzeit-gro-bold.ttf
│ ├── neuzeit-gro-bold.woff
│ ├── neuzeit-gro-reg.eot
│ ├── neuzeit-gro-reg.ttf
│ ├── neuzeit-gro-reg.woff
│ ├── neuzeit-s-book.eot
│ ├── neuzeit-s-book.ttf
│ └── neuzeit-s-book.woff
├── images
│ ├── favicon.ico
│ ├── icons
│ │ ├── github.svg
│ │ ├── linkedin.svg
│ │ └── twitter.svg
│ ├── made-tech-logo-blk.png
│ ├── made-tech-logo-colour.png
│ └── made-tech-logo-wht.png
└── js
│ └── madetech-frontend.js
├── design
└── index.html
├── digital
├── images
│ ├── delivery.jpg
│ ├── design.jpg
│ ├── product.jpg
│ ├── technology.jpg
│ └── venn-diagram.png
└── index.html
├── index.html
├── katas
├── README.md
├── bowling
│ └── README.md
├── mars-rover
│ └── README.md
├── mumbling
│ └── README.md
├── number-to-lcd
│ ├── README.md
│ └── part2.md
├── roman-numerals
│ └── README.md
├── snake
│ └── README.md
├── tennis-refactoring
│ └── README.md
├── tennis
│ └── README.md
├── test-framework
│ └── README.md
├── turnstile
│ ├── README.md
│ └── part2.md
├── video-store
│ └── README.md
├── word-wrap
│ └── README.md
└── wordle
│ └── README.md
├── made-tech-logo.svg
├── product
└── index.html
└── technology
├── articles
├── README.md
└── cost-of-delay.md
├── calendar
├── cleancode.html
├── index.html
└── testing.html
├── core-skills
├── frontend-development
│ ├── README.md
│ ├── resources
│ │ ├── cross-browser-testing.md
│ │ ├── css-architecture.md
│ │ ├── grids.md
│ │ ├── html-css-standards.md
│ │ ├── icons.md
│ │ ├── progressive-enhancement.md
│ │ ├── responsive-design.md
│ │ ├── rhino-expected-styles.png
│ │ ├── semantic-html.md
│ │ ├── seo.md
│ │ ├── web-accessibility.md
│ │ ├── web-performance.md
│ │ ├── web-typography.md
│ │ └── working-with-photoshop.md
│ └── rhino.jpg
├── infrastructure
│ └── README.md
├── react
│ ├── README.md
│ ├── fox.png
│ ├── functional-and-class.md
│ ├── fundamentals
│ │ └── README.md
│ ├── hedgehog.png
│ ├── owl.png
│ ├── setup.md
│ └── why-and-when.md
└── tdd
│ ├── README.md
│ ├── discipline.md
│ ├── dragon.jpg
│ ├── giraffe.jpg
│ ├── inappropriate.md
│ ├── performance.md
│ ├── remote-services.md
│ ├── test-doubles.md
│ ├── triangulation.md
│ ├── well-designed-tests.md
│ ├── well-written-tests.md
│ └── wolf.jpg
├── event-plans
├── README.md
└── mld
│ ├── common-lisp.md
│ ├── erlang.md
│ ├── facilitators-guide.md
│ ├── fsharp.md
│ └── gnu-smalltalk.md
├── goals
└── README.md
├── guides
├── 00-Setup
│ ├── Build-Tools.md
│ ├── Common-Tools.md
│ ├── README.md
│ ├── Ruby-Version-Manager.md
│ ├── Ruby.md
│ ├── Terminal.md
│ └── Your-Shell.md
├── 01-Command-Line
│ ├── Challenge 1
│ │ ├── Empty Folder
│ │ │ └── .keep
│ │ └── Text Files
│ │ │ ├── Less Text.txt
│ │ │ ├── More Text.txt
│ │ │ └── generate.sh
│ └── README.md
├── 02-Git
│ └── README.md
├── 03-Debugging
│ ├── BuggyProject
│ │ ├── .gitignore
│ │ ├── .ruby-version
│ │ ├── Gemfile
│ │ ├── Gemfile.lock
│ │ ├── Guardfile
│ │ ├── Makefile
│ │ ├── README.md
│ │ ├── app.rb
│ │ ├── lib
│ │ │ ├── list_topics.rb
│ │ │ └── view_topic.rb
│ │ └── spec
│ │ │ ├── list_topics_spec.rb
│ │ │ ├── topics_shared_context.rb
│ │ │ └── view_topic_spec.rb
│ └── README.md
├── 04-Retrospective-Planning
│ └── README.md
├── 05-Refactoring
│ └── README.md
├── 06-Gem-Packaging
│ └── README.md
├── 07-Simplest-Next-Test
│ └── README.md
├── 08-Continuous-Integration
│ ├── README.md
│ ├── simple-sinatra-app-to-deploy
│ │ ├── .rspec
│ │ ├── Gemfile
│ │ ├── Gemfile.lock
│ │ ├── README.MD
│ │ ├── config.ru
│ │ ├── lib
│ │ │ ├── index.rb
│ │ │ └── super_simple_usecase.rb
│ │ └── spec
│ │ │ ├── index_spec.rb
│ │ │ ├── spec_helper.rb
│ │ │ └── super_simple_usecase_spec.rb
│ └── simple-sinatra-app
│ │ ├── .circleci
│ │ └── config.yml
│ │ ├── .rspec
│ │ ├── Gemfile
│ │ ├── Gemfile.lock
│ │ ├── README.MD
│ │ ├── config.ru
│ │ ├── lib
│ │ ├── index.rb
│ │ └── super_simple_usecase.rb
│ │ └── spec
│ │ ├── spec_helper.rb
│ │ └── super_simple_usecase_spec.rb
├── 09-Polymorphism
│ └── README.md
├── 10-Database
│ ├── README.md
│ └── screen-cap-workshop.gif
├── 11-Docker
│ ├── README.md
│ └── story.md
├── 12-Pull-Requests
│ └── README.md
├── README.md
├── aws
│ └── cloud-practitioner
│ │ └── README.md
├── controllers-routing
│ └── README.md
├── intro_to_ruby
│ └── README.md
├── orm-ar-models
│ └── README.md
└── views
│ └── README.md
├── ideas
├── README.md
├── get-feedback-on-code.md
├── learn-a-new-language.md
├── learn-how-to-setup-ruby.md
├── learn-software-architecture.md
├── learn-to-tdd.md
└── practice-tdd.md
├── index.html
├── katas
├── README.md
├── bowling
│ └── README.md
├── mars-rover
│ └── README.md
├── mumbling
│ └── README.md
├── number-to-lcd
│ ├── README.md
│ └── part2.md
├── roman-numerals
│ └── README.md
├── snake
│ └── README.md
├── tennis-refactoring
│ └── README.md
├── tennis
│ └── README.md
├── test-framework
│ └── README.md
├── turnstile
│ ├── README.md
│ └── part2.md
├── video-store
│ └── README.md
├── word-wrap
│ └── README.md
└── wordle
│ └── README.md
├── koans
└── README.md
├── scenarios
├── README.md
└── cloud
│ ├── README.md
│ ├── distributed-comms-queues.md
│ └── webserver.md
├── seminars
├── 01-The-Power-of-Naming
│ ├── README.md
│ └── examples
│ │ ├── example1.rb
│ │ ├── example2.rb
│ │ ├── example3.rb
│ │ └── example4.rb
├── 02-Functions
│ └── README.md
├── 03-Architecture
│ └── README.md
├── 04-Single-Responsibility-Principle
│ └── README.md
├── 05-Open-Closed-Principle
│ └── README.md
├── 06-Liskov-Substitution-Principle
│ └── README.md
├── 07-Interface-Segregation-Principle
│ └── README.md
├── 08-Dependency-Inversion-Principle
│ └── README.md
└── README.md
├── skills
├── c-sharp-and-dotnet
│ ├── README.md
│ ├── eagle.jpg
│ ├── goat.jpg
│ └── mantis.jpg
└── git
│ └── README.md
├── sparring
├── README.md
├── payroll
│ └── README.md
└── tic-tac-toe
│ ├── README.md
│ ├── part2.md
│ ├── part3.md
│ ├── part4.md
│ ├── part5.md
│ └── part6.md
└── videos
├── README.md
├── general-ledger.md
└── tennis.md
/.bin/spelling.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | if [[ $* == *interactive* ]]
3 | then
4 | echo 'interactive'
5 | docker run -ti -v $(pwd):/workdir tmaier/markdown-spellcheck:latest "**/*.md"
6 | else
7 | docker run -ti -v $(pwd):/workdir tmaier/markdown-spellcheck:latest --report "**/*.md"
8 | fi
9 |
--------------------------------------------------------------------------------
/.circleci/config.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | jobs:
3 | check_links:
4 | docker:
5 | - image: cimg/node:lts
6 | steps:
7 | - run:
8 | name: check links
9 | command: npx broken-link-checker https://learn.madetech.com --exclude microsoft --exclude linkedin --exclude twitter --exclude codewars.com -ro
10 | workflows:
11 | version: 2
12 | weekly_checks:
13 | triggers:
14 | - schedule:
15 | cron: "0 0 * * 0"
16 | filters:
17 | branches:
18 | only:
19 | - master
20 | jobs:
21 | - check_links
22 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: bundler
4 | directory: "/"
5 | schedule:
6 | interval: daily
7 | timezone: Europe/London
8 | open-pull-requests-limit: 99
9 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | _site
2 | .DS_Store
3 | /guides/01-Command-Line/Challenge 1/Text\ Files/x*
4 | /technology/guides/01-Command-Line/Challenge 1/Text\ Files/x*
--------------------------------------------------------------------------------
/.ruby-version:
--------------------------------------------------------------------------------
1 | 3.3.4
2 |
--------------------------------------------------------------------------------
/.spelling:
--------------------------------------------------------------------------------
1 | # markdown-spellcheck spelling configuration file
2 | # Format - lines beginning # are comments
3 | # global dictionary is at the start, file overrides afterwards
4 | # one word per line, to define a file override use ' - filename'
5 | # where filename is relative to this configuration file
6 | kata
7 | codingdojo.org
8 | 2
9 | 3
10 | 1
11 | emilybache
12 | README.md
13 | Wii
14 | 0
15 | 15
16 | 30
17 | 40
18 | FSM
19 | event_name
20 | FSMs
21 | katas
22 | xcode
23 | cli
24 | macOS
25 | homebrew
26 | 1.2
27 | 1.3
28 | lastpass
29 | 4
30 | 5
31 | 6
32 | standalone
33 | rbenv
34 | init
35 | autogenerated
36 | builtins
37 | zsh
38 | builtin
39 | eval
40 | subshell
41 | zshrc
42 | 2.5.0
43 | iTerm
44 | 1.1
45 | plugins
46 | 1.4
47 | 1.5
48 | 1.6
49 | 1.0
50 | newfile
51 | mkdir
52 | txt
53 | grep
54 | env
55 | ps
56 | wc
57 | shebang
58 | 8
59 | unstash
60 | stacktraces
61 | stacktrace
62 | read_file
63 | 2.1
64 | BuggyProject
65 | 2.2
66 | destructured
67 | parameterized
68 | params
69 | spec
70 | Movies
71 | Movie
72 | exercism
73 | ORM
74 | ActiveRecord
75 | movie
76 | movies
77 | 1982
78 | whos
79 | - katas/turnstile/README.md
80 | 3E
81 | MenuClosed
82 | 20
83 | MenuOpen
84 | - guides/01-Command-Line/README.md
85 | chrome.list
86 | hello.rb
87 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "git.ignoreLimitWarning": true,
3 | "makefile.configureOnOpen": false
4 | }
--------------------------------------------------------------------------------
/CNAME:
--------------------------------------------------------------------------------
1 | learn.madetech.com
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | source 'https://rubygems.org'
4 |
5 | git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
6 |
7 | gem 'github-pages', group: :jekyll_plugins
8 |
9 | gem "webrick", "~> 1.9"
10 |
11 | ruby File.read(".ruby-version").strip
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | serve: bundle
2 | bundle exec jekyll serve
3 |
4 | bundle:
5 | bundle install
6 |
7 | spelling:
8 | ./.bin/spelling.sh --interactive
9 |
10 | check-all:
11 | ./.bin/spelling.sh
12 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Learning Materials for Software Delivery [](https://circleci.com/gh/madetech/learn)
2 |
3 | A guide to delivering digital services and technology outcomes using The Made Tech Way.
4 |
5 | [Get Started](https://learn.madetech.com)
6 |
7 | ## Making Changes
8 |
9 | 1. Install Ruby [using rbenv](./technology/guides/00-Setup/Ruby-Version-Manager.md)
10 | 1. Run `$ make serve` which will start a local webserver.
11 | 1. Open the local webserver in your browser to preview your changes.
12 | 1. Raise Pull Request on GitHub 🚀
--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 | theme: jekyll-theme-minimal
2 | title: Learn Tech by Made Tech
3 | logo: /learn-tech-draft.png
4 | google_analytics: UA-46200988-6
5 |
--------------------------------------------------------------------------------
/_data/tech-courses.yml:
--------------------------------------------------------------------------------
1 | - type: clean-code
2 | title: Clean Code
3 | booking-page: cleancode.html
4 | bookable: true
5 | summary: |-
6 | A bootcamp covering programming concepts, lots of discussion and practical exercises.
7 | Suitable for all Engineering levels.
8 | dates:
9 | - title: Clean Code
10 | location: Bristol
11 | available: false
12 | subtitle: Days 1 to 3
13 | date: Upcoming (March 2025)
14 | description: |-
15 | Days 1 to 3. Covers programming concepts, pairing and TDD.
16 | Suitable for all Engineering levels. This course is *in-person* only.
17 | register-url: '#'
18 |
19 | - title: Clean Code
20 | location: Bristol
21 | available: false
22 | subtitle: Days 4 and 5
23 | date: Upcoming
24 | description: |-
25 | Days 4 to 5. More programming concepts, pairing and TDD, following on from Clean Code Days 1-3.
26 | Suitable for all Engineering levels. This course is *in-person* only.
27 | You must have attended Clean Code Days 1 to 3 before attending this course.
28 | register-url: '#'
29 |
30 | - title: Clean Code
31 | location: London
32 | available: false
33 | subtitle: Days 1 to 3
34 | date: Upcoming (May 2025)
35 | description: |-
36 | Days 1 to 3. Covers programming concepts, pairing and TDD.
37 | Suitable for all Engineering levels. This course is *in-person* only.
38 | register-url: '#'
39 |
40 | - title: Clean Code
41 | location: London
42 | available: false
43 | subtitle: Days 4 & 5
44 | date: Upcoming
45 | description: |-
46 | Days 4 to 5. More programming concepts, pairing and TDD, following on from Clean Code Days 1-3.
47 | Suitable for all Engineering levels. This course is *in-person* only.
48 | You must have attended Clean Code Days 1 to 3 before attending this course.
49 | register-url: '#'
50 |
51 | - title: Clean Code
52 | location: Manchester
53 | available: false
54 | subtitle: Days 1 to 3
55 | date: Upcoming (June 2025)
56 | description: |-
57 | Days 1 to 3. Covers programming concepts, pairing and TDD.
58 | Suitable for all Engineering levels. This course is *in-person* only.
59 | register-url: '#'
60 |
61 | - title: Clean Code - Remote
62 | location: Remote
63 | available: true
64 | subtitle: Days 1 to 3
65 | date: Monday 27th January - Wednesday 29th January 2025
66 | description: |-
67 | Days 1 to 3. Covers programming concepts, pairing and TDD.
68 | Suitable for all Engineering levels.
69 |
70 | This course is being offered as a *remote* option and we will attempt to prioritise those who are unable to attend in-person sessions at an office.
71 | register-url: 'https://forms.gle/ogLdmaWTDE5JnX7Q9'
72 |
73 | - type: consulting101
74 | title: What is Consulting and how should I do it at Made Tech?
75 | booking-page: ''
76 | bookable: false
77 | summary: |-
78 | A one day bootcamp covering the consulting market, how Made Tech fits into that market, how to approach account strategy & influence your client, as well as dealing with difficult scenarios.
79 | Suitable for all billable roles. This course is *in-person* only.
80 | dates: []
81 |
82 | - type: tdd
83 | title: Recapping TDD and Testing Along the Spectrum
84 | booking-page: 'testing.html'
85 | bookable: false
86 | summary: |-
87 | A 1.5 day bootcamp aimed to build confidence in TDD, use different tools across different areas of testing, and how to bug fix through testing.
88 | Suitable for all levels.
89 | *Please note: Part 1 will be online, Parts 2 and 3 will be in person. You need to be able to attend all three parts.*
90 | dates: []
91 |
--------------------------------------------------------------------------------
/_includes/digital_element_container.html:
--------------------------------------------------------------------------------
1 |
19 |
Develop your knowledge
20 |
21 | Resources for improving your research and design skills, lovingly crafted by the team at Made Tech.
22 |
23 |
24 |
25 |
18 |
We're under-going a re-design
19 |
20 | We are re-organising and re-designing learn.madetech.com to ensure the site continues to meet its purpose for the future.
21 |
22 |
23 | {% endcapture %}
24 |
25 | {% include digital_element_container.html content=content %}
--------------------------------------------------------------------------------
/katas/bowling/README.md:
--------------------------------------------------------------------------------
1 | # Bowling
2 |
3 | Create a program, which, given a valid sequence of rolls for one line of American Ten-Pin Bowling, produces the total score for the game.
4 |
5 | * The input is a valid sequence of rolls
6 | * The output is the resulting score
7 |
8 | ## Example input
9 |
10 | For instance, for a game that is partway through, your input might be:
11 |
12 | > "X 45 4/ 32"
13 |
14 | This indicates that:
15 |
16 | * Four frames have been played
17 | * The first frame was a "strike" (all 10 pins knocked over in one roll - symbolised by "X")
18 | * The second frame ("45") consisted of the maximum two rolls
19 | * The first roll knocked down 4 pins
20 | * The second roll knocked down 5 pins
21 | * The third frame was a "spare" (all 10 pins knocked down in two rolls - symbolised by "/" on the second roll)
22 | * The first roll knocked down 4 pins
23 | * The second roll knocked down the remaining 6 pins
24 | * The fourth frame ("32") consisted of two rolls
25 | * The first roll knocked down 3 pins
26 | * The second roll knocked down 2 pins
27 |
28 | ## Example output
29 |
30 | For the above input of "X 45 4/ 32", the score would be 46 - scored as follows:
31 |
32 | * The first frame is a strike, which scores `10 + (all rolls from the following frame) = 10 + 4 + 5 = 19`
33 | * The second frame scores `4 + 5 = 9`
34 | * The third frame is a spare, which scores `10 + (the first roll from the following frame) = 10 + 3 = 13`
35 | * The fourth frame scores `3 + 2 = 5`
36 |
37 | For detailed scoring rules, see [below](#summarised-scoring).
38 |
39 | ## What your solution will not do
40 |
41 | Here are some things that the program will not do:
42 |
43 | * We will not check for valid rolls.
44 | * We will not check for correct number of rolls and frames.
45 | * We will not provide scores for intermediate frames.
46 |
47 | Depending on the application, this might or might not be a valid way to define a complete story, but we do it here for purposes of keeping the kata light. I think you’ll see that improvements like those above would go in readily if they were needed for real.
48 |
49 | ## Summarised scoring
50 |
51 | We can briefly summarize the scoring for this form of bowling:
52 |
53 | Each game, or “line” of bowling, includes ten turns, or “frames” for the bowler.
54 |
55 | * In each frame, the bowler gets up to two tries to knock down all the pins.
56 | * If in two tries, the bowler fails to knock them all down, their score for that frame is the total number of pins knocked down in their two tries.
57 | * If in two tries the bowler knocks them all down, this is called a “spare” and their score for the frame is ten plus the number of pins knocked down on their next throw (in their next turn).
58 | * If on their first try in the frame the bowler knocks down all the pins, this is called a “strike”. Their turn is over, and their score for the frame is ten plus the simple total of the pins knocked down in their next two rolls.
59 | * If the bowler gets a spare or strike in the last (tenth) frame, the bowler gets to throw one or two more bonus balls, respectively. These bonus throws are taken as part of the same turn. If the bonus throws knock down all the pins, the process does not repeat: the bonus throws are only used to calculate the score of the final frame.
60 | * The game score is the total of all frame scores.
61 |
62 | [More detailed scoring rules available here](https://www.myactivesg.com/sports/bowling/how-to-play/bowling-rules/how-are-points-determined-in-bowling).
63 |
64 | ## References
65 |
66 | [codingdojo.org](http://codingdojo.org/kata/Bowling/)
67 |
--------------------------------------------------------------------------------
/katas/mars-rover/README.md:
--------------------------------------------------------------------------------
1 | # Mars Rover Kata
2 |
3 | You’re part of the team that explores Mars by sending remotely controlled vehicles to the surface of the planet. Develop an API that translates the commands sent from earth to instructions that are understood by the rover.
4 |
5 | ## Requirements
6 |
7 | * You are given the initial starting point (x,y) of a rover and the direction (N,S,E,W) it is facing.
8 | * The rover receives a character array of commands.
9 | * Implement commands that move the rover forward/backward (f,b).
10 | * Implement commands that turn the rover left/right (l,r).
11 | * Implement wrapping from one edge of the grid to another. (planets are spheres after all)
12 | * Implement obstacle detection before each move to a new square. If a given sequence of commands encounters an obstacle, the rover moves up to the last possible point, aborts the sequence and reports the obstacle.
13 |
14 | ## Rules
15 |
16 | * Be careful about edge cases and exceptions. We can not afford to lose a mars rover, just because the developers overlooked a null pointer.
17 |
18 | ## References
19 |
20 | * [Kata Log Rocks: Mars Rover](http://kata-log.rocks/mars-rover-kata)
21 |
--------------------------------------------------------------------------------
/katas/mumbling/README.md:
--------------------------------------------------------------------------------
1 | # Mumbling Kata
2 |
3 | The goal of this kata is to implement the `mumble_letters()` method which takes a string as input and returns a formatted output string. The output string contains sequences of repeating letters with each letter repeated a number of times based on its position in the input string i.e. the 3rd letter in the string is repeated 3 times. Each sequence of repeated letters is separated with a hyphen(-) and the first letter of each sequence is capitalised.
4 |
5 | The following examples illustrate the `mumble_letters()` method:
6 |
7 | ```ruby
8 | mumble_letters("a")
9 | => "A"
10 |
11 | mumble_letters("abC")
12 | => "A-Bb-Ccc"
13 |
14 | mumble_letters("aBCd")
15 | => "A-Bb-Ccc-Dddd"
16 |
17 | mumble_letters("QWERTY")
18 | => "Q-Ww-Eee-Rrrr-Ttttt-Yyyyyy"
19 | ```
20 |
21 | ## Rules
22 |
23 | Note that your `mumble_letters()` implementation should also handle an empty string input appropriately.
24 |
25 | ## References
26 |
27 | * [Codewars Mumbling Kata](https://www.codewars.com/kata/mumbling)
28 |
--------------------------------------------------------------------------------
/katas/number-to-lcd/README.md:
--------------------------------------------------------------------------------
1 | # Number to LCD
2 |
3 | Goal: write a program that displays LCD style numbers.
4 |
5 | ### Part 1
6 |
7 | Write a program that given a number (with arbitrary number of digits), converts it into LCD style numbers using the following format:
8 |
9 | ```
10 | _ _ _ _ _ _ _
11 | | _| _||_||_ |_ ||_||_|
12 | ||_ _| | _||_| ||_| _|
13 | ```
14 |
15 | (each digit is 3 lines high)
16 |
17 | Note: Please do *NOT* read the second part before completing the first. Part of the purpose of this kata is to make you practice refactoring and adapting to changing requirements. [Part two is here](part2.md)
18 |
19 |
20 |
21 | ## References
22 |
23 | [codingdojo.org](http://codingdojo.org/kata/NumberToLCD/)
24 |
--------------------------------------------------------------------------------
/katas/number-to-lcd/part2.md:
--------------------------------------------------------------------------------
1 | ### Part 2
2 |
3 | Change your program to support variable width or height of the digits.
4 | For example for width = 3 and height = 2 the digit 2 will be:
5 |
6 | ```
7 | ___
8 | |
9 | |
10 | ___
11 | |
12 | |
13 | ___
14 |
15 | ```
16 |
--------------------------------------------------------------------------------
/katas/roman-numerals/README.md:
--------------------------------------------------------------------------------
1 | # Roman Numerals
2 |
3 | Given an integer input, produce output in [Roman Numeral](https://en.wikipedia.org/wiki/Roman_numerals) format.
4 |
5 | ## Example
6 |
7 | `2 => II`
8 |
9 | `5 => V`
10 |
11 | `10 => X`
12 |
13 | ## Variations
14 |
15 | * Can you make the code really beautiful and highly readable?
16 | * Consider applying the Single Responsibility Principle to the absolute extreme when you are refactoring
17 | * What's the best way to verify your tests are correct?
18 | * Compare your solutions to others
19 |
20 | ## Reference
21 |
22 | [codingdojo.org](http://codingdojo.org/kata/RomanNumerals/)
23 |
--------------------------------------------------------------------------------
/katas/snake/README.md:
--------------------------------------------------------------------------------
1 | # Snake Kata
2 |
3 | This kata is based on the classic snake game that you may be familiar from the old Nokia 6110 or the Nokia 3210 phones.
4 |
5 | 
6 |
7 | ## Requirements
8 | * The snake can move in any direction on the grid
9 | * When the snake reaches one edge of the grid it appears at the other side
10 | * The snake can turn left and right
11 | * The snake can grow in length when feeding
12 | * The snake can crash into its own body
13 |
14 | ## Rules
15 | * The snake should only turn one unit at a time, hard turns are not allowed. For instance, the snake is facing N; it should be able to turn W or E but NOT towards S.
16 |
17 | ## References
18 | * [Nokia Wiki](https://nokia.fandom.com/wiki/Snakea)
19 | * [Snake Wiki](https://en.wikipedia.org/wiki/Snake_(video_game_genre))
20 |
--------------------------------------------------------------------------------
/katas/tennis-refactoring/README.md:
--------------------------------------------------------------------------------
1 | # Tennis Refactoring
2 |
3 | You'll find the starting code for the refactoring kata at [emilybache/Tennis-Refactoring-Kata](https://github.com/emilybache/Tennis-Refactoring-Kata).
4 |
5 | Follow the instructions in [Tennis-Refactoring-Kata/README.md](https://github.com/emilybache/Tennis-Refactoring-Kata/blob/master/README.md)
6 |
--------------------------------------------------------------------------------
/katas/tennis/README.md:
--------------------------------------------------------------------------------
1 | # Tennis
2 |
3 | This Kata is about implementing a simple tennis game.
4 |
5 | Rather than using standard Tennis scoring, **we consider scoring in Wii tennis**, which has a simplified version of tennis, so each set is one game.
6 |
7 | The scoring system is as follows:
8 |
9 | 1. Each player can have either of these points in one game 0 15 30 40
10 |
11 | 2. If you have 40 and you win the ball you win the game, however there are special rules.
12 |
13 | 3. If both have 40 the players are deuce.
14 | - a. If the game is in deuce, the winner of a ball will have advantage and game ball.
15 | - b. If the player with advantage wins the ball they win the game
16 | - c. If the player without advantage wins they are back at deuce.
17 |
18 | ## Alternative description of rules
19 |
20 | 1. A game is won by the first player to have won at least four points in total and at least two points more than the opponent.
21 |
22 | 2. The running score of each game is described in a manner peculiar to tennis: scores from zero to three points are described as “love”, “fifteen”, “thirty”, and “forty” respectively.
23 |
24 | 3. If at least three points have been scored by each player, and the scores are equal, the score is “deuce”.
25 |
26 | 4. If at least three points have been scored by each side and a player has one more point than their opponent, the score of the game is “advantage” for the player in the lead.
27 |
28 | ## Reference
29 |
30 | [codingdojo.org](http://codingdojo.org/kata/Tennis/)
31 |
--------------------------------------------------------------------------------
/katas/test-framework/README.md:
--------------------------------------------------------------------------------
1 | # Test Framework
2 |
3 | For this Kata you need to build a test framework from scratch.
4 |
5 | * It should provide some way to separate tests, so that users can follow the single assert rule.
6 | * It should provide some way to name each test.
7 | * It should have a plugin architecture. (Up to you to decide where flexibility is desirable).
8 |
9 | Obviously, you should TDD your solution. (Some creativity required!).
10 |
11 | ## Variations
12 |
13 | * Do you use another testing framework to test your framework?
14 | * Do you bootstrap testing your test framework with the test framework?
15 | * TDD another Kata using your test framework, how usable is it?
16 |
17 | ## Useful Links
18 |
19 | * [Destroy all software: building rspec from scratch](https://www.destroyallsoftware.com/screencasts/catalog/building-rspec-from-scratch)
20 |
21 |
--------------------------------------------------------------------------------
/katas/turnstile/README.md:
--------------------------------------------------------------------------------
1 | # Turnstile
2 |
3 | ## Finite State Machines
4 |
5 | If you've never encountered finite state machine (FSM) modelling before, here is what it looks like.
6 |
7 | The following state machine is comprised of two states: "State 1" and "State 2". There is a single event "event_name" that can take the state machine from State 1 to State 2.
8 |
9 | -event_name>(State 2))
10 |
11 | One use case of FSMs is User Interface logic, consider the following:
12 |
13 | -open%3E(MenuClosed),%20(MenuOpen)-open%3E(MenuOpen),%20(MenuClosed)-close%3E(MenuOpen),%20(MenuClosed)-close%3E(MenuClosed))
14 |
15 | Each event of the finite state machine can be bound to application methods e.g.
16 |
17 | -open[show]>(MenuClosed),%20(MenuOpen)-open[nil]>(MenuOpen),%20(MenuClosed)-close[hide]>(MenuOpen),%20(MenuClosed)-close[nil]>(MenuClosed))
18 |
19 | ## The Kata
20 |
21 | Build a finite state machine from scratch, that replicates the following Finite State Machine
22 |
23 | -coin[unlock]%3E(Unlocked),%20(Unlocked)-pass[lock]%3E(Locked),%20(Unlocked)-pass[alarm]%3E(Unlocked),%20(Locked)-coin[thanks]%3E(Locked))
24 |
25 | Once you have completed that, continue on to part 2 (remember the point is to learn about the impact of changing requirements, so no peeking!) [you can find part 2 here](./part2.md)
26 |
--------------------------------------------------------------------------------
/katas/turnstile/part2.md:
--------------------------------------------------------------------------------
1 | # Part 2
2 |
3 | Now extend it to the following states
4 |
5 | 
6 |
--------------------------------------------------------------------------------
/katas/video-store/README.md:
--------------------------------------------------------------------------------
1 | # Video Store
2 |
3 | Write a system that can build a `statement`, when given `rentals`.
4 |
5 | When there are 3 regular movie rentals for 1, 2 and 3 days respectively, the statement looks like:
6 |
7 | ```
8 | Rental Record for Customer Name
9 | Crazynotes £2.0
10 | Teeth £2.0
11 | The Web £3.5
12 | You owe £7.5
13 | You earned 3 frequent renter points
14 | ```
15 |
16 | ## Regular Movies
17 |
18 | Are £2 for the first 2 days, and £1.50 for each day thereafter.
19 |
20 | You earn 1 frequent renter point no matter the length of the rental.
21 |
22 | ## New Release Movies
23 |
24 | Are £3 per day.
25 |
26 | You earn 1 frequent renter point for a 1 day rental, and 2 for any rental of 2 days or more.
27 |
28 | ## Childrens Movies
29 |
30 | Are £1.50 for the first 3 days, and £1.50 for each day thereafter.
31 |
32 | You earn 1 frequent renter point no matter the length of the rental.
33 |
34 | # References
35 |
36 | This Kata is based upon an example in Martin Fowler's Refactoring book, and is also covered in Episode 3 of [Clean Coders](https://cleancoders.com).
37 |
38 |
--------------------------------------------------------------------------------
/katas/word-wrap/README.md:
--------------------------------------------------------------------------------
1 | # Word Wrap
2 |
3 | You write a class called Wrapper, that has a single static function named wrap that takes two arguments, a string, and a column number. The function returns the string, but with line breaks inserted at just the right places to make sure that no line is longer than the column number. You try to break lines at word boundaries.
4 |
5 | Like a word processor, break the line by replacing the last space in a line with a newline.
6 |
7 | ## References
8 |
9 | [codingdojo.org](http://codingdojo.org/kata/WordWrap/)
10 |
--------------------------------------------------------------------------------
/katas/wordle/README.md:
--------------------------------------------------------------------------------
1 | # Wordle
2 |
3 |
4 | Create a program, which, given a 5 character string as a target word, and a 5 character string as a guess, return a 5 character string where:
5 | ```
6 | ‘2’ = this letter is in this position
7 | ‘1’ = this letter is in the target word but not this position
8 | ‘0’ = this letter is either not in the target word, or is not in the target word as many times as it is in the guess
9 | ```
10 |
11 | ## Examples
12 |
13 | ### No matching characters
14 | ```
15 | Target = “ropes”
16 | Guess = “child”
17 | Result = “00000”
18 | ```
19 |
20 | ### Characters match in correct positions
21 | ```
22 | Target = “alert”
23 | Guess = “alarm”
24 | Result = “22020”
25 | ```
26 |
27 | ### Character in wrong position
28 | ```
29 | Target = “stair”
30 | Guess = “chore”
31 | Result = “00010”
32 | ```
33 |
34 | ### Mix of match and wrong position
35 | ```
36 | Target = “hairy”
37 | Guess = “charm”
38 | Result = “01120”
39 | ```
40 |
41 | ### Multiple characters in wrong positions
42 | ```
43 | Target = “reads”
44 | Guess = “elect”
45 | Result = “10000”
46 | ```
47 |
48 |
49 |
--------------------------------------------------------------------------------
/product/index.html:
--------------------------------------------------------------------------------
1 | ---
2 | layout: main
3 | title: Learn product best practices
4 | ---
5 |
6 | {% capture title %}
7 | Learn product best practices
8 | {% endcapture %}
9 |
10 | {% capture text %}
11 | Use these resources to understand what you are delivering to make sure user needs are met.
12 | {% endcapture %}
13 |
14 | {% include digital_element_header.html title=title text=text %}
15 |
16 | {% capture content %}
17 |
18 |
19 |
Maximise your outcomes
20 |
21 | Resources for improving proficiency in delivering made by the team at Made Tech.
22 |
23 |
24 |
25 |
19 |
20 | {% for course in site.data.tech-courses %}
21 | {% if course.bookable %}
22 | {% include tech_course_summary.html course=course %}
23 | {% endif %}
24 | {% endfor %}
25 |
26 |
27 |
33 |
34 |
35 |
London, Tuesday PM 24th October (online) and Wednesday 25th October (in person)
36 |
37 | A 1.5 day bootcamp aimed to build confidence in TDD, use different tools across different areas of testing, and how to bug fix through testing.
38 | Suitable for all levels.
39 | Part 1 will be online, Parts 2 and 3 will be in person. You need to be able to attend all three parts.
40 |
Register
41 |
42 |
43 |
44 |
45 |
46 |
47 | {% endcapture %}
48 |
49 | {% include digital_element_container.html content=content %}
50 |
--------------------------------------------------------------------------------
/technology/core-skills/frontend-development/README.md:
--------------------------------------------------------------------------------
1 | # Frontend development
2 |
3 | ## Aim
4 | This course is intended to guide learning to a level where you can write and contribute semantic, and maintainable HTML and CSS to a project.
5 |
6 | {% capture resources %}
7 | - [Grids](./resources/grids.md)
8 | - [Semantic HTML](./resources/semantic-html.md)
9 | - [Responsive Design](./resources/responsive-design.md)
10 | - [CSS Architecture](./resources/css-architecture.md)
11 | - [Web Typography](./resources/web-typography.md)
12 | - [Icons](./resources/icons.md)
13 | - [Cross Browser Testing](./resources/cross-browser-testing.md)
14 | - [Web Accessibility](./resources/web-accessibility.md)
15 | - [HTML/CSS Standards](./resources/html-css-standards.md)
16 | - [Progressive Enhancement](./resources/progressive-enhancement.md)
17 | - [Web Performance](./resources/web-performance.md)
18 | - [SEO](./resources/seo.md)
19 | {% endcapture %}
20 | {% include skill_resources.html resources=resources %}
21 |
22 |
23 | ## Badges
24 |
25 | ### Rhino
26 |
27 |

28 |
29 | This assessment is in three parts, and can take up to three hours to complete.
30 |
31 |
32 |
33 | #### 1. Semantic HTML
34 |
35 | First, open [this link][rhino-semantic-html-page].
36 |
37 | You'll need to **change five of the HTML tags** so they're more semantic. This might change the page's look slightly.
38 |
39 | You'll also need to **explain why you chose each new tag**.
40 |
41 | [rhino-semantic-html-page]: https://codepen.io/kjdchapman/pen/zXzQYw
42 |
43 | #### 2. Basic CSS
44 |
45 | You need to add styles to [this prepared HTML][rhino-unstyled-html-page], so that it looks like the picture below.
46 |
47 | It doesn't need to be pixel perfect, but the whitespace around the content should look similar.
48 |
49 | 
50 |
51 | [rhino-unstyled-html-page]: https://codepen.io/kjdchapman/pen/mgwYKZ
52 |
53 | #### 3. Accessibility
54 |
55 | You'll need to **identify who** would find using each page difficult.
56 |
57 | Next, you'll need to make a change to **make the page easier** to use.
58 |
59 | Finally, you'll need to **explain why your changes make it better**.
60 |
61 | These are the pages:
62 |
63 | * [Example one][rhino-big-button]
64 | * [Example two][rhino-delivery-healthchecks]
65 | * [Example three][rhino-control-panel]
66 | * [Example four][rhino-click-heres]
67 | * [Example five][rhino-favourite-number]
68 |
69 | [rhino-big-button]: https://codepen.io/anon/pen/YbQyEL
70 | [rhino-delivery-healthchecks]: https://codepen.io/anon/pen/WBOQXV
71 | [rhino-control-panel]: https://codepen.io/anon/pen/xNrZbW
72 | [rhino-click-heres]: https://codepen.io/anon/pen/WBOQLb
73 | [rhino-favourite-number]: https://codepen.io/anon/pen/YbQwbP
--------------------------------------------------------------------------------
/technology/core-skills/frontend-development/resources/cross-browser-testing.md:
--------------------------------------------------------------------------------
1 | # Cross Browser Testing
2 |
3 | A software engineer should be able to validate their front end across multiple browsers and devices in order to ensure that their HTML/CSS looks correct in many browsers.
4 |
5 | An engineer should use tools like [caniuse.com](https://caniuse.com/) to ensure the CSS properties they want to use will be supported by all their target browsers, before even cutting some CSS.
6 |
7 | Often an engineer will be missing some of the browsers they need to test against [Mainly IE] for this they'd install a Virtual Machine (VM). Microsoft make their VMs available on [modern.ie](https://developer.microsoft.com/en-us/microsoft-edge/tools/vms/).
8 |
9 | An easy approach is to use a SaaS tool such a [BrowserStack](https://www.browserstack.com) which allows testing on a myriad of real devices and browsers, without requiring physical access to those devices or those browsers installed on your own machine.
10 |
11 | While testing their front end an Engineer should use a tool like [Pixel Perfect](http://www.welldonecode.com/perfectpixel/) to overlay the expected design, and then adjust their HTML/CSS using the browsers web inspector.
12 |
13 | ## Which browsers to test
14 |
15 | Usually, delivery teams will agree with the customer a list of supported browsers an engineer should test on. However, as a rule of thumb they should always test against:
16 |
17 | - [Firefox](https://www.mozilla.org/en-GB/firefox/new/)
18 | - [Google Chrome](https://www.google.co.uk/chrome/)
19 | - [Safari](https://support.apple.com/en-us/HT204416)
20 | - [Microsoft Edge](https://www.microsoft.com/en-gb/windows/microsoft-edge)
21 |
22 | **Recommended in delivery, but not required for the core skill**
23 |
24 | - [Interet Explorer 11](https://www.microsoft.com/en-gb/download/internet-explorer-11-for-windows-7-details.aspx)
25 |
26 | IE11 is recommended as its the last version of IE pre-installed on Windows machines that doesn't auto update. However, if the user stats point to low usage (less than 2%) then a team could make a case to not support it.
27 |
28 | ## A Caveat, and its controversial.
29 |
30 | While we should always strive to realise a Designer’s vision, there will be some elements of the page (mainly typography) that will be harder to replicate in code. There are situations where the cost of implementing perfect typography outweighs the value derived.
31 |
32 | When working closely with Designers, it is beneficial to help them understand the technical limitations of HTML & CSS. Often, for aspects of a design where perfect typography matters, a designer should be advised to provide SVG assets instead.
33 |
34 | Using the example of Typography an engineer should match the common sense things like `line-height`, `font-size`, `font-family`, there are some things they wont be able to control in a scenario where dynamic text is being used. Kerning is the best example of this. An engineer can broadly apply a `letter-spacing` to all the letters but doing this on a per letter basis is not scalable when the copy is liable to change.
35 |
--------------------------------------------------------------------------------
/technology/core-skills/frontend-development/resources/css-architecture.md:
--------------------------------------------------------------------------------
1 | # CSS Architecture
2 |
3 | A well-written set of stylesheets balance a number of factors including
4 |
5 | * Browser support - does the styling render the same in a wide range of commonly used browsers?
6 | * Ease of change - can we easily change the styles to meet changing customer needs?
7 | * Reuse - can we reuse commonly used styles easily?
8 | * Stability - can we safely change our styles without worrying about unrelated breakages?
9 | * Expressiveness - can we understand what our styles do, and do they make sense?
10 | * Performance - are our styles fast to load and render?
11 |
12 | If this seems overwhelming, don't worry, we're here to help.
13 |
14 | ## CSS Resets
15 |
16 | One issue you will face is that even with a brand-new HTML file, without any stylesheets imported, different browsers will render this file differently. The cause of this is differing browser-default styling.
17 |
18 | The defacto-accepted solution to this is to use a CSS reset stylesheet (of which there are many). A CSS reset will ensure that all browsers have the same basic styles upon which you can start layering custom styles ontop of.
19 |
20 | **Note:** most CSS frameworks prepackage a CSS reset.
21 |
22 | ## CSS Methodologies
23 |
24 | You will also need to choose an approach to achieve a well-architected set of CSS styles.
25 |
26 | ### Component Based CSS
27 |
28 | If you are using React (or similar), it is likely that a Component-based approach makes the most sense
29 |
30 | ### BEM
31 |
32 | Block Element Modifier.
33 |
34 | - http://getbem.com/
35 |
36 | ### we also give a mention to...
37 |
38 | * Component-based CSS
39 | * OOCSS
40 | * Atomic CSS
41 | * Scalable and Modular Architecture for CSS (SMACSS)
42 |
43 | - http://atomicdesign.bradfrost.com/table-of-contents/
44 | - https://smacss.com/book/
45 | - https://maintainablecss.com/chapters/semantics/
46 | - https://css-tricks.com/when-using-important-is-the-right-choice/
47 |
48 | ## CSS Frameworks
49 |
50 | On the one hand, CSS Frameworks are usually battle-tested in multiple browsers. Leveraging one can provide the benefit of support in many browsers. It is also much faster to get going with a CSS Framework, as many common components are likely implemented for you.
51 |
52 | The downside is that many CSS frameworks are usually very large slabs of CSS code, which will have a significant impact on the size of your CSS assets - larger assets mean that your page load times will become slower.
53 |
54 | Another criticism is that CSS frameworks allow you to do things their way, but provide little-to-no help when you want to implement a custom set of styles, and can sometimes hinder this process.
55 |
56 | - https://hacks.mozilla.org/2016/04/you-might-not-need-a-css-framework/
57 | - https://css-tricks.com/what-are-the-benefits-of-using-a-css-framework/
58 |
59 | ## CSS Preprocessors
60 |
61 | - https://designmodo.com/introduction-sass/
62 | - https://lincolnloop.com/blog/linting-scss-sass-lint/
63 |
64 | ## CSS Layout
65 |
66 | - https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout
67 | - https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Floats
68 | - https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox
69 | - https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Basic_Concepts_of_Flexbox
70 | - https://css-tricks.com/snippets/css/a-guide-to-flexbox/
71 |
72 |
--------------------------------------------------------------------------------
/technology/core-skills/frontend-development/resources/grids.md:
--------------------------------------------------------------------------------
1 | # Grids
2 |
3 | Long gone are the days of table based layouts. Engineers use CSS to achieve basic to the most complex of page layouts.
4 |
5 | Understanding of the CSS box model (margin, border, padding etc) should be essential too. Need to get that in here?
6 |
7 | Without using a grid system for creating a layout, there are:
8 |
9 | Floats (including clear for vertical layout considerations)
10 | Positioning (including position relative and absolute)
11 | Flexbox (including flex-direction for vertical layout considerations)
12 |
13 | Engineer can describe each of these and think of both positives and negatives for using each.
14 |
15 | Do we want to list some of the pros/cons that we think there might be? Not all, but some might be subjective.
16 |
17 | Floats will work well in all browsers as this has been around far longer. More complex though (potentially) to build your layout, with having to manage the floats and clears, and calculating various widths and heights manually.
18 |
19 | Flexbox will work well in modern browsers, but not in older ones.
20 |
21 | If not using floats or flexbox, then you could use a grid layout system, such as Twitter Bootstrap.
22 |
23 | Frameworks like Bootstrap are great, but sometimes you don’t need the kitchen sink i.e.bloat, tag soup. The engineer should know when to be pragmatic about the use of a framework, and when to handwrite CSS.
24 |
25 | ### Reading material
26 |
27 | - [CSS layouts](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout)
28 | - [Floats for CSS layouts](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Floats)
29 | - [Flexbox for CSS layouts](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox)
30 | - [Basic Concepts of Flexbox](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Basic_Concepts_of_Flexbox)
31 | - https://hacks.mozilla.org/2016/04/you-might-not-need-a-css-framework/
32 | - https://css-tricks.com/what-are-the-benefits-of-using-a-css-framework/
33 |
--------------------------------------------------------------------------------
/technology/core-skills/frontend-development/resources/html-css-standards.md:
--------------------------------------------------------------------------------
1 | # HTML/CSS Standards
2 |
3 | ### Useful Tools
4 |
5 | - [WebHint](https://webhint.io/)
6 | - [SASS Lint](https://github.com/sasstools/sass-lint)
7 | - [HTML Lint](https://github.com/htmllint/htmllint)
8 |
--------------------------------------------------------------------------------
/technology/core-skills/frontend-development/resources/icons.md:
--------------------------------------------------------------------------------
1 | # Icons
2 |
3 | ### Useful links
4 |
5 | - https://css-tricks.com/icon-fonts-vs-svg/
6 | - https://css-tricks.com/svg-sprites-use-better-icon-fonts/
7 |
8 |
9 | ### Useful tools
10 |
11 | - [IcoMoon](https://icomoon.io/app/#/select)
12 |
--------------------------------------------------------------------------------
/technology/core-skills/frontend-development/resources/progressive-enhancement.md:
--------------------------------------------------------------------------------
1 | # Progressive Enhancement
2 |
3 | ### Useful Links
4 |
5 | https://www.smashingmagazine.com/2009/04/progressive-enhancement-what-it-is-and-how-to-use-it/
6 | https://zurb.com/word/progressive-enhancement
7 |
--------------------------------------------------------------------------------
/technology/core-skills/frontend-development/resources/responsive-design.md:
--------------------------------------------------------------------------------
1 | # Responsive Design
2 |
3 | ## What does it mean for a design to be 'responsive'?
4 | Your site/app _responds_ to the screen it's being browsed on.
5 |
6 | More generally, it's about _responding to user need_, but screen size is the most common consideration.
7 |
8 | ## What's this 'viewport' that people keep mentioning?
9 |
10 | Your user's _viewport_ is their view of your site, which may be smaller than all of the content you're trying to show.
11 |
12 | ## Why should I care about responsive design?
13 |
14 | If you have to work to adjust your site for only some of your users, you're spending time (and money!) not providing value to _the rest_ of your users.
15 |
16 | The most efficient way to build things is to make them usable by _everyone_. This won't always be practical, but it's a good starting point.
17 |
18 | It's also the best way to build things for the long-term. How people browse the web will continue to evolve in ways we haven't predicted.
19 |
20 | ## Why should I design 'mobile-first'?
21 |
22 | This is often justified by the increasing number of people browsing on mobile devices.
23 |
24 | Even if your site isn't heavily used on mobile right now, it's still worth considering, because _doing the hardest thing first tends to lead to better results_.
25 |
26 | **Restrictions breed creativity**. You'll often find simpler and more efficient ways to present your content if you start without the freedom of a large viewport.
27 |
28 | ## What are some techniques I can use to achieve a responsive design?
29 |
30 | - Design for smaller viewports first (this is sometimes called 'mobile-first')
31 | - Change some components at certain size breakpoints using [media queries](https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Using_media_queries)
32 | - Use modern styling techniques like [the CSS flexbox layout](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Basic_Concepts_of_Flexbox)
33 | - Use a styling framework with responsivity built-in, like [Bootstrap](https://getbootstrap.com/) or [Foundation](https://foundation.zurb.com/)
34 |
35 | ## Where can I learn more?
36 |
37 | [Responsive Web Design Basics](https://developers.google.com/web/fundamentals/design-and-ux/responsive) from Google's "Web Fundamentals" guide.
38 |
39 | Ethan Marcotte, coiner of the term "Responsive Design", [going into some detail about why it's important](https://alistapart.com/article/responsive-web-design).
40 |
41 | A [Government Digital Service blog post](https://gds.blog.gov.uk/2012/11/02/designing-for-different-devices) diving into how to use some of the techniques.
42 |
--------------------------------------------------------------------------------
/technology/core-skills/frontend-development/resources/rhino-expected-styles.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madetech/learn/5a0c5dce6caf79dd4723ef9261c09198c5fb9dae/technology/core-skills/frontend-development/resources/rhino-expected-styles.png
--------------------------------------------------------------------------------
/technology/core-skills/frontend-development/resources/semantic-html.md:
--------------------------------------------------------------------------------
1 | # Semantic HTML
2 |
3 | ## What do we mean by 'Semantic'?
4 | Semantic HTML is the use of HTML markup emphasising the _meaning_ of the information that it contains.
5 |
6 | This is in contrast to markup that focuses on _presentation_ or _visual structure_.
7 |
8 | ### Why worry about being 'Semantic'?
9 |
10 | - It helps produce clearer, simpler code, which reduces total cost of ownership.
11 |
12 | - It helps you, your team, and any of the next readers of your code, as they will find it easier to understand your original intent.
13 |
14 | - It has benefits for [accessibility](/technology/core-skills/frontend-development/resources/web-accessibility) - not everyone will consume your content the same way, so describing things more clearly will help.
15 |
16 | ## Examples
17 |
18 | [This article](https://internetingishard.com/html-and-css/semantic-html/) has excellent examples of using the HTML5 semantic elements to produce more meaningful markup.
19 |
20 | Mozilla highlights [some of these new elements](https://developer.mozilla.org/en-US/docs/Glossary/Semantics#Semantic_elements), and has [references and guides around their use](https://developer.mozilla.org/en-US/docs/Web/HTML)
21 |
--------------------------------------------------------------------------------
/technology/core-skills/frontend-development/resources/seo.md:
--------------------------------------------------------------------------------
1 | # SEO
2 |
3 | ### Useful links
4 |
5 | - https://moz.com/learn/seo/schema-structured-data
6 | - https://developers.google.com/search/docs/guides/intro-structured-data
7 |
8 | ### Useful references
9 |
10 | - http://schema.org/
11 | - http://microformats.org/
12 |
13 | ### Useful tools
14 |
15 | - https://search.google.com/structured-data/testing-tool/u/0/
16 |
--------------------------------------------------------------------------------
/technology/core-skills/frontend-development/resources/web-accessibility.md:
--------------------------------------------------------------------------------
1 | # Web Accessibility
2 |
3 | - Accessibility
4 | - ARIA
5 | - WCAG
6 | - Screen Reader
7 | - Colour blindness/Contrast
8 | - Accessibility tags on forms
9 | - Tab indexing?
10 | - Keyboard shortcuts for standard links, home etc?
11 |
12 | ### Reading materials
13 |
14 | - [https://alistapart.com/blog/topic/accessibility/](https://alistapart.com/blog/topic/accessibility/)
15 | - [https://alistapart.com/article/color-accessibility-workflows](https://alistapart.com/article/color-accessibility-workflows)
16 | - [https://www.w3.org/WAI/gettingstarted/tips/developing](https://www.w3.org/WAI/gettingstarted/tips/developing)
17 |
18 | ### Useful tools
19 |
20 | - [https://dynomapper.com/blog/27-accessibility-testing/246-top-25-awesome-accessibility-testing-tools-for-websites]()
21 | - [http://code.viget.com/interactive-wcag/#role=&level=aa]()
22 | - [https://webaim.org/techniques/screenreader/]()
23 | - [http://www.color-blindness.com/coblis-color-blindness-simulator/]()
24 | - [https://www.wuhcag.com/wcag-checklist/]()
25 | - [https://www.marcozehe.de/2018/04/11/introducing-the-accessibility-inspector-in-the-firefox-developer-tools/]()
26 |
27 | ### The Standard
28 |
29 | - [https://www.w3.org/TR/wai-aria-1.1/]()
30 |
--------------------------------------------------------------------------------
/technology/core-skills/frontend-development/resources/web-performance.md:
--------------------------------------------------------------------------------
1 | # Web Performance
2 |
3 | ### Useful Links
4 |
5 | https://developers.google.com/speed/docs/insights/rules
6 | https://responsivedesign.is/articles/prefetch-preconnect-dns-priority/
7 | https://www.cloudflare.com/learning/cdn/what-is-a-cdn/
8 |
9 | ### Useful Tools
10 |
11 | #### Online Image Optimizers
12 |
13 | - https://imageoptim.com/online
14 | - https://imagecompressor.com/
15 |
--------------------------------------------------------------------------------
/technology/core-skills/frontend-development/resources/web-typography.md:
--------------------------------------------------------------------------------
1 | # Web Typography
2 |
3 | ### Useful Links
4 |
5 | https://practicaltypography.com/straight-and-curly-quotes.html
6 | https://css-tricks.com/almanac/properties/f/font-feature-settings/
7 | http://pierrickcalvez.com/journal/a-five-minutes-guide-to-better-typography
8 | https://blog.marvelapp.com/body-text-small/
9 |
--------------------------------------------------------------------------------
/technology/core-skills/frontend-development/resources/working-with-photoshop.md:
--------------------------------------------------------------------------------
1 | https://www.netguru.co/blog/photoshop-for-front-end-developers
2 |
--------------------------------------------------------------------------------
/technology/core-skills/frontend-development/rhino.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madetech/learn/5a0c5dce6caf79dd4723ef9261c09198c5fb9dae/technology/core-skills/frontend-development/rhino.jpg
--------------------------------------------------------------------------------
/technology/core-skills/infrastructure/README.md:
--------------------------------------------------------------------------------
1 | # Infrastructure
2 |
3 | ## Goal
4 |
5 | 1. Increase the reliability of services
6 | 2. Ensure compliance with international security standards
7 | 3. Reduce the chance of knowledge silos developing within teams
8 |
9 | ## Summary
10 |
11 | Demonstrate understanding of:
12 |
13 | 1. Making a service Scalable
14 | 2. Making a service Highly Available
15 | 3. Principle of Least Privilege
16 | 4. Zero-downtime deployments
17 |
18 | ## Assessments
19 |
20 | *The infra badge assessments are designed to be undertaken in any order, Spider is recommended to be taken first*
21 |
22 | ### Ant (Level 1)
23 |
24 | #### Brief
25 |
26 | Be able to set up a highly available, internet-facing web application.
27 |
28 | #### Theory
29 |
30 | 1. What are IaaS, PaaS, and FaaS?
31 | 1. For each of these; Discuss a scenario where the technology is appropriate
32 | 2. For each of these; Discuss a scenario where the technology is not appropriate
33 | 2. What is the importance of having a highly available service?
34 |
35 | #### Practical
36 |
37 | You will be provided a Linux Container Image, though you can use your own if you wish.
38 |
39 | - Run the image with your choice of IaaS.
40 | - Make the service highly available
41 | - Draw a diagram of your infrastructure
42 | - Demonstrate that you can remove an instance, and your infrastructure will self-heal
43 | - Demonstrate that you can roll out a new deployment without causing any downtime.
44 | Use the provided [downtime detection script][downtime-script].
45 |
46 |
47 | ### Spider (Level 2)
48 | Be able to make secure cloud applications and services.
49 |
50 | #### Brief
51 |
52 | Resources:
53 | - http://progressivecoder.com/understanding-aws-security-groups-and-best-practices-to-use-them/
54 | - https://www.jakoblell.com/blog/2013/08/13/quick-blind-tcp-connection-spoofing-with-syn-cookies/
55 | - - no need to read this entire article ^ section V is relevant
56 |
57 | #### Theory
58 |
59 |
60 | There is a cloud-hosted public web server that talks to a backend API in a private network. The private server's network allows the IP of the public server via an allow list rule on its Firewall.
61 |
62 | 1. Explain what maintenance overhead IP allow-listing adds for future developers?
63 | 2. Explain the security problems with using only IP allow-listing for authentication?
64 | 3. What are the benefits of investing in monitoring and alerting in software environments?
65 |
66 | #### Practical
67 |
68 | - You will need to show and demonstrate a infrastructure as code project (e.g. terraform) that can setup and teardown the following:
69 | - 2 file storage buckets (or azure blob storage containers)
70 | - A new user with a set of access credentials that only has permission to retrieve (***not list or modify**) files in **one** bucket
71 | - Enable request monitoring on the bucket so that the assessor can get the number of HTTP GET requests made to bucket over time.
72 | - You will be asked to setup and take down you infa
73 |
74 | ### Bee (Level 3)
75 |
76 | #### Brief
77 |
78 | #### Theory
79 |
80 | #### Practical
81 |
82 | ## Limitations
83 |
84 | ### Provider requirements
85 |
86 | There are certain providers, usually PaaS only providers, that do not offer the
87 | the functionality we require for testing people on all the above aspects.
88 |
89 | As such, we recommend avoiding solutions that hide:
90 |
91 | - load balancing
92 | - autoscaling
93 | - networking rules (routing, Firewalls)
94 |
95 | Providers that can definitely be used are:
96 |
97 | - AWS
98 | - ECS with FARGATE is fine, though be prepared for increased theory work around deployment processes
99 | - Lambda is not recommended, as it hides a lot of networking rules, autoscaling, and deployment processes
100 | - Elastic Beanstalk is not allowed, as it does everything for you, but in a way that makes it hard to adapt after the fact.
101 | - Azure
102 | - GCP
103 |
104 | ## Appendix
105 |
106 | ### Downtime Script
107 |
108 | ```sh
109 | target="
"
110 | while :; do
111 | if (curl -m 1 "$target" &>/dev/null); then
112 | printf '.'
113 | else
114 | echo "target is down"
115 | break
116 | fi
117 | sleep 0.5
118 | done
119 | ```
120 |
121 | [downtime-script]: #downtime-script
122 |
--------------------------------------------------------------------------------
/technology/core-skills/react/fox.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madetech/learn/5a0c5dce6caf79dd4723ef9261c09198c5fb9dae/technology/core-skills/react/fox.png
--------------------------------------------------------------------------------
/technology/core-skills/react/functional-and-class.md:
--------------------------------------------------------------------------------
1 | # React - Functional and Class Components
2 |
3 | An Engineer with this core skill should be able to write components as either class based or functional components
4 | and decide what is best suited for their use case.
5 |
6 | This involves being able to identify which type an existing component is, along with being able to write both types, with props, state and lifecycle hooks.
7 |
8 | ### Reading material
9 |
10 | - [Understand Functional and Class Components](https://codeburst.io/react-js-understanding-functional-class-components-e65d723e909)
11 |
--------------------------------------------------------------------------------
/technology/core-skills/react/fundamentals/README.md:
--------------------------------------------------------------------------------
1 | # React Fundamentals
2 |
3 | ## Summary
4 |
5 | React is a framework with a number of moving parts, components, states, props, etc. It
6 | can be very easy to begin writing components without properly understanding how each of
7 | these should be used and how to use them.
8 |
9 | An Engineer who has passed this core skill would be expected to understand what each of these
10 | parts are, and when to use one over the other (i.e. When should you put something in a prop instead
11 | of the state).
12 |
13 | The first chapter of React's documentation, [Describing the UI](https://react.dev/learn/describing-the-ui) is important reading.
14 |
15 | - [Passing props to a component](https://react.dev/learn/passing-props-to-a-component)
16 | - [State: A Component's Memory](https://react.dev/learn/state-a-components-memory)
17 | - [Responding to Events](https://react.dev/learn/responding-to-events)
18 | - Handling Application State
19 | - To handle application state, you can either use something like the [React Context API](https://react.dev/learn/passing-data-deeply-with-context),
20 | or look into a library such as [Redux](https://redux.js.org/introduction)
21 |
--------------------------------------------------------------------------------
/technology/core-skills/react/hedgehog.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madetech/learn/5a0c5dce6caf79dd4723ef9261c09198c5fb9dae/technology/core-skills/react/hedgehog.png
--------------------------------------------------------------------------------
/technology/core-skills/react/owl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madetech/learn/5a0c5dce6caf79dd4723ef9261c09198c5fb9dae/technology/core-skills/react/owl.png
--------------------------------------------------------------------------------
/technology/core-skills/react/setup.md:
--------------------------------------------------------------------------------
1 | # Setting up a React Project
2 |
3 | An Engineer with this core skill should be able to adequetly set up a React app in
4 | an understandable and consistent manner.
5 |
6 | This would involve ensuring that the application can be run on any development machine,
7 | have easy to run tests, and have a tool to aid in rapid prototyping of React components.
8 |
9 | ### Reading material
10 |
11 | - Setup
12 | - Setting up a React application can be done by hand, or by using
13 | [Create React App](https://github.com/facebook/create-react-app).
14 | - Testing
15 | - Coming soon
16 | - Prototyping React Components
17 | - A popular tool for this is [Storybook](https://storybook.js.org/)
18 |
--------------------------------------------------------------------------------
/technology/core-skills/react/why-and-when.md:
--------------------------------------------------------------------------------
1 | # React - Why and when should I use it?
2 |
3 | An Engineer with this core skill should be able to make well informed decisions on whether or not
4 | the application they are building would be helped or hindered by the introduction of React.
5 |
6 | ### Reading material
7 |
8 | - [When does a project need React? - CSS Tricks](https://css-tricks.com/project-need-react/)
9 |
10 | ### What situations is React suited for?
11 |
12 | Things to think about when making the decision as to whether you should use React for a project:
13 |
14 | - Does your application require a lot of client side business logic?
15 | - Would the customer benefit significantly from having fast page load times?
16 | - Do you need simple and reusable components?
17 | - Could your application benefit from selective reloading? I.e. does anything on the page need to react?
18 | - Is an existing customer development team already using React or NodeJS?
19 | - Does your application require a lot of DOM manipulation?
20 |
21 |
--------------------------------------------------------------------------------
/technology/core-skills/tdd/discipline.md:
--------------------------------------------------------------------------------
1 | # Demonstrating the Discipline
2 |
3 | An Engineer with this core skill must be able to demonstrate the ability to follow this discipline religiously.
4 |
5 | Test-Driven Development is defined as a discipline with three rules:
6 |
7 | 1. You MUST write a failing test before you write any production code.
8 | 2. You MUST not write more of a test than is sufficient to fail, or fail to compile.
9 | 3. You MUST not write more production code than is sufficient to make the currently failing test pass.
10 |
11 | ## Reading material
12 |
13 | - [Red-Green-Refactor definition, explanation; The Art of Agile - James Shore](http://www.jamesshore.com/Blog/Red-Green-Refactor.html)
14 | - [Code wars - Library of programming exercises](http://www.codewars.com)
15 | - [Transformation Priority Premise](https://en.wikipedia.org/wiki/Transformation_Priority_Premise)
16 |
17 | ## Marking Scheme
18 |
19 | * Writes a failing test before writing production code
20 | * Watches the failing test fail for right reason before writing production code
21 | * Writes only the minimum production code for a test to pass
22 | * Watches the passing test pass before moving onto refactoring
23 | * Refactors tests
24 | * Refactors production code
25 |
26 |
--------------------------------------------------------------------------------
/technology/core-skills/tdd/dragon.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madetech/learn/5a0c5dce6caf79dd4723ef9261c09198c5fb9dae/technology/core-skills/tdd/dragon.jpg
--------------------------------------------------------------------------------
/technology/core-skills/tdd/giraffe.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madetech/learn/5a0c5dce6caf79dd4723ef9261c09198c5fb9dae/technology/core-skills/tdd/giraffe.jpg
--------------------------------------------------------------------------------
/technology/core-skills/tdd/inappropriate.md:
--------------------------------------------------------------------------------
1 | # When is TDD inappropriate
2 |
3 | ## Validation of correctness cannot be obtained via an automated check.
4 |
5 | Sometimes you can find a proxy for "correctness" which will make you feel like TDD is possible.
6 | If you aren't feeling confident that your tests are guarding against regression, this is a signal that you shouldn't be using TDD.
7 |
8 | Graphical UIs are an example of software not suitable for TDD, they are usually defined in a markup language which can only be asserted for correctness by visually inspecting the rendered output.
9 | There may still be some tests which are useful to add to your UI components, e.g. an automated accessibility checker, but this shouldn't replace a professional accessibility audit of your product.
10 |
11 | Configurations are also not suitable for TDD, their correctness can only be ascertained by testing the configuration in conjunction with whatever they are configuring.
12 | State machines are configuration. Unit testing is still important, but the discipline of TDD is not.
13 |
14 | ## Testing feedback cycles are slow
15 |
16 | Some software is hard to test because of inadequate test tooling.
17 | A slow test driven development cycle is painful and unproductive.
18 | Appropriate TDD makes your development cycle faster via fewer defects, and testable code.
19 | Weigh up the benefits of test driven development vs the cost of delaying your development in this scenario.
20 |
21 | Investing time into researching how to create fast feedback cycles can have huge gains in productivity.
22 |
23 | ## Marking Scheme
24 |
25 | * Does not TDD markup (e.g. HTML, LaTeX).
26 |
--------------------------------------------------------------------------------
/technology/core-skills/tdd/performance.md:
--------------------------------------------------------------------------------
1 | # Test suite performance
2 |
3 | TDD relies on quick feedback cycles,
4 | therefore Delivery Teams SHOULD make it possible to run
5 | individual test suites within the ecosystem of an application
6 | in under 30 seconds. Furthermore, it SHOULD be possible to run
7 | the test suites of an entire application in under 5 minutes.
8 | If this time limit is exceeded,
9 | Delivery Teams SHOULD plan in effort to reduce test suite run times.
10 |
11 | Test suite performance is also an indicator of structural defects.
12 |
13 | ## Reading Materials
14 |
15 | * [TDD test suites should run in 10 seconds or less - Mark Seemann](http://blog.ploeh.dk/2012/05/24/TDDtestsuitesshouldrunin10secondsorless/)
16 | * [Are Slow Tests Killing Your Feedback Loop? - Jon Reid](https://qualitycoding.org/slow-tests/)
17 | * [Working Effectively with Legacy Code - book by Michael Feathers](https://www.amazon.co.uk/dp/0131177052)
18 |
19 | ## Marking scheme
20 |
21 | * Can describe why test suite performance is important.
22 | * Can identify structural defects that result in poor test suite performance.
23 | * Can identify that a test suite has poor test suite performance.
24 | * Can improve the performance of a slow test suite.
25 |
26 |
--------------------------------------------------------------------------------
/technology/core-skills/tdd/remote-services.md:
--------------------------------------------------------------------------------
1 | # Testing remote services
2 |
3 | A remote services is any cross process communication. Let’s look at some examples:
4 |
5 | * MySQL
6 | * A Solidus API
7 | * S3
8 |
9 | In each case you want to be able to test that your communication with this remote service is set up correctly. However your approach to each will likely be very different.
10 |
11 | ### Running your tests against the service
12 |
13 | Your MySQL integration will usually be tested by running a copy of MySQL configured as closely to your production instance as possible.
14 |
15 | A Solidus API could be tested similarly, this would require setting up the Rails server + MySQL backend. As remote services get more complex, the cost of booting up the service gets more expensive and therefore more unattractive.
16 |
17 | Another approach to testing against the real service would be to use the production instance but authenticating a different user, say with S3.
18 |
19 | ### Running your tests against a simulator
20 |
21 | In some instances it may be impossible or impractical to run your tests against the real service, in which case there are number of simulation options available.
22 |
23 | * WebMock
24 | * VCR
25 |
26 | Simulators are designed to allow you to easily configure how the remote service will respond in a test. This can be very attractive when the remote service you want to test is hard to get it a specified state, e.g. creating Solidus orders.
27 |
28 | ## Reading Material
29 |
30 | * [How to Stub External Services in Tests - Harlow Ward](https://robots.thoughtbot.com/how-to-stub-external-services-in-tests)
31 |
32 | ## Marking Scheme
33 |
34 | * Can explain benefits of the different ways of testing remote services.
35 | * Can implement an appropriate method of testing a remote service.
36 |
37 | ## Other Notes
38 |
39 | Strategies for other types of protocols e.g. AMQP, RADIUS, UDP-packets?
40 |
41 | Can explain what testing technique they would recommend to use for a remote service.
42 |
43 |
--------------------------------------------------------------------------------
/technology/core-skills/tdd/test-doubles.md:
--------------------------------------------------------------------------------
1 | # Test Doubles
2 |
3 | At Made Tech we have adopted the Martin Fowler terminology of test doubles.
4 | You can read an in depth explanation of test doubles on his website.
5 | When using one of these test doubles you should be able to
6 | explain which type you are using.
7 |
8 | * Dummy
9 | * Stubs
10 | * Spies
11 | * Fake
12 | * True Mocks
13 |
14 | ## Reading material
15 |
16 | * [Mocks Aren't Stubs - Martin Fowler](https://martinfowler.com/articles/mocksArentStubs.html)
17 | * [Understanding Test Double Types](https://nirajrules.wordpress.com/2011/08/27/dummy-vs-stub-vs-spy-vs-fake-vs-mock/)
18 |
19 | ## Marking scheme
20 |
21 | * Can identify the type of test double from code they haven’t written.
22 | * Can hand-write each of the test doubles.
23 | * Can explain when you should and shouldn’t use test doubles.
24 | * Can explain why minimizing the number of test doubles a single test case uses is desirable
25 |
26 |
--------------------------------------------------------------------------------
/technology/core-skills/tdd/triangulation.md:
--------------------------------------------------------------------------------
1 | # Triangulation
2 |
3 | Given a method f which has the production code as follows:
4 |
5 | ```ruby
6 | def eat_cake(cake)
7 | unwrap(cake)
8 | eat(cake)
9 | end
10 | ```
11 |
12 | When TDDing you need at least 2 tests to be confident that your method hasn’t been slimed. With only 1 test you can pass the test by hard coding the tested value. E.g.
13 |
14 | ```ruby
15 | def test_eating_cake_eats_carrot_cake
16 | eat_cake(:carrot_cake)
17 | expect(eat).called_with :carrot_cake
18 | end
19 |
20 | def eat_cake(cake)
21 | eat(:carrot_cake)
22 | end
23 | ```
24 |
25 | ## Marking scheme
26 |
27 | * Can describe the situations where using triangulation helps improve test quality.
28 | * Can demonstrate examples of where they have used triangulation.
29 | * Can demonstrate triangulation when TDDing an example piece of code.
30 |
31 |
--------------------------------------------------------------------------------
/technology/core-skills/tdd/well-designed-tests.md:
--------------------------------------------------------------------------------
1 | # Well-designed tests
2 |
3 | An Engineer with this core skill must be able to demonstrate good Test Design.
4 |
5 | * Avoid tight coupling between test code and production code
6 | * Conciseness of test suite
7 | * Maximizing behaviours tested by 1 suite
8 | * Minimizing audiences that a test suite speaks to
9 |
10 | ### Conciseness
11 |
12 | Something about conciseness.
13 |
14 | ### Coupling between Test Cases and Production Code
15 |
16 | Engineers that consider coupling avoid causing unnecessary code churn induced by too much tight coupling.
17 |
18 | If there is one call-site to a particular function then that function is easy to change
19 |
20 | It is desirable to ensure that the public interface of production code can evolve at a different rate to the test cases.
21 |
22 | Conversely it is not desirable to need to update all your test cases to change the public interface
23 |
24 | ## Reading Material
25 |
26 | * [Smells in Test that indicate Design problems - AgileFAQs](https://blogs.agilefaqs.com/2009/02/01/smells-in-test-that-indicate-design-problems/)
27 |
28 | ## Marking scheme
29 |
30 | * Can identify smells within code they have written.
31 | * Can identify smells within somebody else's code.
32 | * Can explain the balancing act of achieving conciseness of a test suite
33 |
34 |
--------------------------------------------------------------------------------
/technology/core-skills/tdd/well-written-tests.md:
--------------------------------------------------------------------------------
1 | # Well-written tests
2 |
3 | An Engineer with this core skill must be able to demonstrate how to write readable tests.
4 |
5 | Talk about the audience of your tests. (end user that uses the behaviour of the program)
6 |
7 | A common pattern to achieve readable tests, is to structure it into 4 components:
8 |
9 | * Arrange [optional]
10 | * Act
11 | * Assert
12 | * Teardown [optional]
13 |
14 | To achieve readability, each of these components needs to be clearly identifiable through self-explanatory descriptors.
15 |
16 | To avoid repetition use of helper methods, common setup/teardown before/after blocks should be used to group common behaviours. This also has the benefit of aiding the identifiability of each component.
17 |
18 | ## Reading material
19 |
20 | * [Four-Phase Test - Gerard Meszaros](http://xunitpatterns.com/Four%20Phase%20Test.html)
21 | * [Writing Better Tests With JUnit - Tobias Goeschel](https://www.codecentric.de/en/knowledge-hub/blog/writing-better-tests-junit)
22 |
23 | ## Marking scheme
24 |
25 | * Can write tests which follow the AAAT
26 | * Can describe expected behaviours from the perspective of the user
27 | * Can refactor poorly written test suite to remove duplication
28 |
--------------------------------------------------------------------------------
/technology/core-skills/tdd/wolf.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madetech/learn/5a0c5dce6caf79dd4723ef9261c09198c5fb9dae/technology/core-skills/tdd/wolf.jpg
--------------------------------------------------------------------------------
/technology/event-plans/README.md:
--------------------------------------------------------------------------------
1 | # Event Plans
2 |
3 | ## Made Learning Day
4 |
5 | The Made Learning Day format is our oldest 100% learning-focused full day format.
6 |
7 | The goal of a Made Learning Day is to focus on learning outcomes, unlike hack days or similar.
8 |
9 | Made Learning Days can be focused around learning any skill.
10 |
11 | * [Facilitator Guide](./mld/facilitators-guide)
12 |
13 | ## Worksheets
14 |
15 | * [GNU Smalltalk](./mld/gnu-smalltalk)
16 | * [Common Lisp](./mld/common-lisp)
17 | * [Erlang](./mld/erlang)
18 | * [F#](./mld/fsharp)
19 |
20 |
--------------------------------------------------------------------------------
/technology/event-plans/mld/common-lisp.md:
--------------------------------------------------------------------------------
1 | # Common Lisp MLD: Worksheet
2 |
3 | **You aren’t expected to finish all these exercises.**
4 |
5 | ## Exercise 1
6 |
7 | Goto [craigjbass/lisp-koans](https://github.com/craigjbass/lisp-koans) and follow the **Docker instructions**
8 |
9 | ## Exercise 2
10 |
11 | You are expected to practice TDD for this exercise
12 |
13 | Build a solution to the [Tennis kata](../../katas/tennis/) in Common Lisp.
14 |
15 | - You can use [this scaffold project](https://github.com/madetech/common-lisp-scaffold) as a basis for TDDing in Common Lisp.
16 |
17 | ### Retrospect
18 |
19 | - Common Lisp has many dialects. Why do you think that is? What benefit does that provide?
20 | - Consider how a UI might use your Tennis game implementation. Do you think you could make any improvements?
21 |
22 |
--------------------------------------------------------------------------------
/technology/event-plans/mld/erlang.md:
--------------------------------------------------------------------------------
1 | # Erlang MLD: Worksheet
2 |
3 | **You aren’t expected to finish all these exercises.**
4 |
5 | ## Exercise 1
6 |
7 | Goto [craigjbass/erlang-koans](https://github.com/craigjbass/erlang-koans) and follow the **Docker instructions**
8 |
9 | ## Exercise 2
10 |
11 | You are expected to practice TDD for this exercise
12 |
13 | Create a process that can
14 |
15 | * Store a piece of data and assign it a unique key
16 | * Lookup a piece of data by it’s key
17 | * Fetch all pieces of data held
18 |
19 | - You can use [this scaffold project](https://github.com/madetech/erlang-scaffold) as a basis for TDDing in Erlang.
20 |
21 | ### Retrospect
22 |
23 | * Is your public API easy to use? Any improvements?
24 | * Is your test suite designed well? How coupled is it to the public API?
25 |
26 |
27 |
--------------------------------------------------------------------------------
/technology/event-plans/mld/facilitators-guide.md:
--------------------------------------------------------------------------------
1 | # Facilitators Guide
2 |
3 | ## Introduction Presentation
4 |
5 | - Agenda
6 | - Models of Learning
7 | - Comfort - Learning - Panic zone
8 | - Deliberate Practice
9 | - Pomodoro Technique
10 | - Overview of MLD Specific Skills (e.g. TDD)
11 |
12 | ## Agenda
13 |
14 | - Presentation
15 | - Learning (repeat pomodoros until lunch)
16 | - 1 hour lunch
17 | - Learning (repeat pomodors until show & tell)
18 | - 30 minute Show & Tell
19 |
20 | ## Self-organisation
21 |
22 | Figure out target mentor group e.g. if doing a MLD on TDD, this could be all the people who have done some TDD before.
23 |
24 | - Ask individuals in your target mentor group to raise their hands
25 | - Tell everyone else to find someone with their hand up
26 | - Give clearly defined amount of time to pair or group up
27 | - Be explicit about whether you expect pairs or small groups (3s)
28 | - If anyone is left over, find them a group quickly and quietly
29 |
30 | ## Time Keeping
31 |
32 | The format is 25 minute pomodoros on a global clock, with 5 minute breaks in between.
33 |
34 | - You should enforce that everyone stands up, hands off keyboards.
35 | - Using loud projected voice to get people's attention.
36 | - Feel free to use Japanese words such as Hajime and Yame.
37 | - Encourage people to mingle and chat about their progress.
38 | - Allow people to discuss other things too.
39 |
40 | ## Coaching
41 |
42 | Go around and look for common anti-patterns, examples:
43 |
44 | - One person doing all the talking, using the screen or even making the screen unavailable to other people in pair/mob.
45 | - Panic zone - one or more individuals unable to make progress.
46 | - You may not have the knowledge to get them out of the panic zone, avoid the temptation to be dragged into the panic zone yourself.
47 | - If you have the knowledge, ask them questions that help them get into the learning zone.
48 | - Explore with the learner how they might discover for themselves the knowledge that they are attempting to seek.
49 | - Find other teams who have that knowledge - suggest that they use the breaks to speak to them.
50 | - Comfort zone - one or more individuals may not be challenged.
51 | - Ask them thought provoking open-ended questions
52 | - Challenge any assumptions that they have made
53 | - If possible, question any opinions that they have
54 | - Mention to individuals interesting things you've noticed that could make good Show & Tells
55 | - Nudge people about Show & Tells gently
56 |
57 | ## Show & Tell
58 |
59 | Invite people to talk a little about what they learned
60 |
61 | Have a screen ready to make it possible for people to show code.
62 |
63 | - This could be to show their favourite feature
64 | - Could be to show some code
65 | - Could be to talk about things that they don't like or found surprising.
66 | - Could be to get criticism on code written during the day
67 |
--------------------------------------------------------------------------------
/technology/event-plans/mld/fsharp.md:
--------------------------------------------------------------------------------
1 | # F# MLD: Worksheet
2 |
3 | **You aren’t expected to finish all these exercises.**
4 |
5 | ## Exercise 1
6 |
7 | Goto [craigjbass/FSharpKoans](https://github.com/craigjbass/FSharpKoans) and follow the **Docker instructions**
8 |
9 | ## Exercise 2
10 |
11 | You are expected to practice TDD for this exercise
12 |
13 | Build a solution to the [Tennis kata](../../katas/tennis/) in F#.
14 |
15 | ### Retrospect
16 |
17 | - F# is a multi-paradigm language, well-known for it's functional programming features. What benefit does type-inference provide?
18 | - Consider your Tennis solution. In what ways could you make it more functional?
19 |
20 |
--------------------------------------------------------------------------------
/technology/event-plans/mld/gnu-smalltalk.md:
--------------------------------------------------------------------------------
1 | # GNU Smalltalk MLD: Worksheet
2 |
3 | **You aren’t expected to finish all these exercises.**
4 |
5 | ## Exercise 1
6 |
7 | Goto [craigjbass/gnu\_smalltalk\_koans](https://github.com/craigjbass/gnu_smalltalk_koans) and follow the **Docker instructions**
8 |
9 | ## Exercise 2
10 |
11 | You are expected to practice TDD for this exercise
12 |
13 | Build a solution to the [Tennis kata](../../katas/tennis/) in GNU Smalltalk.
14 |
15 | - You can use [this scaffold project](https://github.com/madetech/gnu-smalltalk-scaffold) as a basis for TDDing in GNU Smalltalk.
16 |
17 | ### Retrospect
18 |
19 | - GNU Smalltalk is a really old language (first release was in 1972!). What can we learn from such an old programming language?
20 | - Consider how a UI might use your Tennis game implementation. Do you think you could make any improvements?
21 |
22 |
--------------------------------------------------------------------------------
/technology/goals/README.md:
--------------------------------------------------------------------------------
1 | # Deliberate Learning Goals
2 |
3 | In order to do deliberate learning, it's important to:
4 |
5 | - set a goal for what it is you are going to learn (it must be **Goal Directed**)
6 | - get feedback from a mentor (it must include opportunity for **Feedback**)
7 | - reflect on what you have learned and improve it (you must do **Self-reflection**)
8 |
9 | Once you achieve these three things; you will realise that in order to really learn you cannot simply _absorb knowledge_ you must also **create knowledge**.
10 |
11 | This new knowledge can be small and discrete, or it can be complex and far reaching.
12 |
13 | Finally, to really solidify your learning - Mentor others.
14 |
15 | **And remember, you do not need to know everything to be a successful mentor.**
16 |
17 | ## Onboarding at Made Tech
18 |
19 | Before joining a delivery team, and after following the onboarding guide in the handbook,
20 | you will spend some time with a mentor focussing on skills relevant to delivery teams.
21 |
22 | As a high level summary, we will cover the following -
23 |
24 | 1. Watch the [introduction to TDD screencast](../videos/tennis.md).
25 | 2. (Pair or mob with a mentor on) [code katas](../katas/) using [Test Driven Development](../core-skills/tdd/) discipline.
26 | 3. (Pair or mob with a mentor on) subcutaneous acceptance testing, and ATDD discipline.
27 | 4. Explore the three central components Clean Architecture
28 | - Use Cases
29 | - Gateways (Adapter Pattern)
30 | - Domain Driven Design
31 | 5. Discuss the SOLID principles with a mentor, with reference to Clean Architecture and (A)TDD.
32 | 6. Be introduced to the [Tic Tac Toe sparring exercise](../sparring/tic-tac-toe/)
33 |
34 | ## Deliberate Learning
35 |
36 | If you are looking to focus on learning new skills, it's sometimes difficult to know what to focus on.
37 |
38 | As we know, in order to do Deliberate Practice our learning must be **Goal Directed**.
39 |
40 | In order of priority, here is a (non-exhaustive) short-list of some skills that we think that Software Engineers should know:
41 |
42 | 1. A range of skills which enable working in a team that is:
43 | - regularly showcasing productionized software to customers
44 | - keeping it's commitments
45 | - is building the right thing
46 | - continuously improving
47 | - is enjoyable to work with
48 | 2. [Test Driven Development](../core-skills/tdd/)
49 | 3. Acceptance Testing
50 | 4. Software Architecture
51 | 5. [Web Application Development with React](../core-skills/react/)
52 | 6. [Frontend Development](../core-skills/frontend-development/)
53 | 7. Continuous Delivery / Continuous Integration / DevOps
54 | - Using a PaaS
55 | - Using CI Tooling
56 | - 12 Factor
57 | - Philosophy of DevOps
58 | - Infrastructure as Code
59 | 8. Containerization
60 | - Docker
61 | - Kubernetes
62 |
63 | Please feel free to use this list as a guide to help you and your mentors set goals on expanding your knowledge.
64 |
65 | ## Core Skills
66 |
67 | Our team has put together a set of [Core Skills with associated animal badges](../#recognition), which are [continuously evolving](https://github.com/madetech/learn/issues).
68 |
69 | These are designed to enable new joiners deliberately practice skills which are valuable to delivery teams.
70 |
--------------------------------------------------------------------------------
/technology/guides/00-Setup/Build-Tools.md:
--------------------------------------------------------------------------------
1 | # Build Tools
2 |
3 | ## xcode cli tools
4 |
5 | Under the hood macOS is a Unix operating system with it's roots in BSD.
6 |
7 | In order to compile source code you need some tools that will do compilation.
8 |
9 | While Ruby code isn't compiled, the most accepted way to install Ruby itself is to compile it from source. You will also find that homebrew needs to compile some things.
10 |
11 | On macOS the accepted way of doing this is by installing xcode
12 |
13 | `$ xcode-select --install`
14 |
15 | _if you already installed homebrew, this will say that you've already got it installed._
16 |
17 | ## Homebrew
18 |
19 | macOS does not come with it's own package manager (like Linux does), however there is a community that has put one together.
20 |
21 | You can install it by running
22 |
23 | `$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"`
24 |
25 | ### Stop and understand
26 |
27 | * Describe what `-fsSL` does
28 | * Describe what `-c` does
29 |
30 | _Hint_
31 |
32 | * `$ man curl` - look up the curl flags
33 | * `$ man bash` - look up the bash flag
34 |
35 |
36 | ## To Do
37 |
38 | * Work through section 1.2 and 1.3 in [Learn Enough Command Line to be Dangerous](https://www.learnenough.com/command-line-tutorial) (just before "Man pages").
39 | * Install xcode cli tools
40 | * Install Homebrew
41 |
42 |
--------------------------------------------------------------------------------
/technology/guides/00-Setup/Common-Tools.md:
--------------------------------------------------------------------------------
1 | # Homebrew cask
2 |
3 | It's also possible to install proprietary software with Homebrew via `cask`
4 |
5 | To enable cask:
6 |
7 | `$ brew tap caskroom/cask`
8 |
9 | ## Stop and understand
10 |
11 | * Describe what `tap` does
12 |
13 | _Hint_ can you use `man` on your own? ;)
14 |
15 | # Install common software
16 |
17 | `$ brew cask install slack`
18 |
19 | `$ brew cask install google-chrome`
20 |
21 | `$ brew cask install firefox`
22 |
23 | # To Do
24 |
25 | * Enable cask
26 | * Install some common software
27 |
--------------------------------------------------------------------------------
/technology/guides/00-Setup/README.md:
--------------------------------------------------------------------------------
1 | # Setup Tutorial
2 |
3 | One of the most under-taught skills is how to setup a good development environment.
4 |
5 | Since you will be using macOS, and this might be your first time we will take it slow.
6 |
7 | 1. [Terminal](./Terminal.md)
8 | 2. [Build Tools](./Build-Tools.md)
9 | 3. [Your Shell](./Your-Shell.md)
10 | 4. [Common Tools](./Common-Tools.md)
11 | 5. [Ruby Version Manager](./Ruby-Version-Manager.md)
12 | 6. [Ruby](./Ruby.md)
13 |
14 | # You should now be all setup
15 |
16 | And hopefully you learned a lot along the way.
17 |
18 | We've automated this process with [First-Boot](https://github.com/madetech/first-boot/), but it's important to understand what is going on!
19 |
20 |
--------------------------------------------------------------------------------
/technology/guides/00-Setup/Ruby-Version-Manager.md:
--------------------------------------------------------------------------------
1 | # Install a Ruby version manager
2 |
3 | It is possible to install Ruby itself as a standalone package, but this creates _a small_ problem: It common to have multiple projects that require different versions of Ruby.
4 |
5 | _To the rescue [rbenv](https://github.com/rbenv/rbenv)_
6 |
7 | You can install rbenv by running
8 |
9 | `$ brew install rbenv`
10 |
11 | **We're not done though!**
12 |
13 | We still need to do two things:
14 |
15 | 1. Configure your shell to work with rbenv
16 | 2. Install a version of Ruby
17 |
18 | # rbenv init
19 |
20 | In order to make `$ ruby` do different things depending on what directory you are in `rbenv` provides a command that outputs autogenerated bash code.
21 |
22 | Have a look yourself! - `$ rbenv init -`
23 |
24 | This is great but you will want to get bash to execute that code, in your current session.
25 |
26 | There is a man page for bash builtins `man builtins`, you can also find zsh builtin extensions in `man zshbuiltins`.
27 |
28 | For now we're only interested in `eval`, which comes from the core bash builtins.
29 |
30 | **Combining eval with another command**
31 |
32 | `$ eval "$(rbenv init -)"`
33 |
34 | You don't need to fully understand this yet, but to break it down:
35 |
36 | * The parenthesis creates a subshell to run a command
37 | * The **$** does Command Expansion, which will turn the output of the subshell from output into literal commands
38 | * The double-quotes will convert the output of the expanded subshell into a single parameter for eval
39 |
40 | **We're not done yet!**
41 |
42 | Running `$ eval "$(rbenv init -)"` will work, but it isn't persistent.
43 |
44 | We want it to run automatically every time we restart our machines and open a Terminal.
45 |
46 | There's a useful file `~/.zshrc` or `~/.bash_profile` that contains commands that are run automatically.
47 |
48 | Go ahead and add the command to the bottom of `~/.zshrc`!
49 |
50 | If you make changes to this file, you can reload it by running
51 |
52 | `$ source ~/.zshrc`
53 |
54 | ## Stop and understand
55 |
56 | Phew! That was a lot.
57 |
58 | * What does `~` mean in a path?
59 | * What does source do? Is it a command or a builtin?
60 |
61 | ## To Do
62 |
63 | * Install rbenv
64 | * Add rbenv to your zshrc file
65 |
66 |
--------------------------------------------------------------------------------
/technology/guides/00-Setup/Ruby.md:
--------------------------------------------------------------------------------
1 | # Install a version of Ruby
2 |
3 | Installing a version of ruby can be done by using rbenv. We should use version 2.6.3
4 |
5 | Lets see if you can put together the command for that yourself.
6 |
7 | _Hint_ you might find `rbenv` doesn't have a man page. If you find this the case, most commands provide help if you give them the `-h` option.
8 |
9 | # Setting your default Ruby version
10 |
11 | You can set your default ruby version by creating a file `~/.ruby-version` with the version number in it.
12 |
13 | `cd ~ ; echo "2.6.3" >> ~/.ruby-version`
14 |
15 | ## Stop and understand
16 |
17 | * What does `;` do?
18 | * What does `>>` do?
19 |
20 | # Bundler
21 |
22 | You will also need Bundler. This is a tool that manages your Ruby Gems on a per project basis and lets you use different versions of the same Gem.
23 |
24 | `$ gem install bundler`
25 |
26 | ## To Do
27 |
28 | * Install a version of Ruby
29 | * Set your default ruby version
30 | * Install bundler
31 | * Work through section 2 in [Learn Enough Command Line to be Dangerous](https://www.learnenough.com/command-line-tutorial) (just before "Our first command").
32 |
--------------------------------------------------------------------------------
/technology/guides/00-Setup/Terminal.md:
--------------------------------------------------------------------------------
1 | # Terminal
2 |
3 | You will need to use a "Terminal Emulator" to run commands in this guide.
4 |
5 | macOS comes with a default Terminal, however you may find it a bit lacking.
6 |
7 | Many people at Made Tech use [iTerm 2](https://www.iterm2.com/downloads.html), however there are also other terminal emulators such as [Hyper](https://hyper.is/).
8 |
9 | You will see this `$` at the beginning of command. You shouldn't include it when you try to run a command.
10 |
11 | ## An aside
12 |
13 | The `$` does have a meaning!
14 |
15 | - `$` signifies you should run a command as your "unprivileged user"
16 | - `#` signifies you should run that command as root
17 |
18 | # To Do
19 |
20 | * Read up to (and including) 1.1 in [Learn Enough Command Line to be Dangerous](https://www.learnenough.com/command-line-tutorial) (just before "Our first command").
21 | * Download an install an alternative terminal
22 |
--------------------------------------------------------------------------------
/technology/guides/00-Setup/Your-Shell.md:
--------------------------------------------------------------------------------
1 | # Your Shell
2 |
3 | By default your shell is the `Bourne-Again shell` (bash) and it will be the default installation.
4 |
5 | This is very minimal and most programmers choose to customise it or even pick an alternative shell.
6 |
7 | The alternative shell [zsh](http://www.zsh.org/) with [oh-my-zsh](http://ohmyz.sh/) is easy to get going with which can be installed by running
8 |
9 | `$ brew install zsh`
10 |
11 | `$ curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh | sh`
12 |
13 | This will install a fairly comprehensive and useful set of helper plugins that make using the terminal much more enjoyable.
14 |
15 | On top of this zsh is a superset of bash, so the two are largely interchangeable.
16 |
17 | You will also need make zsh your default shell.
18 |
19 | `$ sudo chsh -s $(which zsh) $(whoami)`
20 |
21 | There is an exhaustive guide [here](https://rick.cogley.info/post/use-homebrew-zsh-instead-of-the-osx-default/) if you get stuck.
22 |
23 | ## Stop and understand
24 |
25 | * What is `chsh`?
26 |
27 | ## To Do
28 |
29 | * Work through section 1.4, 1.5 and 1.6, 2.1, 2.2 and 2.3 in [Learn Enough Command Line to be Dangerous](https://www.learnenough.com/command-line-tutorial) (just before "Summary").
30 | * Install an alternative shell (zsh)
31 | * Install some plugins (oh-my-zsh)
32 | * Make zsh your default shell
33 |
--------------------------------------------------------------------------------
/technology/guides/01-Command-Line/Challenge 1/Empty Folder/.keep:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/technology/guides/01-Command-Line/Challenge 1/Text Files/Less Text.txt:
--------------------------------------------------------------------------------
1 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut vitae volutpat quam. Aliquam ut consequat turpis. Proin tempus lorem eu orci faucibus, vel luctus nisl pretium. Etiam diam turpis, consectetur ut sem eget, convallis tempor est. Praesent purus dui, bibendum tempus leo eu, mattis pharetra arcu. Donec quis ex blandit, fringilla justo a, tempor leo. Suspendisse eget iaculis sem. Etiam nec nisi urna. Nulla in ex magna. Curabitur dapibus egestas tempor. Mauris et odio tristique, rutrum neque sed, bibendum lectus. Mauris non tortor ex. Maecenas tincidunt et metus vel interdum. Aliquam suscipit, lorem non lobortis accumsan, ligula est efficitur turpis, a egestas nunc tellus et magna. Vestibulum metus quam, placerat non purus vitae, auctor pharetra felis. Quisque pellentesque ornare ante ac finibus.
2 |
3 | Nunc gravida in justo sit amet accumsan. Phasellus a quam lacinia, porttitor augue sit amet, facilisis nunc. Nulla sed congue mauris. Morbi pretium gravida erat a porta. Suspendisse felis ante, gravida eu mattis eu, auctor in libero. Proin libero elit, pretium non est aliquet, dignissim mattis ex. Phasellus nisi enim, mattis id justo ut, cursus ultrices urna. Aliquam erat volutpat. Donec libero mi, tincidunt et condimentum ac, rhoncus et lacus. Etiam hendrerit erat ac dolor vestibulum, sed pharetra.
4 |
--------------------------------------------------------------------------------
/technology/guides/01-Command-Line/Challenge 1/Text Files/generate.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | getRandom()
4 | {
5 | echo $(($1 + RANDOM % $2))
6 | }
7 |
8 | for i in `seq 1 $(getRandom 2000 4000)`; do
9 | filename="xaaaa$(echo $i | tr '[0-9]' '[a-j]')"
10 | if (($i <= 600))
11 | then
12 | random=$(getRandom 1 39)
13 | if (( $random % 2 ))
14 | then
15 | filename="$filename.txt"
16 | sed -n "$(($random))p" "./More Text.txt" > $filename
17 | fi
18 | else
19 | touch $filename
20 | fi
21 | echo $filename
22 | done
23 |
24 |
--------------------------------------------------------------------------------
/technology/guides/02-Git/README.md:
--------------------------------------------------------------------------------
1 | # Git Tutorial
2 |
3 | Writing code is collaborative and requires large amounts of editing sometimes at
4 | a blistering pace, naturally a number of problems arise as a result of this and
5 | for those problems we have source control.
6 |
7 | Git is a program that provides source control originally written Linus Torvalds
8 | to replace the controversial use of BitKeeper in the development of Linux. Other
9 | than Git, you may also encounter Subversion on occasion.
10 |
11 | ## To Do
12 |
13 | 1. Work through [Learn Enough Git to Be Dangerous](https://www.learnenough.com/git-tutorial)
14 | 2. If you get to the end of the Learn Enough tutorial (you might not - that's fine), you can test what you've learnt by working through the exercises below
15 |
16 | ## Stop and Understand
17 |
18 | What is the purpose of source control?
19 |
20 | How does Git differ from other source control tools?
21 |
22 | Explain the Git tree visually
23 |
24 | Draw a Git tree that has 8 commits, where a branch was created off of the second commit and merged back in after 3 further commits.
25 |
26 | Explain what the difference between `git pull` and `git fetch` is
27 |
28 | Draw and explain how `git merge` works compared to `git rebase`
29 |
30 | ## Exercises
31 |
32 | ### 1.0 Initialising a new Git repository
33 |
34 | Create a new directory
35 |
36 | Create a new Git repository
37 |
38 | Add a file with the text "Hello" from the command line
39 |
40 | Add this file and commit it using Git
41 |
42 | ### 1.1 "Pushing" to GitHub
43 |
44 | Create a new repository on GitHub
45 |
46 | Setup your local repository to have a new remote
47 |
48 | Push your code to GitHub
49 |
50 | ### 1.2 Working with changes
51 |
52 | Open the file in your text editor and make some changes to it
53 |
54 | Stash these changes
55 |
56 | Unstash them and commit them
57 |
58 | Reset to the first commit you made using the `--hard` flag
59 |
60 | Recover the previous commit using `reflog`
61 |
62 | ### 1.3 Branching
63 |
64 | Create a new branch and switch to it
65 |
66 | Add and commit a new file with your name in it
67 |
68 | Switch back to the master branch and merge your branch in
69 |
70 | Delete your merged branch
71 |
72 | ### 1.4 Aliases
73 |
74 | Add the following alias:
75 | ```bash
76 | git config --global alias.l "log
77 | --graph
78 | --pretty=oneline
79 | --abbrev-commit
80 | --decorate"
81 | ```
82 |
83 | Compare `git log` and your new alias `git l`
84 |
85 | ### 1.5 Diffs
86 |
87 | Make changes to both files
88 |
89 | Using `git diff` identify your changes
90 |
91 | Add one of the files but do not commit it
92 |
93 | Compare `git diff` to `git diff --staged`
94 |
95 | ## Resources
96 |
97 | - [Git](https://git-scm.com/)
98 | - [Git tutorial](https://www.learnenough.com/git-tutorial)
99 | - [Merging vs Rebasing](https://www.atlassian.com/git/tutorials/merging-vs-rebasing)
100 | - [Git challenges](https://try.github.io/levels/1/challenges/1)
101 | - [Codecademy - Learn Git](https://www.codecademy.com/learn/learn-git)
102 | - [Mastering Git](https://thoughtbot.com/upcase/mastering-git)
103 | - [5 Useful Tips For A Better Commit Message](https://robots.thoughtbot.com/5-useful-tips-for-a-better-commit-message)
104 | - [Tig - TUI for Git](https://github.com/jonas/tig)
105 | - [`git bisect` Documentation](https://git-scm.com/docs/git-bisect)
106 | - [Code Sleuthing with Git](https://robots.thoughtbot.com/code-sleuthing-with-git)
107 |
--------------------------------------------------------------------------------
/technology/guides/03-Debugging/BuggyProject/.gitignore:
--------------------------------------------------------------------------------
1 | tmp
2 |
--------------------------------------------------------------------------------
/technology/guides/03-Debugging/BuggyProject/.ruby-version:
--------------------------------------------------------------------------------
1 | 2.5.0
2 |
--------------------------------------------------------------------------------
/technology/guides/03-Debugging/BuggyProject/Gemfile:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | source 'https://rubygems.org'
4 |
5 | gem 'guard-rspec', require: false
6 | gem 'rspec'
7 | gem 'sinatra'
8 | gem 'redcarpet'
9 |
--------------------------------------------------------------------------------
/technology/guides/03-Debugging/BuggyProject/Gemfile.lock:
--------------------------------------------------------------------------------
1 | GEM
2 | remote: https://rubygems.org/
3 | specs:
4 | coderay (1.1.2)
5 | diff-lcs (1.3)
6 | ffi (1.9.25)
7 | formatador (0.2.5)
8 | guard (2.14.2)
9 | formatador (>= 0.2.4)
10 | listen (>= 2.7, < 4.0)
11 | lumberjack (>= 1.0.12, < 2.0)
12 | nenv (~> 0.1)
13 | notiffany (~> 0.0)
14 | pry (>= 0.9.12)
15 | shellany (~> 0.0)
16 | thor (>= 0.18.1)
17 | guard-compat (1.2.1)
18 | guard-rspec (4.7.3)
19 | guard (~> 2.1)
20 | guard-compat (~> 1.1)
21 | rspec (>= 2.99.0, < 4.0)
22 | listen (3.1.5)
23 | rb-fsevent (~> 0.9, >= 0.9.4)
24 | rb-inotify (~> 0.9, >= 0.9.7)
25 | ruby_dep (~> 1.2)
26 | lumberjack (1.0.13)
27 | method_source (0.9.0)
28 | mustermann (1.0.2)
29 | nenv (0.3.0)
30 | notiffany (0.1.1)
31 | nenv (~> 0.1)
32 | shellany (~> 0.0)
33 | pry (0.11.3)
34 | coderay (~> 1.1.0)
35 | method_source (~> 0.9.0)
36 | rack (2.2.8.1)
37 | rack-protection (2.0.3)
38 | rack
39 | rb-fsevent (0.10.3)
40 | rb-inotify (0.9.10)
41 | ffi (>= 0.5.0, < 2)
42 | redcarpet (3.5.1)
43 | rspec (3.7.0)
44 | rspec-core (~> 3.7.0)
45 | rspec-expectations (~> 3.7.0)
46 | rspec-mocks (~> 3.7.0)
47 | rspec-core (3.7.1)
48 | rspec-support (~> 3.7.0)
49 | rspec-expectations (3.7.0)
50 | diff-lcs (>= 1.2.0, < 2.0)
51 | rspec-support (~> 3.7.0)
52 | rspec-mocks (3.7.0)
53 | diff-lcs (>= 1.2.0, < 2.0)
54 | rspec-support (~> 3.7.0)
55 | rspec-support (3.7.1)
56 | ruby_dep (1.5.0)
57 | shellany (0.0.1)
58 | sinatra (2.0.3)
59 | mustermann (~> 1.0)
60 | rack (~> 2.0)
61 | rack-protection (= 2.0.3)
62 | tilt (~> 2.0)
63 | thor (0.20.0)
64 | tilt (2.0.8)
65 |
66 | PLATFORMS
67 | ruby
68 |
69 | DEPENDENCIES
70 | guard-rspec
71 | redcarpet
72 | rspec
73 | sinatra
74 |
75 | BUNDLED WITH
76 | 1.16.1
77 |
--------------------------------------------------------------------------------
/technology/guides/03-Debugging/BuggyProject/Guardfile:
--------------------------------------------------------------------------------
1 | guard :rspec, cmd: "bundle exec rspec" do
2 | watch(%r{^spec/(.+)\.rb$}) { "spec" }
3 | watch(%r{^lib/(.+)\.e?rb$}) { "spec" }
4 | end
5 |
6 |
--------------------------------------------------------------------------------
/technology/guides/03-Debugging/BuggyProject/Makefile:
--------------------------------------------------------------------------------
1 | serve:
2 | bundle exec ruby app.rb -o 0.0.0.0
3 |
4 | test:
5 | bundle exec guard
6 |
7 |
--------------------------------------------------------------------------------
/technology/guides/03-Debugging/BuggyProject/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madetech/learn/5a0c5dce6caf79dd4723ef9261c09198c5fb9dae/technology/guides/03-Debugging/BuggyProject/README.md
--------------------------------------------------------------------------------
/technology/guides/03-Debugging/BuggyProject/app.rb:
--------------------------------------------------------------------------------
1 | require 'sinatra'
2 | require 'redcarpet'
3 | require_relative 'lib/view_topic'
4 |
5 | get '/' do
6 | response = List.new.execute(directory: "#{__dir__}/../../")
7 |
8 | output = 'Learning Topics
'
9 | output << ''
10 | response[:topics].each do |topic|
11 | output << "- #{topic[:title]}
"
12 | end
13 | output << '
'
14 |
15 | output
16 | end
17 |
18 | get '/topic/:id' do
19 | response = ViewTopic.new.execute(
20 | directory: "#{__dir__}/../../",
21 | id: params[:id]
22 | )
23 |
24 | markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML)
25 |
26 | markdown.render(response[:content])
27 | end
28 |
--------------------------------------------------------------------------------
/technology/guides/03-Debugging/BuggyProject/lib/list_topics.rb:
--------------------------------------------------------------------------------
1 | class ListTopics
2 | def execute(directory:)
3 | @directories = Dir.glob("#{directory}/**/README")
4 |
5 | return { topics: [] } if @directories.empty?
6 |
7 | { topics: to_presentable_topics(topics) }
8 | end
9 |
10 | private
11 |
12 | def to_presentable_topics(topics)
13 | topics.map do |topic|
14 | { title: topic.title, id: topic.id }
15 | end
16 | end
17 |
18 | def topics
19 | @directories.map { |directory| Topic.new(path: directory) }.sort
20 | end
21 |
22 | class Topic
23 | include Comparable
24 |
25 | def initialize(path:)
26 | @path = path
27 | end
28 |
29 | def <=>(other)
30 | ranking <=> other.ranking
31 | end
32 |
33 | def id
34 | @path.gsub(%r{.*([0-9]{2}.*?)\/.*}, '\1')
35 | end
36 |
37 | def ranking
38 | @path.gsub(%r{.*/([0-9]{2}).*?/}, '\1').to_i
39 | end
40 |
41 | def title
42 | @path.gsub(%r{.*[0-9]{2}(.*?)\/.*}, '\1')
43 | .tr('-', ' ')
44 | .strip
45 | end
46 | end
47 | end
48 |
--------------------------------------------------------------------------------
/technology/guides/03-Debugging/BuggyProject/lib/view_topic.rb:
--------------------------------------------------------------------------------
1 | class ViewTopic
2 | def execute(directory:, id:)
3 | File.open("#{directory}/#{id}/README.md", 'r') do |file|
4 | { content: file.read }
5 | end
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/technology/guides/03-Debugging/BuggyProject/spec/list_topics_spec.rb:
--------------------------------------------------------------------------------
1 | require 'list_topics'
2 | require 'topics_shared_context'
3 |
4 | describe ListTopics do
5 | include_context 'topics'
6 |
7 | def list_topics_for(path)
8 | described_class.new.execute(directory: path)
9 | end
10 |
11 | it 'finds no topics for an empty directory' do
12 | path = create_directory!('no-topics')
13 |
14 | response = list_topics_for(path)
15 |
16 | expect(response[:topics]).to eq([])
17 | end
18 |
19 | it 'can find one topic' do
20 | path = create_directory!('one-topic')
21 |
22 | create_topic!(path, title: '00-Hello-World')
23 |
24 | response = list_topics_for(path)
25 |
26 | expect(response[:topics]).to(
27 | eq(
28 | [{ title: 'Hello World', id: '00-Hello-World' }]
29 | )
30 | )
31 | end
32 |
33 | it 'can order 4 topics correctly' do
34 | path = create_directory!('one-topic')
35 |
36 | create_topic!(path, title: '05-Csh-The-Second')
37 | create_topic!(path, title: '07-Zsh-The-Third')
38 | create_topic!(path, title: '01-First')
39 | create_topic!(path, title: '20-Bye-World')
40 |
41 | response = list_topics_for(path)
42 |
43 | expect(response[:topics]).to(
44 | eq(
45 | [
46 | { title: 'First', id: '01-First' },
47 | { title: 'Csh The Second', id: '05-Csh-The-Second' },
48 | { title: 'Zsh The Third', id: '07-Zsh-The-Third' },
49 | { title: 'Bye World', id: '20-Bye-World' }
50 | ]
51 | )
52 | )
53 | end
54 | end
55 |
--------------------------------------------------------------------------------
/technology/guides/03-Debugging/BuggyProject/spec/topics_shared_context.rb:
--------------------------------------------------------------------------------
1 | shared_context 'topics' do
2 | def create_directory!(name)
3 | path = "#{__dir__}/tmp/#{name}"
4 | FileUtils.mkdir_p path
5 | path
6 | end
7 |
8 | def clean_up_temporary_directory!
9 | FileUtils.rm_rf "#{__dir__}/tmp"
10 | end
11 |
12 | def create_topic!(path, title:)
13 | topic_path = "#{path}/#{title}"
14 | FileUtils.mkdir_p(topic_path)
15 | FileUtils.touch("#{topic_path}/README.md")
16 | end
17 |
18 | before do
19 | clean_up_temporary_directory!
20 | end
21 | end
22 |
--------------------------------------------------------------------------------
/technology/guides/03-Debugging/BuggyProject/spec/view_topic_spec.rb:
--------------------------------------------------------------------------------
1 | require 'view_topic'
2 | require 'topics_shared_context'
3 |
4 | describe ViewTopic do
5 | include_context 'topics'
6 |
7 | def save_topic_content!(path, title:, content:)
8 | file = File.open("#{path}/#{title}/README.md", 'w')
9 | file << content
10 | end
11 |
12 | def view_topic(path, id)
13 | described_class.new.execute(directory: path, id: id)
14 | end
15 |
16 | it 'can view a topic with no content' do
17 | path = create_directory!('one-topic')
18 |
19 | create_topic!(path, title: '00-Hello-World')
20 | save_topic_content!(path, title: '00-Hello-World', content: '')
21 |
22 | response = view_topic(path, '00-Hello-World')
23 |
24 | expect(response[:content]).to eq('')
25 | end
26 |
27 | it 'can view a topic with some content' do
28 | path = create_directory!('one-topic')
29 |
30 | create_topic!(path, title: '01-Hello-World')
31 | save_topic_content!(path, title: '01-Hello-World', content: '# Hello World')
32 |
33 | response = view_topic(path, '01-Hello-World')
34 |
35 | expect(response[:content]).to eq('# Hello World')
36 | end
37 | end
38 |
--------------------------------------------------------------------------------
/technology/guides/04-Retrospective-Planning/README.md:
--------------------------------------------------------------------------------
1 | # Retrospective Planning
2 |
3 | ## Exercises
4 |
5 | 1. Before continuing you should read the information below.
6 | 2. As a whole group, brainstorm the purpose of a retrospective for your team.
7 | 3. As a whole group, brainstorm what you think an ideal retrospective facilitator;
8 | - Should do
9 | - Should not do
10 | 4. Individually think of some specific challenges that would be hard to uncover or work past in a retrospective.
11 | 5. In pairs, work together to design or choose two retrospective plans
12 | - Write down what extra materials you will need to run them
13 | - (If applicable) Decide between you who will facilitate which plan
14 | 6. Present back to the group your retrospective plans and any specific reasons for choosing them given what you discovered in 2, 3 and 4.
15 |
16 | ## The Prime Directive
17 |
18 | Retrospectives are meant to be a healthy,
19 | fun activity in which the team discusses the way they work together.
20 |
21 | This is in direct contrast to blame culture,
22 | where people feel the need to hide what they are struggling with.
23 |
24 | A healthy "safe" agile culture is one where every team member feels comfortable
25 | enough to discuss their own and other's mistakes.
26 |
27 | We remember this quote every retrospective as a reminder of this:
28 |
29 | > "Regardless of what we discover,
30 | > we understand and truly believe that everyone did the best job they could,
31 | > given what they knew at the time,
32 | > their skills and abilities,
33 | > the resources available,
34 | > and the situation at hand."
35 | >
36 | > Norm Kerth in _Project Retrospectives: A Handbook for Team Review_
37 |
38 | ## A basic retrospective
39 |
40 | * What went well?
41 | * What did not go well?
42 | * What can be done differently?
43 | * What do we still not understand?
44 |
45 | ## Facilitating retrospectives
46 |
47 | Extending from the basic questions, a facilitator may choose to get creative
48 | with formats. To make the retrospective _fun_.
49 |
50 | There are a number of plans on the [retrospectivewiki.org](http://retrospectivewiki.org/index.php?title=Retrospective_Plans).
51 |
52 | However it also possible to build your own plans, either free form, or by using other resources such as [Liberating Structures](http://liberatingstructures.com).
53 |
54 | ## Six thinking hats.
55 |
56 | Another angle to look at retrospectives is using the six thinking hats approach.
57 |
58 | * Blue Hat - Discuss objectives for the retrospective (5 mins)
59 | * White hat - Discuss _facts_ from the last iteration. (10 mins)
60 | * Yellow Hat - Discuss only good things from the last iteration. (10 mins)
61 | * Black Hat - Discuss only the bad things that happened. (10 mins)
62 | * Green Hat - Discuss solving problems. Blue sky thinking encouraged. (10 mins)
63 | * Red Hat - On the shared board, write down 2 emotive statements for each issue / solution. (5 mins)
64 |
65 | Spend some time looking at the Red Hat output.
66 |
67 | Are there any themes?
68 |
69 | Do any particularly stand out?
70 |
71 | Ensure the actions are easy to execute.
72 |
73 | ## References
74 |
75 | [retrospectivewiki.org](http://retrospectivewiki.org)
76 |
--------------------------------------------------------------------------------
/technology/guides/05-Refactoring/README.md:
--------------------------------------------------------------------------------
1 | # Refactoring
2 |
3 | You probably have already done some refactoring as part of code katas.
4 |
5 | Refactoring, like TDD, is a disciplined skill with rules.
6 |
7 | * Refactoring leaves the external behaviour of code the same.
8 | * Good tests[1] are essential to refactoring. Disciplined TDD is a great way to have a reliable test suite.
9 | * We refactor by applying _small changes_ to our code (a single refactoring) from a [catalog of refactorings](https://refactoring.com/catalog/?filter=books-rubyref,books-radio-appear), or by generalising code e.g. turning duplicated if statements into a loop
10 | * Your tests should be passing before and after each refactoring or generalisation.
11 | * By performing multiple refactorings in a row it is possible to significantly change the structure of your code.
12 |
13 | # A Single Refactoring: what is a small change?
14 |
15 | Small reversible operations. They should have a name, with a clearly defined before and after state.
16 |
17 | When mobbing or pairing it's useful to be able to immediately describe a refactoring.
18 |
19 | # Generalising code: I can't find it in the catalog!
20 |
21 | While in the blue phase (refactoring step) we should look for appropriate generalisations to make.
22 |
23 | A good rule of thumb is the [RuleOfThree](http://wiki.c2.com/?RuleOfThree) - if you see the same thing duplicated three times, create a more general solution.
24 |
25 | Generalising code is part of refactoring. However, they do not result in like-for-like behaviour, so you will not find them in the catalog.
26 |
27 | ## The process
28 |
29 | Here is the process for performing the **Extract Method** refactoring, which is a _single refactoring_ that you can find in the [catalog of refactorings](https://refactoring.com/catalog/?filter=books-rubyref,books-radio-appear).
30 |
31 | 1. Run your tests. Do they pass? If they don't you need to solve that first.
32 | 2. Apply the refactoring
33 |
34 | **Before**
35 | ```ruby
36 | class PayslipPrinter
37 | def print(payslip)
38 | puts "======================"
39 | puts "Owed #{payslip.total_owed}."
40 | puts "Total Deducted #{payslip.total_deducted}"
41 | end
42 | end
43 | ```
44 |
45 | ```
46 | .
47 | .
48 | . ;.
49 | .;
50 | ;;.
51 | ;.;;
52 | ;;;;.
53 | ;;;;;
54 | ;;;;;
55 | ;;;;;
56 | ;;;;;
57 | ;;;;;
58 | ..;;;;;..
59 | ':::::'
60 | ':`
61 | ```
62 |
63 | **After**
64 | ```ruby
65 | class PayslipPrinter
66 | def print(payslip)
67 | puts "======================"
68 | print_totals(payslip.total_owed, payslip.total_deducted)
69 | end
70 |
71 | def print_totals(total_owed, total_deducted)
72 | puts "Owed #{total_owed}."
73 | puts "Total Deducted #{total_deducted}"
74 | end
75 | end
76 | ```
77 |
78 | 3. Run your tests. Do they pass? _If they don't, you've incorrectly performed your refactoring._
79 |
80 | ## Stop and understand
81 |
82 | * Why do we run the tests before and afterwards?
83 | * Why not make lots of changes in one go?
84 |
85 | # To Do
86 |
87 | Using the [Yatzy Refactoring Kata](https://github.com/emilybache/Yatzy-Refactoring-Kata) by Emily Bache,
88 | practice applying refactorings from the [catalog of refactorings](https://refactoring.com/catalog/?filter=books-rubyref,books-radio-appear).
89 |
90 | # Notes
91 |
92 | * [1] - https://www.madetech.com/blog/semantically-stable-test-suites
93 |
94 |
--------------------------------------------------------------------------------
/technology/guides/08-Continuous-Integration/simple-sinatra-app-to-deploy/.rspec:
--------------------------------------------------------------------------------
1 | --require spec_helper
2 |
--------------------------------------------------------------------------------
/technology/guides/08-Continuous-Integration/simple-sinatra-app-to-deploy/Gemfile:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | source "https://rubygems.org"
4 |
5 | git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
6 |
7 | gem "rspec"
8 | gem "sinatra"
9 | gem 'capybara'
10 | gem 'puma'
--------------------------------------------------------------------------------
/technology/guides/08-Continuous-Integration/simple-sinatra-app-to-deploy/Gemfile.lock:
--------------------------------------------------------------------------------
1 | GEM
2 | remote: https://rubygems.org/
3 | specs:
4 | addressable (2.8.6)
5 | public_suffix (>= 2.0.2, < 6.0)
6 | capybara (3.34.0)
7 | addressable
8 | mini_mime (>= 0.1.3)
9 | nokogiri (~> 1.8)
10 | rack (>= 1.6.0)
11 | rack-test (>= 0.6.3)
12 | regexp_parser (~> 1.5)
13 | xpath (~> 3.2)
14 | diff-lcs (1.4.4)
15 | mini_mime (1.0.2)
16 | mustermann (1.1.1)
17 | ruby2_keywords (~> 0.0.1)
18 | nio4r (2.7.0)
19 | nokogiri (1.16.2-x86_64-linux)
20 | racc (~> 1.4)
21 | public_suffix (5.0.4)
22 | puma (6.4.2)
23 | nio4r (~> 2.0)
24 | racc (1.7.3)
25 | rack (2.2.8.1)
26 | rack-protection (2.1.0)
27 | rack
28 | rack-test (1.1.0)
29 | rack (>= 1.0, < 3)
30 | regexp_parser (1.8.2)
31 | rspec (3.10.0)
32 | rspec-core (~> 3.10.0)
33 | rspec-expectations (~> 3.10.0)
34 | rspec-mocks (~> 3.10.0)
35 | rspec-core (3.10.0)
36 | rspec-support (~> 3.10.0)
37 | rspec-expectations (3.10.0)
38 | diff-lcs (>= 1.2.0, < 2.0)
39 | rspec-support (~> 3.10.0)
40 | rspec-mocks (3.10.0)
41 | diff-lcs (>= 1.2.0, < 2.0)
42 | rspec-support (~> 3.10.0)
43 | rspec-support (3.10.0)
44 | ruby2_keywords (0.0.2)
45 | sinatra (2.1.0)
46 | mustermann (~> 1.0)
47 | rack (~> 2.2)
48 | rack-protection (= 2.1.0)
49 | tilt (~> 2.0)
50 | tilt (2.0.10)
51 | xpath (3.2.0)
52 | nokogiri (~> 1.8)
53 |
54 | PLATFORMS
55 | x86_64-linux
56 |
57 | DEPENDENCIES
58 | capybara
59 | puma
60 | rspec
61 | sinatra
62 |
63 | BUNDLED WITH
64 | 2.2.2
65 |
--------------------------------------------------------------------------------
/technology/guides/08-Continuous-Integration/simple-sinatra-app-to-deploy/README.MD:
--------------------------------------------------------------------------------
1 | # simple-sinatra-app
2 |
3 | For the MT academy - demonstrating continuous integration
4 |
5 | # To run the app locally:
6 |
7 | - Navigate to the root of the project in Terminal
8 | - Run the following command: `bundle exec rackup -p 300`
9 | - Visit the following url in the browser: http://127.0.0.1:3000/
10 |
11 | # To deploy via Circle CI and Heroku
12 |
13 | Follow instructions [here](https://learn.madetech.com/technology/guides/08-Continuous-Integration/).
--------------------------------------------------------------------------------
/technology/guides/08-Continuous-Integration/simple-sinatra-app-to-deploy/config.ru:
--------------------------------------------------------------------------------
1 | require './lib/index'
2 | run Sinatra::Application
3 |
--------------------------------------------------------------------------------
/technology/guides/08-Continuous-Integration/simple-sinatra-app-to-deploy/lib/index.rb:
--------------------------------------------------------------------------------
1 | require 'sinatra'
2 | require_relative './super_simple_usecase'
3 |
4 | before do
5 | @super_simple_usecase = SuperSimpleUsecase.new
6 | end
7 |
8 | get '/' do
9 | request_url = request.url
10 | text_to_display = @super_simple_usecase.execute(request_url)
11 | text_to_display
12 | end
13 |
--------------------------------------------------------------------------------
/technology/guides/08-Continuous-Integration/simple-sinatra-app-to-deploy/lib/super_simple_usecase.rb:
--------------------------------------------------------------------------------
1 | class SuperSimpleUsecase
2 | def execute(url)
3 | return "I'm deployed to Heroku!" if url.include? "herokuapp"
4 |
5 | 'Deploy me to Heroku, please!'
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/technology/guides/08-Continuous-Integration/simple-sinatra-app-to-deploy/spec/index_spec.rb:
--------------------------------------------------------------------------------
1 | Capybara.app = Sinatra::Application
2 |
3 | describe 'home page', type: :feature do
4 | it 'displays correct text' do
5 | visit '/'
6 | expect(page).to have_content('Deploy me to Heroku, please!')
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/technology/guides/08-Continuous-Integration/simple-sinatra-app-to-deploy/spec/super_simple_usecase_spec.rb:
--------------------------------------------------------------------------------
1 | require 'super_simple_usecase'
2 |
3 | describe SuperSimpleUsecase do
4 | let(:use_case) { described_class.new }
5 |
6 | context 'given url is localhost' do
7 | it 'returns Deploy me to Heroku!' do
8 | expect(use_case.execute('http://localhost:1234')).to eq('Deploy me to Heroku, please!')
9 | end
10 | end
11 |
12 | context 'given url is heroku' do
13 | it 'returns one item total' do
14 | expect(use_case.execute('https://super-simple-app.herokuapp.com')).to eq("I'm deployed to Heroku!")
15 | end
16 | end
17 |
18 | end
19 |
--------------------------------------------------------------------------------
/technology/guides/08-Continuous-Integration/simple-sinatra-app/.circleci/config.yml:
--------------------------------------------------------------------------------
1 | # Note that this was originally created in early 2021.
2 | # The Ruby orb was updated March 17th 2022
3 | # The Heroku orb was updated March 17th 2022
4 |
5 | version: 2.1
6 | orbs:
7 | ruby: circleci/ruby@1.4.0
8 | heroku: circleci/heroku@1.2.6
9 |
10 | jobs:
11 | build_and_test:
12 | docker:
13 | - image: cimg/ruby:2.7-node
14 | steps:
15 | - checkout
16 | - ruby/install-deps
17 | - ruby/rspec-test
18 |
19 | workflows:
20 | build_and_test_deploy:
21 | jobs:
22 | - build_and_test
23 | - heroku/deploy-via-git:
24 | requires:
25 | - build_and_test
26 | filters:
27 | branches:
28 | only: main
29 |
30 |
--------------------------------------------------------------------------------
/technology/guides/08-Continuous-Integration/simple-sinatra-app/.rspec:
--------------------------------------------------------------------------------
1 | --require spec_helper
2 |
--------------------------------------------------------------------------------
/technology/guides/08-Continuous-Integration/simple-sinatra-app/Gemfile:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | source "https://rubygems.org"
4 |
5 | git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
6 |
7 | gem "rspec"
8 | gem "sinatra"
9 | gem 'puma'
10 | gem 'rspec_junit_formatter'
11 |
--------------------------------------------------------------------------------
/technology/guides/08-Continuous-Integration/simple-sinatra-app/Gemfile.lock:
--------------------------------------------------------------------------------
1 | GEM
2 | remote: https://rubygems.org/
3 | specs:
4 | diff-lcs (1.5.0)
5 | mustermann (2.0.2)
6 | ruby2_keywords (~> 0.0.1)
7 | nio4r (2.7.0)
8 | puma (5.6.8)
9 | nio4r (~> 2.0)
10 | rack (2.2.8.1)
11 | rack-protection (2.2.3)
12 | rack
13 | rspec (3.11.0)
14 | rspec-core (~> 3.11.0)
15 | rspec-expectations (~> 3.11.0)
16 | rspec-mocks (~> 3.11.0)
17 | rspec-core (3.11.0)
18 | rspec-support (~> 3.11.0)
19 | rspec-expectations (3.11.0)
20 | diff-lcs (>= 1.2.0, < 2.0)
21 | rspec-support (~> 3.11.0)
22 | rspec-mocks (3.11.0)
23 | diff-lcs (>= 1.2.0, < 2.0)
24 | rspec-support (~> 3.11.0)
25 | rspec-support (3.11.0)
26 | rspec_junit_formatter (0.5.1)
27 | rspec-core (>= 2, < 4, != 2.12.0)
28 | ruby2_keywords (0.0.5)
29 | sinatra (2.2.3)
30 | mustermann (~> 2.0)
31 | rack (~> 2.2)
32 | rack-protection (= 2.2.3)
33 | tilt (~> 2.0)
34 | tilt (2.3.0)
35 |
36 | PLATFORMS
37 | ruby
38 | x86_64-darwin-20
39 | x86_64-darwin-21
40 |
41 | DEPENDENCIES
42 | puma
43 | rspec
44 | rspec_junit_formatter
45 | sinatra
46 |
47 | BUNDLED WITH
48 | 2.2.2
49 |
--------------------------------------------------------------------------------
/technology/guides/08-Continuous-Integration/simple-sinatra-app/README.MD:
--------------------------------------------------------------------------------
1 | # simple-sinatra-app
2 |
3 | For the MT academy - demonstrating continuous integration
4 |
5 | # To run the app locally:
6 |
7 | - Navigate to the root of the project in Terminal
8 | - Run the following command: `bundle exec rackup -p 300`
9 | - Visit the following url in the browser: http://127.0.0.1:3000/
10 |
11 | # To deploy via Circle CI and Heroku
12 |
13 | Follow instructions [here](https://learn.madetech.com/technology/guides/08-Continuous-Integration/).
--------------------------------------------------------------------------------
/technology/guides/08-Continuous-Integration/simple-sinatra-app/config.ru:
--------------------------------------------------------------------------------
1 | require './lib/index'
2 | run Sinatra::Application
3 |
--------------------------------------------------------------------------------
/technology/guides/08-Continuous-Integration/simple-sinatra-app/lib/index.rb:
--------------------------------------------------------------------------------
1 | require 'sinatra'
2 | require_relative './super_simple_usecase'
3 |
4 | before do
5 | @super_simple_usecase = SuperSimpleUsecase.new
6 | end
7 |
8 | get '/' do
9 | request_url = request.url
10 | text_to_display = @super_simple_usecase.execute(request_url)
11 | text_to_display
12 | end
13 |
--------------------------------------------------------------------------------
/technology/guides/08-Continuous-Integration/simple-sinatra-app/lib/super_simple_usecase.rb:
--------------------------------------------------------------------------------
1 | class SuperSimpleUsecase
2 | def execute(url)
3 | return "I'm deployed to Heroku!" if url.include? "herokuapp"
4 |
5 | 'Deploy me to Heroku, please!'
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/technology/guides/08-Continuous-Integration/simple-sinatra-app/spec/super_simple_usecase_spec.rb:
--------------------------------------------------------------------------------
1 | require 'super_simple_usecase'
2 |
3 | describe SuperSimpleUsecase do
4 | let(:use_case) { described_class.new }
5 |
6 | context 'given url is localhost' do
7 | it 'returns Deploy me to Heroku!' do
8 | expect(use_case.execute('http://localhost:1234')).to eq('Deploy me to Heroku, please!')
9 | end
10 | end
11 |
12 | context 'given url is heroku' do
13 | it 'returns one item total' do
14 | expect(use_case.execute('https://super-simple-app.herokuapp.com')).to eq("I'm deployed to Heroku!")
15 | end
16 | end
17 |
18 | end
19 |
--------------------------------------------------------------------------------
/technology/guides/10-Database/screen-cap-workshop.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madetech/learn/5a0c5dce6caf79dd4723ef9261c09198c5fb9dae/technology/guides/10-Database/screen-cap-workshop.gif
--------------------------------------------------------------------------------
/technology/guides/12-Pull-Requests/README.md:
--------------------------------------------------------------------------------
1 | # Pull requests
2 | When collaborating with others on a project it is often useful to have a
3 | way to present code for review before it enters the codebase so that any
4 | changes decisions can be discussed and issues can be mitigated. Many
5 | projects use *pull requests* for this.
6 |
7 | Pull requests can take many forms, but we will be focusing on the way GitHub
8 | implements them. Generally other git hosting platforms implement them
9 | similarly.
10 |
11 | ## To do
12 | If you aren't familiar with Git have a look at the [Git tutorial](/technology/guides/02-Git/)
13 |
14 | You'll want to pair up so that you can practice the workflow.
15 |
16 | ## Discuss
17 | Consider why you might create a branch as opposed to committing to
18 | master, what are the pros and cons? How do you decide what belongs in
19 | a particular branch?
20 |
21 | # Exercises
22 | ## 1. In your own repository
23 | Creating and using pull requests within your own repository is easier
24 | than doing it for repositories belonging to others. We'll use this to
25 | get to grips with the basic workflow.
26 |
27 | ## 1.1 Create a repository
28 | Create a new GitHub repository, clone it and push an initial commit to
29 | master.
30 |
31 | ## 1.2 Make changes
32 | Checkout a new branch, make some changes and push them to your new branch.
33 |
34 | ## 1.3 Create your pull request
35 | Go to your repository on GitHub, you will see a notification asking you if
36 | you want to create a new branch.
37 | Alternatively you can simply click the link that appears in the terminal
38 | when you push your new branch.
39 | Fill out some details about the changes you've made and create your pull
40 | request.
41 |
42 | ## 1.4 Merge into master
43 | There will be a merge button at the bottom of the page. You can also use
44 | `git pull origin ` from the command line to merge the branch
45 | into master, hence the term 'pull request'.
46 |
47 | ## 2. Collaborating
48 | ## 2.1 Add your partner to your repository
49 | Go to your repository's page in GitHub and click on 'Settings' then
50 | 'Manage access'. From here you should be able to invite your partner.
51 |
52 | ## 2.2 Create a pull request
53 | Have your partner clone the repository make a branch, push some changes
54 | and create a pull request.
55 |
56 | ## 2.3 Review
57 | Go to their pull request, go to the 'Files changed' tab and review their
58 | changes. You can make comments on each line by clicking the `+` icon that
59 | appears as you hover.
60 |
61 | ## 2.4 Approve and merge
62 | Once you're happy with their changes you can click 'Review changes' and
63 | 'Approve'. You can also 'Request changes' if you so desire. Once approved
64 | you can merge their changes into master.
65 |
66 | ## 3 Experiment
67 | You can try:
68 | - Having your partner fork from your repository and merging their changes in
69 | - Different access rules
70 | - Doing a pull request and review with git only
71 |
72 | ## Resources
73 | - [Branching Strategies](https://www.perforce.com/blog/vcs/best-branching-strategies-high-velocity-development)
74 | - [git request-pull Documentation](https://git-scm.com/docs/git-request-pull)
75 |
--------------------------------------------------------------------------------
/technology/guides/README.md:
--------------------------------------------------------------------------------
1 | # Guides
2 |
3 | * [Setup Tutorial](./00-Setup/) _macOS, terminal, rbenv, ruby_
4 | * [Command Line Tutorial](./01-Command-Line/) _bash_
5 | * [Git Tutorial](./02-Git/) _git, bash_
6 | * [Debugging Tutorial](./03-Debugging/) _ruby, debugging, testing_
7 | * [Retrospective Planning Tutorial](./04-Retrospective-Planning/) _retrospectives, liberating structures_
8 | * [Refactoring Tutorial](./05-Refactoring/) _refactoring_
9 | * [Gem Packaging Tutorial](./06-Gem-Packaging/) _gems_, _bundler_
10 | * [Simplest Next Test Tutorial](./07-Simplest-Next-Test/) _tdd_
11 | * [Continuous Integration Tutorial](./08-Continuous-Integration/) _ci_
12 | * [Polymorphism Tutorial](./09-Polymorphism/) _oo, polymorphism_
13 | * [Database Tutorial](./10-Database/) _relational, sql, database, migration, postgresql_
14 | * [Docker Tutorial](./11-Docker/) _docker, containerization, docker-compose_
15 | * [Pull Requests](./12-Pull-Requests/) _git, github_
16 | * [AWS Certified Cloud Practitioner Playbook](./aws/cloud-practitioner/) _cloud concepts_
17 |
--------------------------------------------------------------------------------
/technology/guides/controllers-routing/README.md:
--------------------------------------------------------------------------------
1 | # Controllers and Routing Tutorial
2 |
3 | ## Resources
4 |
5 | - https://developer.mozilla.org/en-US/docs/Web/HTTP/Overview
6 | - https://www.ibm.com/developerworks/library/ws-restful/index.html
7 | - http://www.restapitutorial.com/
8 | - http://guides.rubyonrails.org/routing.html
9 | - https://richonrails.com/articles/understanding-rails-routing
10 | - https://www.theodinproject.com/courses/ruby-on-rails/lessons/routing
11 | - https://www.codecademy.com/articles/standard-controller-actions
12 | - http://guides.rubyonrails.org/action_controller_overview.html
13 | - https://www.theodinproject.com/courses/ruby-on-rails/lessons/controllers
14 | - https://relishapp.com/rspec/rspec-rails/docs/controller-specs
15 | - https://relishapp.com/rspec/rspec-rails/v/3-6/docs/request-specs/request-spec
16 |
17 | ## Tutorial
18 |
19 | What are the 3 main components of HTTP systems?
20 |
21 | Can you visualise how they fit together?
22 |
23 | What are the main HTTP methods/verbs?
24 |
25 | What routes and request types would you use for the following:
26 | - Viewing a user profile page
27 | - Creating a user
28 | - Editing a user
29 | - Deleting a user
30 | - Updating a user
31 |
32 | In a Rails app that followed the normal conventions what controller and actions would you expect the above to map to?
33 |
34 | If you wanted to view a user's profile page what would:
35 | - the destructured/parameterized route look like?
36 | - the request contain?
37 | - the response contain?
38 |
39 | Can you discuss and explain the concept of permitted params?
40 |
41 | Can you discuss and explain the concept Controller filters?
42 |
43 | Can you describe some examples of custom (non-resourced) routes?
44 |
45 | Can you describe some success and error HTTP status codes and where you would use them?
46 |
47 | What's the difference between `resource` and `resources`
48 |
49 | What response types are available in Rails?
50 |
51 | How can you handle returning responses to a user if there isn't a view?
52 |
53 | ## Exercise
54 |
55 | In your academy-tutorial-repo
56 |
57 | Manually create a new controller and spec for handling requests related to Movies
58 |
59 | Write tests to handle creating a new Movie via a HTTP request and make these pass (be sure to include tests for failing validation)
60 |
61 | Write tests to handle viewing all Movies via a HTTP request and make these pass
62 |
63 | Write tests to handle editing and updating a Movie via a HTTP request and make these pass (be sure to include tests for failing validation)
64 |
65 | Add tests for error messages for creating and updating a Movie and return these to the user from the controller
66 |
67 | Write tests to handle viewing a Movie via a HTTP request and make these pass
68 |
69 | Refactor the above to do the loading of the Movie before the method is called and make sure your tests still pass
70 |
71 | Add tests for handling when a Movie doesn't exist and returning a message with the correct status code and make these pass
72 |
73 | Open a pull request and ask for a review when you're done
74 |
--------------------------------------------------------------------------------
/technology/guides/intro_to_ruby/README.md:
--------------------------------------------------------------------------------
1 | # Intro to Ruby Tutorial
2 |
3 | ## Resources
4 |
5 | ### Required reading
6 |
7 | - http://tryruby.org/levels/1/challenges/0
8 | - https://rubymonk.com/ (primer and primer ascent)
9 |
10 | ### If you want to go further
11 |
12 | - https://www.ruby-lang.org/en/
13 | - https://www.ruby-lang.org/en/documentation/quickstart/
14 | - http://ruby-doc.org/docs/Tutorial/
15 | - https://ruby-doc.org/core-2.4.1/Enumerable.html
16 |
17 | ## Tutorial
18 |
19 | What are:
20 | - Classes?
21 | - Objects?
22 | - Methods?
23 |
24 | What's the difference between a Module and a Class?
25 |
26 | Can you name and discuss the differences between the three method access control levels for classes and modules?
27 |
28 | Can you discuss the difference between an Array and a Hash?
29 |
30 | In a hash of:
31 |
32 | ```ruby
33 | tutorial_hash = { foo: 1, bar: '5', 'baz': 'yolo', 'qux' => 24 }
34 | ```
35 |
36 | how could you extract the values for each item individually? How could you get all the values at once?
37 |
38 | What are some different methods of looping over arrays?
39 |
40 | Given the code:
41 |
42 | ```ruby
43 | 5.next.next
44 | ```
45 |
46 | what would be returned?
47 |
48 | In the following array:
49 |
50 | ```ruby
51 | tutorial_array = [ 1, 'foo', 5, 'bar', :baz ]
52 | ```
53 |
54 | What are some ways to extract the first, third and fifth values?
55 |
56 | In the following array:
57 |
58 | ```ruby
59 | another_array = [1, 20, 42, 6, 10]
60 | ```
61 |
62 | What are some ways to add all of the values together?
63 |
64 | ## Exercise
65 |
66 | - Set up [exercism](http://exercism.io/clients/cli)
67 | - Fetch a [ruby problem](http://exercism.io/languages/ruby/about), work on it and submit your solution.
68 |
--------------------------------------------------------------------------------
/technology/guides/orm-ar-models/README.md:
--------------------------------------------------------------------------------
1 | # ORM/ActiveRecord/Models Tutorial
2 |
3 | ## Resources
4 |
5 | - http://guides.rubyonrails.org/active_record_basics.html
6 | - https://www.theodinproject.com/courses/ruby-on-rails/lessons/active-record-basics
7 | - http://guides.rubyonrails.org/active_model_basics.html
8 | - https://www.schneems.com/post/25503708759/databases-rails-week-2-modeling-relationships-and
9 | - https://semaphoreci.com/community/guides/how-to-test-rails-models-with-rspec
10 |
11 | ## Tutorial
12 |
13 | How could you write the following SQL statements in ActiveRecord format?
14 | - `SELECT * FROM movies`
15 | - `SELECT * FROM movies WHERE name='Die Hard'`
16 | - `SELECT * FROM movies WHERE release_year=2000 AND genre='Action'`
17 | - `SELECT COUNT(*) FROM movies WHERE genre='Romance'`
18 |
19 | Can you visualise and draw a table diagram for a movie rating site with the following requirements?
20 | - Directors have many movies
21 | - Directors have a name
22 | - Movies have a title, release year, and budget
23 | - Movies have many ratings
24 |
25 | Can you identify what the foreign keys would be for the above?
26 |
27 | Given the above how would you return the top 5 movies by budget from 1982?
28 |
29 | What is returned by an ActiveRecord query?
30 |
31 | What different ways could you use return all the movies released in the current year?
32 |
33 | What is the difference between using `User.find(1)`, `User.find_by(id: 1)` and `User.where(id: 1)`?
34 |
35 | What do `db:create`, `db:setup`, `db:seed`, `db:schema:load` and `db:migrate` do?
36 |
37 | ## Exercise
38 |
39 | Fork the [academy-tutorial-application](https://github.com/madetech/academy-tutorial-application) repo
40 |
41 | Set up the database and ensure any existing tests are passing
42 |
43 | Use the ActiveRecord queries you came up with in the tutorial in the `rails console` and make sure data is returned
44 |
45 | Create a migration for a Directors table and associate them with the existing Movies table (make sure to actually write your migration in the file)
46 |
47 | Write tests to ensure that Movies have a Director when they are created and that if they do not they will not be saved
48 |
49 | Make the above tests pass, remember to write as little code as needed to make them pass initially
50 |
51 | Write tests for returning the director who has made the most movies and the top 5 movies by budget in a given year and make these pass
52 |
53 | Create a migration for a Ratings table and associate them with the existing Movies table
54 |
55 | Write tests to ensure ratings are associated with movies and will not be created if they aren't
56 |
57 | Write tests to ensure ratings have a score of 1-5 and will not be created if they do not
58 |
59 | Write tests for returning all of a movies ratings and it's average rating and make these pass
60 |
61 | Write tests for returning the Director whos movies have the highest average ratings and make these pass
62 |
63 | Open a pull request and ask for a review when you're done
64 |
--------------------------------------------------------------------------------
/technology/guides/views/README.md:
--------------------------------------------------------------------------------
1 | # Views Tutorial
2 |
3 | ## Resources
4 |
5 | - http://guides.rubyonrails.org/layouts_and_rendering.html
6 | - http://guides.rubyonrails.org/action_view_overview.html
7 | - https://www.theodinproject.com/courses/ruby-on-rails/lessons/views
8 | - http://www.stuartellis.name/articles/erb/
9 | - http://guides.rubyonrails.org/form_helpers.html
10 | - https://relishapp.com/rspec/rspec-rails/docs/view-specs/view-spec
11 | - https://github.com/teamcapybara/capybara
12 | - https://robots.thoughtbot.com/how-we-test-rails-applications
13 |
14 | ## Tutorial
15 |
16 | What ways do we have of making something in the controller available to the view?
17 |
18 | What situations would you use a view spec over a feature spec and vice versa?
19 |
20 | If we wished to re-use part of one view in another how would we accomplish this?
21 |
22 | What methods are there of passing data/variables to a partial?
23 |
24 | How can we use methods in a specific controllers views without making them available to all views?
25 |
26 | Can you name and discuss any built in view helpers?
27 |
28 | ## Exercise
29 |
30 | In your academy-tutorial-repo
31 |
32 | Write tests to handle viewing a Movie's page and showing it's title and year of release and make them pass
33 |
34 | Write tests to handle viewing a Movie's page and showing it's director and make them pass
35 |
36 | Write tests to handle viewing a Movie's page and showing it's average rating (if it has any) and make them pass
37 |
38 | Write tests to handle creating a new movie from a form (using the create action you implemented in the controller/routing tutorial) and make them pass. You can assign the director randomly for now.
39 |
40 | In the same view add tests and the ability to select an existing director when creating a movie
41 |
42 | Write tests for handling editing a movie in the view and make these pass too, this should use the same form as creating a movie and the details should be pre-filled.
43 |
--------------------------------------------------------------------------------
/technology/ideas/README.md:
--------------------------------------------------------------------------------
1 | # Learning Ideas
2 |
3 | No matter how much experience, there is always more to learn or practice.
4 |
5 | Remember, practice must be deliberate.
6 |
7 | If you have some free time to learn by yourself, or in a pair, or even a mob, here are some ideas to help you use your time fruitfully.
8 |
9 | ## I want to...
10 |
11 | * [learn how to setup a Ruby development environment](./learn-how-to-setup-ruby.md)
12 | * [learn a new language](./learn-a-new-language.md)
13 | * [learn more about software architecture](./learn-software-architecture.md)
14 | * [learn to TDD](./learn-to-tdd.md)
15 | * [practice TDD](./practice-tdd.md)
16 | * [get feedback on my code style](./get-feedback-on-code.md)
17 |
18 | ## I'm not sure...
19 |
20 | ### Code Katas
21 |
22 | Go and do some Katas, either the ones [in this repository](/technology/katas/).
23 |
24 | Or from one of the following sources:
25 |
26 | * [Coding Dojo Kata](http://codingdojo.org/kata/)
27 | * [sleepyfox London Code Dojo](https://github.com/sleepyfox?utf8=%E2%9C%93&tab=repositories&q=dojo)
28 | * [Code Kata](http://codekata.com/)
29 |
30 | ### Repeat Code Katas
31 |
32 | It goes without saying, but code katas are meant to be repeated.
33 |
34 | Each time, you should focus on honing a particular part of your skill set.
35 |
36 | You will pick up new knowledge as you finish guides and seminars.
37 |
38 | Focus on applying that new knowledge in practice.
39 |
40 | #### Examples
41 |
42 | * Focus on getting names absolutely perfect, break out a thesaurus and choose the absolute most precise words for the problem at hand.
43 | * Is your code open for extension and closed for modification? Think of ways that it could be extended, and create plugin points
44 | * Do your classes and methods have one reason to change? Can you increase cohesion by refactoring?
45 |
46 | ### Read
47 |
48 | Pick up a book and read. In no particular order, here are a few that are invaluable
49 |
50 | * Test Driven Development: By Example (Kent Beck)
51 | * Growing Object-Oriented Software Guided By Tests (Steve Freeman, Nat Pryce)
52 | * Domain Driven Design (Eric Evans)
53 | * The Pragmatic Programmer (Andy Hunt)
54 | * Clean Code (Robert C. Martin)
55 | * Refactoring (Martin Fowler)
56 | * The Clean Coder (Robert C. Martin)
57 | * Clean Architecture (Robert C. Martin)
58 | * Working Effectively with Legacy Code (Michael C. Feathers)
59 | * Practical Object Oriented Design in Ruby (Sandi Metz)
60 | * The Software Craftsman (Sandro Mancuso)
61 |
62 | ### Watch
63 |
64 | Watch screencasts and other programming related videos
65 |
66 | * [Destroy All Software](https://www.destroyallsoftware.com/screencasts)
67 | * [Clean Coders](https://cleancoders.com/videos)
68 | * [Rails Casts](http://railscasts.com/) some _free videos are outdated_
69 |
70 | ### Go back over guides
71 |
72 | Can you apply the knowledge you picked up in a previous tutorial or seminar in a new project.
73 |
74 | Do you need to follow the guide, or can you remember what to do?
75 |
76 | ### Shadow others
77 |
78 | If you're currently not on a delivery team.
79 | If possible, arrange to shadow a team actively developing software.
80 |
81 | ### Code Review
82 |
83 | Go and review some code. (You don't even need to comment).
84 |
85 | * Read the code + understand it.
86 | * Do you think it's well designed.
87 | * Clone the project, try to run it locally.
88 |
89 | ### Work on a project
90 |
91 | If you have a burning desire to build something, do so.
92 |
93 | Make sure you're building it well, though.
94 |
95 | Remember:
96 |
97 | * Open small pull requests - less than ~400 lines (At Made Tech you can drop a link into #engineering or #learntech)
98 | * Make lots of mistakes, and don't fear them.
99 | * ATDD your code
100 | * Refactor relentlessly
101 | * Put into practice your ever growing knowledge
102 | * Ask for help when stuck
103 |
--------------------------------------------------------------------------------
/technology/ideas/get-feedback-on-code.md:
--------------------------------------------------------------------------------
1 | # Get feedback on code
2 |
3 | ## Find a mentor
4 |
5 | Find a mentor willing to provide feedback.
6 |
7 | ## Learn Tech
8 |
9 | Show & Tell your code at Learn Tech. Ask for constructive feedback.
10 |
11 | ## Wider team
12 |
13 | Share your code with the team on slack in an appropriate channel #engineering, #learntech, #python etc.
14 |
15 |
--------------------------------------------------------------------------------
/technology/ideas/learn-a-new-language.md:
--------------------------------------------------------------------------------
1 | # Learn a new language
2 |
3 | We have found that [Koans](../koans/) have worked well for us.
4 | Enabling us to gain a broad understanding of a new language's syntax in a very short window.
5 |
6 | ## Also to consider
7 |
8 | * What dependency management tool does that community use?
9 | * What build tool does that community use?
10 | * What is the most common testing framework in that language?
11 | * Is there a linting tool used in that language?
12 |
13 |
--------------------------------------------------------------------------------
/technology/ideas/learn-how-to-setup-ruby.md:
--------------------------------------------------------------------------------
1 | # learn how to setup Ruby
2 |
3 | We have [a tutorial for this](../guides/00-Setup/), which covers setting up a macOS development for Ruby with rbenv.
4 |
--------------------------------------------------------------------------------
/technology/ideas/learn-software-architecture.md:
--------------------------------------------------------------------------------
1 | # Learn Software Architecture
2 |
3 | A good software architecture keeps options open, allows you to defer decisions about tools and frameworks, and keep the cost of change low.
4 |
5 | We have a work in progress [learning guide on Clean Architecture](https://github.com/madetech/clean-architecture).
6 |
7 | ## Learn Tech
8 |
9 | Learn Tech is a good opportunity to learn software architecture by practicing alongside a mentor.
10 |
11 | ## There are videos on this topic
12 |
13 | * [Clean Coders](https://cleancoders.com)
14 |
15 | ## There are books on this topic
16 |
17 | * Growing Object-Oriented Software Guided By Tests (Steve Freeman, Nat Pryce)
18 | * Domain Driven Design (Eric Evans)
19 | * Object Oriented Software Engineering: A Use Case Driven Approach (Ivar Jacobson)
20 | * Clean Architecture (Robert C. Martin)
21 | * Clean Code (Robert C. Martin)
22 | * Refactoring (Martin Fowler)
23 | * Working Effectively with Legacy Code (Michael C. Feathers)
24 | * Practical Object Oriented Design in Ruby (Sandi Metz)
25 |
26 |
--------------------------------------------------------------------------------
/technology/ideas/learn-to-tdd.md:
--------------------------------------------------------------------------------
1 | # Learn to TDD
2 |
3 | ## Learn the basics
4 |
5 | We have found that the best way to learn the basics of Test Driven Development is to watch a practitioner.
6 |
7 | Some screencasts which allow you to do so:
8 |
9 | * [Destroy All Software](https://www.destroyallsoftware.com/screencasts)
10 | * [Clean Coders](https://cleancoders.com/videos)
11 |
12 | Alternatively, find a mentor willing to show you.
13 |
14 | If that is not possible, then there are some books that are quite useful:
15 |
16 | * Test Driven Development: By Example (Kent Beck)
17 | * Test Driven Development (Jason Gorman, Codemanship) [PDF](http://www.codemanship.co.uk/tdd_jasongorman_codemanship.pdf)
18 |
19 | ## Okay I know the basics of TDD, what now?
20 |
21 | After that, you'll be wanting to learn new techniques to strengthen your TDD technique.
22 |
23 | A good book for that is:
24 |
25 | * Growing Object-Oriented Software Guided By Tests (Steve Freeman, Nat Pryce)
26 |
27 | In the end, you'll want to improve your software design knowledge to unlock the benefits of TDD.
28 |
29 | ## Practice
30 |
31 | Ultimately, it's all about [practice](./practice-tdd.md).
32 |
33 |
--------------------------------------------------------------------------------
/technology/katas/README.md:
--------------------------------------------------------------------------------
1 | # Katas
2 |
3 | We use Code Katas which are programming exercises to develop our skills. This could be knowledge of a particular programming language or applying concepts such as Test Driven Development (TDD). Below is a list of Code Katas that we have found useful.
4 |
5 | * [Bowling](./bowling/)
6 | * [Wordle](./wordle/)
7 | * [Number to LCD](./number-to-lcd/)
8 | * [Roman numerals](./roman-numerals/)
9 | * [Snake](./snake/)
10 | * [Tennis](./tennis/)
11 | * [Tennis Refactoring](./tennis-refactoring/)
12 | * [Turnstile](./turnstile/)
13 | * [Word Wrap](./word-wrap/)
14 | * [Test Framework](./test-framework/)
15 | * [Video Store](./video-store/)
16 | * [Mars Rover](./mars-rover/)
17 |
--------------------------------------------------------------------------------
/technology/katas/bowling/README.md:
--------------------------------------------------------------------------------
1 | # Bowling
2 |
3 | Create a program, which, given a valid sequence of rolls for one line of American Ten-Pin Bowling, produces the total score for the game.
4 |
5 | * The input is a valid sequence of rolls
6 | * The output is the resulting score
7 |
8 | ## Example input
9 |
10 | For instance, for a game that is partway through, your input might be:
11 |
12 | > "X 45 4/ 32"
13 |
14 | This indicates that:
15 |
16 | * Four frames have been played
17 | * The first frame was a "strike" (all 10 pins knocked over in one roll - symbolised by "X")
18 | * The second frame ("45") consisted of the maximum two rolls
19 | * The first roll knocked down 4 pins
20 | * The second roll knocked down 5 pins
21 | * The third frame was a "spare" (all 10 pins knocked down in two rolls - symbolised by "/" on the second roll)
22 | * The first roll knocked down 4 pins
23 | * The second roll knocked down the remaining 6 pins
24 | * The fourth frame ("32") consisted of two rolls
25 | * The first roll knocked down 3 pins
26 | * The second roll knocked down 2 pins
27 |
28 | ## Example output
29 |
30 | For the above input of "X 45 4/ 32", the score would be 46 - scored as follows:
31 |
32 | * The first frame is a strike, which scores `10 + (all rolls from the following frame) = 10 + 4 + 5 = 19`
33 | * The second frame scores `4 + 5 = 9`
34 | * The third frame is a spare, which scores `10 + (the first roll from the following frame) = 10 + 3 = 13`
35 | * The fourth frame scores `3 + 2 = 5`
36 |
37 | For detailed scoring rules, see [below](#summarised-scoring).
38 |
39 | ## What your solution will not do
40 |
41 | Here are some things that the program will not do:
42 |
43 | * We will not check for valid rolls.
44 | * We will not check for correct number of rolls and frames.
45 | * We will not provide scores for intermediate frames.
46 |
47 | Depending on the application, this might or might not be a valid way to define a complete story, but we do it here for purposes of keeping the kata light. I think you’ll see that improvements like those above would go in readily if they were needed for real.
48 |
49 | ## Summarised scoring
50 |
51 | We can briefly summarize the scoring for this form of bowling:
52 |
53 | Each game, or “line” of bowling, includes ten turns, or “frames” for the bowler.
54 |
55 | * In each frame, the bowler gets up to two tries to knock down all the pins.
56 | * If in two tries, the bowler fails to knock them all down, their score for that frame is the total number of pins knocked down in their two tries.
57 | * If in two tries the bowler knocks them all down, this is called a “spare” and their score for the frame is ten plus the number of pins knocked down on their next throw (in their next turn).
58 | * If on their first try in the frame the bowler knocks down all the pins, this is called a “strike”. Their turn is over, and their score for the frame is ten plus the simple total of the pins knocked down in their next two rolls.
59 | * If the bowler gets a spare or strike in the last (tenth) frame, the bowler gets to throw one or two more bonus balls, respectively. These bonus throws are taken as part of the same turn. If the bonus throws knock down all the pins, the process does not repeat: the bonus throws are only used to calculate the score of the final frame.
60 | * The game score is the total of all frame scores.
61 |
62 | [More detailed scoring rules available here](https://www.myactivesg.com/sports/bowling/how-to-play/bowling-rules/how-are-points-determined-in-bowling).
63 |
64 | ## References
65 |
66 | [codingdojo.org](http://codingdojo.org/kata/Bowling/)
67 |
--------------------------------------------------------------------------------
/technology/katas/mars-rover/README.md:
--------------------------------------------------------------------------------
1 | # Mars Rover Kata
2 |
3 | You’re part of the team that explores Mars by sending remotely controlled vehicles to the surface of the planet. Develop an API that translates the commands sent from earth to instructions that are understood by the rover.
4 |
5 | ## Requirements
6 |
7 | * You are given the initial starting point (x,y) of a rover and the direction (N,S,E,W) it is facing.
8 | * The rover receives a character array of commands.
9 | * Implement commands that move the rover forward/backward (f,b).
10 | * Implement commands that turn the rover left/right (l,r).
11 | * Implement wrapping from one edge of the grid to another. (planets are spheres after all)
12 | * Implement obstacle detection before each move to a new square. If a given sequence of commands encounters an obstacle, the rover moves up to the last possible point, aborts the sequence and reports the obstacle.
13 |
14 | ## Rules
15 |
16 | * Be careful about edge cases and exceptions. We can not afford to lose a mars rover, just because the developers overlooked a null pointer.
17 |
18 | ## References
19 |
20 | * [Victor Farcic](https://technologyconversations.com/2014/10/17/java-tutorial-through-katas-mars-rover/)
21 | * [Kata Log Rocks: Mars Rover](http://kata-log.rocks/mars-rover-kata)
22 |
--------------------------------------------------------------------------------
/technology/katas/mumbling/README.md:
--------------------------------------------------------------------------------
1 | # Mumbling Kata
2 |
3 | The goal of this kata is to implement the `mumble_letters()` method which takes a string as input and returns a formatted output string. The output string contains sequences of repeating letters with each letter repeated a number of times based on its position in the input string i.e. the 3rd letter in the string is repeated 3 times. Each sequence of repeated letters is separated with a hyphen(-) and the first letter of each sequence is capitalised.
4 |
5 | The following examples illustrate the `mumble_letters()` method:
6 |
7 | ```ruby
8 | mumble_letters("a")
9 | => "A"
10 |
11 | mumble_letters("abC")
12 | => "A-Bb-Ccc"
13 |
14 | mumble_letters("aBCd")
15 | => "A-Bb-Ccc-Dddd"
16 |
17 | mumble_letters("QWERTY")
18 | => "Q-Ww-Eee-Rrrr-Ttttt-Yyyyyy"
19 | ```
20 |
21 | ## Rules
22 |
23 | Note that your `mumble_letters()` implementation should also handle an empty string input appropriately.
24 |
25 | ## References
26 |
27 | * [Codewars Mumbling Kata](https://www.codewars.com/kata/mumbling)
28 |
--------------------------------------------------------------------------------
/technology/katas/number-to-lcd/README.md:
--------------------------------------------------------------------------------
1 | # Number to LCD
2 |
3 | Goal: write a program that displays LCD style numbers.
4 |
5 | ### Part 1
6 |
7 | Write a program that given a number (with arbitrary number of digits), converts it into LCD style numbers using the following format:
8 |
9 | ```
10 | _ _ _ _ _ _ _
11 | | _| _||_||_ |_ ||_||_|
12 | ||_ _| | _||_| ||_| _|
13 | ```
14 |
15 | (each digit is 3 lines high)
16 |
17 | Note: Please do *NOT* read the second part before completing the first. Part of the purpose of this kata is to make you practice refactoring and adapting to changing requirements. [Part two is here](part2.md)
18 |
19 |
20 |
21 | ## References
22 |
23 | [codingdojo.org](http://codingdojo.org/kata/NumberToLCD/)
24 |
--------------------------------------------------------------------------------
/technology/katas/number-to-lcd/part2.md:
--------------------------------------------------------------------------------
1 | # Number to LCD: Part 2
2 |
3 | Change your program to support variable width or height of the digits.
4 | For example for width = 3 and height = 2 the digit 2 will be:
5 |
6 | ```
7 | ___
8 | |
9 | |
10 | ___
11 | |
12 | |
13 | ___
14 |
15 | ```
16 |
--------------------------------------------------------------------------------
/technology/katas/roman-numerals/README.md:
--------------------------------------------------------------------------------
1 | # Roman Numerals
2 |
3 | Given an integer input, produce output in [Roman Numeral](https://en.wikipedia.org/wiki/Roman_numerals) format.
4 |
5 | ## Example
6 |
7 | `2 => II`
8 |
9 | `5 => V`
10 |
11 | `10 => X`
12 |
13 | ## Variations
14 |
15 | * Can you make the code really beautiful and highly readable?
16 | * Consider applying the Single Responsibility Principle to the absolute extreme when you are refactoring
17 | * What's the best way to verify your tests are correct?
18 | * Compare your solutions to others
19 |
20 | ## Reference
21 |
22 | [codingdojo.org](http://codingdojo.org/kata/RomanNumerals/)
23 |
--------------------------------------------------------------------------------
/technology/katas/snake/README.md:
--------------------------------------------------------------------------------
1 | # Snake Kata
2 |
3 | This kata is based on the classic snake game that you may be familiar from the old Nokia 6110 or the Nokia 3210 phones.
4 |
5 | 
6 |
7 | ## Requirements
8 | * The snake can move in any direction on the grid
9 | * When the snake reaches one edge of the grid it appears at the other side
10 | * The snake can turn left and right
11 | * The snake can grow in length when feeding
12 | * The snake can crash into its own body
13 |
14 | ## Rules
15 | * The snake should only turn one unit at a time, hard turns are not allowed. For instance, the snake is facing N; it should be able to turn W or E but NOT towards S.
16 |
17 | ## References
18 | * [Nokia Wiki](https://nokia.fandom.com/wiki/Snake)
19 | * [Snake Wiki](https://en.wikipedia.org/wiki/Snake_(video_game_genre))
20 |
--------------------------------------------------------------------------------
/technology/katas/tennis-refactoring/README.md:
--------------------------------------------------------------------------------
1 | # Tennis Refactoring
2 |
3 | You'll find the starting code for the refactoring kata at [emilybache/Tennis-Refactoring-Kata](https://github.com/emilybache/Tennis-Refactoring-Kata).
4 |
5 | Follow the instructions in [Tennis-Refactoring-Kata/README.md](https://github.com/emilybache/Tennis-Refactoring-Kata/blob/master/README.md)
6 |
--------------------------------------------------------------------------------
/technology/katas/tennis/README.md:
--------------------------------------------------------------------------------
1 | # Tennis
2 |
3 | This Kata is about implementing a simple tennis game.
4 |
5 | Rather than using standard Tennis scoring, **we consider scoring in Wii tennis**, which has a simplified version of tennis, so each set is one game.
6 |
7 | The scoring system is as follows:
8 |
9 | 1. Each player can have either of these points in one game 0 15 30 40
10 |
11 | 2. If you have 40 and you win the ball you win the game, however there are special rules.
12 |
13 | 3. If both have 40 the players are deuce.
14 | - a. If the game is in deuce, the winner of a ball will have advantage and game ball.
15 | - b. If the player with advantage wins the ball they win the game
16 | - c. If the player without advantage wins they are back at deuce.
17 |
18 | ## Alternative description of rules
19 |
20 | 1. A game is won by the first player to have won at least four points in total and at least two points more than the opponent.
21 |
22 | 2. The running score of each game is described in a manner peculiar to tennis: scores from zero to three points are described as “love”, “fifteen”, “thirty”, and “forty” respectively.
23 |
24 | 3. If at least three points have been scored by each player, and the scores are equal, the score is “deuce”.
25 |
26 | 4. If at least three points have been scored by each side and a player has one more point than their opponent, the score of the game is “advantage” for the player in the lead.
27 |
28 | ## Reference
29 |
30 | [codingdojo.org](http://codingdojo.org/kata/Tennis/)
31 |
--------------------------------------------------------------------------------
/technology/katas/test-framework/README.md:
--------------------------------------------------------------------------------
1 | # Test Framework
2 |
3 | For this Kata you need to build a test framework from scratch.
4 |
5 | * It should provide some way to separate tests, so that users can follow the single assert rule.
6 | * It should provide some way to name each test.
7 | * It should have a plugin architecture. (Up to you to decide where flexibility is desirable).
8 |
9 | Obviously, you should TDD your solution. (Some creativity required!).
10 |
11 | ## Variations
12 |
13 | * Do you use another testing framework to test your framework?
14 | * Do you bootstrap testing your test framework with the test framework?
15 | * TDD another Kata using your test framework, how usable is it?
16 |
17 | ## Useful Links
18 |
19 | * [Destroy all software: building rspec from scratch](https://www.destroyallsoftware.com/screencasts/catalog/building-rspec-from-scratch)
20 |
21 |
--------------------------------------------------------------------------------
/technology/katas/turnstile/README.md:
--------------------------------------------------------------------------------
1 | # Turnstile
2 |
3 | ## Finite State Machines
4 |
5 | If you've never encountered finite state machine (FSM) modelling before, here is what it looks like.
6 |
7 | The following state machine is comprised of two states: "State 1" and "State 2". There is a single event "event_name" that can take the state machine from State 1 to State 2.
8 |
9 | -event_name>(State 2))
10 |
11 | One use case of FSMs is User Interface logic, consider the following:
12 |
13 | -open%3E(MenuClosed),%20(MenuOpen)-open%3E(MenuOpen),%20(MenuClosed)-close%3E(MenuOpen),%20(MenuClosed)-close%3E(MenuClosed))
14 |
15 | Each event of the finite state machine can be bound to application methods e.g.
16 |
17 | -open[show]>(MenuClosed),%20(MenuOpen)-open[nil]>(MenuOpen),%20(MenuClosed)-close[hide]>(MenuOpen),%20(MenuClosed)-close[nil]>(MenuClosed))
18 |
19 | ## The Kata
20 |
21 | Build a finite state machine from scratch, that replicates the following Finite State Machine
22 |
23 | -coin[unlock]%3E(Unlocked),%20(Unlocked)-pass[lock]%3E(Locked),%20(Unlocked)-pass[alarm]%3E(Unlocked),%20(Locked)-coin[thanks]%3E(Locked))
24 |
25 | Once you have completed that, continue on to part 2 (remember the point is to learn about the impact of changing requirements, so no peeking!) [you can find part 2 here](./part2.md)
26 |
--------------------------------------------------------------------------------
/technology/katas/turnstile/part2.md:
--------------------------------------------------------------------------------
1 | # Turnstile: Part 2
2 |
3 | Now extend it to the following states
4 |
5 | 
6 |
--------------------------------------------------------------------------------
/technology/katas/video-store/README.md:
--------------------------------------------------------------------------------
1 | # Video Store
2 |
3 | Write a system that can build a `statement`, when given `rentals`.
4 |
5 | When there are 3 regular movie rentals for 1, 2 and 3 days respectively, the statement looks like:
6 |
7 | ```
8 | Rental Record for Customer Name
9 | Crazynotes £2.0
10 | Teeth £2.0
11 | The Web £3.5
12 | You owe £7.5
13 | You earned 3 frequent renter points
14 | ```
15 |
16 | ## Regular Movies
17 |
18 | Are £2 for the first 2 days, and £1.50 for each day thereafter.
19 |
20 | You earn 1 frequent renter point no matter the length of the rental.
21 |
22 | ## New Release Movies
23 |
24 | Are £3 per day.
25 |
26 | You earn 1 frequent renter point for a 1 day rental, and 2 for any rental of 2 days or more.
27 |
28 | ## Childrens Movies
29 |
30 | Are £1.50 for the first 3 days, and £1.50 for each day thereafter.
31 |
32 | You earn 1 frequent renter point no matter the length of the rental.
33 |
34 | # References
35 |
36 | This Kata is based upon an example in Martin Fowler's Refactoring book, and is also covered in Episode 3 of [Clean Coders](https://cleancoders.com).
37 |
38 |
--------------------------------------------------------------------------------
/technology/katas/word-wrap/README.md:
--------------------------------------------------------------------------------
1 | # Word Wrap
2 |
3 | You write a class called Wrapper, that has a single static function named wrap that takes two arguments, a string, and a column number. The function returns the string, but with line breaks inserted at just the right places to make sure that no line is longer than the column number. You try to break lines at word boundaries.
4 |
5 | Like a word processor, break the line by replacing the last space in a line with a newline.
6 |
7 | ## References
8 |
9 | [codingdojo.org](http://codingdojo.org/kata/WordWrap/)
10 |
--------------------------------------------------------------------------------
/technology/katas/wordle/README.md:
--------------------------------------------------------------------------------
1 | # Wordle
2 |
3 |
4 | Create a program, which, given a 5 character string as a target word, and a 5 character string as a guess, return a 5 character string where:
5 | ```
6 | ‘2’ = this letter is in this position
7 | ‘1’ = this letter is in the target word but not this position
8 | ‘0’ = this letter is either not in the target word, or is not in the target word as many times as it is in the guess
9 | ```
10 |
11 | ## Examples
12 |
13 | ### No matching characters
14 | ```
15 | Target = “ropes”
16 | Guess = “child”
17 | Result = “00000”
18 | ```
19 |
20 | ### Characters match in correct positions
21 | ```
22 | Target = “alert”
23 | Guess = “alarm”
24 | Result = “22020”
25 | ```
26 |
27 | ### Character in wrong position
28 | ```
29 | Target = “stair”
30 | Guess = “chore”
31 | Result = “00010”
32 | ```
33 |
34 | ### Mix of match and wrong position
35 | ```
36 | Target = “hairy”
37 | Guess = “charm”
38 | Result = “01120”
39 | ```
40 |
41 | ### Multiple characters in wrong positions
42 | ```
43 | Target = “reads”
44 | Guess = “elect”
45 | Result = “10000”
46 | ```
47 |
48 |
49 |
--------------------------------------------------------------------------------
/technology/koans/README.md:
--------------------------------------------------------------------------------
1 | # Koans
2 |
3 | The word Koan comes from Zen Practice, there it is used to provoke the "great doubt" and test a student's progress in Zen practice.
4 |
5 | In programming, we use Koans to provoke "great doubt" in our knowledge of how to wield programming languages.
6 |
7 | You can usually find Koans for languages by Googling "\ koans", but here we have comprised a list of Koans that we have found particularly helpful.
8 |
9 | * [Ruby](http://rubykoans.com/)
10 | * [Elixir](https://github.com/elixirkoans/elixir-koans)
11 | * [Go](https://github.com/cdarwin/go-koans)
12 | * [Kotlin](https://github.com/Kotlin/kotlin-koans)
13 | * [Java](https://github.com/matyb/java-koans)
14 | * [C# (.NET Core)](https://github.com/NotMyself/DotNetCoreKoans) / [.NET](https://github.com/CoryFoy/DotNetKoans) / [C# (MSTest)](https://github.com/jtigger/csharp-koans)
15 | * [F#](https://github.com/craigjbass/FSharpKoans)
16 | * [Clojure](https://github.com/functional-koans/clojure-koans)
17 | * [GNU Smalltalk](https://github.com/craigjbass/gnu_smalltalk_koans)
18 | * [Common Lisp](https://github.com/craigjbass/lisp-koans)
19 | * [Elm](https://github.com/robertjlooby/elm-koans)
20 | * [Erlang](https://github.com/patrickgombert/erlang-koans)
21 | * [Python](https://github.com/gregmalcolm/python_koans)
22 |
--------------------------------------------------------------------------------
/technology/scenarios/README.md:
--------------------------------------------------------------------------------
1 | # Scenarios
2 |
3 | Not all of our work as technologists is writing software. In this section we explore scenarios for other aspects of delivery such as infrastructure, devops and data expertise.
4 |
5 | * [Cloud](./cloud/) scenarios
6 |
--------------------------------------------------------------------------------
/technology/scenarios/cloud/README.md:
--------------------------------------------------------------------------------
1 | # Scenarios for the cloud
2 |
3 | Many services are now served from and managed via cloud providers. Part of the delivery of a new service, or changes to an existing one, will be getting the infrastructure it works on ready and able to support communication with other services; these could be within or outside your organisations.
4 |
5 | Here are some common scenarios for you to try for yourself or mob or pair on with others:
6 |
7 | * Standing up an [observable webserver](./webserver) to receive traffic
8 | * Setting up a [communication method](./distributed-comms-queues) to help distributed services talk to one another
9 |
--------------------------------------------------------------------------------
/technology/scenarios/cloud/distributed-comms-queues.md:
--------------------------------------------------------------------------------
1 | # Distributed communications scenario - Queues
2 |
3 | ## Goal
4 |
5 | Set up a queuing mechanism to enable distributed services to communicate with each other within an organisation so they can remain (or become more) decoupled.
6 |
7 | ## The task
8 |
9 | You are required to set up a queue in a cloud provider (let's assume AWS with SQS as a starting point).
10 |
11 | The queue should:
12 |
13 | * Be created and decomissioned via code
14 | * Be updated by code to adjust properties such as message retention
15 | * Have a mechanism to pick up messages
16 | * Have a mechanism to remove a message from a queue once it has been processed
17 |
18 | ## Prerequisites
19 |
20 | You will want some AWS creds for an account you can work in.
21 |
22 | ## Work
23 |
24 | * Create a queue using infrastructure as code such as terraform
25 | * Adjust the queue so that any messages older than 12 hours will be automatically deleted
26 | * Send a test message to the queue
27 | * Write something, maybe a script in your favourite language, to:
28 | * retrieve the test message from the queue
29 | * print the message body
30 | * remove the message from the queue
31 |
--------------------------------------------------------------------------------
/technology/scenarios/cloud/webserver.md:
--------------------------------------------------------------------------------
1 | # Web server scenario
2 |
3 | ## Goal
4 |
5 | Automate the creation of a web server, and provide a healthcheck script to verify the server is up and responding correctly.
6 |
7 | ## The Task
8 |
9 | You are required to provision and deploy a new service in a cloud provider (let's assume AWS). It must:
10 |
11 | * Be publicly accessible, but *only* on port 80.
12 | * Run Nginx.
13 | * Serve a `/version.txt` file, containing only static text representing a version number, for example:
14 |
15 | ```txt
16 | 1.0.6
17 | ```
18 |
19 | ## Prerequisites
20 |
21 | You will want some AWS creds for an account you can work in.
22 |
23 | ## Work
24 |
25 | * Bootstrap and provision the server however you wish. Use user-data or a configuration management tool (such as Puppet, Chef or Ansible). Alternatively launch an idempotent AMI with packer and terraform, or even via the console.
26 |
27 | * Provide a heatlhcheck script that can be run externally to periodically check if the server is up and serving the expected version number.
28 |
29 | * Alter the README to contain the steps required to:
30 | * Create the server.
31 | * Run the healthcheck script.
32 |
33 | ## Hints
34 |
35 | If you want to run this exercise as time-boxed, these might shortcut the process by making it easier in the long-run so they might be worth considering before you start.
36 |
37 | * Make the service resilient in 2 availability zones.
38 | * Run Nginx inside a Docker container.
39 | * Use the healthcheck script to start Nginx if it is not running.
40 |
41 | ```txt
42 | For example, you might decide to modify the script to SSH in to the instances and start if needed.
43 | Alternatively you might configure a process manager to use the script on the hosts themselves,
44 | such as supervisord or plain old systemd.
45 | ```
46 |
--------------------------------------------------------------------------------
/technology/seminars/01-The-Power-of-Naming/README.md:
--------------------------------------------------------------------------------
1 | # The Power of Naming
2 |
3 | [Presentation](https://docs.google.com/presentation/d/1-yh9S1I4wdVXJcrOhftJshmlFuDQmq3Rt7vrdfpVvEY/edit?usp=sharing)
4 |
5 | [Examples](https://github.com/madetech/learn/tree/master/technology/seminars/01-The-Power-of-Naming/examples) for the Seminar
6 |
7 | * Pronounceable
8 | * Reveal Intent / Avoid Disinformation
9 | * Avoid Lack of Specificity
10 | * No Comments
11 | * The Scope Rule
12 | * Searchable
13 | * System Metaphor
14 | * Single Letter Variables
15 | * Avoid Entertaining Names
16 | * Avoid Multiple Names for the Same Concept
17 | * Avoid Multiple Concepts with the Same Name
18 |
--------------------------------------------------------------------------------
/technology/seminars/01-The-Power-of-Naming/examples/example1.rb:
--------------------------------------------------------------------------------
1 | class TrainManager
2 | def initialize(signals)
3 | @signals = signals
4 | end
5 |
6 | def slow(train)
7 | signal = @signals.next(train.sigid, train.dir) # next signal for the train
8 | signal.to(:slower)
9 |
10 | true
11 | end
12 |
13 | def stop(train)
14 | signal = @signals.next(train.sigid, train.dir) # next signal for the train
15 | signal.red
16 |
17 | true
18 | end
19 | end
20 |
--------------------------------------------------------------------------------
/technology/seminars/01-The-Power-of-Naming/examples/example2.rb:
--------------------------------------------------------------------------------
1 | class Wrapper
2 | def initialize(text, width)
3 | @text = text
4 | @width = width
5 | end
6 |
7 | def fit
8 | ls = []
9 | l = ''
10 | @text.lines do |line|
11 | line.chomp! "\n"
12 | if line.empty?
13 | unless l.empty?
14 | ls.push l
15 | l = ''
16 | end
17 | ls.push ''
18 | end
19 |
20 | words = line.split ' '
21 |
22 | words.each do |word|
23 | word.chomp! "\n"
24 |
25 | if l.length + word.length < @width
26 | if !l.empty?
27 | l << ' ' << word
28 | else
29 | l = word
30 | end
31 | else
32 | if word.length >= @width
33 | ls.push l unless l == ''
34 | ls.push word
35 | l = ''
36 | else
37 | ls.push l
38 | l = word
39 | end
40 | end
41 | end
42 | end
43 |
44 | ls.push l
45 | if l.length <= 0
46 | ls.join("\n")
47 | else
48 | ls.join("\n") + "\n"
49 | end
50 | end
51 |
52 | def wrap
53 | listy = []
54 |
55 | @text.lines do |ruler|
56 | ruler.chomp! "\n"
57 | if ruler.length > @width
58 | new_lines = split_line(ruler, @width)
59 | while new_lines.length > 1 && new_lines[1].length > @width
60 | listy.push new_lines[0]
61 | new_lines = split_line new_lines[1], @width
62 | end
63 | listy += new_lines
64 | else
65 | listy.push ruler
66 | end
67 | end
68 | listy.map(&:rstrip!)
69 | listy.join("\n") + "\n"
70 | end
71 |
72 | def split_line(l, cols)
73 | at = l.index /\s/
74 | last_at = at
75 |
76 | while !at.nil? && at < cols
77 | last_at = at
78 | at = l.index /\s/, last_at + 1
79 | end
80 |
81 | if last_at.nil?
82 | [l]
83 | else
84 | [l[0, last_at], l[last_at + 1, l.length]]
85 | end
86 | end
87 | end
88 |
--------------------------------------------------------------------------------
/technology/seminars/01-The-Power-of-Naming/examples/example3.rb:
--------------------------------------------------------------------------------
1 | class RomanNumeral
2 | def convert(iNumber)
3 | @sNumeral = ''
4 | @iNumber = iNumber
5 | return 'There is no Roman Numeral for 0' if @iNumber == 0
6 | mNumberConversion
7 | @sNumeral
8 | end
9 |
10 | private
11 |
12 | def mNumberConversion(number = @iNumber)
13 | aNumeralConversion.keys.each do |divisor|
14 | iR, iM = number.divmod(divisor)
15 | @sNumeral << aNumeralConversion[divisor] * iR
16 | return mNumberConversion(iM) if iR > 0
17 | return mNumberConversion(iM) if iR > 0
18 | end
19 | end
20 |
21 | def aNumeralConversion
22 | {
23 | 1000 => 'M',
24 | 900 => 'CM',
25 | 500 => 'D',
26 | 400 => 'CD',
27 | 100 => 'C',
28 | 90 => 'XC',
29 | 50 => 'L',
30 | 40 => 'XL',
31 | 10 => 'X',
32 | 9 => 'IX',
33 | 5 => 'V',
34 | 4 => 'IV',
35 | 1 => 'I'
36 | }
37 | end
38 | end
39 |
--------------------------------------------------------------------------------
/technology/seminars/01-The-Power-of-Naming/examples/example4.rb:
--------------------------------------------------------------------------------
1 | class MovePlayer
2 | def initialize(player_gateway:)
3 | @player_gateway = player_gateway
4 | end
5 |
6 | def execute(player_id:, x:, y:)
7 | player = @player_gateway.player(player_id)
8 | player.x = x
9 | player.y = y
10 |
11 | player.save
12 |
13 | { successful: true }
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/technology/seminars/02-Functions/README.md:
--------------------------------------------------------------------------------
1 | # Eloquent Functions
2 |
3 | [Presentation](https://docs.google.com/presentation/d/139E2O0SShJ8tSKGiLPxlda2QHMpPYG8jEN_abciGONA/edit#slide=id.g1d0b0611da_0_55)
4 |
5 | * Short
6 | * Do one thing
7 | * One Level of Abstraction
8 | * Switch statements / polymorphism
9 | * Arguments
10 | * Argument objects
11 | * Side-effects
12 | * CQS
13 |
--------------------------------------------------------------------------------
/technology/seminars/03-Architecture/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madetech/learn/5a0c5dce6caf79dd4723ef9261c09198c5fb9dae/technology/seminars/03-Architecture/README.md
--------------------------------------------------------------------------------
/technology/seminars/04-Single-Responsibility-Principle/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madetech/learn/5a0c5dce6caf79dd4723ef9261c09198c5fb9dae/technology/seminars/04-Single-Responsibility-Principle/README.md
--------------------------------------------------------------------------------
/technology/seminars/05-Open-Closed-Principle/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madetech/learn/5a0c5dce6caf79dd4723ef9261c09198c5fb9dae/technology/seminars/05-Open-Closed-Principle/README.md
--------------------------------------------------------------------------------
/technology/seminars/06-Liskov-Substitution-Principle/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madetech/learn/5a0c5dce6caf79dd4723ef9261c09198c5fb9dae/technology/seminars/06-Liskov-Substitution-Principle/README.md
--------------------------------------------------------------------------------
/technology/seminars/07-Interface-Segregation-Principle/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madetech/learn/5a0c5dce6caf79dd4723ef9261c09198c5fb9dae/technology/seminars/07-Interface-Segregation-Principle/README.md
--------------------------------------------------------------------------------
/technology/seminars/08-Dependency-Inversion-Principle/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madetech/learn/5a0c5dce6caf79dd4723ef9261c09198c5fb9dae/technology/seminars/08-Dependency-Inversion-Principle/README.md
--------------------------------------------------------------------------------
/technology/seminars/README.md:
--------------------------------------------------------------------------------
1 | # Seminar Content
2 |
3 | **Note:** These seminars are meant as broad outlines for mentors to deliver, not for mentees.
4 |
5 | * [The Power of Naming](./01-The-Power-of-Naming/)
6 | * [Functions](./02-Functions/)
7 |
8 | ## References
9 |
10 | * [Clean Code](https://www.amazon.co.uk/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882)
11 |
12 |
--------------------------------------------------------------------------------
/technology/skills/c-sharp-and-dotnet/eagle.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madetech/learn/5a0c5dce6caf79dd4723ef9261c09198c5fb9dae/technology/skills/c-sharp-and-dotnet/eagle.jpg
--------------------------------------------------------------------------------
/technology/skills/c-sharp-and-dotnet/goat.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madetech/learn/5a0c5dce6caf79dd4723ef9261c09198c5fb9dae/technology/skills/c-sharp-and-dotnet/goat.jpg
--------------------------------------------------------------------------------
/technology/skills/c-sharp-and-dotnet/mantis.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madetech/learn/5a0c5dce6caf79dd4723ef9261c09198c5fb9dae/technology/skills/c-sharp-and-dotnet/mantis.jpg
--------------------------------------------------------------------------------
/technology/sparring/README.md:
--------------------------------------------------------------------------------
1 | # Sparring
2 |
3 | The name comes from Martial Arts; sparring is a form of practice that allows students of a martial art to try out the sum total of all their knowledge in practice.
4 |
5 | Whilst katas are useful at building knowledge... At some point, it is necessary to assemble your experience into a much larger exercise.
6 |
7 | The purpose of a larger "sparring" exercise is to simulate a real world scenario.
8 |
9 | While doing these exercises you should retrospect on your previous decisions.
10 |
11 | **These exercises are split into multiple parts, it's important to not skip ahead**
12 |
13 | * [Tic Tac Toe](./tic-tac-toe/)
14 | * [Payroll](./payroll/)
15 |
16 |
--------------------------------------------------------------------------------
/technology/sparring/payroll/README.md:
--------------------------------------------------------------------------------
1 | # Payroll
2 |
3 | This is an exercise in Software Design and Changing Requirements.
4 |
5 | Don't peek ahead at the later steps of this challenge, as part of the point of this is to deal with changing requirements.
6 |
7 | ## Requirements
8 |
9 | Using the discipline of TDD, and Acceptance Testing, build a Payroll system.
10 |
11 | Architectural design is up to you, but design wisely! Avoid a big ball of mud!
12 |
13 | * The payroll system should calculate pay for salaried employees.
14 | * Salaried employees can receive their pay weekly or monthly.
15 | * Payslips should calculate the amount of tax deductable
16 | * Payslips should be viewable via a web interface
17 | * If an employee is a member of a union, their union dues should be deducted from their post-tax salary.
18 | * The tax year is January 2nd to January 1st.
19 | * There should be a web interface.
20 |
21 | ## Tax Rules
22 |
23 | * Up to £10,000, pay is tax-free.
24 | * For the sum of pay between £10,000-25,000 tax is deducted at a rate of 20%.
25 | * For the remainder amount over £25,000 tax is deducted at a rate of 40%.
26 |
27 | ## Payslips
28 |
29 | Should contain:
30 |
31 | * Total gross pay for current tax year.
32 | * Total gross pay for tax period (week, month).
33 | * List of deducted amounts pre-tax incl. rates.
34 | * List of deducated amounts post-tax incl. what for.
35 | * The length of the tax period, with start and end dates.
36 |
37 | ## Out of scope
38 |
39 | * No need to implement a secure login system
40 | * No need to implement an emailing system
41 |
42 | # Next
43 |
44 | Coming soon!
45 |
--------------------------------------------------------------------------------
/technology/sparring/tic-tac-toe/README.md:
--------------------------------------------------------------------------------
1 | # Tic Tac Toe
2 |
3 | This is an exercise in Software Design and Changing Requirements.
4 |
5 | Don't peek ahead at the later steps of this challenge, as part of the point of this is to deal with changing requirements.
6 |
7 | ## Requirements
8 |
9 | Using the discipline of TDD, build a game of tic tac toe.
10 |
11 | * The game should allow a human to play against an AI.
12 | * The AI should be unbeatable.
13 | * The game should have a user interface of some kind.
14 |
15 | **Rules**
16 |
17 | 1. The game is played on a 3x3 grid.
18 |
19 | 2. You are X, your opponent is O. Players take turns putting their marks in empty squares.
20 |
21 | 3. The first player to get 3 of their marks in a row (up, down, across, or diagonally) is the winner.
22 |
23 | 4. If all 9 squares are full and no player has 3 marks in a row, the game is over.
24 |
25 | ## Next
26 |
27 | Once you have implemented all the rules here, and are happy with your system's design go [here](./part2.md)
28 |
29 |
--------------------------------------------------------------------------------
/technology/sparring/tic-tac-toe/part2.md:
--------------------------------------------------------------------------------
1 | # Tic Tac Toe: Part 2
2 |
3 | You may have chosen to implement a web interface or a command line user interface, or perhaps another type of UI.
4 |
5 | These UIs can be divided into two categories, client-side (e.g. web interface) and server-side (e.g. command line).
6 |
7 | Implement a UI from the opposite category.
8 |
9 | ## Considerations
10 |
11 | * Avoid testing the same logic from multiple test suites
12 | * Avoid coupling your business logic to specifics of different UIs (e.g. if ui == 'cli' then ... else ...).
13 | * Can you deploy your game rules independently of your UI? Could your game rules be [packaged up into a separate Gem](../../guides/06-Gem-Packaging/)?
14 |
15 | ## Next Steps
16 |
17 | Once you have implemented your alternative UI, go [here](./part3.md).
18 |
19 |
--------------------------------------------------------------------------------
/technology/sparring/tic-tac-toe/part3.md:
--------------------------------------------------------------------------------
1 | # Tic Tac Toe: Part 3
2 |
3 | Implement the [Misère](https://en.wikipedia.org/wiki/Tic-tac-toe_variants#Misere_Tic-tac-toe) variant of Tic-Tac-Toe
4 |
5 | ## Rules
6 |
7 | * The player wins if their opponent gets 3 in a row.
8 |
9 | ## Game Features
10 |
11 | * The user should be able to choose between Standard and Misère tic-tac-toe.
12 |
13 | # Part 4
14 |
15 | Once you've implemented Misère continue to [part 4](./part4.md).
16 |
--------------------------------------------------------------------------------
/technology/sparring/tic-tac-toe/part4.md:
--------------------------------------------------------------------------------
1 | # Tic Tac Toe: Part 4
2 |
3 | Allow multiple boards to be played simultaneously
4 |
5 | ## Rules
6 |
7 | * The winner is the one who wins the majority of boards
8 |
9 | ## Game Features
10 |
11 | * The user should be able to specify the number of games to be played
12 |
13 | # Part 5
14 |
15 | Once you can play multiple boards continue to [part 5](./part5.md)
16 |
--------------------------------------------------------------------------------
/technology/sparring/tic-tac-toe/part5.md:
--------------------------------------------------------------------------------
1 | # Tic Tac Toe: Part 5
2 |
3 | Implement [Notakto](https://en.wikipedia.org/wiki/Notakto)
4 |
5 | ## Rules
6 |
7 | * Like Misère but both players play as X
8 |
9 | ## Game Features
10 |
11 | * The user should be able to choose between Standard, Misère and Notakto
12 |
13 | # Part 6
14 |
15 | Once you can play Notakto progress to [part 6](./part6.md)
16 |
--------------------------------------------------------------------------------
/technology/sparring/tic-tac-toe/part6.md:
--------------------------------------------------------------------------------
1 | # Tic Tac Toe: Part 6
2 |
3 | Add a local co-op mode.
4 |
5 | ## Game Features
6 |
7 | * The user should be able to play against a player on the same machine
8 | * The user should be able to choose between playing against the AI or a player on the same machine
9 |
10 | # Fin.
11 | If you've reached this point I'm impressed.
12 |
--------------------------------------------------------------------------------
/technology/videos/README.md:
--------------------------------------------------------------------------------
1 | # Screencasts
2 |
3 | What we have discovered is that observing other practice, is for some skills the easiest way to pick up nuances that would otherwise be missed.
4 |
5 | * [An introduction to TDD with the Tennis Kata](./tennis.md) _by Craig J. Bass_ ~TDD, Ruby, Refactoring, RSpec
6 | * [Build a General Ledger in .NET Core using Clean Architecture](./general-ledger.md) _by Craig J. Bass_ ~ATDD, Clean Architecture, C#, NUnit, Refactoring
7 |
8 |
--------------------------------------------------------------------------------
/technology/videos/general-ledger.md:
--------------------------------------------------------------------------------
1 | # Build a General Ledger in .NET Core using Clean Architecture
2 |
3 | This series is designed to demonstrate using ATDD discipline to build a .NET Core General Ledger using Clean Architecture.
4 |
5 | [Source code is available](https://github.com/madetech/dotnet-general-ledger)
6 |
7 | 1. [Part 1 - Start with acceptance testing](https://drive.google.com/open?id=1eNRRkTVf3OSDtGHGQZpnzUwJTxKeg-Zb)
8 | 2. [Part 2 - Emerging Domain](https://drive.google.com/open?id=1_aO22OssMKkpyBzdhzyEvBsanErdPYgh)
9 | 3. [Part 3 - Second passing acceptance test!](https://drive.google.com/open?id=12lIbf598kHet5m0-LdHstvJVEdzQw4Xv)
10 | 4. [Part 4 - Another Use Case?](https://drive.google.com/open?id=1seqKZi9JRM8BEYsKIPuRM9TV3aiLCfOk)
11 | 5. _coming soon_
12 |
13 |
--------------------------------------------------------------------------------
/technology/videos/tennis.md:
--------------------------------------------------------------------------------
1 | # Introduction to Test Driven Development (Tennis Kata)
2 |
3 | This series is design to be a quick taster to demonstrate the discipline of Test Driven Development.
4 |
5 | 1. [Part 1 - Introduction](https://drive.google.com/file/d/1WxjDGg8DXm0rwW0bpCRKl1LOrgJJlQ9p/view?usp=sharing)
6 | 2. _coming soon._
7 |
8 |
--------------------------------------------------------------------------------