Phillip Trelford's Array

POKE 36879,255

.Net Developer – Opportunities to work with F#

Are you a high performing Developer looking to use the latest technologies? Perhaps you want to be more than just a cog in the wheel, playing an integral part in high level projects? Or maybe you are looking for a company that puts an emphasis on work life balance? If so we would be keen to hear from you.

What you’ll be doing

We are currently looking for a passionate Developer to join the front end team. Working as part of a high performing team, the role will involve

· Working as part of one of the three software teams at Trayport, you’ll develop top-of-class trading software – both front ends and servers

· Having the responsibility and flexibility to choose and develop tools and technology required to meet the goals of the product owner

· Working on a range of features and products, producing top quality tested code and having a say in all areas across the business

· Innovating new product features

· Taking an active role in all stages of development including the analysis of business requirements, planning, implementation and delivery.

· Producing high quality code with automated tests

You…

We are looking for candidates who have a mix of being able to work effectively as part of a team while at the same time being passionate about coding. The ability and willingness to pick up new technologies is paramount and you will be rewarded with the chance to work on some exciting projects. The successful candidate will be;

· Enthusiastic about designing and building exceptional software.

· Skilled with C#, .NET and / or C++ and have knowledge of design patterns, algorithms and data structures.

· Want to work with a team of talented technologists who will challenge and inspire you

Us…..

· Have a track record of delivering the software that powers energy trading.

· Offer a great benefits package including healthcare, gym membership, profit share and a well-stocked kitchen.

· Hold regular social events for the whole company, including an annual weekend away.

Why work for us

