🛌🐩❤ 💨🧡🛀👁️🗨️❤💬🛌
🐩🖤💛🛀 💚💬
🕊💛💬🛌 💭❤🤖🖤🛀❤
🛌🐩❤ 💨🧡🐚👀.
Author: claresudbery
Tips on Organising Hack Days / Hackathons
Caroline on Twitter asked “Currently researching “how to put on a data hack day” Any tips?”
Here is my very notey response, mostly based on my experience as (a) participant at Hack Manchester (RIP) and (b) being a judge myself at various different events over the years.
- Think about the comfort of the participants – both physical and emotional.
- How can you be welcoming and supportive?
- Give them the opportunity to solve real-world problems but with a lot of scope for creativity.
- Give them a choice of different challenges.
- Don’t expect judges to do full code reviews (too time consuming) – judge by presented results instead.
- Ask participants to present their results in an easy to digest format (to streamline the judges’ job).
- Let people present vision as well as working results (it’s hard to get things fully functional in a short space of time).
- Recruit helpers to give a hand when participants are stuck.
- When recruiting helpers, emphasise they do NOT have to know all the answers. Their job is to help people seek solutions, not provide solutions themselves.
- Have a v strict time limit for final presentations. How many teams do you have? How long will presentations take overall if (eg) you give them 2 mins each and allow extra for changeovers? Is that too much?
- You’ll be surprised how much people can present in even 1 min. Let them know in advance that time limits will be strict. Cut them off if they overrun.
- One great approach if you have a v big event is to get them to create a 1-min video each, to be watched separately by judges.
SDDConf May 2022 – Compassionate Refactoring
Part 1 – Refactor Tennis1
git clone https://github.com/emilybache/Tennis-Refactoring-Kata.git
Choose your language
Refactor TennisGame1
Part 2 – Example of unit tests retrofitted
Either… git clone git@github.com:claresudbery/gilded-rose-kata.git
or… git clone https://github.com/claresudbery/gilded-rose-kata.git
(if in doubt choose the second)
cd gilded-rose-kata
git checkout csharp-test-start
Look at this file for description of problem (GildedRoseRequirements.md in root of repo)
Look at this file to see tests (/csharp/GildedRoseTests.cs)
Part 4 – Easier to understand / cheaper to modify
Demo 1 – Easier to understand / cheaper to modify
Part 6 – Extract Method
Part 7 – Refactoring tools
All Parts – Sticky notes from Walls
Part 8 – Further resources and ideas
Recursion / Recursive Functions
[Image by Maurits Cornelis Escher]
A recursive function is a function which calls itself.
It sounds like a simple concept, but in practice it can be hard to get your head around.
Here’s a lovely example of a recursive function:
void ExplainRecursion () { var explained = GetInput(“Do you understand recursion yet?”); if (!explained) { ExplainRecursion(); } }
It’s particularly nice because it uses recursion to explain recursion. It calls itself – it’s a recursive function. Every time it calls itself, it asks the question “Has recursion been explained yet?” and if the answer is No it calls itself again. It keeps calling itself repeatedly until recursion is finally understood, at which point it quits. What might not be immediately obvious is that when it quits, it will still be inside the previous call, and will keep returning until it reaches the first time it was called. Like this:
ExplainRecursion()
—–>Do you understand recursion yet?
—–>No => ExplainRecursion()
———->Do you understand recursion yet?
———->No => ExplainRecursion()
—————>Do you understand recursion yet?
—————>No => ExplainRecursion()
——————–>Do you understand recursion yet?
——————–>Yes! => Exit function
—————>Exit function
———->Exit function
—–>Exit function
Exit function
It’s true that this is a slightly jokey example. It works if you see the source code, but if you only ever saw the output you wouldn’t learn much about recursion. You’d just be asked the same question repeatedly and probably get a bit angry.
Here’s another simple example:
void Factorial(int n) { if (n == 1) { return 1; } else { return n * Factorial(n-1); } }
This function is calculating “n factorial”, which is written as “n!” in mathematical notation. In case you’ve forgotten or haven’t come across this concept before, it’s easiest to explain with a concrete example: 5! (“five factorial”) is a quick way of writing 5 x 4 x 3 x 2 x 1. So n! means take the number n and multiply it by all the whole positive numbers that lie between itself and zero.
The above function calls itself, which means that unless n is 1 (because 1 factorial just equals 1), it will return a result… to itself.
Don’t worry if you’re feeling lost already. It took me a long time to be able to look at recursive functions without getting an instant headache. I found it helpful to draw little diagrams. For instance, if we use the above function to calculate 5 factorial.
Remember, the answer we expect is 5 x 4 x 3 x 2 x 1.
The first time we enter the function, we call Factorial(5), so n = 5. The function returns 5 x Factorial(4), so it gets called again and this time n = 4. That returns 4 x Factorial(3), which returns 3 x Factorial(2), which returns 2 x Factorial(1). Factorial(1) just returns 1. Here’s a diagram to help:
Factorial(5) = 5 x Factorial(4)
—–>Factorial(4) = 4 x Factorial(3)
———->Factorial(3) = 3 x Factorial(2)
—————>Factorial(2) = 2 x Factorial(1)
——————–>Factorial(1) = 1
—————>= 2 x 1
———->= 3 x (2 x 1)
—–>= 4 x (3 x (2 x 1))
= 5 x (4 x (3 x (2 x 1)))
Normally when a function returns a value, it’s over. We can move on. But with a recursive function, we might just land back inside ourselves again, and then we might return a value to yet another version of ourselves. With complex functions, this can be hard to trace through in your head without losing track. It’s also horribly easy to get stuck in an infinite loop.
Hopefully this helped. If not, don’t worry. It’s not just you! It’s a notoriously head-twisty concept.
Refactoring: This Class is too Large
This is a cross-post to an article I’ve written about refactoring on Martin Fowler’s site – “This class is too large – An example of refactoring from a real (flawed) code base.“
Liskov Substitution Principle
Some notes I made on the Liskov Substitution Principle (LSP) – which is the L in SOLID.
I can never remember the details of Liskov, which is why I made these notes.
These notes are also visible on my new personal wiki site, where I briefly describe the S, O, I and D in SOLID as well.
- “objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program.” See also design by contract.
- Code that uses a base class must be able to substitute a subclass without knowing it
- The specific functionality of the subclass may be different but must conform to the expected behaviour of the base class.
- EXAMPLE:
- So, I can call FemaleMammal.GiveBirth and I can substitute a cow into that – Cow.GiveBirth without breaking anything
- No matter which version I choose, I should be confident that I will end up with a baby animal. Even though the specifics might be slightly different.
- These are the principles which must be adhered to:
- Contravariance with parameters
- There should be contravariance between parameters of the base class’s methods and the matching parameters in subclasses. This means that the parameters in subclasses must either be the same types as those in the base class or must be less restrictive.
- Parameters in subclasses are either the same or have more / add extra functionality
- EXAMPLE:
- FemaleMammal.GiveBirth(Mammal mothersBestFriend)
- Cow.GiveBirth(Animal mothersBestFriend)
- See Covariance and Contravariance
- Covariance with return values
- There must be covariance between method return values in the base class and its subclasses. This specifies that the subclass’ return types must be the same as, or more restrictive than, the base class’ return types.
- Return values in subclasses are either the same or have less functionality
- EXAMPLE:
- Mammal baby = FemaleMammal.GiveBirth();
- Bovine baby = Cow.GiveBirth();
- See Covariance and Contravariance
- Preconditions
- The preconditions of a base class must not be strengthened by a subclass
- A precondition of a class is a rule that must be in place before an action can be taken.
- EXAMPLE:
- FemaleMammal must not be a virgin and must never have had a Caesarian before giving birth
- Cow must not be a virgin before giving birth
- Postconditions
- Postconditions cannot be weakened in subclasses.
- Postconditions describe the state of objects after a process is completed.
- EXAMPLE:
- After female mammal gives birth, it must have an associated baby that is a mammal
- After cow gives birth, it must have an associated baby that is a bovine (this is fine)
- After cow gives birth, it must have an associated baby that is any kind of animal (this would not be fine)
- Invariants
- The invariants of a base class must not be changed by a subclass.
- An invariant describes a condition of a process that is true before the process begins and remains true afterwards.
- EXAMPLE:
- FemaleMammal is female both before and after birth
- Cow is female both before and after birth
- History
- New or modified members should not modify the state of an object in a manner that would not be permitted by the base class
- EXAMPLE:
- FemaleMammal gains a newly populated Baby property and the baby has a head
- Cow gains a newly populated Baby property (this is fine)
- Cow gains a newly populated CowUdders property (this is not fine)
- Exceptions
- A subclass should not throw exceptions that are not thrown by the base class unless they are subtypes of exceptions that may be thrown by the base class
- EXAMPLE:
- FemaleMammal.GiveBirth throws a BreachedBaby exception
- Cow.GiveBirth throws a BreachedBabyCow exception (this is fine)
- Cow.GiveBirth throws a NotEnoughGrass exception (this is not fine)
- Contravariance with parameters
- For instance, if you want a read-only file type, it should not inherit from File – and File should not have a Save method. Rather, the base File type has a Load method, and it has a subclass – WriteableFile – which has a Save method. Thus the base class cannot be saved. (otherwise you would have ReadOnlyFile which was not able to implement the Save method on its parent, and also left the object in a different state after calling Save than what you would expect – particularly if its Save method threw an exception which was not thrown by the base class)
Clare Sudberry is Spelt Wrong
My name is surprisingly hard to spell. It’s actually Clare Sudbery: There’s no I in Clare, and my surname ends ERY – like surgery or carvery).
(This page exists in a vague attempt to make this site easier to find when people spell my name wrong in search engines.)
Claire Sudberry is Spelt Wrong
My name is surprisingly hard to spell. It’s actually Clare Sudbery: There’s no I in Clare, and my surname ends ERY – like surgery or carvery).
(This page exists in a vague attempt to make this site easier to find when people spell my name wrong in search engines.)
Claire Sudbery is Spelt Wrong
My name is surprisingly hard to spell. It’s actually Clare Sudbery: There’s no I in Clare, and my surname ends ERY – like surgery or carvery).
(This page exists in a vague attempt to make this site easier to find when people spell my name wrong in search engines.)
Claire Sudbury is Spelt Wrong
My name is surprisingly hard to spell. It’s actually Clare Sudbery: There’s no I in Clare, and my surname ends ERY – like surgery or carvery).
(This page exists in a vague attempt to make this site easier to find when people spell my name wrong in search engines.)