Alexis Rondeau

Newsfeed

Everything I publish, in the order I published it: dispatches from Twitter, videos from YouTube and notes from my vault, archived here in full — text, images, video and links — so they outlive the platforms.

857 dispatches since March 2014 · page 33 of 35

The Little Schemer in Clojure – Recap Chapter 5

Oh My Gawd, It’s Full Of Stars

Dealing With Nested Lists

Learned how to deal with nested lists by asking at least 3 questions:

  • Is the list null? If so, return the empty element (an empty list if the value of the function is to be a list, or 0 if you’re evaluating to a number)
  • Is the first element in the list an atom? – If so, operate on that atom and cons it onto the natural recursion of the function.
  • Else, cons the natural recursion of the function of car list onto the natural recursion of the function of cdr list

You can see this pattern in action on rember* which removes any occurrence of a in l regardless of how deep as are hidden in the nested list. (*, or star is added to the function name to denote that it’s recurring on both, car and cdr.)

(with-test
  (def rember* 
    (fn [a l]
      (cond (null? l) '()
            (atom? (car l)) (cond (eq? (car l) a) (rember* a (cdr l))
                                  :else (cons (car l)
                                              (rember* a (cdr l))))
            :else (cons (rember* a (car l))
                        (rember* a (cdr l))))))

  (is (= (rember* 'cup '()) '()))
  (is (= (rember* 'cup '(coffee)) '(coffee)))
  (is (= (rember* 'cup '(cup)) '()))
  (is (= (rember* 'cup '(coffee cup)) '(coffee)))
  (is (= (rember* 'cup '((cup))) '(())))
  (is (= (rember* 'cup '(coffee (cup) and (another) cup)) '(coffee () and (another))))
  (is (= (rember* 'sauce '(((tomato sauce)) ((bean) sauce) (and ((flying)) sauce))) '(((tomato)) ((bean)) (and ((flying)))))))

The same applies to insertR and insertL* which respectively return a new list with new inserted next to to old in l.

The questions are again:

  • null? – return an empty list that can be cons-ed onto from previous calls
  • atom? – checks if car l is what we’re looking for and if so, adds a new element
  • else – recurs on both car l and cdr l
(with-test
  (def insertR*
    (fn [new old l]
      (cond (null? l) '()
            (atom? (car l)) (cond (eq? (car l) old) (cons old 
                                                          (cons new (insertR* new old 
                                                                              (cdr l))))

                                  :else (cons (car l) 
                                              (insertR* new old 
                                                        (cdr l))))
            :else (cons (insertR* new old (car l))
                        (insertR* new old (cdr l))))))

  (is (= (insertR* 'new 'old '()) '()))
  (is (= (insertR* 'new 'old '(old)) '(old new)))
  (is (= (insertR* 'new 'old '((old))) '((old new))))
  (is (= (insertR* 'new 'old '((these) old ((shoes old) perfume))) '((these) old new ((shoes old new) perfume)))))
(with-test
  (def insertL*
    (fn [new old l] 
      (cond (null? l) '()
            (atom? (car l)) (cond (eq? (car l) old) (cons new (cons old (insertL* new old (cdr l))))
                                  :else (cons (car l) (insertL* new old (cdr l))))
            :else (cons (insertL* new old (car l))
                        (insertL* new old (cdr l))))))

  (is (= (insertL* 'new 'old '()) '()))
  (is (= (insertL* 'new 'old '(old)) '(new old)))
  (is (= (insertL* 'new 'old '((old))) '((new old))))
  (is (= (insertL* 'new 'old '((these) old ((shoes old) perfume))) '((these) new old ((shoes new old) perfume)))))

Then, the same pattern applies to subst* which substitutes new with old in l

(with-test 
  (def subst*
    (fn [new old l] 
      (cond (null? l) '()
            (atom? (car l)) (cond (eq? (car l) old) (cons new (subst* new old (cdr l)))
                                  :else (cons (car l) (subst* new old (cdr l))))
            :else (cons (subst* new old (car l))
                        (subst* new old (cdr l))))))

  (is (= (subst* 'orange 'banana '()) '()))
  (is (= (subst* 'orange 'banana '(banana)) '(orange)))
  (is (= (subst* 'orange 'banana '((banana))) '((orange))))
  (is (= (subst* 'cup 'mug '((a mug) in the (((kitchen (mug)))))) '((a cup) in the (((kitchen (cup))))))))

Then, member* returns true if a can be found in l, otherwise it returns false:

Note that instead of returning a list on (null l) it returns false which represents that the element couldn’t be found and we’ve reached the end where we can’t look no further.

(with-test
  (def member* 
    (fn [a l] 
      (cond (null? l) false
            (atom? (car l)) (or (eq? (car l) a)
                                (member* a (cdr l)))
            :else (or (member* a (car l))
                      (member* a (cdr l))))))

  (is (= (member* 'foo '()) false))
  (is (= (member* 'foo '(foo)) true))
  (is (= (member* 'foo '(bar)) false))
  (is (= (member* 'foo '((foo))) true))
  (is (= (member* 'foo '((the quick) ((((brown (springy foo)) jumps over)) the dog))))))

Traversing a Tree

A personal favorite of mine is leftmost which returns the left-most element in l. It’s a bit simpler than the functions before. It recurs only on (car l) unless it is an atom:

(with-test
  (def leftmost 
    (fn [l]
      (cond (null? l) nil
            (atom? (car l)) (car l)
            :else (leftmost (car l)))))

  (is (= (leftmost '()) nil))
  (is (= (leftmost '(apple)) 'apple))
  (is (= (leftmost '((apple))) 'apple))
  (is (= (leftmost '(((hot cider) with (green) tea))) 'hot)))

Testing equality

At the end of the chapter, the authors use recurring on a nested list to test for equality of any s-expression:

(with-test
  (def eqlist?
    (fn [l1 l2] 
      (cond (and (null? l1) (null? l2)) true
            (or (null? l1) (null? l2)) false
            :else (and (equal? (car l1) (car l2))
                       (eqlist? (cdr l1) (cdr l2))))))

  (is (= (eqlist? '() '()) true))
  (is (= (eqlist? '() '(foot)) false))
  (is (= (eqlist? '(foot) '()) false))
  (is (= (eqlist? '(foot) '(foot)) true))
  (is (= (eqlist? '(foot rub) '(foot sub)) false))
  (is (= (eqlist? '(strawberry ice cream) '(strawberry ice cream)) true))
  (is (= (eqlist? '(strawberry ice cream) '(strawberry cream ice)) false))
  (is (= (eqlist? '((coffee) (cup)) '((coffee) (cup))) true)))

(with-test
  (def equal? 
    (fn [s1 s2]
      (cond (and (atom? s1) (atom? s2)) (equan? s1 s2)
            (or (atom? s1) (atom? s2)) false
            :else (eqlist? s1 s2))))

  (is (= (equal? 'a 'a) true))
  (is (= (equal? 'a 'b) false))
  (is (= (equal? 'a '(a)) false))
  (is (= (equal? '(a) 'a) false))
  (is (= (equal? '(a) '(a)) true))
  (is (= (equal? '(a) '(b)) false)))

I am starting to realize how great it is to have a set of tests right away with any function definition. Refactoring will be easy and give me confidence that everything still works. Pretty stoked!

The Little Schemer in Clojure – Chapter 4 Recap

Number Games

I’ve enjoyed working through chapter 4. It’s simpler and more dense at the same time since it’s all about numbers. Over the course of this chapter I (re)implemented several arithmetic basic functions such as add1, sub1 – Those were rather helper functions – and moved on to implementing pluss and minuss, multiply and divide (I added the extra “s” to pluss and minuss to avoid redefining built-in functions).

The cool thing about this chapter is that I was able to implement these functions only in terms of very simple operations (add1, sub1) and recursion.

For example, pluss works as follows:

Given n and m, I want to evaluate their sum. For that to happen, I need to ask two questions:

  • Is m equal to 0? If so, return n. This would make an addition such as 1 + 0 work straight away.
  • Else, add1 to the natural recursion of pluss with n and (sub1 m). This counts m down with each recursion until it reaches 0.

If we were to add 1 and 3, the result of 4 would be calculated as:

(pluss 1 3)
1 + (pluss 1 2)
1 + 1 + (pluss 1 1)
1 + 1 + 1 (pluss 1 0)
1 + 1 + 1 + 1

Pretty cool.

(with-test
  (def pluss
    (fn [n m]
      (cond (zero? m) n
            :else (add1 (pluss n (sub1 m))))))

  (is (= (pluss 0 0) 0))
  (is (= (pluss 1 0) 1))
  (is (= (pluss 0 1) 1))
  (is (= (pluss 1 1) 2))
  (is (= (pluss 1 2) 3))
  (is (= (pluss 46 12) 58)))

For every function I write, I also make sure I start with the smallest possible test-case and then only add the code necessary to fix that test. I quiet enjoy it because it gives me confidence that, once I refactor, the functions still work.

For example, take occur which takes an atom a and a list lat as its arguments and returns the count of a in lat.

To build the simple algorithm, I start out writing the bare minimum setup for the first, smallest test:

(with-test
  (def occur
    (fn [a lat]))

  (is (= (occur 'a '()) 0)))

Running the test will fail since the function currently, and intentionally, only returns nil and not 0 when given 'a and '() as its inputs.

I can fix this situation by writing the smallest possible solution which is to return 0, hardcoded:

(with-test
  (def occur
    (fn [a lat] 0))

  (is (= (occur 'a '()) 0)))

Our first test will now pass. We could, if we wanted to, make a commit at this point. On to the next.

(with-test
  (def occur
    (fn [a lat] 0))

  (is (= (occur 'a '()) 0))
  (is (= (occur 'a '(a)) 1)))

Running the tests will now fail for scenario 2 when we expect to receive 1 as the value and not 0. The smallest fix to solve for this is to introduce a conditional.

(with-test
  (def occur
    (fn [a lat]
      (cond (null? lat) 0
            :else 1)))

  (is (= (occur 'a '()) 0))
  (is (= (occur 'a '(a)) 1)))

Great! All tests are passing now. Now, on to the next, simplest test-case where (occur 'a '(b)) should evaluate to 0.

(with-test
  (def occur
    (fn [a lat]
      (cond (null? lat) 0
            :else 1)))

  (is (= (occur 'a '()) 0))
  (is (= (occur 'a '(a)) 1))
  (is (= (occur 'a '(b)) 0)))

The third test fails naturally. To fix it, I now have to introduce a new condition to check if (car lat) is equal to a:

(with-test
  (def occur
    (fn [a lat]
      (cond (null? lat) 0
            (equan? (car lat) a) 1
            :else 0)))

  (is (= (occur 'a '()) 0))
  (is (= (occur 'a '(a)) 1))
  (is (= (occur 'a '(b)) 0)))

Now, let’s test for multiple occurrences of a in lat: (is (= (occur 'a '(a a)) 2))

(with-test
  (def occur
    (fn [a lat]
      (cond (null? lat) 0
            (equan? (car lat) a) 1
            :else 0)))

  (is (= (occur 'a '()) 0))
  (is (= (occur 'a '(a)) 1))
  (is (= (occur 'a '(b)) 0))
  (is (= (occur 'a '(a a)) 2)))

The test will fail when run. Now we have to fix it by introducing adding 1 to the natural recursion of the function as follows: (add1 (occur a (cdr lat)))

(with-test
  (def occur
    (fn [a lat]
      (cond (null? lat) 0
            (equan? (car lat) a) (add1 (occur a (cdr lat)))
            :else 0)))

  (is (= (occur 'a '()) 0))
  (is (= (occur 'a '(a)) 1))
  (is (= (occur 'a '(b)) 0))
  (is (= (occur 'a '(a a)) 2)))

Splendid, all tests are passing.

Now, I want to make sure that we get the right result, when the list is mixed, such as (is (= (occur 'a '(a b c a)) 2))

(with-test
  (def occur
    (fn [a lat]
      (cond (null? lat) 0
            (equan? (car lat) a) (add1 (occur a (cdr lat)))
            :else 0)))

  (is (= (occur 'a '()) 0))
  (is (= (occur 'a '(a)) 1))
  (is (= (occur 'a '(b)) 0))
  (is (= (occur 'a '(a a)) 2))
  (is (= (occur 'a '(a b c a)) 2)))

Adding the test makes it fail of course, since we’re not accounting for this scenario. It’s a simple fix, we need to allow our :else branch to continue searching for as with (occur a (cdr lat)). The final solution to occur is

(with-test
  (def occur
    (fn [a lat]
      (cond (null? lat) 0
            (equan? (car lat) a) (add1 (occur a (cdr lat)))
            :else (occur a (cdr lat)))))

  (is (= (occur 'a '()) 0))
  (is (= (occur 'a '(a)) 1))
  (is (= (occur 'a '(b)) 0))
  (is (= (occur 'a '(a a)) 2))
  (is (= (occur 'a '(a b c a)) 2)))

I think this is pretty cool. We’ve got a first set of reasonable inputs and outputs covered. This would be a great time to run the full test-suite with lein test, and if everything passes, make a commit and push to master. For this I usually make myself a tiny script named ship.sh that runs the test-suite one final time and does the git push for me:

ship.sh

#!/bin/bash

lein test && git push origin master

Nothing fancy, but it keeps me from habitually doing a git push origin master without running all tests beforehand.

Anyways, I enjoyed showing you how I build my functions with TDD and baby-steps to arrive at a good place to commit and push. The full listing of my (un-refactored) chapter 4 is as follows:

(ns the-little-clojurian.chapter4
  (:require [clojure.test :refer :all]
            [the-little-clojurian.chapter1 :refer :all]
            [the-little-clojurian.chapter2 :refer :all]
            [the-little-clojurian.chapter3 :refer :all]))

(with-test 
  (def add1 
    (fn [x] (+ x 1)))

  (is (= (add1 0) 1))
  (is (= (add1 67) 68))
  (is (= (add1 68) 69)))

(with-test
  (def sub1
    (fn [x] (- x 1)))

  (is (= (sub1 0) -1))
  (is (= (sub1 1) 0))
  (is (= (sub1 2) 1))
  (is (= (sub1 3) 2)))

(with-test
  (def pluss
    (fn [n m]
      (cond (zero? m) n
            :else (add1 (pluss n (sub1 m))))))

  (is (= (pluss 0 0) 0))
  (is (= (pluss 1 0) 1))
  (is (= (pluss 0 1) 1))
  (is (= (pluss 1 1) 2))
  (is (= (pluss 1 2) 3))
  (is (= (pluss 46 12) 58)))

(with-test
  (def minuss 
    (fn [n m]
      (cond 
       (zero? m) n
       :else (sub1 (minuss n (sub1 m))))))

  (is (= (minuss 0 0) 0))
  (is (= (minuss 1 1) 0))
  (is (= (minuss 2 1) 1))
  (is (= (minuss 3 2) 1))
  (is (= (minuss 100 1) 99)))

(with-test
  (def tup?
    (fn [l] 
      (cond (null? l) true
            (not (number? (car l))) false
            :else (tup? (cdr l)))))

  (is (= (tup? '()) true))
  (is (= (tup? '(a)) false))
  (is (= (tup? '(1)) true))
  (is (= (tup? '(1 a)) false))
  (is (= (tup? '(1 2)) true))
  (is (= (tup? '(2 11 3 79 47 6))))
  (is (= (tup? '(8 55 5 555))))
  (is (= (tup? '(1 2 8 apple 4 3)) false))
  (is (= (tup? '(3 (7 4) 13 9)) false)))

(with-test
  (def addtup 
    (fn [tup] 
      (cond (null? tup) 0
            :else (pluss (car tup) (addtup (cdr tup))))))

  (is (= (addtup '()) 0))
  (is (= (addtup '(1)) 1))
  (is (= (addtup '(1 2)) 3))
  (is (= (addtup '(1 2 3)) 6))
  (is (= (addtup '(3 5 2 8)) 18))
  (is (= (addtup '(15 6 7 12 3)) 43)))

(with-test
  (def multiply 
    (fn [n m]
      (cond (zero? m) 0
            :else (pluss n (multiply n (sub1 m))))))

  (is (= (multiply 0 0) 0))
  (is (= (multiply 1 1) 1))
  (is (= (multiply 1 0) 0))
  (is (= (multiply 5 3) 15))
  (is (= (multiply 13 4) 52)))

(with-test
  (def tup+ 
    (fn [tup1 tup2]
      (cond (null? tup1) tup2
            (null? tup2) tup1
            :else (cons (pluss (car tup1) (car tup2)) 
                        (tup+ 
                         (cdr tup1) (cdr tup2))))))

  (is (= (tup+ '() '()) '()))
  (is (= (tup+ '(1) '(1)) '(2)))
  (is (= (tup+ '(2 3) '(4 6)) '(6 9)))
  (is (= (tup+ '(3 6 9 11 4) '(8 5 2 0 7)) '(11 11 11 11 11)))
  (is (= (tup+ '(3 7) '(4 6 8 1)) '(7 13 8 1))))

(with-test
  (def greater-than
    (fn [n m] false
      (cond (zero? n) false
            (zero? m) true
            :else (greater-than (sub1 n) (sub1 m)))))

  (is (= (greater-than 0 0) false))
  (is (= (greater-than 1 0) true))
  (is (= (greater-than 12 133) false))
  (is (= (greater-than 120 11) true))
  (is (= (greater-than 4 6) false)))

(with-test
  (def smaller-than
    (fn [n m] 
      (cond (zero? m) false
            (zero? n) true
            :else (smaller-than (sub1 n) (sub1 m)))))

  (is (= (smaller-than 0 0) false))
  (is (= (smaller-than 0 1) true))
  (is (= (smaller-than 4 6))))

(with-test
  (def equal 
    (fn [n m] 
      (cond (smaller-than n m) false
            (greater-than n m) false
            :else true)))

  (is (= (equal 0 0) true))
  (is (= (equal 0 1) false))
  (is (= (equal 1 1) true))
  (is (= (equal 44 44) true)))

(with-test
  (def expt 
    (fn [n m]
      (cond (zero? m) 1
            :else (multiply n (expt n (sub1 m))))))

  (is (= (expt 1 1) 1))
  (is (= (expt 2 2) 4))
  (is (= (expt 2 3) 8))
  (is (= (expt 5 3) 125)))

(with-test
  (def divide
    (fn [n m]
      (cond (zero? m) (throw (IllegalArgumentException.))
            (smaller-than n m) 0
            :else (add1 (divide (minuss n m) m)))))
  (is (= (divide 0 1) 0))
  (is (thrown? IllegalArgumentException (divide 1 0)))
  (is (= (divide 15 4) 3))
  (is (= (divide 15 3) 5))
  (is (= (divide 100 10) 10)))

(with-test
  (def length 
    (fn [lat] 
      (cond (null? lat) 0
            :else (add1 (length (cdr lat))))))

  (is (= (length '()) 0))
  (is (= (length '(hotdogs)) 1))
  (is (= (length '(hotdogs with mustard sauerkraut and pickles)) 6))
  (is (= (length '(ham and cheese on rye)) 5)))

(with-test 
  (def pick 
    (fn [n lat] 
      (cond (zero? n) nil
            (one? n) (car lat)
            :else (pick (sub1 n) (cdr lat)))))

  (is (= (pick 0 '(apple)) nil))
  (is (= (pick 1 '()) nil))
  (is (= (pick 1 '(apple)) 'apple))
  (is (= (pick 2 '(apple bananas)) 'bananas))
  (is (= (pick 4 '(apple)) nil)))

(with-test
  (def rempick 
    (fn [n lat]
      (cond (zero? n) nil
            (one? n) (cdr lat)
            :else (cons (car lat) 
                        (rempick (sub1 n) 
                                 (cdr lat))))))

  (is (= (rempick 0 '()) nil))
  (is (= (rempick 1 '(apple)) '()))
  (is (= (rempick 2 '(apple bananas gin)) '(apple gin))))


(with-test 
  (def no-nums 
    (fn [lat]
      (cond (null? lat) '()
            (number? (car lat)) (no-nums (cdr lat))
            :else (cons (car lat) 
                        (no-nums 
                         (cdr lat))))))

  (is (= (no-nums '()) '()))
  (is (= (no-nums '(1)) '()))
  (is (= (no-nums '(apple)) '(apple)))
  (is (= (no-nums '(5 pears 6 prunes 9 dates)) '(pears prunes dates))))

(with-test
  (def all-nums
    (fn [lat]
      (cond (null? lat) '()
            (number? (car lat)) (cons (car lat)
                                      (all-nums (cdr lat)))
            :else (all-nums (cdr lat)))))

  (is (= (all-nums '()) '()))
  (is (= (all-nums '(1)) '(1)))
  (is (= (all-nums '(apple)) '()))
  (is (= (all-nums '(1 apple 2 pears 3 bananas)) '(1 2 3))))

(with-test
  (def equan?
    (fn [a1 a2]
      (cond (and (number? a1) (number? a2)) (equal a1 a2)
            (or (number? a1) (number? a2)) false
            :else (eq? a1 a2))))

  (is (= (equan? 0 0) true))
  (is (= (equan? 0 1) false))
  (is (= (equan? 0 'a) false))
  (is (= (equan? 'a 'a) true))
  (is (= (equan? 'a 'b) false)))

(with-test
  (def occur
    (fn [a lat] 
      (cond (null? lat) 0
            (equan? (car lat) a) (add1 (occur a (cdr lat)))
            :else (occur a (cdr lat)))))

  (is (= (occur 'a '()) 0))
  (is (= (occur 'a '(a)) 1))
  (is (= (occur 'a '(b)) 0))
  (is (= (occur 'a '(a a)) 2))
  (is (= (occur 'a '(a b c a)) 2))
  (is (= (occur 'a '(b c d e)) 0)))

(with-test
  (def one?
    (fn [x] (equal x 1)))

  (is (= (one? 0) false))
  (is (= (one? 1) true))
  (is (= (one? 2) false)))

The Little Schemer in Clojure – Chapter 3 Recap

Cons the magnificent

In this chapter I learned how to create lists using cons and recursion.

The first function discussed was rember, which removes the first occurrence of a in lat and returns the result as a new list.

As you can see from below, the function asks three questions:

  1. Is lat null?, or empty. If so, return the empty list `()
  2. Is (car lat) equal to the atom we’re looking to drop? If so, return the rest of the list (cdr lat) and effectively drop (car lat) from the list, implementing the requirement of “remove member”.
  3. If neither of the above is true, (cons (car lat)) onto the natural recursion of rember with a and the rest of lat, which is (cdr lat).

*Note that I am using cones in my listings to stay consistent with the book.

(with-test
  (def rember 
    (fn [a lat] 
      (cond (null? lat) '()
            (eq? (car lat) a) (cdr lat)
            :else (conss (car lat) (rember a 
                                           (cdr lat))))))

  (is (= (rember 'and '()) '()))
  (is (= (rember 'and '(and)) '()))
  (is (= (rember 'and '(bacon lettuce and tomato)) '(bacon lettuce tomato)))
  (is (= (rember 'mint '(lamb chops and mint jelly)) '(lamb chops and jelly)))
  (is (= (rember 'mint '(lamb chops and mint flavored mint jelly)) '(lamb chops and flavored mint jelly))))

I have begun to always start my tests with the null-case, here it’s…

(is (= (rember 'and '()) '()))

…which drives out the question #1.

Then I write the minimal test that drives out the main behavior without the need for recursion…

(is (= (rember 'and '(and)) '()))

…which drives out the question #2

And then finally I write a test that drives out question #3 such as…

(is (= (rember 'and '(bacon lettuce and tomato)) '(bacon lettuce tomato)))

As the books describes in the beginning, over time, patterns emerge from this simple example.

The second function I learned was firsts which takes the first s-expression of each nested list in the list.

This time there are only two questions we ask: 1. Is the list null?, then return the empty list (). This is the necessary terminal clause that will cause a recursion to stop. 2. Else,(cons (car (car l))onto the natural recursion offirstswith(cdr l)`.

So, for example (firsts '((a b) (c d) (e f))) evaluates to (a c e).

Here, again, I started with the simplest case with '() for l and worked through the rest of the example step by step following the book.

(with-test
  (def firsts 
    (fn [l]
      (cond (null? l) '()
            :else (cons (car (car l))
                        (firsts (cdr l))))))

  (is (= (firsts '()) '()))
  (is (= (firsts '((apple peach pumpkin)
                   (plum pear cherry)
                   (grape raisin pea)
                   (bean carrot eggplant)))
         '(apple plum grape bean)))
  (is (= (firsts '((a b) (c d) (e f)))
         '(a c e)))
  (is (= (firsts '((five plums)
                   (four)
                   (eleven green oranges)))
         '(five four eleven)))
  (is (= (firsts '(((five plums) four)
                   (eleven green oranges)
                   ((no) more)))
         '((five plums)
           eleven
           (no)))))

After that I wrote insertR which inserts a new s-expression to the right of an the first occurrence of an existing s-expression inside a list.

The questions this function needs to ask and answer are:

  1. Is lat null? If so, return the empty list `().
  2. Is (car lat) equal to old and if so, (cons old (cons new (cdr lat))) which basically says append new, then old onto the rest.
  3. Else (cons (car lat)) onto the natural recursion of this function with new, old and (cdr lat).
(with-test
  (def insertR 
    (fn [new old lat]
      (cond (null? lat) '()
            (eq? (car lat) old) (cons old
                                      (cons new (cdr lat)))
            :else (cons (car lat)
                        (insertR new old 
                                 (cdr lat))))))

  (is (= (insertR 'topping 'fudge '())
         '()))
  (is (= (insertR 'topping 'fudge '(ice cream with fudge for dessert))
         '(ice cream with fudge topping for dessert)))
  (is (= (insertR 'jalapeno 'and '(tacos tamales and salsa))
         '(tacos tamales and jalapeno salsa)))
  (is (= (insertR 'e 'd '(a b c d f g d h))
         '(a b c d e f g d h))))

Now, the next function, insertL inserts a new element to the left of an existing one. The only difference here was what we do in case (eq? (car lat) old) namely (cons new lat)

(with-test
  (def insertL
    (fn [new old lat]
      (cond (null? lat) '()
            (eq? (car lat) old) (conss new lat)
            :else (cons (car lat) (insertL new old (cdr lat))))))

  (is (= (insertL 'topping 'fudge '())
         '()))
  (is (= (insertL 'topping 'fudge '(ice cream with fudge for dessert))
         '(ice cream with topping fudge for dessert))))

Now up to this point the functions only replace or insert or remove the first occurence of whatever the matching function was. What about multiple occurrences and manipulations?

When you look at multimember you’ll notice that we drop the current occurrence of a in lat and recur via (multirember a (cdr lat) which will drop any following occurrences as well.

(with-test
  (def multirember 
    (fn [a lat]
      (cond (null? lat) '()
            (eq? (car lat) a) (multirember a (cdr lat))
            :else (conss (car lat) (multirember a (cdr lat))))))
  (is (= (multirember 'cup '())
         '()))
  (is (= (multirember 'cup '(coffee cup tea cup and hick cup))
         '(coffee tea and hick))))

This pattern persisted for the following, improved versions of insertL, insertR and subst:

(with-test
  (def multiinsertR
    (fn [new old lat]
      (cond (null? lat) '()
            (eq? (car lat) old) (conss old (conss new (multiinsertR new old (cdr lat))))
            :else (conss (car lat) (multiinsertR new old (cdr lat))))))

  (is (= (multiinsertR 'new 'old '())
         '()))
  (is (= (multiinsertR 'new 'old '(old socks old beer))
         '(old new socks old new beer))))

(with-test
  (def multiinsertL
    (fn [new old lat]
      (cond (null? lat) '()
            (eq? (car lat) old) (conss new (conss old (multiinsertL new old (cdr lat))))
            :else (cons (car lat) (multiinsertL new old (cdr lat))))))

  (is (= (multiinsertL 'new 'old '())
         '()))
  (is (= (multiinsertL 'new 'old '(old socks old beer))
         '(new old socks new old beer))))

(with-test
  (def multisubst
    (fn [new old lat]
      (cond (null? lat) '()
            (eq? (car lat) old) (conss new (multisubst new old (cdr lat)))
            :else (conss (car lat) (multisubst new old (cdr lat))))))
  (is (= (multisubst 'new 'old '())
         '()))
  (is (= (multisubst 'new 'old '(frog))
         '(frog)))
  (is (= (multisubst 'new 'old '(old))
         '(new)))
  (is (= (multisubst 'new 'old '(old old old))
         '(new new new))))

All in all I had great fun really digging into it. The question/answer style still lends itself to writing the test first and then following along with the implementation.

The Little Schemer in Clojure – Chapter 2 Recap

Yesterday I made it through Chapter 2 and as before I’ve enjoyed it. I have come to copy the question/answer style from the book into the tests:

First I write the application of the function under test, then the expectation such as:

(is (= (lat? '(Jack Sprat could eat no chicken fat)) true))

I understand that calling functions recursively, as done in the book, isn’t idiomatic in Clojure.

(def lat? 
    (fn [l]
      (cond (null? l) true
            (atom? (car l)) (lat? (cdr l))
            :else false)))

There’s recur for that. For now, I like to continue with calling functions regardless. The data-size is small and, since I have tests in place, once I’m through with the book, I can imagine a refactor using recur.

On the same note, I recognize that Clojure has great helper functions such as every? that I could leverage directly. For example, the above mentioned function lat? could become a one-liner such as by asking “is every expression in the list not a list itself”.

(def lat? 
  (fn [l] 
    (every? #(not (list? %))) l)))

This is much cleaner (and every? Itself is a recursive function) but in the spirit of the book, I’m going to stick with the functions as they are discussed. Again, my test-suite will allow for refactoring as needed later.

Lastly, I am getting into the habit of tiny, regular commits. I now make a commit when I have fully tested a function just before moving on to the next one. I can see even smaller commits on every red-to-green test cycle.

If you are interested, the full listing for Chapter 2 is as follows:

(ns the-little-clojurian.chapter2
  (:require [clojure.test :refer :all]
            [the-little-clojurian.chapter1 :refer :all]))

(with-test 
  (def lat? 
    (fn [l]
      (cond (null? l) true
            (atom? (car l)) (lat? (cdr l))
            :else false)))
  (testing "returns true"
    (is (= (lat? '(Jack Sprat could eat no chicken fat)) true))
    (is (= (lat? '()) true))
    (is (= (lat? '(bacon and eggs)) true)))
  (testing "returns false"
    (is (= (lat? '((Jack) Sprat could eat no chicken fat)) false))
    (is (= (lat? '(Jack (Sprat could) eat no chicken fat)) false))
    (is (= (lat? '(bacon (and eggs))) false))))

(deftest boolean-operators
  (is (= (or (null? '())
             (atom? '(d e f g)))
         true))
  (is (= (or (null? '(a b c))
             (null? '()))
         true))
  (is (= (or (null? '(a b c))
             (null? '(atom)))
         false)))

(with-test 
  (def member? 
    (fn [a lat]
      (cond (null? lat) false
            :else (or (eq? (car lat) a) 
                      (member? a (cdr lat))))))
  (testing "evaluates to true"
    (is (= (member? 'meat '(meat)) true))
    (is (= (member? 'tea '(coffee tea and milk))))
    (is (= (member? 'meat '(mashed potatoes and meat gravy)) true)))
  (testing "evaluates to false"
    (is (= (member? 'meat '()) false))
    (is (= (member? 'liver '(bagels and lox)) false))
    (is (= (member? 'poached '(fried eggs and scrambled eggs))))))

The Little Schemer in Clojure – Chapter 1 Recap

This is a series of small blog posts about following along the book ‘The Little Schemer’ using Clojure.

The book is great fun to read and it is easy to understand. The format is a kind conversation between the author and reader. And finally, the book even has dedicated pages for jelly-stains! It teaches programming small but realistic applications with the least amount of jargon and concepts. I think it is a perfect place to start learning to program if you haven’t done so yet. It also helps seasoned developers like myself get back to the fundamentals of how to think about computation.

For me, the challenge was to follow along in the book via programming in Clojure, a recent JVM-based Lisp. I recently worked on a side-project where the most smartest solution would have been a recursive algorithm but I wasn’t able to solve it without head-scratching all the way through. With this series I want to recap my recursion skills and learn them through Clojure, my favorite programming language.

I’m currently using a very barebones setup to follow along: I used Leiningen to create a standalone Clojure project lein new the-little-clojurian. I use GNU Emacs 25 with Cider on a 3-year old Macbook Air.

Workflow

My workflow is as follows:

Once… 1. I open project.clj in a buffer and 2. run M-x cider-jack-in to get a REPL

Then, I… 1. Write the test as it appears in the book, 2. use C-c k to compile the file and 3. C-c , to run the tests.

When I have a failing test, I fix the implementation only as much as to get the test to pass. Following the book, I continue this pattern until the chapter is over.

I am using the with-test macro and write my tests and implementation all in the main core namespace. Normally, we tend to write our tests in separate files but I’ve grown fond of with-test because of

  1. less switching between buffers
  2. having all code right in front of me.

I like it.

In a way, the book is written in a conversational, assumptions-first, almost test-driven way, so I write the assertion first and then gradually implement the function itself.

The function-definition, including tests for lat? looks like this for example:

(ns the-little-clojurian.chapter2
  (:require [clojure.test :refer :all]
            [the-little-clojurian.chapter1 :refer :all]))

(with-test 
  ;; Function-definition
  (def lat? 
    (fn [l]
      (cond (null? l) true
            (atom? (car l)) (lat? (cdr l))
            :else false)))
  ;; Tests
  (testing "returns true"
    (is (= (lat? '(Jack Sprat could eat no chicken fat)) true))
    (is (= (lat? '()) true))
    (is (= (lat? '(bacon and eggs)) true)))
  (testing "returns false"
    (is (= (lat? '((Jack) Sprat could eat no chicken fat)) false))
    (is (= (lat? '(Jack (Sprat could) eat no chicken fat)) false))
    (is (= (lat? '(bacon (and eggs))) false))))

The full transcript of Chapter 1 in Clojure is:

(ns the-little-clojurian.chapter1
  (:require [clojure.test :refer :all]))

(declare listp? atom? s-expression? car cdr conss null? eq?)

(with-test 
  (def atom? 
    (fn [a] 
      (not (listp? a))))
  (testing "returns true"
    (is (= true (atom? 'atom)))
    (is (= true (atom? 'turkey)))
    (is (= true (atom? '1492)))
    (is (= true (atom? 'u)))
    (is (= true (atom? '*abc$)))
    (is (= (atom? 'Harry) true))
    (is (= (atom? (car '(Harry had a heap of apples))) true))
    (is (= (atom? (car (cdr '(swing low sweet cherry oat)))) true)))
  (testing "returns false"
    (is (= false (atom? '())))
    (is (= false (atom? '(a b c))))
    (is (= (atom? '(Harry had a heap of apples)) false))
    (is (= (atom? (cdr '(Harry had a heap of apples))) false))
    (is (= (atom? (car (cdr '(swing (low sweet) cherry oat)))) false))))

(with-test 
  (def listp? 
    (fn [s] 
      (list? s)))
  (testing "returns true"
    (is (= true (listp? '(atom))))
    (is (= true (listp? '(atom? turkey or))))
    (is (= true (listp? '((atom turkey) or))))
    (is (= true (listp? '())))
    (is (= true (listp? '(() () () ())))))
  (testing "returns false"
    (is (= false (listp? 'atom)))
    (is (= false (listp? nil)))))

(with-test
  (def s-expression? 
    (fn [x] 
      (not (nil? x))))
  (testing "returns true"
    (is (= true (s-expression? 'xyz)))
    (is (= true (s-expression? '(x y z))))
    (is (= true (s-expression? '((x y) z))))
    (is (= true (s-expression? '(how are you doing so far))))
    (is (= true (s-expression? '(((how) are) ((you) (doing so)) far)))))
  (testing "returns false"
    (is (= false (s-expression? nil)))))

(with-test
  (def car 
    (fn [x] 
      (first x)))
  (testing "returns s-expression"
    (is (= 'a (car '(a b c))))
    (is (= '(a b c) (car '((a b c) x y z))))
    (is (= '((hotdogs)) (car '(((hotdogs)) (and) (pickle) relish))))
    (is (= '(hotdogs) (car (car '(((hotdogs)) (and)))))))
  (testing "returns nil"
    (is (nil? (car '()))))
  (testing "throws Exception"
    (is (thrown? IllegalArgumentException  (car 'hotdog)))))

(with-test 
  (def cdr 
    (fn [l] 
      (rest l)))
  (testing "returns list"
    (is (= '(b c) (cdr '(a b c))))
    (is (= '(x y z) (cdr '((a b c) x y z))))
    (is (= '() (cdr '(hamburger))))
    (is (= '(t r) (cdr '((x) t r))))
    (is (= '() (cdr '())))
    (is (= (cdr nil) '())))
  (testing "throws Exception"
    (is (thrown? IllegalArgumentException (cdr 'hotdogs)))))

(deftest car-and-cdr-tests
  (is (= '(x y) (car (cdr '((b) (x y) (()))))))
  (is (= '(((c))) (cdr (cdr '((b) (x y) ((c)))))))
  (is (thrown? IllegalArgumentException (cdr (car '(a (b (c)) d))))))

(with-test 
  (def conss 
    (fn [a l] 
      (cons a l)))
  (testing "returns the consed list"
    (is (= '(peanut butter and jelly) (conss 'peanut '(butter and jelly))))
    (is (= '((banana and) peanut butter and jelly) (conss '(banana and) '(peanut butter and jelly))))
    (is (= '(((help) this) is very ((hard) to learn)) (conss '((help) this) '(is very ((hard) to learn)))))
    (is (= '((a b (c))) (conss '(a b (c)) '())))
    (is (= '(a) (conss 'a '()))))
  (testing "throws Exception"
    (is (thrown? IllegalArgumentException (conss '() 'a)))
    (is (thrown? IllegalArgumentException (conss 'a 'b)))))

(deftest cons-and-car-and-cdr-tests
  (is (= '(a b) (conss 'a (car '((b) c d)))))
  (is (= '(a c d) (conss 'a (cdr '((b) c d))))))

(with-test 
  (def null? 
    (fn [x] 
      (empty? x)))
  (testing "returns true"
    (is (= true (null? '())))
    (is (= (null? (quote ())) true)))
  (testing "returns false"
    (is (= (null? '(a b c)) false)))
  (testing "throws Exception"
    (is (thrown? IllegalArgumentException (null? 'spaghetti)))))

(with-test
  (def eq? 
    (fn [x y] 
      (if (or
           (and (atom? x)
                (listp? y))
           (and (listp? x)
                (atom? y)))
        (throw (IllegalArgumentException.)) 
        (= x y))))
  (testing "returns true"
    (is (= (eq? 'Harry 'Harry) true))
    (is (= (eq? '() '(strawberry))) true)
    (is (= (eq? (car '(Mary had a little lamb)) 'Mary)))
    (is (= (eq? (car '(beans beans)) (car (cdr '(beans beans)))) true)))
  (testing "returns false"
    (is (= (eq? 'margarine 'butter) false))
    (is (= (eq? 6 7)) false))
  (testing "throws Exception"
    (is (thrown? IllegalArgumentException (eq? (cdr '(soured milk)) 'milk)))
    (is (thrown? IllegalArgumentException (eq? 'milk (cdr '(soured milk)))))))

My Journey Into Deep Work – Retrospective Week 13

Come and learn what I’ve learned! I haven’t posted my retrospectives in a while. Last week was the first week that I had fully to myself and I challenged myself to establish a solid deep work routine at home. Here are some of the things that worked, that were okay and some that didn’t work.

Retrospective Week 13 – A total of 13 hours completed.

What worked:

  • I got 13 hours of fully concentrated work in. Awesome! I built myself a custom Scoreboard, too, to keep track of each day’s work-hours.
  • I felt productive.
  • Started and finished a fully functional Minimum Viable Product called “RedditGrowth” which helps identify trending subreddits that show sustained growth. A simple market research tool for Reddit, basically.
  • Creating a backlog, physically with stickies and virtually with Trello worked really well to structure and slice down my work-items
  • I used Pomodoros the full week. That made concentrating easier and less exhausting.
  • I rewarded myself for staying focussed with a 30 minute break after work. I took a nap, watched a movie or just chilled.
  • I made myself an idea backlog.
  • I built myself a standing desk and it felt good to focus yet not sit.
  • With a simple, physical “Todo -> Doing -> Done” system I always felt in control.
  • I used my awesome WASD mechanical keyboard which made me feel really cool.
  • I finally got to make a dream come true and code a web-application in Clojure.
  • I wrote my own little DSL for “Given, When, Then”, cucumber-style integration tests.
  • I pushed the app to Heroku and learned how to use multiple buildpacks for one app because I needed to have custom apt packages installed for running the linear regression. Once I figured out how to do it, it worked really well.
  • I wasted far less time on Facebook, Instagram etc. by adding blocking rules directly on my router.

Check out RedditGrowth as the result of this week’s work!

]

Behind the scenes, in case you’re interested, my Trello board:

What went so-so

  • I didn’t get as much writing done as I had planned to. My action item here is to establish a TinyHabit for it instead.
  • I charged ahead and built a product for myself. Not sure if anyone else cares about it but I think it’s pretty cool.
  • Getting up in the morning got harder towards Friday. Not sure why, but I couldn’t fall asleep at night. Probably because I didn’t spend insane amounts of energy.
  • I spent a lot of time at home by myself because I set myself up with a home office. So far I like it and it makes me productive but I have to make sure that I get outside at least once a day.
  • Because all other time-wasting sites like Facebook and News are blocked, I spent a lot of time on Reddit (which wasn’t blocked because my MVP needed access to it.)
  • I forgot to celebrate each completed Pomodoro sometimes. Rewards are super important to settle into the new habit and so I want to make sure I reward myself more immediately this week.

What didn’t (yet) work so well

  • I felt a sharp drop in productivity during the afternoons.
  • I haven’t been biking as much as I used to the week before.

Action Items:

  • Celebrate each Pomodoro!
  • Clean up my done tasks from last week
  • Plan my lunch-time better so that I can overcome the concentration slump at around 1:30pm
  • Recap and organize my goals, epics and backlog. Basically do an IPM Monday morning.
  • Find a new, lovely project to work on now that the MVP is built.
  • Start creating a blogging habit

Well, thanks for reading. If you have any questions how to implement Deep Work in your life, feel free to reach out at alexis dot rondeau at gmail dot com.

Week 5 – Logbook: My Journey Into Deep Work

Strategizing is easy. Executing is really hard. In his book “Deep Work”, Cal Newport recommends to make use of the 4 Disciplines of Execution to get work done and improve your process along the way.

The 4 Disciplines of Execution are:

First, have a wildly important goal (As in my case: “Deeply understand and absorb Customer Development as taught by Steve Blank”)

Second, act on those (lead) measures that you have direct control over (As in my case “Hours spent fully focused on this topic”)

Third, keep track of your daily progress with a scoreboard (I have a sheet of paper where I track every minute of focused work)

Fourth, create a weekly cadence of accountability to reflect and improve (As in my case: A Retrospective at the end of the week)

Given this context, I would like to share with you my results from this weeks’ Deep Work accountability session.

But first some high-level information:

When and how much did I work?

With my scoreboard, I was able to track 6.75h of Deep Work this week. It is 5% less than the week before (7h).

  • Monday: 2h
  • Tuesday: 1.5h
  • Wednesday: 15m
  • Thursday: 1.5h
  • Friday: 0h
  • Saturday: 0h
  • Sunday: 1.5h

I am still proud about this achievement even it is the lowest amount of focused work I’ve done since I started 5 weeks ago. I am proud of it because my regular full-time work at Pivotal Labs has started again and I got the flu on Friday.

In general, I have gotten up at 5:00 - 5:15am to get going. My morning routine has changed slightly, too. I have come back to practice Yoga again instead of writing morningpages. I felt that 26 weeks of daily writing was enough for now.

You may already see some oddities here. Wednesday I barely had time in the morning to sit down. I did a quick Anki recall session but it was very short. On Friday I couldn’t clock in any time because, as it turned out throughout the day, I got the flu and needed rest. Saturday and Sunday were to be my regular days off but on Sunday I felt better and had the energy to put in some work. It turned out to be good.

What went well?

The Scoreboard helped me keep track This is the first week that I feel that the scoreboard helped me become aware how outside influences impact my morning routine. Also, the scoreboard was crucial to do a retrospective like this one because I would, otherwise, likely have forgotten what happened this week.

Planning ahead what and how I’ll work was crucial When I made a quick list of how I was going to spend the 1.5h beforehand, it was much easier for me to start a timer and dive into the work. In best case, I had made that plan the day before, but even just scribbling down a bullet list of tasks at the outset of the morning session helped to take my mind off planning and focus better.

Made progress on the course and book I feel like I have made solid, if a little slow, progress on the course and book. I am still trying to figure out the best rhythm between reading, taking notes and recalling facts. I started to notice my own speed of learning and what works good for me.

I was able to better reason about product and customer development at work. As a consultant it’s important to have my facts straight. In several instances I was able to apply my new learnings and past experience to help my clients understand and solve their issues.

I started my days with Yoga again While somewhat tangential to the time spent focusing, it felt great to start the day with breathing, asanas, relaxation and a short meditation again. While I only had 30 minutes, a short practice session still gave me more focus and calmness.

My kitchen-timer keeps me focused With the recommendation to split the time up into more manageable chunks of time, all I really need is a $5 kitchen timer. I’m amazed at how effective this little plastic tool is.

“Oh, hey! I can use some of my weekend mornings, too!” Structure is good for me. As it turns out, I felt happier throughout the week than during my usually unstructured, free-flowing weekends. So, I’ve decided to add a pinch of deep work schedule on Saturday and Sunday just because it makes me feel good.

What went okay?

Here are a few things that were “okay” or came up as questions. Not really bad or good, just sort of “Hm?”.

1.5 hours in the morning seem to be the practical maximum. Given that getting up at 5 is already pretty hard, and given that I want to shower, stretch, meditate and eat, 1.5h hours is a practical maximum before I have to head to work. It’s not good or bad, just a clear limit to my set-up.

Am I learning to slow? So, I set out to learn (about) Customer Development and just had the feeling that I wasn’t moving as fast as I could/should/would bla. I guess, I’m still getting used to this whole thing, so it’s too early to tell. But of course I want to know everything NOW!

How does such a schedule work with a partner? This is a question I wonder about. As a single I am in the position to completely command my time spent. Which is great. But how does it work when there is a lovely partner with me? Is it sensible to keep up such a strict regimen? Is it possible?

What has been my output? I feel like I haven’t produced much for others besides these blog-posts that are sort of meta to the whole experience. Then again, I have been able to pin-point clients to very specific Customer Development ideas and concepts to help them understand how to approach new customers.

Little time for breakfast and getting ready. I have to really get up at 5:15am latest to be able to get everything done. Breakfast is somewhat hurried and I usually wind up with 10 minutes to get ready for my day. It’s not ideal yet but also no deal-breaker.

What went bad?

Looking back, what didn’t go well and what can I improve upon this week?

Even just one drink in the evening throws my morning off. I’m not a huge fan of drinking anyways but it was significantly harder to get out of bed early on Wednesday and Friday because of drinks the night before. The main learning here for me is to really be careful when I go to town. It’s fun sometimes but it has its implications on my ability to get up and concentrate the next day.

Learning is not practicing. I am proud to have learned a lot, in an academic sense. But I am also not yet at the point where I have tackled the hard stuff “by hand.” In case of Customer Development, there is much I can learn about it but the hard work comes when you actually ‘get out of the building’. These are the skills I truly want to learn and master. And that takes practice not mere learning. (Learning is important to practice, but it’s just a step).

To mitigate this issue, I have looked to Josh Kaufman’s “The First 20 Hours” which is a great book to learn how to practice.

What am I working on?

The main focus of my work in the morning has been to learn and deeply understand Steve Blank’s Customer Development processes. For this, I have started to take his Course “How To Build a Startup” and have done most exercises and suggested reading. Since the video lectures are relatively short, most of my time was spent reading, annotating, transcribing and memorizing the key-facts from his book “The Startup Owner’s Manual.” I have also started to deconstruct the book “Business Model Generation” alongside. My goal here is to really get into this original work and better understand where I made mistakes in the past, make better decisions in the future and better serve my clients at work.

With this in mind, here is my assessment of what went well, okay and bad this week as I continued to learn and establish my concentrated practice:

--

Wow, so there you have it. A recap of last week’s working on my own early in the morning. I have learned a bunch about myself already and I am looking forward to continuing.

If you have any questions yourself, please feel free to contact me here or on my blog.

My Journey Into Deep Work

Three weeks ago, my colleague Oleksii Fedorov mentioned that “adults are able to deeply work for about 4 hours per day.”

Something clicked in my brain. Deeply working? Deep work? I hadn’t heard the use of deep and work in the same sentence in years. I was curious. What is this deep work? And why are there only 4 hours of it per day?

I’ve felt so distracted and confused and frustrated for so years. Even before I moved to Berlin I would, after work, just go home and do nothing. A vicious cycle of depleted willpower and bad habits developed. Sure, I longed for an exciting, creative life with every cell of my body. But I ended up on my couch surfing the web, Facebook, Instagram, Hacker News and Reddit for hours. I would continue to do so until I was tired. My life had slowly emptied itself from meaning and wonder. I felt exhausted and deeply distracted. I felt like I was stuck. Trapped in a cycle of sleep, work, couch. I felt hopeless.

Cal Newport’s book Deep Work had the answer to the question I was too distracted to even ask:

“How can I be happy again and feel a depth and appreciation of my creative and professional life?”

With Cal Newport’s book I have re-created space and time for Deep Work. It has helped me regain a sense of focus, growth and creativity that I have missed for years.

What is Deep Work?

  1. Deep Work is the ability to quickly learn and master hard things and then produce tangible results that others value at an elite quality and speed.
  2. The ability to do Deep Work is rare and valuable in today’s economy. In a default state where everyone is distracted with “shallow” (low-value, high-stimuli tasks that are easily replicated) tasks, the missing link is to focus on “deep” (high-value, low-stimuli) tasks. To thrive, Deep Work is a competitive advantage that a knowledge worker like myself must develop.
  3. Deep Work means to apply a craftsman’s approach to your work. It doesn’t matter what the work is but how one approaches it. I felt stuck in my work and complained that “This isn’t my passion” while at the same time I could not point you to what my passion was otherwise. As it turns out, focusing on turning your profession into a craft, appreciating it and improving your skill over time through active, deliberate practice, will create a sense of wonder and happiness that the quest for the “job of passion”, if it exists, will not produce. The key to happiness at work isn’t to work a rare and special job but to bring a rarified approach to one’s work whatever it may be. Side note: Newport has an excellent book on this that I am currently devouring: “So good they can’t ignore you.”
  4. Deep Work can be incorporated in my daily life. I realized that my feeble attempts to “do stuff after work” never took roots because at that point in the day my resources for willpower were depleted. Instead, I have decided to front-load a daily session of working deeply in the morning just before heading out for work.
  5. Having supporting structure and a plan (even if it changes) for my deep work is crucial. Willpower and focus is limited and distractions, the lack of structure and ambiguity siphon off precious glucose molecules (the raw material of focus) from the work itself.

What have I worked on deeply?

The first (meta) skill that I wanted to deeply learn and master has been to learn how to focus again and to learn how to learn hard things quickly. For this I intensely studied, practiced and rehearsed

  1. Everything there is to know about “Deep Work” itself
  2. The craftsmanship approach through “So Good They Can’t Ignore You”, also by Cal Newport
  3. How to approach new scientific concepts and ideas with “A Mind For Numbers” by Barbara Oakley, Ph.D.

How did I incorporate Deep Work into my day?

In the past 2 weeks I created myself a simple structure where I worked right in the morning for 2 hours with full attention and focus.

I already had a daily ritual to write 2-3 handwritten pages after breakfast for the past (!) 26 weeks. This made it easy to introduce deep work right after the existing writing routine. This meant, after I finished writing my “morningpages”, I launched into a 1.5-2h deep work session. Monday through Friday.

Then I followed the book and implemented the following changes:

  1. I decided on a deep work schedule strategy: The “Rhythmic Scheduling Strategy” where I allocate time every day to work deeply. I have found that I am the sharpest in the morning and so I have scheduled my deep work time in the hours before heading to work.
  2. I created myself an environment, a clean table, a good desk lamp, a comfortable chair and snacks to support me during the work.
  3. I used a kitchen-timer to keep track of the 25-minute focus sprints and short breaks in between. This was particularly important for me because my attention has been so shot that knowing that the intense focus will eventually end helps.
  4. I rewarded myself for every 25 minutes of focus with a quick attaboy such as “You’re doing great!”
  5. After each 25 minute session I got up, streched, ate some fruit. To embed a new habit, especially a low-stimuli one like concentrated work, it is crucial to be generous with rewards even if they feel silly at first. I’ve made myself a sticky note right in front of my workspace that reads “CELEBRATE EVERYTHING.” It’s doing a good job.
  6. I shut off any internet notifications and noises. Sometimes a classical playlist from Spotify plays in the background.
  7. I set myself a “wildly important goal” – Which is to learn how work deeply in order to apply it to the topics that I am professionally interested in (Customer Development, Software Craftsmanship). While the last 2 weeks were sort of “meta” in that I focused on the skill of deep work in order to do deep work on other things, I believe it was absolutely the right way to start.
  8. I put up a scoreboard. I kept track of every minute that I worked with full focus. In week 1 I scored 10 hours and in the past week I scored 9 hours of uninterrupted focused work.
  9. I created a schedule for the coming day every night in order to create structure and not waste willpower on having to figure that out every day anew.
  10. To quickly learn and master this skill of deep work and focused attention, I learned to use Anki and spaced repetition to capture, rehearse and ultimately remember facts and ideas from several non-fiction books.
  11. I recapped each week’s work on Saturday. I evaluated what worked and what didn’t work. How my flow was and where I lost concentration. I then planned small changes that would support me better in the coming week. For example, I learned that by the 4th “Pomodoro” (25-minute session), I struggled to concentrate. I realized that eating a piece of fruit, like an apple, just before helped give me focus again.

What was challenging?

Following Newport’s Rule #2 “Embrace Boredom” has been incredibly challenging for me. “Embrace Boredom” means to fight the urges to give in to low-value, high-stimuli indulgences like “The Internet”. The problem aren’t sites like Facebook or Instagram themselves (although they have sucked more hours from life than TV at this point). It’s the constant switching of attention that costs focus. Needless to say, before I started Deep Work, I was switching HARD.

The problem is: You can deeply work as much as you want but it’s not going to work if you feed your brain junk. High-stimuli, low-value tasks like checking the internet compulsively or watching YouTube videos or the news have been hard to quit. Really hard.

To mitigate this risk, I installed a website blocker on my phone to fight my trained routine response to boredom. I am however still struggling with scheduling internet access at home.

To help myself with weaning off from the the urge to distract myself, I also bought a really cool toy, an “Addict-a-ball” that I propped on my couch. Now, whenever I sit on my couch now and usually would have picked up my phone to check any and all internet (and lose an hour and not realizing) I now pick up the “Addict-a-ball” and play with it. Since it’s a high-stimuli game, I feel quiet entertained by it. It definitely has helped me deal with the withdrawal.

What’s next?

Next up is the challenge to continue my deep work before work (and at work) with a regular 40 hour full time job. I am confident I can do it because I study the topics I teach at work: Make something people want! I expect there will be significant synergies but there is also the reality of working before work.

I also started to be absent from any social media for the month of January and believe this will be a challenge to the habit of “just checking Facebook and Instagram to brighten up boring moments in my life.”

Deep Work has been an immensely rewarding journey so far. I have learned so much about myself, my life, my habits and my creativity. It hasn’t always been easy but I feel confident it has already changed me for the better.

Finally. If you are curious or would like to learn more about Deep Work, I highly recommend you get the print copy of “DEEP WORK – Cal Newport” and “A Mind For Numbers” by Barbara Oakley, Ph.D., like, today.

I am also happy to help you if you get stuck with implementing the structure in your life. It isn’t easy but it isn’t as hard as it may first seem.

Thanks

I would not have stumbled across “Deep Work” unless my awesome colleague Olekssi Fedorov had mentioned it. Clearly, I thank Cal Newport for writing the book and making it so clear and easy how to create Deep Work in my own life. I want to thank Chris Castiglione for giving me a good idea of what the tangible results of Deep Work can look like. He has consistently created great work with his podcast “On Books” and his classes at OneMonth that have led him to great places and people. My friend Marc Petri who recently showed me Sun Ra’s businesscards from the 50’s. To come up with a punch-line such as “Beta Music for Beta People”, you have to deeply love your work. Thank you.

The Weekend

The weekend was a good one.

I very much enjoyed it, especially because I got to spend time with Volker and Chris together last night. We went out, first Chris and I met up and had Pizza at the cool place right by the canal. It took a while until the food came and we were both a little tired but eventually we ate, drank and enjoyed the time together, talking, rambling. Then at some point Volker called, he’s currently alone at home because his baby momma and his son are in Italy on vacation, and about an hour later, he joined Chris and I. During that time, Johannes, a mutual friend of Volker and I also came by and we sat down on the bridge among many young and old people who were already sitting there, and we talked and laughed and the sun set and it got dark and we drank beer in the warm summer night. Then, we learned that there was a birthday party just a few minutes away and we got everyone together, walked there, spent some time and played bocci-ball. I wasn’t the most happening scene, although people were nice and all, and then Volker said he had heard of yet another birthday party and we took off to go to that one.

Now, it was around 11pm if I remember correctly. We walked over into Neu-Koelln and tried to find the place that Google maps had located but it turned out that there were two streets in Berlin with the same name “Weserstrasse” – The one we were supposed to be at, where the two girls had their birthday party, was actually in Friedrichshain! So, not much time to think, we decided to make the hike from where we were and head over to F’Hain. Since Chris and I both had our bikes and Volker was there by foot, Volker jumped on the back-seat with Chris and we rode quickly towards the Baumgarten-Bridge. Chris’ bike made a bunch of funny sounds because it is an old bike and not used to carrying two people’s weight. When we got to the bridge we saw hundreds of people partying in the street, it got so crowded. We crossed the bridge meandering between lots of people and at the foot of the bridge decided we would better take a right-turn to go into F’Hain via the Gaertnerstrassen-Bridge to the East instead of trying to go via Warschauer Strasse where more people were one the street than I had ever seen. So, at this point, Volker jumped on my back-seat and he sat side-ways which I wasn’t sure if it would work but it turned out that it’s a very efficient way to drive and I rode the bike and it felt almost as if I was alone because he didn’t add much weight. So we drove to the East and then, right on the crossing of where I work during the week, we took a left and headed up the street, over the bridge, past Boxhagener Platz and towards the bar we were supposed to be at. The name of the bar was something with “Teddy” and we soon found it, locked our bikes and walked in.

Volker introduced us to two very cute young ladies, one whose birthday it was and one of her friends and it was obvious how stoked they were that Volker (and his friends) took the long ride to come and see them. There were other people in the bar and I think some of them were friends of the girls but we weren’t introduced. Then we got ourselves beers, and Chris and I stood outside for a moment to just chill and talk about writing and the world. It felt good, the air was still completely warm, it was a great night to be out in the streets of Berlin. Eventually, Volker also came out and we sat ourselves on one of the tables right in front of the bar and chatted. At some point I had the idea to play with an iPhone game called “Heads Up” where you place the phone on your forehead, it shows, for example the name of a movie, and the others have to explain to me what that movie is without mentioning the title. We had great fun, first we did movie titles and then we did accents and because we had had a second round of beers at that point, we were jovially laughing and genuinely having a good time. Especially with the accents since they’re a lot of fun and hard to get right. The game recouperated our spirits and we felt awake and alive from all the laughing and gesturing and shouting. That was a lot of fun. Then, the second birthday girl, Eloise I believe was her name, came and sat with us and we spoke about how she knows Philip Glass and that made me listen carefully because I love his music and also I think I would very much like him as a person if I met him. Our group grew and 2 more people joined us and it was a quiet night now, the conversations deeper and we all enjoyed it tremendously.

4 New Things I Have Noticed About Berlin

I would like to share a summary of my first impressions of Berlin with you. I have had a great first week. I worked. I walked around the city. I spent time with friends.

Here is what I’ve noticed:

People are friendlier than I expected

This is the biggest surprise to me. Having spent weeks here before, I was expecting people to be grumpy, especially during winter. “People don’t smile here” I thought I remembered. This time around however I have had very positive moments with strangers. In coffee shops. On the subway. At work. They actually smiled! And made light conversations!

Having had those positive interactions with strangers has definitely made a difference for me. I feel comfortable asking people without having to expect to deal with much negativity. If you had asked me what to look out for when going to Berlin if you’re coming from New York, it would have been ‘the people and their attitude’. Today, I will say that you should not worry about them and instead strike up a fun conversation.

The city changes and grows faster than before

Ever since my first stay it is clear: Berlin is changing. This time around, change and growth have accelerated. The city looks more modern, cleaner, more organized than ever before. Berlin seems richer. Berlin seems more planned. Designed. Berlin used to be “Young”. Now it’s also “Professional”. It feels like it is moving into a bright future now. While it felt it was shedding its skin for two decades, trying to reinvent itself, now it is coming into its own.

Winter in Berlin is cold and beautiful

I was expecting to be turned off by the perpetual overcast sky but I have found the city to be very charming even without the sun for most of the day. It has been really cold and I recommend to bring your warmest coat if you ever are planning to visit in early January. So as long as you’re warm, make sure you go and explore the city. You can take the subway from anywhere to anywhere.

If you like coffee, you’ll love Berlin

I’ve been binging on a lot of coffee since I got here. Pretty much any coffee tends to be stronger more flavorful than what you can get on the streets of New York. And there is little fanfare around coffee. So, even the dedicated coffee shops are not pretentious. They just make good coffee and give it to you for money. So, I’m pretty excited about going out more, getting more coffee with old and new friends. Get a solid caffeine jolt.

I am happy to write so many good things because, honestly, I’ve had my troubles with Berlin on prior stays. It was too easy for me to feel lonely and disconnected. Even while having friends close-by. Also, the scale and strangeness of the city has intimidated me before. I worried if I could settle in for a few months. If it would be too different coming from New York.

A week in, my concerns are mostly gone. Berlin has space. And interesting people you can talk to. It changes before your eyes. The winter keeps you on your toes. And then, a cup of good coffee will pull it all together for you.

Use the Force, Luke! 3 Effective Breathing Techniques For Decision-Makers

Volume 1 of A Short Course for the Use of Your Nervous System According to the Instructions of the Manufacturers

Welcome!

The better you know how to breathe, the better you can perform the mental activities of your day.

If you spend a lot of time making decisions and solving hard problems with your mind, having access to simple techniques like these will help you stay focussed, keep your calm and guide your thoughts towards your goals and aspirations.

Personally, what I always loved about these techniques is that I can adjust my current mental state rapidly to what I need it to be depending on the situation and challenge ahead.

It is like an app-store for your mind!

For example:

  1. If you have trouble focussing, breathing deeply will get your focus back in mere seconds.
  2. If you feel stressed out, alternating your breath between your left and right nostril will take off the edge quickly.
  3. If thoughts crowd your mind and you need to make a decision, practicing one-minute breath will help you rapidly control your mind.

These techniques exist.

They’re easy to learn.

Yet, until recently these techniques were kept secret. You are at the fore-front of learning how to train like a Jedi!

In the coming days, I would like to teach you 3 essential Kundalini Yoga breathing techniques that I have personally tested and validated their benefits over extended periods of time. I will introduce you to each technique individually and provide you with a simple set of homework exercises respectively.

The goal for me is to show you simple, easy and effective techniques that you can easily incorporate into your daily life.

The real Jedi-Training

Kundalini Yoga is the closest we have to real Jedi-Training.

Historically, Kundalini Yoga is considered the most powerful, most comprehensive and effective yogic school in existence. In practical terms, the techniques taught in Kundalini Yoga are designed to rapidly affect the two control-systems in your body: Your nervous and hormonal system.

Originating in the north-indian region of Punjab, and passed on through the centuries within the Sikh culture. Its techniques were kept strictly secret until recently.

In 1969, Kundalini Yoga and Meditation was first openly taught in the West by Harbhajan Singh Khalsa as a very accessible way to feel better, think better and make better decisions.

It is the only Yogic school that is taught “within society.” This means the techniques I will teach you were designed **for people who have a real life, run businesses, and have a social and a family life to attend to.

Kundalini Yoga is free of “magical mystery mumbo-jumbo” and instead provides a straight-forward approach to utilizing millennia-old yogic techniques to deal with the challenges of our times.

It is for people who want to increase their decision-making ability to increase their personal success and the success of the people around them.

Lastly, Kundalini Yoga does not require you to “believe” in anything else but your personal success. It is practiced and taught very matter-of-factly. Again, if your day-to-day is spent making decisions and solving hard problems you’ll gain an advantage having these tools in your tool-belt.

Setting your mind

First things first.

Let’s set you up for success with these 3 techniques.

The first thing I will teach you is to mentally prepare yourself to benefit at a maximum from these and future breathing techniques. When you have the right mind-set, it will be easier for you to get the most out of the other techniques.

This first part is considered a Psycho-Cybernetic exercise in which you “pre-experience” your desired outcome by imagination. When given vivid mental scenarios, your nervous system can not distinguish between what is real and what is imagined. We will be using this opportunity to pre-program an ideal outcome before moving on to the actual techniques.

This type of pre-experiencing a desired outcome is common in sports psychology to maximize the success of the actual practice.

Instructions

To kick-start your learning process, set aside 3 minutes and read the following section carefully. While you are reading it, mentally form a detailed picture of yourself acting out the instructions. Use your imagination to the fullest and enjoy the process.

Notice that this is a mental exercise and you are not required to physically act-out the instructions just yet. In the next sections, I will instruct you to implement the actual techniques but for the this first part all you have to do is use your imagination.

  • Imagine yourself sitting on a comfortable chair in a quiet room.
  • See your feet planted firmly on the floor. Your feet and legs feel alert and relaxed.
  • See yourself turning off your phone and any other distractions around you.
  • See yourself straightening your spine.
  • Notice how the muscles of your back stay relaxed.
  • Notice that your chest, your shoulders, your arms and your face relax.
  • See yourself sitting calmly with your focus on your breath.
  • See yourself breathing deeply and without effort.
  • Notice how you feel confident about your breathing.
  • Observe yourself staying focussed and staying free of distractions.
  • See yourself experiencing a sense of success and accomplishment.
  • See yourself calm and clear-headed.
  • See yourself bringing this calmness and clear-headedness into your work day.
  • See yourself calmly thinking and evaluating options.
  • See yourself finding solutions to hard problems.
  • See yourself staying calm in the midst of a stressful work day.

Your homework for the next 3 days

For the next 3 days, find 3 minutes and re-read and mentally rehearse the preceding list carefully.

While you are reading it, create a clear and sharp mental picture of yourself. Increase the fidelity, the sights, sounds and feelings with every session.

While you can continue giving the techniques a spin, I highly recommend doing this prep-work beforehand.

Next steps

Now that you have prepared your mind-set correctly, you are ready to move on the actual techniques.

In the following parts, we will look at 3 specific breathing techniques. With your mind-set prepared correctly, I am certain that you will quickly pick up the practice.

I recommend you to learn one technique for a few days instead of rushing through all of them at once.

1. Increase your focus with Deep Breathing

Deep breathing is an essential yogic technique that underlies all others.

It is a simple technique but it also is still possible to do it wrong. I want you to know the exact way to do it right. Deep breathing will rapidly relax your body and calm your mind.

After just a minute of deep breathing you will notice a significant improvement in how you think and feel about yourself, your environment and your challenges ahead.

And, as a little a teaser, there is a trick to breathing deeper that you most likely do not know.

Instructions

Here is how to prepare your Deep Breathing session:

  1. Sit up and straighten your spine.
  2. Place your feet firmly on the ground.
  3. Slightly tilt your pelvis forward to further elongate your spine.
  4. Gently lift your chest to allow your belly to relax.
  5. Relax your shoulders.
  6. Relax your face.
  7. Close your eyes.

For the next moments I want you to observe your breath without manipulating it. If your breath is currently shallow, that’s okay. Give yourself 10–20 seconds for this observation.

Start deep breathing through your nose on your next EXHALE:

  1. Begin by gently relaxing your upper lungs letting your breath flow out.
  2. Continue your exhale by gently squeezing your ribcage from top to bottom.
  3. Continue your exhale by slowly pulling in your navel towards your spine pushing out more air.
  4. Finish your exhale by pulling your navel just one or two more inches further towards your spine.
  5. To begin your inhale, relax the muscles around your navel, ribcage and shoulders.
  6. Let air naturally and without effort flow into your abdominal region, let your belly expand.
  7. Continue your inhale by letting your ribcage fill and expand itself.
  8. Finish your inhale by letting your upper lungs fill and expand. It’s easy to tense up a bit here, so mentally remind yourself to relax here.
  9. Repeat by starting at step 1.
  10. Finish your session by holding in your last inhale for 3–5 seconds.
  11. Exhale and relax for 10 seconds.

Your homework for the next 3 days

Day 1

  • Set aside 3 minutes and re-read the instructions above.
  • Begin with 10 seconds of observing your current breath without manipulation.
  • Complete 5 deep breaths using the instructions with your eyes closed.

Day 2:

  • Set aside 3 minutes and re-read the instructions above.
  • Begin with 10 seconds of observing your current breath without manipulation.
  • Complete 10 deep breaths using the instructions with your eyes closed.

Day 3:

  • Set aside 5 minutes and re-read the instructions above.
  • Begin with 10 seconds of observing your current breath without manipulation.
  • Complete 15 deep breaths using the instructions with your eyes closed.

Notes

The exhale is done “mechanically.” That is to say, you will use the power of the muscles of your upper chest, the muscles around your ribcage and the muscles of your abdomen to squeeze out the air from your lungs. You start at the top of your lungs and finish with your abdomen and navel.

The inhale should happen “effortlessly.” That is to say, try to relax the muscles around your lungs and let air flow in. You start inhaling into your abdomen and finish at the top of your lungs.

2. Make better, more rational decisions with Alternate Nostril Breathing

When your mind is clear and your emotions calm you can observe a situation from all angles and make your best decision.

When you feel stressed and emotionally crowded it is much harder to make an objective decision.

This technique will help reset your thinking/feeling system within a minute or two. This is one of my personal all-time favorite ways to feel better when things get crazy and I have to make a clear decision. Alternate nostril breathing is easy and can be done pretty much anywhere and anytime.

I can’t wait to show you this one.

Instructions

Here is how to prepare your alternate nostril breathing session:

  1. Sit up and straighten your spine.
  2. Place your feet firmly on the ground.
  3. Slightly tilt your pelvis forward to further elongate your spine.
  4. Gently lift your chest to allow your belly to relax.
  5. Relax your shoulders.
  6. Relax your face.
  7. Close your eyes.

After giving yourself a few seconds to settle into this position, place your left hand on your left thigh. The fingers of your left hand are relaxed.

Now bring your right hand towards your face. The fingers of your right hand are together and your fingertips point towards the ceiling.

To practice Alternate Nostril breathing do this:

  1. Your INHALE: Place the soft padding of your right thumb under your right nostril to block it off and deeply inhale through your left nostril.
  2. Your EXHALE: Use your right pinky to gently block off your left nostril. Blocking off your left nostril will direct all the air of your exhale to exit through your right nostril.
  3. Repeat: INHALE through your LEFT nostril and EXHALE through your RIGHT nostril.
  4. Continue for 1–3 minutes.
  5. To finish up, exhale completely and hold your breath out for 3–5 seconds. The relax for a few seconds.

Your homework for the next 3 days

Day 1:

  • Set aside 3 minutes and re-read the instructions above.
  • Begin with 10 seconds of observing your current breath without manipulation.
  • Complete 10 rounds of alternate nostril breathing with your eyes closed.

Day 2:

  • Set aside 3 minutes and re-read the instructions above.
  • Begin with 10 seconds of observing your current breath without manipulation.
  • Complete 15 rounds of alternate nostril breathing with your eyes closed.

Day 3:

  • Set aside 3 minutes and re-read the instructions above.
  • Begin with 10 seconds of observing your current breath without manipulation.
  • Complete 20 rounds of alternate nostril breathing with your eyes closed.

Notes

One of your nostrils is usually more stuffed than the other. If you feel you’re not getting air in or out fast enough, quickly blow your nose before a session.

Re-use the deep breathing technique you learned earlier to really get the most out of this one.

When you use your pinky to block your left nostril, be gentle but ensure that you block off air-flow completely.

When you use the soft padding of your thumb to block off your right nostril, place it under the opening. You will notice it fits nicely.

3. Learn how to control your mind with One-Minute Breath

Here is a challenge.

With the two preceding techniques under your belt, it’s time to step up your game.

Our mind produces hundreds of thoughts per minute (and that’s a good thing.) However, only when you have a steering-wheel you can guide and direct your thoughts towards the goals you have in your professional and personal life. Learning to do the one-minute breath will allow you to rapidly gain control over your thoughts in hectic and stressful times.

Technically speaking, breathing at the rate of one breath per minute develops cooperation between the hemispheres of the brain, brings the mind under control and releases worry and anxieties.

Another cool thing is that like Deep Breathing, it’s pretty easy to do without anyone around you noticing you’re doing it. So, here is another really cool stealth technique for you.

A heads-up

In practice, the goal of a One-Minute Breath is to segment your breath into three 20-second partitions:

  • Inhale for 20 seconds
  • Hold your breath in for 20 second
  • Exhale for 20 seconds

However, this takes real practice and can be overwhelming the first few times. So, to make it easier for you to learn, we will begin with smaller partitions starting at 3 seconds each and gradually increase over time.

Instructions

Here is how to prepare your one-minute breath session:

  1. Sit up and straighten your spine.
  2. Place your feet firmly on the ground.
  3. Slightly tilt your pelvis forward to further elongate your spine.
  4. Gently lift your chest to allow your belly to relax.
  5. Relax your shoulders.
  6. Relax your face.
  7. Close your eyes.

For the next moments I want you to observe your breath without manipulating it. If your breath is currently shallow, that’s okay. Give yourself 10 seconds for this observation.

  1. Slowly inhale through your nose for 5 seconds.
  2. Suspend your breath for 5 seconds, lifting your chest and relaxing your shoulders.
  3. Slowly exhale through your nose for 5 seconds.
  4. Without pausing, inhale through your nose 5–6 seconds
  5. Suspend your breath for 5–6 seconds, lifting your chest and relaxing your shoulders.
  6. Slowly exhale through your nose for 5–6 seconds.
  7. Continue this cycle for 1–3 minutes while gradually increasing the length of each breath respectively.
  8. To finish, inhale deeply, hold your breath for 3 seconds, exhale and relax for a few more seconds.

Your homework for the coming 3 days

Day 1:

  • Set aside 3 minutes and re-read the instructions above.
  • Begin with 10 seconds of observing your current breath without manipulation.
  • Complete 5 rounds of one-minute breath starting at 5-second partitions and working up towards 8 seconds.

Day 2:

  • Set aside 3 minutes and re-read the instructions above.
  • Begin with 10 seconds of observing your current breath without manipulation.
  • Complete 10 rounds of one-minute breath starting at 5-second partitions and working up towards 8 seconds.

Day 3:

  • Set aside 3 minutes and re-read the instructions above.
  • Begin with 10 seconds of observing your current breath without manipulation.
  • Complete 20 rounds of one-minute breath starting at 5-second partitions and working up towards 10 seconds.

Notes

On suspending your breath:

It’s easy to tense up around your shoulders when suspending your breath. I know I still do sometimes. So, remind yourself periodically to relax your shoulders.

If you really feel like you’re running out of air, you can always inhale a few more ‘sips’ to make it easier and take away the tension.

The tip of the iceberg

What you have learned is the tip of the ice-berg.

There are hundreds more Kundalini Yoga breathing and meditation techniques that, just like an app-store for your mind, can benefit you immensely when tackling the inner and outer challenges you face today and tomorrow.

You now know how to…

  1. Optimize your practice by pre-programming your mind for success
  2. Regain focus and clarity using Deep Breathing
  3. Overcome stress and anxieties using Alternate Nostril Breathing
  4. Learn to control your thoughts using One-Minute Breath

With a little bit of practice, I am confident these techniques can serve you well as they have served me and prepare you for learning more.

Finally, if you have followed this short course and want to learn more or have questions, I would love to hear from you. Please email me atalexis.rondeau@gmail.com or comment below.

Thank you and with best wishes,

Alexis Rondeau

Do the Right Things Right

The odds are 3 to 1 against you, so how will you make sure you win?

I would like to share a simple map on how Understanding (What to do to succeed) and Skill (How to do things correctly) work either for or against you in your quest to personal and professional success.

(Right now, I am learning a lot after having done the right things in the wrong order in a recent venture.)

But, learning is good, so let me indulge you in my failures and successes alike and provide you with a map that will hopefully make sailing smoother for you.

1. The North-Eastern Land of Milk and Honey: Doing the Right Things Right

The best-case scenario (aptly colored in green in our map.)

You’ve done your research and you’ve practiced your skill-set. You’ve gained an understanding of what the right steps are and you’ve deeply learned how to do them right.

For example: You know that, to start a business, you want to talk to customers to understand their pain. You understand the premise of it. Plus, you’ve done your research about how to do these customer interviews correctly! You’ve read up on how to avoid leading questions, and that talking to your potential customers actually means listening most of the time.

There is a very good chance you’ll learn something of value for yourself and create the success you seek.

2. The South-Eastern Mountains of Jon Snow: Doing the Right Things Wrong

One of the two “better” worse-case scenarios (because you’ll at least learn a little bit if you are lucky, but likely you’ll still fail)

“You know you want to do the right thing but you know nothing on how to do it.”

For example: You understand how important it is to talk to customers. You’ve read high-level blog posts about how to find them and gotten a few leads. Unfortunately, you did not spend any time learning how to talk to them. So, instead of listening, you wind up pitching your idea and receive luke-warm enthusiasm and a bunch of maybes. You tried to do the right thing (talk to customers) but wound up sweating the technique. This will likely kill your startup. Not right now but in the future.

3. The North-Western Desert of Confusion: Doing the Wrong Things Right

Another one of the “better” worse-case scenarios (because you’ll at least learn a little bit):

“You’re really good at it but it still doesn’t work.”

For example: You didn’t read about listening to customers first but instead plowed through (months) of learning to code up web-applications. At this point you can build anything and so you do. An idea pops into your head, you go full-force on it without considering “who” would actually use it. It’s a great idea. You mom thinks it’s a sure winner. And because you’re skilled, you build this thing with all the latest hoo-ha’s the market has to offer. It’s a TDDNoSQLAgileScalaHerokuSSL of a beast. It works and it will scale to millions of users.

But they never come. Because you did the wrong thing. Albeit, technically, you did it well. It’s a sad story.

4. The South-Western Swamps of Ignorance: Doing the Wrong Things Wrong

This one is arguably the worst. You’re uninformed about what your first step should be and you do not have the skills to execute.

You’re screwed.

You “think” that starting a startup today means that, just like Zuck in The Social Network, you bang your fingers (or head) against a keyboard just long enough until, magically, someone throws $100k at you (while you’re wearing a bathrobe.)

Then, after a bit more banging against your keyboard, mysteriously, millions of users flock to your thing. And although you don’t even know how to code or how to deploy to a server your company is valued at billions of dollar. It’s all magic. Just like in the movies. Except it isn’t.

If you do the wrong things incorrectly, you’ll wind up with nothing, not even a solid lesson or two. You’ll have to completely revisit how you think about this stuff.

How to Increase Your Chance of Success

Whatever your doing right now–be it starting a company, trying to do a better job at work, improving your lifestyle–you can increase your odds of success knowing about the map above.

Broaden Your Horizon

Increasing your understanding means you have to broaden your horizon.

Aim to deeply understand the place you’re trying to reach. Understand the dynamics and its life-cycles. You can’t learn enough, always strive to learn more and vaster. Cover a lot of ground. Read books, blogs, newsletters, watch videos, listen to podcasts and talk to experienced entrepreneurs and practitioners. Never stop learning more.

Sharpen your skills

Sharpening your skills means you want to go really deep and master a skill.

Because, even when you know the right things to do, you’ll still need to make sure you’re doing them right.

Learn a skill and get really deep into it. Become the reigning expert on it. For example, if you want to be the technical person, learn to program and then implement a couple of projects end-to-end. From the first line of code to the finishing touches on running it in a production environment.

Final words

First of all, thank you for reading this. Clearly, this isn’t a complete theory. But I’ve been using it regularly now to monitor what I am doing against my personal success metrics.

My examples have been around technology entrepreneurship but I think it can be applied to other fields of interest: Love, sex, education, diets.

How do you navigate yourself to success? Share your experience in the comments below.

Huddle Metrics

Dear Friends,

It’s been an exciting journey and you are literally the first ones to learn about this.

I would like to share with what my friend Adrian and I have been working on.

It’s called “Huddle Metrics” and basically it let’s you safely share and compare the important numbers in your life with other people in a similar place.

To kick off with an example on how these “Huddles” can help you make better decisions, I’ve created one all around rent and roommates in Brooklyn.

I’ll explain it in detail below and I think you will like it:

Do you live with roommates in Brooklyn?

Do you spend a significant portion of your income on rent and utilities?

Would you like to know what’s market in your neighborhood?

This “Huddle” is a safe place to share and compare your own monthly rent with everyone else’s. All you need to do is provide your own rent and utilities anonymously. Then you get to see what everyone else is paying. Filter, slice and dice rent by square footage, the neighborhood, and how many roommates there are.

Why join? Having access to “real data” allows you to make better decisions for your next move. By joining this Huddle you’ll get a better understanding of the roommate rent market in Brooklyn. In particular, when enough people have joined, you’ll be able to learn what’s market in a neighborhood you’ve been maybe eyeing to move to.

So, here is what you need to do to get started if you would like to join:

* First, check out this demo to get an idea how this works. * Secondly, if you like what you’re seeing, you should sign up! * Lastly, the more people join, the more data you get. If you dig it, please share this link with your Brooklyn friends.

Happy Huddlin’!

Alexis

PS: Feedback, questions are absolutely welcome! Please feel free to comment here or send me an email to alexis.rondeau@gmail.com.