Bullet points formatter

0

Hey guys,

So this week I worked on a small code kata. The purpose of this project is to simply be able to format text into a bullet point like any text editor allows you to do it. To complete this challenge, I decide to use F# since it’s so great for prototyping and get fast results. The project had the following requirements:

  • Produce an outline of headings
  • Heading values are provided

Here’s an example of what should be printed in console :

  1. Software development is

A. An awesome thing to do

2.  Why do code katas ?

A. They are

i. Entertaining

ii. Challenging

So as we can, we have three different level of formatting to do on the string and heading values are provided for the formatting. Those requirements led to the following code :

code language="fsharp"]
 open System
 open System.Linq 

type Indexes = {
     Primaryint 
     Secondary int
     Third int 
 }
type BulletPointStyle =
     | NumberedStyle 
     | LetteredStyle 

type HeadingWeight = 
     | HW1 
     | HW2 
     | HW3 

type Heading = {
     Weight HeadingWeight
     Text string
 }

type Node = {
     Line Heading 
 }

type Outline = {
     Text string 
     HeadingIndexes Indexes
 }
 with 
     member x.addContent str = { x with Text = x.Text + Environment.NewLine  + str }

let updateIndexes (oOutline) (hHeading) = 
     match h.Weight with 
     | HW1 -> 
         let indexes = { o.HeadingIndexes with Primary = o.HeadingIndexes.Primary + 1Secondary = 1 ;Third = 1 }
         { o with HeadingIndexes = indexes }
     | HW2 -> 
         let indexes = { o.HeadingIndexes with Secondary = o.HeadingIndexes.Secondary + 1Third = 1 }
         { o with HeadingIndexes = indexes }
     | HW3 ->
         let indexes = { o.HeadingIndexes with Third = o.HeadingIndexes.Third + 1 }
         { o with HeadingIndexes = indexes }       

let determineBulletStyle (hwHeadingWeight) = 
     match hw with 
     | HW1 -> NumberedStyle
     | HW2 | HW3 -> LetteredStyle

let getLetter (indexint)=
     (("ABCDEFGHIJKLMNOPQRSTUVWXYZ".[index-1]).ToString())

let formatTextNode(nNode) (oOutline)
     let header = n.Line
     let mutable text = ""
     let style = determineBulletStyle header.Weight
     let indexer = o.HeadingIndexes
     match style with 
     | NumberedStyle -> 
         text <(indexer.Primary.ToString()) + "" + header.Text
     | LetteredStyle -> 
         let head = 
             match header.Weight with 
             | HW2 -> String.Join(""Enumerable.Repeat(" ",4)) + getLetter indexer.Secondary
             | HW3 -> String.Join(""Enumerable.Repeat(" "8)) + String.Join(""Enumerable.Repeat("i"indexer.Third))
             | _ -> ""
          text <head + "" + header.Text 
     text

// Folds an Outline and a list Nodes to an Outline
 let formatTextOutline(nodeListNode list) =
     ( { Text = ""HeadingIndexes = { Primary = 1Secondary = 1Third = 1 } }nodeList) 
     ||> Seq.fold (fun outline node -> 
         let text = formatTextNode node outline
         let outline = outline.addContent text
         updateIndexes outline node.Line
     )

[<EntryPoint>]
 let main argv = 
     let nList = 
         [
              { Line = { Weight = HW1Text = "Software development is" } } 
              { Line ={ Weight = HW2Text = "Super fun" } } 
              { Line ={ Weight = HW3Text = "But challenging" } } 
              { Line ={ Weight = HW3Text = "And rewarding" } }
         ]
     let outline = formatTextOutline nList
     printf "%s" outline.Text
     0 // return an integer exit code

[/code]

So basically, the process is made thanks to formatTextOutline and formatTextNode. Through those functions, I can create the Outline record that holds the formatted text and the indices for the level of formatting (Indexes). When I get in formatTextNode, I can first establish the heading style of the line thanks BulletPointStyle discriminated union(DU) type. Using the style enables me to know if I only have to take care of numbers or the letters. When I have to deal with characters, the HeadingWeight DU becomes handy to see whether or not I’ll be using a single tab (4 spaces) or a 2 tabs (8 spaces).

There you go ! 🙂

Kevin out

Advertisements

Software development challenge

0

Hi,

Yeah, it’s me again ! I’ve been missing writing here, so tonight, I’m going to write more than usual ! During the last few days, I’m been surfing the web and I found something quite fun to follow. There’s this woman, Jennifer Dewalt, which was an artist before. Well, it’s my belief that once you’re something, you can’t really say that you’re not anymore even though you don’t practice it. So let’s say she’s still an artist. That’s not the point. She was into programming but had no background. She decided that reading books or going to boot camps wasn’t her thing and did something else entirely.

She gave herself the challenge to program 180 web sites in 180 days. So basically, 1 web site per day. She started small, using HTML5 and CSS3 and then, as she got more comfortable, started using things like Ruby on Rails (Framework derived from the Ruby programming language) or Backbone.js (Framework derived from the javascript). You can read more about it her blog .

So, it got me thinking. Yeah, I do have some programming experiences, but I haven’t been around for that long and there is so much that I don’t know that I can wait to get to know! Basically, for the moment, I’m really into mobile and web application. I’ve thought about to do 100 days challenge in which I do one application per day in which I’m trying to get better with

  • WinRT & WIndows Phone 8.1 +Universal apps
  • Cross-platform development with Xamarin.Android
  • ASP.NET
  • AngularJS
  • Javascript + Backbone.js

I haven’t pick out the exact day when I’ll be doing this, but I will mention it soon (February maybe). For this challenge, what I am going to do is link every project in my GitHub acocunt. But, I won’t go through every project in this blog. Some, which I’ll try to pick out in order to make most out of the learning experience, will be explained.

Kevin