HOWTO: Publish Your reveal.js Presentations on GitHub Pages

Tags

, , ,

Every now and then I need to publish my presentation on the Web and – of course – each time I have to figure it out. So here is my recipe:

  1. I prepare my presentation on the branch in forked reveal.js repo. For example: this is source code for my talk at 4Developers Conference.
  2. When I’m done, I create new repo with a meaningful name (the name will be part of the url) – mytalk is just an example:

    git init
    git remote add origin https://github.com/username/mytalk
    git checkout -b gh-pages
    git remote add reveal.js https://github.com/username/reveal.js
    git fetch reveal.js
    git merge --ff-only reveal.js/mytalk
    git push -u origin gh-pages
    After some time (needed by GitHub to process repo) my presentation will show up at: http://username.github.io/mytalk/

You can also set custom (sub)domain for GitHub Pages:

  1. Add CNAME record via your DNS provider pointing from mytalk.mydomain.com to username.github.io.
  2. Add CNAME file to your repo (on gh-pages branch) containing single line with your domain (mytalk.mydomain.com). See working example: https://github.com/orient-man/4Dev2015/blob/gh-pages/CNAME

Connect the Dots aka ASCIImage in F#

Tags

, ,

Recently I came across a great blog post introducing ASCIImage program. What does it do?

Given:

. . . . . . . . . . .
. . A B . . . . . . .
. . J # # . . . . . .
. . . # # # . . . . .
. . . . # # # . . . .
. . . . . I # C . . .
. . . . . H # D . . .
. . . . # # # . . . .
. . . # # # . . . . .
. . G # # . . . . . .
. . F E . . . . . . .
. . . . . . . . . . .

Then:

chevron

Yay! Now every programmer can be an icon designer …and it makes for decent F# kata.

We need to connect the dots (denoted by letters) and following rules apply:

  • A single isolated dot encodes 1 pixel
  • A sequence of dots (i.e. consecutive letters: A, B, C…) translates to a polygon
  • A dot repeated four times defines an ellipse
  • Finally, a dot repeated two times defines a line

I decided to introduce some minor format changes. I wanted the input format to be self-contained without the need for providing additional code (i.e. blocks in Objective-C version). Just create a text file, run program and voilà, see the result. I choose to support only black (solid) and white (transparent) shapes. Now letters A..Z encode the former and a..z the latter.

Let’s start with type-first approach:

type Dot = int * int

type Shape =
    | Pixel of Dot
    | Line of Dot * Dot
    | Ellipse of Dot * Dot * Dot * Dot
    | Polygon of Dot list

type Opacity = Solid | Transparent

type ParserApi = string [] -> (Opacity * Shape) list

Our goal is to implement ParserApi function transforming ASCII representation into list of shapes. We can start by extracting dots with their positions (string [] -> ((Dot * Opacity) * int) list):

let ascii2dots (arr : string []) = 
    let (|InRange|_|) first last = function
        | c when c >= first && c <= last -> Some(int(c) - int(first))
        | _ -> None

    [ for y in 0..arr.Length - 1 do
          let row = arr.[y].Replace(" ", "")
          for x in 0..row.Length - 1 do
              match row.[x] with
              | InRange 'A' 'Z' idx -> yield (((x, y), Solid), idx)
              | InRange 'a' 'z' idx -> yield (((x, y), Transparent), idx)
              | _ -> () ]

As you can see, F# features like pattern matching, active patterns (|InRange|) and defining list with “yields” ([ for … ]) make for very concise and readable code.

Let’s pretend that we have an active pattern for every rule. Those patterns would examine the beginning of the list and if matched return one or more dots making the shape, its opacity and the tail – list of unmatched dots. Given that we could write parser in just a few lines:

let rec parse dots = 
    [ match dots with
      | Single(p, op, tail) -> yield op, Pixel(p); yield! parse tail
      | Sequence(points, op, tail) -> yield op, Polygon(points); yield! parse tail
      | Quad(points, op, tail) -> yield op, Ellipse(points); yield! parse tail
      | Duo(points, op, tail)-> yield op, Line(points); yield! parse tail
      | _ -> () ]

