diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml
index 9455a4d5..402d2f19 100644
--- a/.github/workflows/build_and_test.yml
+++ b/.github/workflows/build_and_test.yml
@@ -2,7 +2,9 @@ name: build_and_test
on:
push:
+ branches: [ main ]
pull_request:
+ branches: [ main ]
workflow_dispatch:
jobs:
diff --git a/README.md b/README.md
index cc316f87..3dd90418 100644
--- a/README.md
+++ b/README.md
@@ -26,8 +26,14 @@ We would like to do some refactoring. This is the plan
1. Add search feature
- [x] bring back nice XML-based test reports in GitHub workflow
- - [ ] search results include unwanted pages (e.g. 404)
- - [ ] ensure the teardown kills the server
+ - [x] search results include unwanted pages (e.g. 404)
+ - [x] ensure the teardown kills the server
+ - [x] add more pages to the search index
+ - [ ] remove signup thankyou pages from search index
+ - [ ] toggle search on in production
+1. Think of a better name for "Activities" - "Learning Segments" and move it under "Reference" which we can rename to "Resources"
+2. Work out what the 'workshops' collection is and whether to keep it and/or add it to the search index
+3. Improve page names for open space signups - too many pages with similar names!
1. switch from scripts to rake
2. Add a field to katas for "difficulty" and allow people to sort them. Possibly tags too?
3. Show a calendar of all upcoming events. Do not show joining info, link to information page for the event. Not sure how to achieve this - base it on the google calendar?
diff --git a/_data/contributors.yml b/_data/contributors.yml
index a83cdc52..00193f22 100644
--- a/_data/contributors.yml
+++ b/_data/contributors.yml
@@ -131,3 +131,8 @@ devill:
url: https://www.ivettordog.com/
affiliation: Independent
member: yes
+nicolerauch:
+ title: Nicole Rauch
+ url: http://nicole-rauch.de
+ affiliation: Independent
+ member: no
diff --git a/_layouts/refactoring.html b/_layouts/refactoring.html
index 4d4a9c95..b8da2a07 100644
--- a/_layouts/refactoring.html
+++ b/_layouts/refactoring.html
@@ -37,7 +37,10 @@
\ No newline at end of file
+
diff --git a/_learning_hours/legacy/extract_override.md b/_learning_hours/legacy/extract_override.md
index 60349893..695949c8 100644
--- a/_learning_hours/legacy/extract_override.md
+++ b/_learning_hours/legacy/extract_override.md
@@ -8,7 +8,7 @@ author: emilybache
# Extract and Override
-"Extract and Override" is a classic dependency breaking technique from Michael Feathers' book "Working Effectively with Legacy Code". In this session we demonstrate it using the classic coding problem "TripService" by Sandro Mancuso.
+This is a classic dependency breaking technique from Michael Feathers' book "Working Effectively with Legacy Code". In this session we learn how to use it on the classic coding problem "TripService" by Sandro Mancuso. Emily Bache has made a video ["Breaking Legacy Code Dependencies with Extract and Override"](https://www.youtube.com/watch?v=hwr9bVyXkTY) that explains more and shows a demo using Java.
## Learning Objectives
- Describe when to use a dependency breaking technique
diff --git a/_learning_hours/refactoring/conditional_to_polymorphism.md b/_learning_hours/refactoring/conditional_to_polymorphism.md
index e52fdc38..a5f8091c 100644
--- a/_learning_hours/refactoring/conditional_to_polymorphism.md
+++ b/_learning_hours/refactoring/conditional_to_polymorphism.md
@@ -6,9 +6,9 @@ difficulty: 3
author: emilybache
affiliation: Praqma
tags: refactoring
+name: replace_conditional_with_polymorphism
---
-
# Replace Conditional With Polymorphism
This refactoring replaces conditional logic with classes and polymorphism. The code smell that leads you to it is having a lot of similar switch statements that switch on type. In this session we'll practice doing it, and hopefully see just how good modern IDE tooling is for this kind of task.
@@ -70,6 +70,7 @@ or (CLion 2022.2.3, C++)
- Change Signature
- Introduce Constant...
+You could also use the refactoring steps outlined in ["Replace Conditional with Polymorphism"]({% link _refactorings/replace_conditional_polymorphism.md %})
### Do Parrot
People should work in pairs to do the same exercise again from the start. If they lack IDE experience, they should follow your list of shortcuts from the whiteboard. More confident pairs may know other shortcuts and can try to achieve the same thing in a different way. Ask them to write down their sequence of steps if so.
diff --git a/_learning_hours/refactoring/decompose_conditional.md b/_learning_hours/refactoring/decompose_conditional.md
new file mode 100644
index 00000000..911919a4
--- /dev/null
+++ b/_learning_hours/refactoring/decompose_conditional.md
@@ -0,0 +1,48 @@
+---
+theme: refactoring
+title: Decompose Conditional
+kata: diagram_printer
+difficulty: 3
+author: emilybache
+tags: refactoring
+name: decompose_conditional
+---
+
+# Decompose Conditional
+This is one of the refactorings from Martin Fowler's book.
+
+## Learning Goals
+
+* Describe the refactoring "Decompose Conditional"
+* Use refactoring tools to decompose a conditional
+
+## Session Outline
+
+* 5 min connect: What is clean & tidy code?
+* 5 min concept: Decompose Conditional
+* 10 mins demo: TennisGame6, using IDE shortcuts
+* 25 min do: Diagram Printer in pairs
+* 5 min conclusions: Explain the main idea
+
+### Connect - What is clean & tidy code?
+[Pick the correct items]({% link _activities/connect/pick_the_correct_items_on_the_list.md %}) from a list like this:
+
+* Write a comment explaining every line of code
+* Instead of duplicating code, extract a method
+* Leave unused variables in code comments for future reference
+* Use short variable names like a,b,c
+* ... your own ideas here
+
+The idea is to get them thinking about what makes code good and readable.
+
+### Concept - Decompose Conditional
+This is one of the refactorings from Martin Fowler's book, explain what it is and why you might want to do it.
+
+### Demo - TennisGame6
+TennisGame6 from [Tennis Refactoring Kata](https://github.com/emilybache/Tennis-Refactoring-Kata) is designed to have a conditional that is easy to decompose. With your refactoring tools you should be able to do it quite quickly and show a version that is much easier to read and understand.
+
+### Exercise - Tennis & DiagramPrinter
+Get them first to repeat what you did with TennisGame6. If they are already quite good with their tools then they will also have time to work on [DiagramPrinter](https://github.com/emilybache/DiagramPrinter-Refactoring-Kata.git) - use the 'with_tests' branch. Ask them to work on decomposing and improving conditional logic in DiagramPrinter.doPrint() and DiagramPhysicalPrinter.doPrint().
+
+### Conclusions - explain the main idea
+[Explain the main idea]({% link _activities/conclusions/explain_main_idea.md %}) of 'Decompose Conditional'.
diff --git a/_learning_hours/refactoring/simplify_conditional.md b/_learning_hours/refactoring/simplify_conditional.md
index 2d6eabc3..5aee8167 100644
--- a/_learning_hours/refactoring/simplify_conditional.md
+++ b/_learning_hours/refactoring/simplify_conditional.md
@@ -32,7 +32,7 @@ Examples of behaviour-preserving transformations for conditionals. I started a [
* Split & join if statements
* Two statements in one if statement -> two if statements (specialization of 'Split Loop')
* redundant 'else' when followed by one more if
-* Normalize Conditional
+* Normalize Conditional (aka lift-up conditional)
## Demo: show the patterns and the shape of the refactoring
diff --git a/_learning_hours/testable_design/replace_loop_with_higher_order_functions.md b/_learning_hours/testable_design/replace_loop_with_higher_order_functions.md
new file mode 100644
index 00000000..8a28eda8
--- /dev/null
+++ b/_learning_hours/testable_design/replace_loop_with_higher_order_functions.md
@@ -0,0 +1,114 @@
+---
+theme: functional_programming
+title: Replace Loop with Higher-Order Functions
+difficulty: 2
+author: nicolerauch
+tags: functional_programming streams higher_order_functions design
+code_smell: loops
+name: replace_loop_with_higher_order_functions
+---
+
+# Replace Loop with Higher-Order Functions
+
+Having a look at other programming paradigms broadens the horizon, and maybe you can even find
+something that's useful in your daily work as a programmer, even while using a different paradigm.
+
+Higher-order functions are at the core of functional programming, and other programming languages
+also introduced this feature, where it may be called "lambda", "functional interface", "anonymous function" or
+the like. Therefore it is worthwhile to find out more about them.
+
+
+## Learning Objectives
+
+* Learn to describe the three common higher-order functions filter, map, and reduce
+* Learn how to apply them by converting a given piece of code that contains a loop.
+
+## Session Outline
+
+* 5 min connect: Higher-order functions
+* 10 min concept: Common higher-order functions in various programming languages
+* 30 min do: Apply common higher-order functions
+* 10 min reflect: Typical use cases
+
+### Connect
+
+Ask these questions in the group, and give them some time to write down some answers on sticky notes etc.
+
+* What do you call a function that takes a function as an argument or that returns a function?
+* Have you ever done this in your code? What was the use-case?
+
+
+The kinds of answers you are looking for are:
+1) These functions are called higher-order functions.
+
+2) - various applications related to the Java streaming API.
+ - callback functions
+ - event listeners
+ - decorators
+ - middleware pipelines
+ - function composition (i.e. building more complex functions from simple ones)
+ - strategy pattern (passing a specific algorithm to a function that implements the general structure)
+
+
+### Concept: Common Higher-Order Functions
+
+Common higher-order functions are:
+
+1. filter
+2. map
+3. fold / reduce
+
+That is their name in many programming languages.
+
+C# LinQ calls them:
+
+1. Where
+2. Select
+3. Aggregate
+
+while Ruby and Smalltalk call them:
+
+1. select
+2. collect
+3. inject
+
+Explain how these work. Maybe draw some images to illustrate the flow of data.
+
+* filter / Where / select:
+
+Array -> Function -> Array
+
+Takes an array and a boolean function, returns a new array that contains only those entries where the function returns true.
+
+* map / Select / collect:
+
+Array -> Function -> Array
+
+Takes an array and a function, returns a new array that contains the results of the function applied to the values of the original array in the same order.
+
+* fold or reduce / Aggregate / inject:
+
+Array -> (V,A)->A -> A -> A
+
+Takes an array of values, an aggregator function that aggregates the array's values one by one into an output value,
+and an initial output value, and returns the final output value (after all array values have been aggregated).
+
+
+### Concrete: Applying Common Higher-Order Functions instead of Using Loops
+
+Give the participants some loops that they can refactor to use filter, map, and reduce.
+
+There are some examples with tests in ...repo... You can pick some or all of the provided examples.
+Make sure to set a time box for each of the functions (~5 min for filter, ~5 min for map,
+~10 min for reduce, with some grace time) so that everybody can work at their own pace.
+Not everybody will be able to finish all of the exercises, which is totally fine.
+
+
+### Conclusions: What are typical use cases for these functions?
+
+Ask the following question in the group. First let them reflect silently for a minute or two, then discuss.
+
+* Now that you have learned about the three common Higher-Order Functions filter, map, and reduce:
+Do you have typical use cases in your production code where you could apply one of the three functions? Which are they?
+
+
\ No newline at end of file
diff --git a/_refactorings/conditional_to_strategy.md b/_refactorings/conditional_to_strategy.md
new file mode 100644
index 00000000..a68db254
--- /dev/null
+++ b/_refactorings/conditional_to_strategy.md
@@ -0,0 +1,42 @@
+---
+layout: refactoring
+title: Replace Conditional Logic with Strategy
+source: Joshua Kerievsky
+source_url: https://www.industriallogic.com/refactoring-to-patterns/catalog/conditionalWithStrategy.html
+code_smells: deep_nesting
+learning_hours:
+---
+
+# Replace Conditional Logic with Strategy
+
+This is one of the refactorings in Joshua Kerievsky's book. This recipe is for the initial steps before the refactoring "Conditional to Polymorphism."
+
+## Examine
+Usually the prompt for this refactoring is unnecessary conditional complexity with deep nesting. In particular, when the program is changing behaviour based on a type code or a particular fixed set of conditions. If the class currently containing this behaviour is plausibly going to become the superclass in the Strategy pattern, then you could just extract a method and then go directly to "Conditional to Polymorphism."
+
+## Prepare
+* Highlight the block of code you intend to replace with the strategy pattern. It should contain all the conditional logic you want to replace. If the logic is contained in a loop, leave that outside.
+* Think of a good class name for the strategy class, note it in a comment 'xxxStrategy'
+
+## Implement
+* 'Extract function' for the code you identified.
+* If the new function is not static or top-level, there are additional steps:
+ * 'Introduce Parameter' for any data members it uses
+ * If necessary, introduce a parameter for an instance of the enclosing class so it can access methods on that class.
+ * Make the new method static or top-level
+* Examine the parameter list to the new function and identify those that are specific to one strategy. [Introduce Parameter Object]({% link _refactorings/introduce_parameter_object.md %} for those parameters, name the new class as you identified earlier - 'xxxStrategy'. If there are no such arguments, just create that class.
+* Make sure the new class is declared as a local variable before you call the new function, and is a parameter to it. Use 'Introduce Variable' or 'Change Signature' if needed.
+* 'Move' the static or top level function to the new class as a static method or top-level function in the same file.
+* For the new function, 'Make non-static' on the new class. If your tool doesn't have that refactoring then these are the steps:
+ * Manually put the function inside the class or remove the 'static' modifier.
+ * One of the arguments will be the xxxStrategy class that you added earlier. Assign this variable to the enclosing instance `var wrapper = this`. Remove the parameter.
+ * Inline the `wrapper` variable
+ * Update the call sites so `foo(wrapper)` becomes `wrapper.foo()`
+
+## Clear
+Check the names of the new method and class make sense. Check all the parameters to the new method make sense. Some of them might want to become constructor arguments, or you might want to move additional methods to this class.
+
+## Follow up
+Use ['Replace Conditional with Polymorphism']({% link _refactorings/replace_conditional_polymorphism.md %}) to make the concrete strategy classes.
+
+
diff --git a/_refactorings/introduce_parameter_object.md b/_refactorings/introduce_parameter_object.md
new file mode 100644
index 00000000..3e94d8b9
--- /dev/null
+++ b/_refactorings/introduce_parameter_object.md
@@ -0,0 +1,33 @@
+---
+layout: refactoring
+title: Introduce Parameter Object
+source: Martin Fowler
+source_url: https://refactoring.com/catalog/introduceParameterObject.html
+code_smells: long_parameter_list
+learning_hours:
+---
+
+# Introduce Parameter Object
+
+This is provided by some tools - Resharper has 'Transform Parameters', IntelliJ has 'Introduce Parameter Object'. If you don't have this available, then this checklist will help you to do it with only Extract Method and Inline Method.
+
+## Identify
+In a long parameter list, some might usefully be grouped together into a new class.
+
+## Prepare
+Work out which parameters you want to group together into a new class and ideally think of a good name for it.
+
+## Implement
+
+* Before the call site to the method, pretend you already have the new class, declare a variable for it and call its constructor with the arguments you want to put in the new type, eg `var wrapper = ParameterWrapper(a, b, c)`.
+* Use your tools to create that class `ParameterWrapper`.
+* Store all the constructor arguments in public fields.
+* change all the references to these variables to use the fields of your new class, eg `a` becomes `wrapper.a`
+* 'Extract method' on all the code that uses `wrapper`. The method should have the signature you wanted, and call the original method.
+* Inline the call to the original method.
+
+## Clear
+Check the name of the new method is the same as the original.
+
+## Follow up
+Often you want to move the method to the type you just created.
diff --git a/_refactorings/lift_up_conditional.md b/_refactorings/lift_up_conditional.md
index 887dab3b..4229c718 100644
--- a/_refactorings/lift_up_conditional.md
+++ b/_refactorings/lift_up_conditional.md
@@ -8,6 +8,8 @@ learning_hours: lift_up_conditional_intro
# Lift-up Conditional
This refactoring was named by Emily Bache. She first learned it from Llewellyn Falco.
+It's also related to Fowler's Remove Flag Argument https://refactoring.com/catalog/removeFlagArgument.html,
+last example from the book is the begining of a lift up conditional.
## Examine
Look for a complex conditional that has a condition that is duplicated in more than one place. This is the conditional you will 'lift up' to be only in one place at the top. Note - in this process another conditional might become duplicated instead, so it doesn't always help.
diff --git a/_refactorings/replace_conditional_polymorphism.md b/_refactorings/replace_conditional_polymorphism.md
new file mode 100644
index 00000000..503bc265
--- /dev/null
+++ b/_refactorings/replace_conditional_polymorphism.md
@@ -0,0 +1,34 @@
+---
+layout: refactoring
+title: Replace Conditional with Polymorphism
+source: Martin Fowler
+source_url: https://refactoring.com/catalog/replaceConditionalWithPolymorphism.html
+code_smells: repeated_switches
+learning_hours: replace_conditional_with_polymorphism
+---
+
+# Replace Conditional with Polymorphism
+
+This refactoring replaces conditional logic with classes and polymorphism. The code smell that leads you to it is having a lot of similar switch statements that switch on type.
+
+## Examine
+Identify all the places with a repeated switch statement, that switch on the same type and have similar cases.
+
+## Prepare
+All these switches should be in functions on the same class - the one which "has" the type that is being switched on. Extract methods as needed and move them to the class which will become the base of the polymorphic hierarchy.
+
+If the constructor to the class is called in a lot of places it's probably worth first doing 'replace constructor with factory method'.
+
+## Implement
+
+* Create new subclasses for each branch of the conditional. They should be empty with only a call to the superclass constructor
+* Replace calls to the constructor of the base type with calls to the relevant subclass constructor. This will probably mean creating a new switch statement.
+* 'Push Down' the first method containing the switch/conditional
+* Remove redundant code in the pushed down method.
+* 'Push Down' any additional fields or methods
+* Remove redundant code and make the superclass abstract
+
+## Clear
+Consider whether the superclass should be an interface or an abstract class.
+
+
diff --git a/_refactorings/split_loop.md b/_refactorings/split_loop.md
index 79df6b7e..46187f5c 100644
--- a/_refactorings/split_loop.md
+++ b/_refactorings/split_loop.md
@@ -4,7 +4,7 @@ title: Split Loop
source: Emily Bache
source_url: https://refactoring.com/catalog/splitLoop.html
code_smells: loops,divergent_change,shotgun_surgery
-learning_hours: split_loop
+learning_hours: split_loop,replace_loop_with_higher_order_functions
---
# Split Loop
diff --git a/_refactorings/transform_return_type.md b/_refactorings/transform_return_type.md
new file mode 100644
index 00000000..9113e1a0
--- /dev/null
+++ b/_refactorings/transform_return_type.md
@@ -0,0 +1,33 @@
+---
+layout: refactoring
+title: Transform Return Type
+source: Emily Bache
+source_url:
+code_smells: variable_with_long_scope, primitive_obsession
+learning_hours:
+---
+
+# Transform Return Type aka Wrap Return Value
+
+Some tools have this, Resharper includes it in the "Transform Parameters" refactoring. IntelliJ has an additional plugin that offers to [Wrap Return Value](https://www.jetbrains.com/help/idea/wrap-return-value.html#wrap_return_value_example). If you don't have those tools then these steps achieve the same thing with only 'Extract Function' and 'Inline Function.'
+
+## Identify
+Usually you want this refactoring when a method has multiple return values that and either you're only getting one of them, or you're putting them in an awkward collection type before returning them.
+
+## Prepare
+I usually find this one goes easier if I inline the method first (provided it's not called from too many places).
+
+## Implement
+* Identify which local variables will be combined into the new wrapper type, eg `var a; var b; var c;`.
+* Identify a position in the code after these local variables have all been declared and where you can create a new variable of the new type to wrap them.
+* Pretend you already have the new class, declare a variable for it. Call its constructor with the arguments you want to put in the new type, eg `var wrapper = ReturnTypeWrapper(a, b, c)`.
+* Use your tools to create that class `ReturnTypeWrapper`.
+* Store all the constructor arguments in public fields.
+* change all the references to these variables to use the fields of your new class, eg `a` becomes `wrapper.a`. (Use search and replace within a selection).
+* 'Extract method' on all the code that uses `wrapper`. The method should have the signature you wanted.
+
+## Clear
+
+
+## Follow up
+
diff --git a/newsletter_and_guide.md b/newsletter_and_guide.md
deleted file mode 100644
index e9b22541..00000000
--- a/newsletter_and_guide.md
+++ /dev/null
@@ -1,8 +0,0 @@
----
-layout: tdd_guide
-title: Newsletter
----
-
-# Newsletter and Free Guide to TDD Heuristics
-
-Please use the form below to sign up for our newsletter and receive your free guide.
diff --git a/routines.md b/routines.md
index 7f4ff79f..19d332e5 100644
--- a/routines.md
+++ b/routines.md
@@ -11,6 +11,7 @@ After an open space, this is what Emily usually does.
3. Create Zoom link & put it in the calendar invite
4. Update the date on the 'next_open_space.md' page
5. Upload the miro pdf to Discord #general channel
+6. Message Discord #general inviting people to sign up for the next event and give them the signup link and the 'add to calendar' link.
There are also tasks for updating things in Hubspot
@@ -19,8 +20,8 @@ There are also tasks for updating things in Hubspot
2. Wipe the 'next_open_space' property from all contacts
3. Update calendr.link "add to calendar" link with the next date
4. Create and schedule email 1 week before with zoom link
-5. Create and schedule email on the day with zoom link
-6. Message Discord #general inviting people to sign up for the next event and give them the signup link and the 'add to calendar' link.
+5. Create and schedule email on the day with zoom link
+6. Create 'routines' meeting invite after the next open space
## Adding new society members
* Make sure they have read and understood [Membership](https://sammancoaching.org/society/membership.html)
diff --git a/search.json b/search.json
index ba3e1c27..05c567ef 100644
--- a/search.json
+++ b/search.json
@@ -13,6 +13,30 @@ layout: none
{
"title" : "Kata: {{ kata.title | escape }}",
"url" : "{{ site.baseurl }}{{ kata.url }}"
+},
+{% endfor %}
+{% for activity in site.activities %}
+{
+"title" : "Activity: {{ activity.title | escape }}",
+"url" : "{{ site.baseurl }}{{ activity.url }}"
+},
+{% endfor %}
+{% for smell in site.code_smells %}
+{
+"title" : "Code Smell: {{ smell.title | escape }}",
+"url" : "{{ site.baseurl }}{{ smell.url }}"
+},
+{% endfor %}
+{% for refactoring in site.refactorings %}
+{
+"title" : "Refactoring: {{ refactoring.title | escape }}",
+"url" : "{{ site.baseurl }}{{ refactoring.url }}"
+},
+{% endfor %}
+{% for lh in site.learning_hours %}
+{
+"title" : "Learning Hour: {{ lh.title | escape }}",
+"url" : "{{ site.baseurl }}{{ lh.url }}"
} {% unless forloop.last %},{% endunless %}
{% endfor %}
]
\ No newline at end of file
diff --git a/society/contributors/nicolerauch.md b/society/contributors/nicolerauch.md
new file mode 100644
index 00000000..411c894f
--- /dev/null
+++ b/society/contributors/nicolerauch.md
@@ -0,0 +1,11 @@
+---
+layout: member
+title: Nicole Rauch
+author: nicolerauch
+role: Technical Coach
+---
+
+# {{ page.title}}
+{% assign author = site.data.contributors[page.author] %}
+{{author.title}} is an Independent Technical Coach. She has a [website]({{author.url}}).
+
diff --git a/society/events/next_open_space.md b/society/events/next_open_space.md
index 1dc84f68..645043f1 100644
--- a/society/events/next_open_space.md
+++ b/society/events/next_open_space.md
@@ -5,7 +5,7 @@ title: Samman Coaching Society Online Open Space Event
# Samman Coaching Society Online Open Space Event
-**Thursday 25th September 2025, 16:00 Stockholm/Berlin/Paris**
+**Thursday 23rd October 2025, 16:00 Stockholm/Berlin/Paris**
_Bring your questions and exchange experiences with other technical coaches._
diff --git a/tests/test_generated_search_json.test_search_json.approved.json b/tests/test_generated_search_json.test_search_json.approved.json
index 0596ec47..5c3368e3 100644
--- a/tests/test_generated_search_json.test_search_json.approved.json
+++ b/tests/test_generated_search_json.test_search_json.approved.json
@@ -15,18 +15,238 @@
"title": "Activities for New Concept",
"url": "/activities/concept.html"
},
+ {
+ "title": "Activity: Code Demo",
+ "url": "/activities/concept/code_demo.html"
+ },
+ {
+ "title": "Activity: Lecture",
+ "url": "/activities/concept/lecture.html"
+ },
+ {
+ "title": "Activity: Table Groups Playing Games",
+ "url": "/activities/concept/table_game_groups.html"
+ },
{
"title": "Activities for Conclusions",
"url": "/activities/conclusions.html"
},
+ {
+ "title": "Activity: Coach's encouraging feedback",
+ "url": "/activities/conclusions/coaches_feedback.html"
+ },
+ {
+ "title": "Activity: Code Comparison",
+ "url": "/activities/conclusions/code_compare.html"
+ },
+ {
+ "title": "Activity: Collect Round Robin Style",
+ "url": "/activities/conclusions/collect_round_robin.html"
+ },
+ {
+ "title": "Activity: Explain the main idea",
+ "url": "/activities/conclusions/explain_main_idea.html"
+ },
+ {
+ "title": "Activity: Raising the Group Temperature",
+ "url": "/activities/conclusions/group_temperature.html"
+ },
+ {
+ "title": "Activity: How does it feel?",
+ "url": "/activities/conclusions/how_does_it_feel.html"
+ },
+ {
+ "title": "Activity: Does our code have this issue?",
+ "url": "/activities/conclusions/how_to_apply_here.html"
+ },
+ {
+ "title": "Activity: Showcase",
+ "url": "/activities/conclusions/showcase.html"
+ },
+ {
+ "title": "Activity: TDD Cycles",
+ "url": "/activities/conclusions/tdd_cycles.html"
+ },
+ {
+ "title": "Activity: When should you use this?",
+ "url": "/activities/conclusions/when_to_use_this.html"
+ },
+ {
+ "title": "Activity: Note down your most important takeaways",
+ "url": "/activities/conclusions/write_important_takeaway.html"
+ },
{
"title": "Activities for Concrete Practice",
"url": "/activities/concrete.html"
},
+ {
+ "title": "Activity: Facilitated Ensemble",
+ "url": "/activities/concrete/facilitated_ensemble.html"
+ },
+ {
+ "title": "Activity: Individual work with showcasing",
+ "url": "/activities/concrete/individual_work_with_showcasing.html"
+ },
+ {
+ "title": "Activity: Work In Pairs",
+ "url": "/activities/concrete/work_in_pairs.html"
+ },
{
"title": "Activities for Connect",
"url": "/activities/connect.html"
},
+ {
+ "title": "Activity: Code Review",
+ "url": "/activities/connect/code_review.html"
+ },
+ {
+ "title": "Activity: Explain previous concepts",
+ "url": "/activities/connect/explain_previous_concepts.html"
+ },
+ {
+ "title": "Activity: Fill in the Blanks",
+ "url": "/activities/connect/fill_in_blanks.html"
+ },
+ {
+ "title": "Activity: Learning Goal Voting",
+ "url": "/activities/connect/learning_goal_voting.html"
+ },
+ {
+ "title": "Activity: Pick only the correct items",
+ "url": "/activities/connect/pick_the_correct_items_on_the_list.html"
+ },
+ {
+ "title": "Activity: Sort these items",
+ "url": "/activities/connect/sort_these_items.html"
+ },
+ {
+ "title": "Activity: Three Facts",
+ "url": "/activities/connect/three_facts.html"
+ },
+ {
+ "title": "Activity: Three Facts and a Question",
+ "url": "/activities/connect/three_facts_and_a_q.html"
+ },
+ {
+ "title": "Activity: True or False mythbusting",
+ "url": "/activities/connect/true_or_false_mythbusting.html"
+ },
+ {
+ "title": "Activity: Web Hunt",
+ "url": "/activities/connect/webhunt.html"
+ },
+ {
+ "title": "Code Smell: Alternative Classes with Different Interfaces",
+ "url": "/code_smells/alternative_classes_different_interfaces.html"
+ },
+ {
+ "title": "Code Smell: Bumpy Road",
+ "url": "/code_smells/bumpy_road.html"
+ },
+ {
+ "title": "Code Smell: Comments",
+ "url": "/code_smells/comments.html"
+ },
+ {
+ "title": "Code Smell: Data Class",
+ "url": "/code_smells/data_class.html"
+ },
+ {
+ "title": "Code Smell: Data Clumps",
+ "url": "/code_smells/data_clumps.html"
+ },
+ {
+ "title": "Code Smell: Deep Nesting",
+ "url": "/code_smells/deep_nesting.html"
+ },
+ {
+ "title": "Code Smell: Divergent Change",
+ "url": "/code_smells/divergent_change.html"
+ },
+ {
+ "title": "Code Smell: Duplicated Code",
+ "url": "/code_smells/duplicated_code.html"
+ },
+ {
+ "title": "Code Smell: Feature Envy",
+ "url": "/code_smells/feature_envy.html"
+ },
+ {
+ "title": "Code Smell: Global Data",
+ "url": "/code_smells/global_data.html"
+ },
+ {
+ "title": "Code Smell: Insider Trading",
+ "url": "/code_smells/insider_trading.html"
+ },
+ {
+ "title": "Code Smell: Large Class",
+ "url": "/code_smells/large_class.html"
+ },
+ {
+ "title": "Code Smell: Lazy Element",
+ "url": "/code_smells/lazy_element.html"
+ },
+ {
+ "title": "Code Smell: Long Function",
+ "url": "/code_smells/long_function.html"
+ },
+ {
+ "title": "Code Smell: Long Parameter List",
+ "url": "/code_smells/long_parameter_list.html"
+ },
+ {
+ "title": "Code Smell: Loops",
+ "url": "/code_smells/loop.html"
+ },
+ {
+ "title": "Code Smell: Message Chains",
+ "url": "/code_smells/message_chains.html"
+ },
+ {
+ "title": "Code Smell: Middle Man",
+ "url": "/code_smells/middle_man.html"
+ },
+ {
+ "title": "Code Smell: Mutable Data",
+ "url": "/code_smells/mutable_data.html"
+ },
+ {
+ "title": "Code Smell: Mysterious Name",
+ "url": "/code_smells/mysterious_name.html"
+ },
+ {
+ "title": "Code Smell: Paragraph of Code",
+ "url": "/code_smells/paragraph.html"
+ },
+ {
+ "title": "Code Smell: Primitive Obsession",
+ "url": "/code_smells/primitive_obsession.html"
+ },
+ {
+ "title": "Code Smell: Refused Bequest",
+ "url": "/code_smells/refused_bequest.html"
+ },
+ {
+ "title": "Code Smell: Repeated Switches",
+ "url": "/code_smells/repeated_switches.html"
+ },
+ {
+ "title": "Code Smell: Shotgun Surgery",
+ "url": "/code_smells/shotgun_surgery.html"
+ },
+ {
+ "title": "Code Smell: Speculative Generality",
+ "url": "/code_smells/speculative_generality.html"
+ },
+ {
+ "title": "Code Smell: Temporary Field",
+ "url": "/code_smells/temporary_field.html"
+ },
+ {
+ "title": "Code Smell: Variable with Long Scope",
+ "url": "/code_smells/variable_with_long_scope.html"
+ },
{
"title": "Contact",
"url": "/contact.html"
@@ -107,6 +327,138 @@
"title": "Kata Descriptions",
"url": "/kata_descriptions/"
},
+ {
+ "title": "Kata: Audit everything",
+ "url": "/kata_descriptions/audit.html"
+ },
+ {
+ "title": "Kata: Bank Account",
+ "url": "/kata_descriptions/bank_account.html"
+ },
+ {
+ "title": "Kata: Bingo Refactoring Kata",
+ "url": "/kata_descriptions/bingo.html"
+ },
+ {
+ "title": "Kata: Birthday Greetings",
+ "url": "/kata_descriptions/birthday_greetings.html"
+ },
+ {
+ "title": "Kata: Calculate Stats",
+ "url": "/kata_descriptions/calc_stats.html"
+ },
+ {
+ "title": "Kata: Christmas Song",
+ "url": "/kata_descriptions/christmas_song.html"
+ },
+ {
+ "title": "Kata: Closest To Zero",
+ "url": "/kata_descriptions/closest_to_zero.html"
+ },
+ {
+ "title": "Kata: Diamond",
+ "url": "/kata_descriptions/diamond.html"
+ },
+ {
+ "title": "Kata: Filename Range",
+ "url": "/kata_descriptions/filename_range.html"
+ },
+ {
+ "title": "Kata: FizzBuzz",
+ "url": "/kata_descriptions/fizzbuzz.html"
+ },
+ {
+ "title": "Kata: Fractions",
+ "url": "/kata_descriptions/fractions.html"
+ },
+ {
+ "title": "Kata: Gilded Rose Refactoring Kata",
+ "url": "/kata_descriptions/gilded_rose.html"
+ },
+ {
+ "title": "Kata: Instavoiced",
+ "url": "/kata_descriptions/instavoiced.html"
+ },
+ {
+ "title": "Kata: Leap Years",
+ "url": "/kata_descriptions/leap_years.html"
+ },
+ {
+ "title": "Kata: Lift",
+ "url": "/kata_descriptions/lift.html"
+ },
+ {
+ "title": "Kata: Lift Button",
+ "url": "/kata_descriptions/lift_button.html"
+ },
+ {
+ "title": "Kata: Mars Rover",
+ "url": "/kata_descriptions/mars_rover.html"
+ },
+ {
+ "title": "Kata: Martian Message",
+ "url": "/kata_descriptions/martian_message.html"
+ },
+ {
+ "title": "Kata: Monty Hall",
+ "url": "/kata_descriptions/monty_hall.html"
+ },
+ {
+ "title": "Kata: Office Cleaning Robot",
+ "url": "/kata_descriptions/office_cleaner.html"
+ },
+ {
+ "title": "Kata: Parse Command-Line Args",
+ "url": "/kata_descriptions/parse_args.html"
+ },
+ {
+ "title": "Kata: RecentlyUsedList",
+ "url": "/kata_descriptions/recently_used_list.html"
+ },
+ {
+ "title": "Kata: RPG Combat",
+ "url": "/kata_descriptions/rpg_combat.html"
+ },
+ {
+ "title": "Kata: Shopping Basket",
+ "url": "/kata_descriptions/shopping_basket.html"
+ },
+ {
+ "title": "Kata: Strange Characters",
+ "url": "/kata_descriptions/strange_characters.html"
+ },
+ {
+ "title": "Kata: String Calculator",
+ "url": "/kata_descriptions/string_calculator.html"
+ },
+ {
+ "title": "Kata: Supermarket Receipt",
+ "url": "/kata_descriptions/supermarket_receipt.html"
+ },
+ {
+ "title": "Kata: Tennis",
+ "url": "/kata_descriptions/tennis.html"
+ },
+ {
+ "title": "Kata: Theatrical Players",
+ "url": "/kata_descriptions/theatrical_players.html"
+ },
+ {
+ "title": "Kata: Tire Pressure",
+ "url": "/kata_descriptions/tire_pressure.html"
+ },
+ {
+ "title": "Kata: Vending Machine",
+ "url": "/kata_descriptions/vending_machine.html"
+ },
+ {
+ "title": "Kata: Word Wrap",
+ "url": "/kata_descriptions/word_wrap.html"
+ },
+ {
+ "title": "Kata: Yatzy",
+ "url": "/kata_descriptions/yatzy.html"
+ },
{
"title": "Learning Hours",
"url": "/learning_hours/"
@@ -115,34 +467,134 @@
"title": "Learning Hours",
"url": "/learning_hours/approval_testing_bdd.html"
},
+ {
+ "title": "Learning Hour: Leap Years with Approvals",
+ "url": "/learning_hours/approval_testing_bdd/compare_ordinary_tdd.html"
+ },
+ {
+ "title": "Learning Hour: Data Driven testing with Approvals",
+ "url": "/learning_hours/approval_testing_bdd/data_driven_approval_tests.html"
+ },
+ {
+ "title": "Learning Hour: Discover and Formulate Scenarios",
+ "url": "/learning_hours/approval_testing_bdd/discover_formulate.html"
+ },
+ {
+ "title": "Learning Hour: Designing a Printer",
+ "url": "/learning_hours/approval_testing_bdd/printer_design.html"
+ },
+ {
+ "title": "Learning Hour: Test Driving Development with Approvals",
+ "url": "/learning_hours/approval_testing_bdd/tdd_approvals.html"
+ },
{
"title": "Learning Hours",
"url": "/learning_hours/approval_testing_texttest.html"
},
+ {
+ "title": "Learning Hour: Filtering output that varies",
+ "url": "/learning_hours/approval_testing_texttest/run_dependent_text.html"
+ },
+ {
+ "title": "Learning Hour: Sandboxing Introduction",
+ "url": "/learning_hours/approval_testing_texttest/sandboxing_intro.html"
+ },
+ {
+ "title": "Learning Hour: TDD with TextTest",
+ "url": "/learning_hours/approval_testing_texttest/tdd_with_sketching.html"
+ },
+ {
+ "title": "Learning Hour: Supplying User Input via stdin",
+ "url": "/learning_hours/approval_testing_texttest/user_input.html"
+ },
{
"title": "Learning Hours - Architecture",
"url": "/learning_hours/architecture.html"
},
+ {
+ "title": "Learning Hour: Architecture Decision Records",
+ "url": "/learning_hours/architecture/architecture_decision_records.html"
+ },
+ {
+ "title": "Learning Hour: Divio Documentation System",
+ "url": "/learning_hours/architecture/divio_system.html"
+ },
+ {
+ "title": "Learning Hour: Modelling vs Diagramming",
+ "url": "/learning_hours/architecture/modelling_vs_diagramming.html"
+ },
+ {
+ "title": "Learning Hour: Simon Brown's C4 model - Container diagram",
+ "url": "/learning_hours/architecture/simon_brown_4c_container.html"
+ },
+ {
+ "title": "Learning Hour: Simon Brown's C4 model - Intro",
+ "url": "/learning_hours/architecture/simon_brown_4c_context.html"
+ },
+ {
+ "title": "Learning Hour: User Documentation and code snippets",
+ "url": "/learning_hours/architecture/snippets_documentation.html"
+ },
{
"title": "BDD Learning Hours",
"url": "/learning_hours/bdd.html"
},
+ {
+ "title": "Learning Hour: Double-Loop TDD",
+ "url": "/learning_hours/bdd/double_loop_tdd.html"
+ },
+ {
+ "title": "Learning Hour: BDD Process",
+ "url": "/learning_hours/bdd/example_mapping.html"
+ },
{
"title": "Code Reading Learning Hours",
"url": "/learning_hours/code_reading.html"
},
+ {
+ "title": "Learning Hour: Code Reading - Identifying Code Smells",
+ "url": "/learning_hours/code_reading/code_smells_intro.html"
+ },
+ {
+ "title": "Learning Hour: Common Code Smells",
+ "url": "/learning_hours/code_reading/common_code_smells.html"
+ },
+ {
+ "title": "Learning Hour: Code Reading - Scanning",
+ "url": "/learning_hours/code_reading/reading_tennis4.html"
+ },
{
"title": "DevOps Learning Hours",
"url": "/learning_hours/devops.html"
},
+ {
+ "title": "Learning Hour: Basic GitHub Actions",
+ "url": "/learning_hours/devops/github_actions.html"
+ },
+ {
+ "title": "Learning Hour: Learn Faster By Practicing Teaching",
+ "url": "/learning_hours/devops/learn_faster.html"
+ },
+ {
+ "title": "Learning Hour: The three ways of DevOps",
+ "url": "/learning_hours/devops/three_ways.html"
+ },
{
"title": "Ensemble Learning Hours",
"url": "/learning_hours/ensemble.html"
},
+ {
+ "title": "Learning Hour: Talking with Intent, Typing Syntax",
+ "url": "/learning_hours/ensemble/talking_typing.html"
+ },
{
"title": "Git Learning Hours",
"url": "/learning_hours/git.html"
},
+ {
+ "title": "Learning Hour: Git Interactive Rebase",
+ "url": "/learning_hours/git/interactive_rebase.html"
+ },
{
"title": "Learning Hours",
"url": "/learning_hours/learning_hour_explanation.html"
@@ -167,14 +619,194 @@
"title": "Legacy Code Learning Hours",
"url": "/learning_hours/legacy.html"
},
+ {
+ "title": "Learning Hour: Approval Testing Intro",
+ "url": "/learning_hours/legacy/approval_testing_intro.html"
+ },
+ {
+ "title": "Learning Hour: Intro to Approvals",
+ "url": "/learning_hours/legacy/approvals_intro.html"
+ },
+ {
+ "title": "Learning Hour: Combination Approvals needs a Pure Function",
+ "url": "/learning_hours/legacy/combination_approvals_pure_function.html"
+ },
+ {
+ "title": "Learning Hour: Approval Testing Combinations",
+ "url": "/learning_hours/legacy/combinations_by_hand.html"
+ },
+ {
+ "title": "Learning Hour: Demo of Approvals with Coverage and Mutation testing",
+ "url": "/learning_hours/legacy/coverage_mutation_approvals_demo.html"
+ },
+ {
+ "title": "Learning Hour: Domain Oriented Observability on Reservation Kata",
+ "url": "/learning_hours/legacy/domain_observability.html"
+ },
+ {
+ "title": "Learning Hour: Extract and Override",
+ "url": "/learning_hours/legacy/extract_override.html"
+ },
+ {
+ "title": "Learning Hour: Design for Approval Testing",
+ "url": "/learning_hours/legacy/handle_dates.html"
+ },
+ {
+ "title": "Learning Hour: Invasive Critical Aggregator",
+ "url": "/learning_hours/legacy/invasive_critical_aggregator.html"
+ },
+ {
+ "title": "Learning Hour: Preparatory Refactoring",
+ "url": "/learning_hours/legacy/preparatory_refactoring.html"
+ },
+ {
+ "title": "Learning Hour: Strangler Fig Pattern",
+ "url": "/learning_hours/legacy/strangler_fig.html"
+ },
+ {
+ "title": "Learning Hour: Test maintenance",
+ "url": "/learning_hours/legacy/test_maintenance.html"
+ },
+ {
+ "title": "Learning Hour: Text-Based Testing",
+ "url": "/learning_hours/legacy/text_based_testing.html"
+ },
+ {
+ "title": "Learning Hour: Text-based Approval Tests for Yatzy",
+ "url": "/learning_hours/legacy/vendor_assessment.html"
+ },
+ {
+ "title": "Learning Hour: Using coverage when adding tests to existing code",
+ "url": "/learning_hours/legacy/verify_xml_reports.html"
+ },
{
"title": "Working with C",
"url": "/learning_hours/low_level_c.html"
},
+ {
+ "title": "Learning Hour: Cover the patient with tests",
+ "url": "/learning_hours/low_level_c/cover_patient.html"
+ },
+ {
+ "title": "Learning Hour: TDD a lamp microcontroller",
+ "url": "/learning_hours/low_level_c/lamp_microcontroller.html"
+ },
+ {
+ "title": "Learning Hour: Move the patient into the surgery",
+ "url": "/learning_hours/low_level_c/patient_into_surgery.html"
+ },
+ {
+ "title": "Learning Hour: Refactor for testability",
+ "url": "/learning_hours/low_level_c/redesign_patient_for_testability.html"
+ },
+ {
+ "title": "Learning Hour: Return the patient",
+ "url": "/learning_hours/low_level_c/return_patient.html"
+ },
+ {
+ "title": "Learning Hour: TDD a state machine",
+ "url": "/learning_hours/low_level_c/tdd_state_machine.html"
+ },
{
"title": "Refactoring Learning Hours",
"url": "/learning_hours/refactoring.html"
},
+ {
+ "title": "Learning Hour: Change Signature",
+ "url": "/learning_hours/refactoring/change_signature.html"
+ },
+ {
+ "title": "Learning Hour: Replace Conditional With Polymorphism",
+ "url": "/learning_hours/refactoring/conditional_to_polymorphism.html"
+ },
+ {
+ "title": "Learning Hour: From Struct to Class",
+ "url": "/learning_hours/refactoring/convert_struct_to_class.html"
+ },
+ {
+ "title": "Learning Hour: Decompose Conditional",
+ "url": "/learning_hours/refactoring/decompose_conditional.html"
+ },
+ {
+ "title": "Learning Hour: Vocabulary for Refactoring",
+ "url": "/learning_hours/refactoring/extract_function.html"
+ },
+ {
+ "title": "Learning Hour: Extracting Data Clumps",
+ "url": "/learning_hours/refactoring/extracting_data_clumps.html"
+ },
+ {
+ "title": "Learning Hour: Refactoring Golf",
+ "url": "/learning_hours/refactoring/golf.html"
+ },
+ {
+ "title": "Learning Hour: Replace Nested Conditional with Guard Clauses",
+ "url": "/learning_hours/refactoring/guard_clause.html"
+ },
+ {
+ "title": "Learning Hour: Identify Paragraphs in Long Methods",
+ "url": "/learning_hours/refactoring/identify_paragraphs.html"
+ },
+ {
+ "title": "Learning Hour: Idiomatic Code",
+ "url": "/learning_hours/refactoring/idiomatic.html"
+ },
+ {
+ "title": "Learning Hour: Keyboarding skills",
+ "url": "/learning_hours/refactoring/keyboarding.html"
+ },
+ {
+ "title": "Learning Hour: Mending Law of Demeter Issues with Refactoring Tools",
+ "url": "/learning_hours/refactoring/law_of_demeter.html"
+ },
+ {
+ "title": "Learning Hour: Lift-Up Conditional on Gilded Rose",
+ "url": "/learning_hours/refactoring/lift_up_conditional.html"
+ },
+ {
+ "title": "Learning Hour: Lift-Up Conditional Introduction",
+ "url": "/learning_hours/refactoring/lift_up_conditional_intro.html"
+ },
+ {
+ "title": "Learning Hour: Misconceptions about Refactoring",
+ "url": "/learning_hours/refactoring/misconceptions.html"
+ },
+ {
+ "title": "Learning Hour: Parallel Change",
+ "url": "/learning_hours/refactoring/parallel_change.html"
+ },
+ {
+ "title": "Learning Hour: Primitive Obsession",
+ "url": "/learning_hours/refactoring/primitive_obsession.html"
+ },
+ {
+ "title": "Learning Hour: Refactoring Without Tools",
+ "url": "/learning_hours/refactoring/refactoring_without_tools.html"
+ },
+ {
+ "title": "Learning Hour: Renaming Variables, Fields and Types",
+ "url": "/learning_hours/refactoring/renaming.html"
+ },
+ {
+ "title": "Learning Hour: Roll Up Loop",
+ "url": "/learning_hours/refactoring/roll_up_loop.html"
+ },
+ {
+ "title": "Learning Hour: Simplify Conditional",
+ "url": "/learning_hours/refactoring/simplify_conditional.html"
+ },
+ {
+ "title": "Learning Hour: Split Loop",
+ "url": "/learning_hours/refactoring/split_loop.html"
+ },
+ {
+ "title": "Learning Hour: Split Phase",
+ "url": "/learning_hours/refactoring/split_phase.html"
+ },
+ {
+ "title": "Learning Hour: Split Variable",
+ "url": "/learning_hours/refactoring/split_variable.html"
+ },
{
"title": "Approval Testing Legacy Code series",
"url": "/learning_hours/series/approval_testing.html"
@@ -199,18 +831,246 @@
"title": "Small Steps Learning Hours",
"url": "/learning_hours/small_steps.html"
},
+ {
+ "title": "Learning Hour: Adding Behavior Instead Of Breaking Behavior",
+ "url": "/learning_hours/small_steps/changing_by_adding.html"
+ },
+ {
+ "title": "Learning Hour: Using TDD to write a Leap Years function",
+ "url": "/learning_hours/small_steps/demo_tdd_intro.html"
+ },
+ {
+ "title": "Learning Hour: Design in the Red step",
+ "url": "/learning_hours/small_steps/design_with_a_test.html"
+ },
+ {
+ "title": "Learning Hour: Example-guided design",
+ "url": "/learning_hours/small_steps/example_guided_design.html"
+ },
+ {
+ "title": "Learning Hour: Golden Rule of TDD",
+ "url": "/learning_hours/small_steps/golden_rule_tdd.html"
+ },
+ {
+ "title": "Learning Hour: Iterative or Incremental",
+ "url": "/learning_hours/small_steps/iterative_or_incremental.html"
+ },
+ {
+ "title": "Learning Hour: Outside-in TDD",
+ "url": "/learning_hours/small_steps/outside_in.html"
+ },
+ {
+ "title": "Learning Hour: Selecting and ordering test cases",
+ "url": "/learning_hours/small_steps/select_order_testcases.html"
+ },
+ {
+ "title": "Learning Hour: Take Smaller Steps",
+ "url": "/learning_hours/small_steps/smaller_steps.html"
+ },
+ {
+ "title": "Learning Hour: TDD cycles",
+ "url": "/learning_hours/small_steps/tdd_cycles.html"
+ },
+ {
+ "title": "Learning Hour: TDD Fluency",
+ "url": "/learning_hours/small_steps/tdd_fluency.html"
+ },
+ {
+ "title": "Learning Hour: TDD with a list",
+ "url": "/learning_hours/small_steps/tdd_with_a_list.html"
+ },
+ {
+ "title": "Learning Hour: Make a test list",
+ "url": "/learning_hours/small_steps/test_list.html"
+ },
+ {
+ "title": "Learning Hour: Test Order",
+ "url": "/learning_hours/small_steps/test_order.html"
+ },
+ {
+ "title": "Learning Hour: Triangulation",
+ "url": "/learning_hours/small_steps/triangulation.html"
+ },
+ {
+ "title": "Learning Hour: Slicing a task using ZOMBIES",
+ "url": "/learning_hours/small_steps/zombies.html"
+ },
{
"title": "Test Design Learning Hours",
"url": "/learning_hours/test_design.html"
},
+ {
+ "title": "Learning Hour: Arrange - Act - Assert",
+ "url": "/learning_hours/test_design/arrange_act_assert.html"
+ },
+ {
+ "title": "Learning Hour: Asserting on Collections of Objects",
+ "url": "/learning_hours/test_design/asserting_on_collections.html"
+ },
+ {
+ "title": "Learning Hour: Benefits of Arrange - Act - Assert",
+ "url": "/learning_hours/test_design/benefits_of_arrange_act_assert.html"
+ },
+ {
+ "title": "Learning Hour: Gherkin intro",
+ "url": "/learning_hours/test_design/cucumber_comparison.html"
+ },
+ {
+ "title": "Learning Hour: Custom Assertions",
+ "url": "/learning_hours/test_design/custom_assert.html"
+ },
+ {
+ "title": "Learning Hour: Parameterized Tests in Doctest",
+ "url": "/learning_hours/test_design/doctest_parameterized.html"
+ },
+ {
+ "title": "Learning Hour: Test Fixture design",
+ "url": "/learning_hours/test_design/fixtures_comparison.html"
+ },
+ {
+ "title": "Learning Hour: Test Fixture Introduction",
+ "url": "/learning_hours/test_design/fixtures_intro.html"
+ },
+ {
+ "title": "Learning Hour: Test Fixtures - Readability vs Duplication",
+ "url": "/learning_hours/test_design/fixtures_readability_vs_duplication.html"
+ },
+ {
+ "title": "Learning Hour: Four Pillars of a Good Test (Khorikov)",
+ "url": "/learning_hours/test_design/four_pillars_khorikov.html"
+ },
+ {
+ "title": "Learning Hour: Parameterized Tests",
+ "url": "/learning_hours/test_design/parameterized_tests.html"
+ },
+ {
+ "title": "Learning Hour: Characteristics of Unit tests",
+ "url": "/learning_hours/test_design/properties_unit_test.html"
+ },
+ {
+ "title": "Learning Hour: Start with the Assertion",
+ "url": "/learning_hours/test_design/start_with_assert.html"
+ },
+ {
+ "title": "Learning Hour: Styles of Unit Tests",
+ "url": "/learning_hours/test_design/styles_of_unit_tests.html"
+ },
+ {
+ "title": "Learning Hour: Test a Bug",
+ "url": "/learning_hours/test_design/test_a_bug.html"
+ },
+ {
+ "title": "Learning Hour: Test data builders",
+ "url": "/learning_hours/test_design/test_data_builders.html"
+ },
+ {
+ "title": "Learning Hour: Test Desiderata",
+ "url": "/learning_hours/test_design/test_desiderata.html"
+ },
+ {
+ "title": "Learning Hour: Unit Tests Should Find Bugs",
+ "url": "/learning_hours/test_design/test_design_assertions.html"
+ },
+ {
+ "title": "Learning Hour: Test Names",
+ "url": "/learning_hours/test_design/test_names.html"
+ },
+ {
+ "title": "Learning Hour: Three parts of a test",
+ "url": "/learning_hours/test_design/three_parts_of_a_test.html"
+ },
+ {
+ "title": "Learning Hour: Unit Test FIRST properties",
+ "url": "/learning_hours/test_design/unit_test_FIRST_properties.html"
+ },
{
"title": "Test Doubles and Mocks Learning Hours",
"url": "/learning_hours/test_doubles.html"
},
+ {
+ "title": "Learning Hour: Faking Dependencies",
+ "url": "/learning_hours/test_doubles/faking_dependencies.html"
+ },
+ {
+ "title": "Learning Hour: Mocking Dependencies",
+ "url": "/learning_hours/test_doubles/mocking_dependencies.html"
+ },
+ {
+ "title": "Learning Hour: Stubbing Dependencies",
+ "url": "/learning_hours/test_doubles/stubbing_dependencies.html"
+ },
+ {
+ "title": "Learning Hour: Test Doubles Intro",
+ "url": "/learning_hours/test_doubles/test_double_intro.html"
+ },
+ {
+ "title": "Learning Hour: When to use a Test Double",
+ "url": "/learning_hours/test_doubles/when_to_use_a_test_double.html"
+ },
+ {
+ "title": "Learning Hour: When you need a fake",
+ "url": "/learning_hours/test_doubles/when_you_need_a_fake.html"
+ },
+ {
+ "title": "Learning Hour: When you need a mock",
+ "url": "/learning_hours/test_doubles/when_you_need_a_mock.html"
+ },
+ {
+ "title": "Learning Hour: When you need a spy",
+ "url": "/learning_hours/test_doubles/when_you_need_a_spy.html"
+ },
+ {
+ "title": "Learning Hour: When you need a stub",
+ "url": "/learning_hours/test_doubles/when_you_need_a_stub.html"
+ },
{
"title": "Testable Design Learning Hours",
"url": "/learning_hours/testable_design.html"
},
+ {
+ "title": "Learning Hour: Beck's 4 rules of simple design",
+ "url": "/learning_hours/testable_design/beck_simple_design.html"
+ },
+ {
+ "title": "Learning Hour: Bottom-up design",
+ "url": "/learning_hours/testable_design/bottom_up_design.html"
+ },
+ {
+ "title": "Learning Hour: Complexity / Collaborator quadrant analysis",
+ "url": "/learning_hours/testable_design/complexity_collaborator_quadrants.html"
+ },
+ {
+ "title": "Learning Hour: The Dependency Inversion Principle",
+ "url": "/learning_hours/testable_design/dependency_inversion_principle.html"
+ },
+ {
+ "title": "Learning Hour: Identify and Resolve Law of Demeter Violations",
+ "url": "/learning_hours/testable_design/law_of_demeter.html"
+ },
+ {
+ "title": "Learning Hour: Reading by Renaming",
+ "url": "/learning_hours/testable_design/naming.html"
+ },
+ {
+ "title": "Learning Hour: Overdesign",
+ "url": "/learning_hours/testable_design/overdesign.html"
+ },
+ {
+ "title": "Learning Hour: Strategy - Peel",
+ "url": "/learning_hours/testable_design/peel.html"
+ },
+ {
+ "title": "Learning Hour: Testing Private Methods",
+ "url": "/learning_hours/testable_design/private_methods.html"
+ },
+ {
+ "title": "Learning Hour: Testing Pure Functions",
+ "url": "/learning_hours/testable_design/pure_functions_are_easy_to_test.html"
+ },
+ {
+ "title": "Learning Hour: Strategy - Slice",
+ "url": "/learning_hours/testable_design/slice.html"
+ },
{
"title": "Newsletter",
"url": "/newsletter.html"
@@ -219,6 +1079,74 @@
"title": "Newsletter",
"url": "/newsletter_and_guide.html"
},
+ {
+ "title": "Refactoring: Replace Command with Function",
+ "url": "/refactorings/command_to_function.html"
+ },
+ {
+ "title": "Refactoring: Replace Conditional Logic with Strategy",
+ "url": "/refactorings/conditional_to_strategy.html"
+ },
+ {
+ "title": "Refactoring: Encapsulate Variable",
+ "url": "/refactorings/encapsulate_variable.html"
+ },
+ {
+ "title": "Refactoring: Extract Function",
+ "url": "/refactorings/extract_function.html"
+ },
+ {
+ "title": "Refactoring: Replace Function with Command",
+ "url": "/refactorings/function_to_command.html"
+ },
+ {
+ "title": "Refactoring: Inline Function",
+ "url": "/refactorings/inline_function.html"
+ },
+ {
+ "title": "Refactoring: Introduce Parameter Object",
+ "url": "/refactorings/introduce_parameter_object.html"
+ },
+ {
+ "title": "Refactoring: Introduce Variable",
+ "url": "/refactorings/introduce_variable.html"
+ },
+ {
+ "title": "Refactoring: Lift Up Conditional",
+ "url": "/refactorings/lift_up_conditional.html"
+ },
+ {
+ "title": "Refactoring: Move Function",
+ "url": "/refactorings/move_function.html"
+ },
+ {
+ "title": "Refactoring: Replace Conditional with Polymorphism",
+ "url": "/refactorings/replace_conditional_polymorphism.html"
+ },
+ {
+ "title": "Refactoring: Replace Primitive with Object",
+ "url": "/refactorings/replace_primitive_with_object.html"
+ },
+ {
+ "title": "Refactoring: Split Loop",
+ "url": "/refactorings/split_loop.html"
+ },
+ {
+ "title": "Refactoring: Split Message Chain",
+ "url": "/refactorings/split_message_chain.html"
+ },
+ {
+ "title": "Refactoring: Split Phase",
+ "url": "/refactorings/split_phase.html"
+ },
+ {
+ "title": "Refactoring: Split Variable",
+ "url": "/refactorings/split_variable.html"
+ },
+ {
+ "title": "Refactoring: Transform Return Type",
+ "url": "/refactorings/transform_return_type.html"
+ },
{
"title": "Reference Materials",
"url": "/reference/"
diff --git a/training/guided_learning_hours.md b/training/guided_learning_hours.md
index 7fa091f0..22a28d19 100644
--- a/training/guided_learning_hours.md
+++ b/training/guided_learning_hours.md
@@ -11,7 +11,7 @@ You will take part in 4 guided learning hours led by experienced technical coach
Guided Learning Hours are based on [the videos by Emily Bache](https://www.youtube.com/playlist?list=PL7GpAlmbnHyAEyVy5S9ZrJSMrbsn4dg6W). You are guided through her materials by an experienced facilitator, learning practical coding skills in a group. We provide materials to do the coding exercises in C#. If you prefer a different programming language then you can bring your own coding environment.
## Equipping you to lead these sessions afterwards
-Once you’ve attended this course we hope you will feel able to lead similar sessions in your own organization. After each learning hour there is an optional Session Briefing and Q&A with your host. If you haven't facilitated or led training before then it can be a little daunting to just call a meeting and ask your team to go through a Guided Learning Hour with you as host. This online training can help demystify the experience.
+Once you’ve attended this course we hope you will feel able to lead similar sessions in your own organization. After each learning hour there is an optional Session Briefing and Q&A with your host. If you haven't facilitated or led training before then it can be a little daunting to just call a meeting and ask your team to go through a Learning Hour with you as host. This online training can help demystify the experience.
## Agenda
All sessions are held online starting 16:00 CET
@@ -23,4 +23,6 @@ All sessions are held online starting 16:00 CET
## Dates and times:
Sessions are held weekly online starting 16:00 CET, and you sign up for a block of 4 sessions. There are currently no dates scheduled, please [Contact us]({% link contact.md %}) to register your interest in the next course. You could also sign up for our [Newsletter]({% link newsletter.md %}) to hear about upcoming trainings.
-For more detailed advice about leading learning hours with your team, we recommend you follow-up this training by attending the course [Deliver Learning Hours]({% link training/deliver_learning_hours.md %}).
\ No newline at end of file
+For more detailed advice about leading learning hours with your team, we recommend you follow-up this training by attending the course [Deliver Learning Hours]({% link training/deliver_learning_hours.md %}).
+
+Emily Bache also offers a package for companies looking to train a group of senior developers in technical coaching skills, based on these kinds of videos: ["Foundations of Software Craft"](https://emilybache.com/foundations-of-software-craft/)