Not only will you be working on the latest technologies (.Net 4.5, C++11, F#), you will be part of a team of talented technologists who will challenge and inspire you. You will be working in a relaxed environment, taking part in regular tech talks and attending top conferences.

If this sounds like you, please forward your CV ASAP to discuss further.

Trayport

Trayport was founded in 1993 and now has 200 employees, but we’re still proud of our small company feel. Our range of clients spans household energy companies, banks, hedge-funds and regulation bodies – providing Windows-based front-ends and servers to facilitate all aspects of trading. We’re moving to top-class offices in a great City location soon – if you’re interested in what you’ve read, apply today by letting us know how you can help shape our future.

Fixed Width Data Files

Scanning over Alvin Ashcraft’s excellent Morning Dew (a must read for .Net devs as is Chris Alcock’s Morning Brew), I came across a short article from Richard Carr on writing Fixed Width Data Files using C#.

Richard creates a class that inherits from StreamWriter, and all-in it’s just over 50 lines of idiomatic C# code:

using System;
using System.IO;
using System.Text;

public class FixedWidthWriter : StreamWriter
{
    public int[] Widths { get; set; }

    public char NonDataCharacter { get; set; }

    public FixedWidthWriter(
          int[] widths, string path, bool append, Encoding encoding)
        : base(path, append, encoding)
    {
        NonDataCharacter = ' ';
        Widths = widths;
    }

    public FixedWidthWriter(int[] widths, string file)
        : this(widths, file, false, Encoding.UTF8) { }

    public FixedWidthWriter(int[] widths, string file, bool append)
        : this(widths, file, append, Encoding.UTF8) { }

    public void WriteLine(string[] data)
    {
        if (data.Length > Widths.Length)
            throw new 
                InvalidOperationException("The data has too many elements.");

        for (int i = 0; i < data.Length; i++)
        {
            WriteField(data[i], Widths[i]);
        }
        WriteLine();
    }

    private void WriteField(string datum, int width)
    {
        char[] characters = datum.ToCharArray();
        if (characters.Length > width)
        {
            Write(characters, 0, width);
        }
        else
        {
            Write(characters);
            Write(new string(NonDataCharacter, width - characters.Length));
        }
    }
}

As you’d probably guess the same functionality takes half the lines to express in F#:

open System
open System.IO
open System.Text

type FixedWidthWriter(widths:int[], path:string, append, encoding) =
    inherit StreamWriter(path, append, encoding)
    member val Widths = widths with get, set
    member val NonDataCharacter = ' '  with get, set
    new(widths, file) = 
        new FixedWidthWriter(widths, file, false, Encoding.UTF8)
    new(widths, file, append) =
        new FixedWidthWriter(widths, file, append, Encoding.UTF8)
    member this.WriteLine(data:string[]) =
        if data.Length > this.Widths.Length
        then invalidOp "The data has too many elements."
        for i = 0 to data.Length-1 do      
            this.WriteField(data.[i], this.Widths.[i])
        base.WriteLine()
    member private this.WriteField(datum:string, width) =
        let xs = datum.ToCharArray()
        if xs.Length > width
        then base.Write(xs, 0, width)
        else        
            base.Write(xs)
            base.Write(String(this.NonDataCharacter, width - xs.Length))

The C# implementation uses classes and inheritance. In F# we’d typically favour composition over inheritance and start with the simplest possible thing that works, which in this case is a function that takes a file path, widths and the lines to write:

let WriteFixedWidth (path:string) (widths:int[]) (lines:string[] seq) =
    let pad = ' '
    use stream = new StreamWriter(path)
    let WriteField (datum:string) width =
        let xs = datum.ToCharArray()
        if xs.Length > width
        then stream.Write(xs, 0, width)
        else        
            stream.Write(xs)
            stream.Write(String(pad, width - xs.Length))
    for line in lines do
        for i = 0 to widths.Length-1 do 
            WriteField line.[i] widths.[i]
        stream.WriteLine()

The function is about half the size again and more closely follows YAGNI. To test it we can simply write:

let widths = [|20; 7; 6|]
[
[|"Company"; "Spend"; "Rating"|]
[|"Quality Foods Limited"; "1000000"; "Gold"|]
[|"The Pieman"; "50000"; "Silver"|]
[|"Bill's Fruit and Veg"; "10000"; "Bronze"|]
]
|> WriteFixedWidth "c:\\test.txt" widths

Does the language you chose make a difference?

Fractal Zoom in Colour

A few years back I put together a simple Fractal Zoom in Silverlight using gray scales.

Time for a little makeover with color:


Hold down the mouse button over the Mandelbrot and move the mouse to highlight a rectangle, then release the mouse button to zoom in on that area.

Implementation

To get a nice colour progression I used the HSB color circle:

let H,S,L = 0.95 + (10.0 * n), 0.6, 0.5

Then created a colour lookup table using a list comprehension:

[|for i in 0..maxIteration ->
    let n = float i / float maxIteration
    let H,S,L = 0.95 + (10.0 * n), 0.6, 0.5
    let H = H - floor H
    let r,g,b = RGB.FromHSL(H,S,L)
    0xff000000 + (r <<< 16) + (g <<< 8) + b|]

For the HSL to RGB conversion I converted Colin Eberhardt’s accepted Stack Overflow answer from C# to F#:

C# F#
double v;
double r, g, b;
if (A > 1.0)
A = 1.0;

r = L;   // default to gray
g = L;
b = L;
v = 
   (L <= 0.5) 
   ? (L * (1.0 + S)) 
   : (L + S - L * S);
if (v > 0)
{
    double m;
    double sv;
    int sextant;
    double fract, vsf, mid1, mid2;

    m = L + L - v;
    sv = (v - m) / v;
    H *= 6.0;
    sextant = (int)H;
    fract = H - sextant;
    vsf = v * sv * fract;
    mid1 = m + vsf;
    mid2 = v - vsf;
    switch (sextant)
    {
       case 0:
        r = v;
        g = mid1;
        b = m;
        break;
       case 1:
        r = mid2;
        g = v;
        b = m;
        break;
       case 2:
        r = m;
        g = v;
        b = mid1;
        break;
       case 3:
        r = m;
        g = mid2;
        b = v;
        break;
       case 4:
        r = mid1;
        g = m;
        b = v;
        break;
       case 5:
        r = v;
        g = m;
        b = mid2;
        break;
    }
}
ColorRGB rgb = new ColorRGB();
rgb.R = Convert.ToByte(r * 255.0f);
rgb.G = Convert.ToByte(g * 255.0f);
rgb.B = Convert.ToByte(b * 255.0f);
rgb.A = Convert.ToByte(A * 255.0f);
return rgb;
let v = 
    if (L <= 0.5) 
    then (L * (1.0 + S)) 
    else (L + S - L * S)
if v > 0.0 then                
    let m = L + L - v;
    let sv = (v - m) / v;
    let H = H * 6.0;
    let sextant = int H
    let fract = H - float sextant
    let vsf = v * sv * fract;
    let mid1 = m + vsf;
    let mid2 = v - vsf;
    match sextant with
    | 0 -> v, mid1, m
    | 1 -> mid2, v, m
    | 2 -> m, v, mid1
    | 3 -> m, mid2, v
    | 4 -> mid1, m, v
    | 5 -> v, m, mid2
    | _ -> L, L, L
else L, L, L
|> fun (r,g,b) –> 
   byte(r*255.),
   byte(g*255.),
   byte(b*255.)

Voila, happy zooming :)