let api : ParserApi = fun rep -> rep |> ascii2dots |> List.sortBy snd |> parse

Recursive list definition with yield bang – sweet! And now the time has come for remaining patterns.

The dot is considered “single” if the next one is skipped (e.g. A, C, E…) or is the last one. Piece of cake:

let (|Single|_|) = function
    | ((p, op), i1)::(d2, i2)::tail when i2 = i1 + 2 -> Some(p, op, (d2, i2)::tail)
    | ((p, op), _)::[] -> Some(p, op, [])
    | _ -> None

Patterns for dots repeated 4 or 2 times are also straightforward:

let (|Quad|_|) = function
    | ((p1, op), i1)::((p2, _), i2)::((p3, _), i3)::((p4, _), i4)::tail
        when i1 = i2 && i2 = i3 && i3 = i4 -> Some((p1, p2, p3, p4), op, tail)
    | _ -> None

let (|Duo|_|) = function
    | ((p1, op), i1)::((p2, _), i2)::tail when i1 = i2 -> Some((p1, p2), op, tail)
    | _ -> None

Beware, they must be applied in order.

The most difficult pattern is the sequence because we need to collect unspecified number of consecutive dots:

let (|Sequence|_|) dots =
    let wrapResult points tail =
        match points with
        | (_, op)::_ -> Some(points |> List.map fst |> List.rev, op, tail)
        | [] -> None

    let rec collect acc = function
        | (d1, i1)::(d2, i2)::tail when i2 = i1 + 1 -> collect (d1::acc) ((d2, i2)::tail)
        | Single(p, op, tail) -> wrapResult ((p, op)::acc) tail
        | tail -> wrapResult acc tail

    collect [] dots

That’s all – parser is ready. What’s left is to generate bitmap from list of shapes. But drawing is boring: mostly an API driven code. I’ll show you only the type signature (the rest is on GitHub):

type DrawingApi = Parser.ParserApi -> int -> string [] -> System.Drawing.Bitmap

Given a parser, scale and ASCII representation, DrawingApi implementation should return a bitmap. Drawing module depends only on a parser abstraction. In the composition root (aka main) you tie it together:

open System
open System.IO

let ascii2image inputFile scale =
    let asciiRep = File.ReadAllLines(inputFile)
    // Poor man's dependency injection
    let draw = DrawingImplementation.api ParserImplementation.api
    let bitmap = draw scale asciiRep
    bitmap.Save(inputFile.Replace(".txt", ".png"), System.Drawing.Imaging.ImageFormat.Png)

[<EntryPoint>]
let main = function
    | [|inputFile|] -> ascii2image inputFile 1; 0
    | [|inputFile; scale|] -> ascii2image inputFile (Int32.Parse(scale)); 0
    | _ -> printfn "Example usage: ascii2image file.txt"; -1

You can find full source code on GitHub.

Final thoughts

Code above is twice as long as my first attempt. For example, you could inline all the active patterns and make it one complicated recursive function. But I wanted it to be explicit – no comments, the code should speak for itself.

Oh, almost forgot. Let’s draw some familiar logo🙂

. . H # I A # . . . .
c . K # # d J # # . .
. . . . . b # # # # .
W # # X . . . # # # #
Z # # Y . . . . # # #
A . b . . . . . b # A
R # # S . . . . # # #
U # # T . . . # # # #
. . . . . b # # # # .
f . M # # e N # # . .
. . P # O A # # . . .

devtalk

Exploratory Unit Tests for Ninject

Tags

, , , , ,

I read an excellent book recently, Dependency Injection in .NET by Mark Seeman. Oh boy, I should have read it 2 years ago before I started playing seriously with DI. Dependency Injection looks like an easy concept to grok and what could possibly go wrong? Go figure! Or better read this book. Don’t be misled by title, it’s not only about DI and .NET. Author gives a rather great overview of modern object programming with examples that happen to be in C# but could be in Java or something else.

My DI container of choice is Ninject but unfortunately author doesn’t cover it. I decided to fill this gap and created exploratory unit tests based on code examples from the book:

https://github.com/orient-man/NinjectExploratoryTests

Quote

… is dead

Ostatnio wszystko mi się kojarzy…

Wszystkich w czambuł krytykujemy, zarzucamy im brak poczucia hierarchii wartości, zupełną dezorientację, jeżeli chodzi o plastykę, zamazywania konfliktów i problemów w plastyce istotnych, skrajny prowincjonalizm i nieprawdopodobną malarską ignorancję.

(…) a teorie, że malarz musi być głupi, wówczas były w Polsce nagminne.

(…) byliśmy dla nich naturalnie sztuką przeszłości, skazaną na zagładę. Dzisiaj na zmianę już ci abstrakcjoniści-konstruktywiści są uznani za okopy św. Trójcy przez taszystów, dla których znów konstruktywizm, wcielenie wstecznictwa, zabił sztukę przez zbytni racjonalizm.

Programowanie to sztuka czy inżynieria? Czy inżynierowie dyskutują w ten sposób o budowie mostów?

Wszystkie cytaty z tomu esejów “Patrząc” Józefa Czapskiego.

Quote

TDD By Example: Quotes

Tags

,

From Kent Beck’s book TDD By Example.

We should teach coding in test first manner from the very beginning:

I taught Bethany, my oldest daughter, TDD as her first programming style when she was about age 12. She thinks you can’t type in code unless there is a broken test. The rest of us have to muddle through reminding ourselves to write the tests.

About the role of tester in post-TDD era:

However, if the defect density of test-driven code is low enough, then the role of professional testing will inevitably change from “adult supervision” to something more closely resembling an amplifier for the communication between those who generally have a feeling for what the system should do and those who will make it do.

About the overwhelming fear in pre-TDD era:

Test-driven development is a way of managing fear during programming […]. Fear makes you tentative. Fear makes you want to communicate less. Fear makes you shy away from feedback. Fear makes you grumpy.

Stop it! Learn TDD instead!

Filtering MiniProfiler results with jQuery

Tags

, , , ,

Today I had to optimize a slow running page. We use MiniProfiler which makes finding such issues a breeze. But this time it was a little bit more difficult: MiniProfiler showed over 200 hundred SQL queries. How to find the slow ones? Maybe I miss something but it seems there is no built in way to filter MiniProfiler results. I came up with quick jQuery snippet to do just that:

// show only slow rows (100ms+)
$('.profiler-info div:last-child')
    .filter(function () {
        // all but having 3+ digit times
        return !$(this).text().match(/^\d{3}.*/);
    })
    .parent()
    .parent()
    .hide()     // tr.profiler-odd
    .next()
    .hide();    // tr.profiler-gap-info

Just run it inside browser’s Console window and result should look like this:

filtering-mini-profiler

Git jest git

Tags

W zeszłym tygodniu przeprowadziłem w końcu szkolenie z git’a dla moich “kołorkerów”. Czyrak musiał nabrzmieć. Minął rok odkąd przywlokłem gita z domu do pracy i po cichutku podpiąłem się przez git-svn do centralnego repo. Może i było lekkie zdziwko, skąd nagle 20 commitów w ciągu minuty, ale generalnie to się nie chwaliłem. Nie chciałem spalić tematu i nie czułem jeszcze mocy. Jak już trochę okrzepłem (m.in. dzięki wpisowi Arka), to zacząłem puszczać balony próbne:

  • “Ech, miałoby się git’a to życie stałoby się piękne i nastałaby Światłość”
  • “Odkryłoby się, że istnieją gałęzie i służą nie tylko do robienia rózg”
  • “Bo przecież w svn ich nie ma, prawda?”
  • “Nie trzymałoby się już 2 lub więcej kopii roboczych i nie przerzucało pomiędzy nimi źródłowców jak za króla Ćwieczka”
  • “Nie robiłoby się kopii zapasowych przed svn update jak jakieś zaszczute zwierzę”
  • “Gdyby był git, to historia miałaby sens i już nie powracała jako farsa”
  • “A wymęczony po trzech dniach pracy commit nie zmieniałby 3/4 systemu” (z komentarzem “fixes #666”)

Itp., itd. za te polskie… tysiące. I nawet obiecałem szkolenie, ale minął jeden miesiąc, potem drugi… Aż przyszedł kryzys, nawał roboty, zbliżająca się Ważna Wystawka i już dłużej nie dało rady. Ja tu śmigam jak tarzan po 5 gałęziach jednocześnie a inni się męczą i nawet o tym nie wiedzą. Gorzej! Dobrze im z tym, uśmiechają się, obraza boska po prostu. Więc poszedłem na spontan i zrobiłem szkolenie z marszu na tydzień przed Wystawką.

Postanowiłem skupić się na podstawach a jednocześnie pokazać wszystko (to był chyba błąd). Pierwsze zdaje się zadziałało. Zaczerpnąłem pełnymi garściami z prezentacji “Git For Ages 4 And Up” i tylko podparłem się GitViz’em zamiast tych fajnych kloczuszków. A na koniec miało być pokazanie, że git jest genialny w swojej prostocie także od podszewki – czyli o strukturze repo. Moje nieociosane notatki są dostępne na GitHub’ie.

Podsumowanie

Plusy dodatnie

  • wałkowałem ten graf acykliczny i podstawowe operacje na nim chyba wystarczająco długo (IMHO gdy już to się załapie, to reszta to pikuś)
  • sam chyba też załapałem🙂
  • nigdzie się nie zaciąłem i git mnie nie zawiódł (zawiodła natomiast pierwsza pierwsza komenda cd katalog, która za każdym razem wieszała ConEmu tak, że pomógł tylko restart)
  • publiczność reagowała żywiołowo i chyba przez większość czasu dyskutowaliśmy (gdy spojrzałem potem na historię poleceń to byłem w szoku, że tylko tyle przez 3h nastukałem)

Plusy ujemne

  • zabrakło agendy – gdybym najpierw powiedział punkt po punkcie o czym zamierzam mówić i dlaczego w tej kolejności to nie musiałbym robić tylu dygresji
  • przykłady zmian i komentarze do commit’ów były od czapy (miałem to przygotować, ale zabrakło czasu i na żywca nic sensowniejszego niż “foo bla bla” mi do głowy nie przychodziło)
  • zabrakło wstępu “po co” przed prezentacją bebechów (.git/objects itp.)

Co dalej

Wygląda na to, że przynajmniej w moim projekcie przejdziemy wszyscy najpierw na git-svn, a potem się zobaczy. Obiecałem już prezentację pt. “Git w praktyce” (git-flow i tym podobne).

PS Plusy ujemne zawdzięczam głównie Michałowi Żmijewskiemu, Adamowi Kruszewskiemu i Hubertowi Trzewikowi – wielkie dzięki!

Good Times Bad Times – mixed bag but more on the good side

Tags

, , ,

2013 in numbers

buildstuff

Learning

24 books is much less than 39 in 2012 when I made a resolution to read 1 book per week. I suppose this time I’ll give up. Those 7 “technical” books were:

I realize this is a low number but from the other hand it was compensated with conferences and videos. Anyhow I hope to improve a little bit this time as my “to read” shelf is frighteningly long. Also “read” label doesn’t accurately show my interests. For the whole year I’ve been pursuing 3 goals:

  • Learn Objective-C (“And Now for Something Completely Different” idea)
  • Improve my VIM skills – I’m proudly (Vs)VIM guy🙂
  • Get proficient in git

I’ve been steadily learning & practicing with help from following books:

I’m not finished with them yet but I’m close.

Day job

At work I almost completely moved from old (C++/WebForms) technologies to “new” ones (ASP.NET MVC/JavaScript). I think ASP.NET MVC is the first framework I really know inside out. I had glimpses of how WebForms page cycle works and wrote whole lot of code which I don’t understand now🙂. This pattern repeated in the past with Java and C++/MFC framework. Now I take care more about learning both internals and the big picture. And I prefer simpler things which leads to this year’s epiphany: I fell in love with JavaScript. Although Visual Studio/R#/NCrunch is indeed very powerful combo I tend to use bare bones VIM for JavaScript (with help of tools like Karma/tin.cr). And finally I switched from SVN to git for most of the projects.

I really enjoy our company’s low key attitude and family like atmosphere. My “technical lead” role gave me a lot of fun and opportunities to pursue new ideas. But… things aren’t always bright. It was my 10th anniversary with the company and sometimes I feel burned out. Driving technical change ain’t easy. I did a lot of code reviews and whiteboard talks but gave only one longer presentation – which is a shame. I should have done more pair programming instead of reviews. Conferences and chats with other developers gave me many insights how can I improve on that field in the near future.

Our Great New System appears to be “2+ years rewrite” with overwhelming work still ahead. I wasn’t involved in the decision to go the full rewrite route but finger-pointing doesn’t help. I had some bad experience with 2 years of hacking behind the closed doors at my startup and I could add my two cents. But doing something new without looking back sounded so cool… Maybe I’m too negative. I just need to focus more on “done done” side of things. Remember: “Real artists ship”.

Night shift

I’m done with it. Really done done🙂.

Summary

For me the main theme of 2013 was socializing. I’ve been to six conferences and I plan to beat this number in 2014. I met great people and had a lot of fun. Thank you guys!

socialising

How To Put Your Toe Into ASP.NET MVC Integration Testing

Tags

, ,

Until now we had many excuses for not writing integration tests:

  • we prefer unit tests over integration tests
  • our business logic (aka services) is separated and thoroughly tested
  • we keep our ontrollers on a diet
  • UI consists mostly of standard elements (aka widgets) which are tested on their own
  • we are lazy

But there was still too much space for error. From time to time a seemingly innocent change in Razor view (or HTML helper, or filter, or “something completely irrelevant”) unexpectedly broke one of the pages. If all tests are green why bother starting an app at all? Our main goal is to pass all tests. Or is it?😉

There are many benefits of attending a user group meeting i.e. good excuse to drink beer. But last Thursday on Warsaw .NET User Group I learned[*] the lazy way of integration testing ASP.NET MVC applications. Adam Kosiński showcased the MvcIntegrationTestFramework. It’s probably originated from Steven Sanderson’s post but since then had many mutations and forks on GitHub. One of them is even released as NuGet package. I went for it:


PM> Install-Package FakeHost

Which added two DLLs to my project and then I could write integration tests as simple as follows:

It’s slow, it’s somewhat brittle but relatively concise, works OOTB and thanks to it we found a few bugs already.

[*] I cannot fail to mention Maciej Aniserowicz talk which convinced me that I should have used Nancy instead of ASP.NET MVC in the first place but… it’s to late to apologize😉

Microsoft.Office.Word.Interop.dll or don’t look here if you are lucky and have more interesting things to do

Tags

, ,

I spent a day with Microsoft.Office.Word.Interop.dll and… surprisingly it hurt less than I expected. API is strange but does the job and it somehow improved over the years. I needed to support Word templates with following functionality:

  • repeatedly filling the same field e.g., CompanyName could occur multiple times (unfortunately fields/bookmarks in Word’s template must have a unique names)
  • adding rows to the existing table
  • checkboxes (easy)
  • export to PDF (again easy – Word 2007+ supports it OOTB)

Not exactly rocket science but could be a time saver: https://github.com/orient-man/WordTemplates

Follow

Get every new post delivered to your Inbox.