Archive

Uncategorized

Intro

This post is meant to document my current understanding of how to build a form using the Elm programming language.

 

Select a File

The following code shows a form for selecting a file:

view : Model -> Html Msg
view model =
    Html.form []
        [ p [] [ text "Upload your song in MP3 format:" ]
        , input [ type_ "text" ] []
        , input [ type_ "file", name "user-song" ] []
        , br [] []
        , input [ type_ "submit", value "Upload" ] []
        ]

Here’s the result:

Elmform1

Label and Textbox

The following code demonstrates one way to associate a textbox to a label:

view model =
    Html.form []
        [ label [] [ text "Age:", input [ type_ "text", name "age" ] [] ]
        ]

Here’s the result:

ElmLabelInput

Labels and Radio Buttons

The following is an example of labels associated to radio buttons:

view model =
    Html.form []
        [ label [] [ text "Gender:" ]
        , input [ id "female", type_ "radio", name "gender", value "f" ] []
        , label [ for "female" ] [ text "Female" ]
        , input [ id "male", type_ "radio", name "gender", value "m" ] []
        , label [ for "male" ] [ text "Male" ]
        ]

Here’s the result:

ElmLabelRadio

Grouping Form Elements

The following code leverages an HTML fieldset to group elements:

view model =
    fieldset []
        [ legend [] [ text "Contact Details" ]
        , label [] [ text "Email:", br [] [], input [ type_ "text", name "email" ] [], br [] [] ]
        , label [] [ text "Mobile:", br [] [], input [ type_ "text", name "mobile" ] [], br [] [] ]
        , label [] [ text "Telephone:", br [] [], input [ type_ "text", name "telephone" ] [] ]
        ]

Here’s the result:

fieldset

Validation

The following code demonstrates validation on required inputs for a form:

view model =
    Html.form []
        [ label [ for "username" ] [ text "UserName:" ]
        , input [ type_ "text", name "username", required True ] []
        , br [] []
        , label [ for "password" ] [ text "Password:" ]
        , input [ type_ "text", name "password", required True ] []
        , input [ type_ "submit", value "Submit" ] []
        ]

Here’s the result:

elmValidation.png

Conclusion

In conclusion, this post attempts to document my current understanding of how to build a form using the Elm programming language.

Today I learned how to implement a method that accepts a variable number of arguments of the same type.

In C#, we use “params” keyword.

In F#, we use the ParamArray attribute.

open System

type MyClass() =

    member this.SomeMethod([<ParamArray>](args:(string*string) array)) = ()
    

let someInstance = MyClass()

someInstance.SomeMethod( ("Table1","Column1"),
                         ("Table2","Column2"),
                         ("Table3","Column3"),
                         ("Table4","Column4") )

The example above demonstrates how an variable number of typed arguments can be passed to a method. The End.

Intro

In this post, I document my understanding of how an F# client can interface with ASP.Net Web API.

Web API (aka: The Server)

The following is my controller:

namespace FnTrade.Server.Controllers
open System
open System.Collections.Generic
open System.Linq
open System.Net.Http
open System.Web.Http
open FnTrade.Server.Models

type TransactionController() =
    inherit ApiController()

    let values = [| { AccountId = "Bizmonger"; Symbol = "TSLA"; Qty = 5  }
                    { AccountId = "Bizmonger"; Symbol = "MSFT"; Qty = 10 }
                    { AccountId = "Scarface" ; Symbol = "ROK" ; Qty = 2  } |]

    member x.Post (shares:Shares) = x.Ok shares

    member x.Get() = values

    member x.Get (id:string) = 
        values |> Array.filter (fun x -> x.AccountId.ToLower() = id.ToLower())

The following is the entity that my controller will work with:

namespace FnTrade.Server.Models

open Newtonsoft.Json

[<CLIMutable>]
type Shares = { 
    AccountId : string
    Symbol    : string
    Qty       : int 
}

C# Style (Old School)

The following would represent the type that I would need to deserialize to:

type Share = { 
    AccountId : string
    Symbol    : string
    Qty       : int 
}

C# is the old school way of accessing data from a REST service.

The following code demonstrates the legacy technique of a Read All:

[<Test>]
let ``WebAPI call for everything`` () =
    
    let client = new HttpClient()
    client.BaseAddress <- Uri("http://localhost:48213/");
    client.DefaultRequestHeaders.Accept.Add(MediaTypeWithQualityHeaderValue("application/json"));

    let response = client.GetAsync("api/transaction").Result;
    if response.IsSuccessStatusCode
    then let result = response.Content.ReadAsStringAsync().Result
         let share = JsonConvert.DeserializeObject<seq<Share>>(result);
         ()
    else failwith "Something bad happened"

The following code demonstrates the legacy technique for accessing data using an argument:

[<Test>]
let ``WebAPI call with argument`` () =
    
    let client = new HttpClient()
    client.BaseAddress <- Uri("http://localhost:48213/");
    client.DefaultRequestHeaders.Accept.Add(MediaTypeWithQualityHeaderValue("application/json"));

    let response = client.GetAsync("api/transaction/bizmonger").Result; // Appended argument
    if response.IsSuccessStatusCode
    then let result = response.Content.ReadAsStringAsync().Result
         let share = JsonConvert.DeserializeObject<seq<Share>>(result);
         ()
    else failwith "Something bad happened"

Type Provider (New School)

F#’s Type Provider is the “cool way” to interface with ASP.NET Web API.

The following is the “cool way” to perform a Read-All:

[<Test>]
let ``Type Provider call for everything`` () =

    Repository.Load "http://localhost:48213/api/transaction"
    |> Array.toList
    |> List.map(fun x -> { AccountId= x.AccountId
                           Symbol=    x.Symbol
                           Qty=       x.Qty })

    |> should equal [{ AccountId = "Bizmonger"; Symbol = "TSLA"; Qty = 5  }
                     { AccountId = "Bizmonger"; Symbol = "MSFT"; Qty = 10 }
                     { AccountId = "Scarface" ; Symbol = "ROK" ; Qty = 2  }]

The following is the “cool way” to perform a Read when supplying an argument:

[<Test>]
let ``Type Provider call with argument`` () =

    let accountId = "bizmonger"
    Repository.Load (sprintf "%s%s" "http://localhost:48213/api/transaction/" accountId)
    |> Array.toList
    |> List.map(fun x -> { AccountId= x.AccountId
                           Symbol=    x.Symbol
                           Qty=       x.Qty })

    |> should equal <| [{ AccountId = "Bizmonger"; Symbol = "TSLA"; Qty = 5  }
                        { AccountId = "Bizmonger"; Symbol = "MSFT"; Qty = 10 }]

Unfortunately, I did not find a “cool way” to post data to a REST server

[<Test>]
let ``WebAPI post`` () =

    let entity = { AccountId = "Bizmonger"; Symbol = "TSLA"; Qty = 5 }
    let json = JsonConvert.SerializeObject(entity)
    let content = new StringContent(json)
    content.Headers.ContentType <- new MediaTypeHeaderValue("application/json")
    
    let client = new HttpClient()
    client.BaseAddress <- Uri("http://localhost:48213/api/");
    let response = client.PostAsync("Transaction", content).Result;
    
    response.IsSuccessStatusCode |> should equal true

Intro



I have been studying Event Sourcing recently and would like to document my understanding. As I understand, Event Sourcing is a technique used as an alternative to a CRUD (i.e. Create, Read, Update, Delete) model. I would like to think of event sourcing as a ledger for recording code execution that ultimately hydrates an aggregate (aka: business entity) into existence. This is an interesting concept because this technique enables a business to observe each event that contributed to the actual state of an aggregate. The events that influence an aggregate’s state is called an Event Stream. An event stream is a set of ordered events that can be “played” to generate an aggregate’s state.

Domain

As I understand, Event Sourcing is an architecture that is reflected within the domain module of an enterprise system. I have attempted to learn Event Sourcing by building a sample banking account program.

The domain is the following:

namespace Domain

module Account =

    (*Types*)    
    type AccountId = AccountId of string
    type FirstName = FirstName of string
    type LastName =  LastName  of string

    type Credentials = { UserId:string; Password:string }

    type Account = {
         AccountId: AccountId
         FirstName: FirstName
         LastName:  LastName
         Balance:   decimal  }

    and Event = 
        | LoggedIn  of Credentials
        | Deposited of balance: decimal
        | Withdrew  of balance: decimal

    (*Functions*)
    let emptyAccount = {
         AccountId= AccountId ""
         FirstName= FirstName ""
         LastName=  LastName  ""
         Balance=   0.00m }

    let getAccount credentials = {
        AccountId= AccountId "myAccountId"
        FirstName= FirstName "Scott"
        LastName= LastName   "Nimrod"
        Balance=  0.00m                    }

    let update = function
        | account , LoggedIn  credentials ->   getAccount credentials
        | account , Deposited balance     -> { account with Balance = account.Balance + balance }
        | account , Withdrew  balance     -> { account with Balance = account.Balance - balance }

    let nextUpdate account event = update (account , event)

Client

I wrote a client to interact with the domain by supplying the domain with a set of events that influences an aggregate’s state.

The client is the following:

    (*Client*)
    let credentials = { UserId="Bizmonger"; Password="MyPassword" }
    let account =       credentials |> getAccount 
    let events =
        [
            LoggedIn  credentials
            Deposited 1000m
            Deposited 5000m
            Withdrew  500m
        ]

    let hydratedAccount = (emptyAccount , events) 
                          ||> List.fold nextUpdate

Replaying events via a fold of the events (i.e. hydratedAccount) is the following:

let hydratedAccount = (emptyAccount , events) 
                      ||> List.fold nextUpdate
> 

val hydratedAccount : Account = {AccountId = AccountId "myAccountId";
                                 FirstName = FirstName "Scott";
                                 LastName = LastName "Nimrod";
                                 Balance = 5500.00M;}

> 

Conclusion

In conclusion, I attempted to document my understanding of Event Sourcing. The code that I provided is an example of how to hydrate an aggregate via an Event Stream. However, this post does not address how events actually get created within the system. I will attempt to address this in my next post.

Intro

This post is the third post within my series of posts regarding the construction of a trading application using Xamarin.Forms and F#. In this post, I share my source code for selling shares of a stock.

User Interface

The following reflects the user-experience for selling a stock:

The following XAML reflects the above UI:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"              xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"              xmlns:manageTrades="clr-namespace:ManageTrades.ViewModels;assembly=ManageTrades"              x:Class="FnTrade.SellPage">

    <Grid Margin="10,5">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
            <RowDefinition Height="auto" />
        </Grid.RowDefinitions>

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>

        <Label Grid.Row="0" Grid.Column="0" Text="{Binding Symbol,     StringFormat='Selling ({0:F0})'}}" FontSize="Large" />
        <Label Grid.Row="2" Grid.Column="0" Text="{Binding Shares,     StringFormat='{0:F0} shares available'}}" FontSize="Medium" HorizontalTextAlignment="Start" HorizontalOptions="Start" />
        <Label Grid.Row="3" Grid.Column="0" Text="{Binding StockPrice, StringFormat='{}{0:c} per share'}}"       FontSize="Medium" HorizontalTextAlignment="Start" HorizontalOptions="Start" />
        <Label Grid.Row="4" Grid.Column="1" Text="{Binding Total,      StringFormat='{}{0:c} Invested'}}" FontSize="Large" HorizontalOptions="Start" />

        <Entry Grid.Row="6" Grid.Column="0" Grid.ColumnSpan="2" Text="{Binding SellQty, Mode=TwoWay}"                 Placeholder="Enter number of shares to sell" HorizontalTextAlignment="Center" Keyboard="Numeric" />

        <Label Grid.Row="7" Grid.Column="1" Text="{Binding SellValue, StringFormat='{}{0:c}'}"                 HorizontalTextAlignment="End" />

        <Button Grid.Row="9" Grid.Column="0" Grid.ColumnSpan="2" Text="Confirm"                  Command="{Binding Confirm}" IsEnabled="{Binding CanSell}" />
    </Grid>

</ContentPage>

Here’s some more UI in regards to the user story of selling shares:

ViewModels

The HomeViewmodel was implemented as follows:

namespace Home.ViewModels

open System.Windows.Input
open Core.IntegrationLogic
open Core.Entities
open Integration.Factories
open Services
open Search
open System.Collections.ObjectModel

type HomeViewModel() as this =

    inherit ViewModelBase()

    let dispatcher = getDispatcher()
    let accountId =  getAccountId()
    let broker =     getBroker() :> IBroker

    let searchCommand =
        DelegateCommand( (fun _ -> this.StockInfo <- getQuote broker this.Symbol) ,                           fun _ -> true) :> ICommand
    let sellCommand =
        DelegateCommand( (fun o -> dispatcher.Sell (o :?> SharesInfo) ) ,
                          fun _ -> true) :> ICommand
    let buyCommand =
        DelegateCommand( (fun o -> dispatcher.Buy  { Owner.AccountId=accountId ; Symbol=o :?> string} ) ,
                          fun _ -> true) :> ICommand

    let mutable symbol = ""
    let mutable stockInfo = None
    let mutable investments = ObservableCollection<SharesInfo>()

    member this.Load() =
        let result = broker.InvestmentsOf accountId
        this.Investments <- ObservableCollection<SharesInfo>(result)

    member this.Symbol
        with get() =      symbol
        and  set(value) = symbol <- value
                          base.NotifyPropertyChanged(<@ this.Symbol @>)
    member this.StockInfo
        with get() =      stockInfo
        and  set(value) = stockInfo <- value
                          base.NotifyPropertyChanged(<@ this.StockInfo @>)
    member this.Investments
        with get() =      investments
        and  set(value) = investments <- value
                          base.NotifyPropertyChanged(<@ this.Investments @>)

    member this.Search = searchCommand
    member this.Sell =   sellCommand
    member this.Buy =    buyCommand

The SellViewModel was implemented as follows:

namespace ManageTrades.ViewModels

open System
open System.Windows.Input
open Core.IntegrationLogic
open Core.Entities
open Integration.Factories
open Services

type SellViewModel(info:SharesInfo) as this =

    inherit ViewModelBase()

    let dispatcher = getDispatcher()
    let accountId =  getAccountId()
    let broker =     getBroker() :> IBroker

    let mutable sellQty = ""
    let mutable canSell = false
    let mutable sellValue = 0m

    let confirm = DelegateCommand( (fun _ -> this.ConfirmSell()) ,
                                    fun _ -> true ) :> ICommand

    member this.Symbol     with get() = info.Shares.Symbol
    member this.Shares     with get() = info.Shares.Qty
    member this.StockPrice with get() = info.PricePerShare
    member this.Total      with get() = ((decimal)info.Shares.Qty * info.PricePerShare)

    member this.SellQty
        with get() =      sellQty
        and  set(value) = sellQty <- value
                          let success , validQty = Int32.TryParse sellQty
                          if  success then this.CanSell <- validQty >  0 &&
                                                           validQty <= this.Shares
                          else this.CanSell <- false
                          this.UpdateSellValue()
                          base.NotifyPropertyChanged(<@ this.SellQty @>)
    member this.SellValue
        with get() =     sellValue
        and set(value) = sellValue <- value
                         base.NotifyPropertyChanged(<@ this.SellValue @>)

    member this.CanSell   with get() =      canSell
                          and  set(value) = canSell <- value
                                            base.NotifyPropertyChanged(<@ this.CanSell @>)
    member this.Confirm = confirm

    member private this.ConfirmSell() =
        if this.CanSell then
            dispatcher.ConfirmSell { AccountId = accountId
                                     Symbol    = this.Symbol
                                     Quantity  = Int32.Parse this.SellQty }

    member private this.UpdateSellValue() =
        let success , validQty = Int32.TryParse sellQty
        if  success
        then this.SellValue <- (decimal)validQty * info.PricePerShare
        else this.SellValue <- 0m

The RequestSellConfirmedViewModel is as follows:

namespace ManageTrades.ViewModels

open Core.IntegrationLogic
open Core.Entities
open Services
open Integration.Factories

type RequestSellConfirmedViewModel(request:RequestInfo) =

    inherit ViewModelBase()

    let broker = getBroker() :> IBroker
    let mutable total = 0m

    member this.Symbol   with get() = request.Symbol
    member this.Quantity with get() = request.Quantity
    member this.Total    with get() =      total
                         and  set(value) = total <- value
                                           base.NotifyPropertyChanged(<@ this.Total @>)
    member this.Load() =
        match broker.GetInfo request.Symbol with
        | Some info -> this.Total <- info.Price * (decimal) request.Quantity
        | None      -> failwith (sprintf "Failed to retrieve stock information for %s" this.Symbol)

Application Logic

My app subscribes to events so that it can manage page navigation:

    public partial class App : Application
    {
        public App()
        {
            InitializeComponent();

            MainPage = new NavigationPage(new HomePage());
        }

        protected override void OnStart()
        {
            getDispatcher().SellRequested +=
                async (s, e) => await MainPage.Navigation.PushAsync(
                    new SellPage(new SellViewModel(e as SharesInfo)));

            getDispatcher().ExecuteSellRequested +=
                async (s, e) => await MainPage.Navigation.PushAsync(
                    new RequestSellConfirmedPage(new RequestSellConfirmedViewModel(e as RequestInfo)));
        }

        protected override void OnSleep() { }
        protected override void OnResume() { }
    }
}

The following are events that are declared within my Dispatcher class:

namespace Services

open System.Diagnostics
open System

type Dispatcher() =

    let sellRequested = new Event<EventHandler<_>,_>()
    let buyRequested =  new Event<EventHandler<_>,_>()
    let confirmSellRequested = new Event<EventHandler<_>,_>()
    let executeSellRequested = new Event<EventHandler<_>,_>()

    [<CLIEvent>]
    member this.SellRequested = sellRequested.Publish
    member this.Sell owner = sellRequested.Trigger(this , owner)

    [<CLIEvent>]
    member this.BuyRequested = buyRequested.Publish
    member this.Buy owner = buyRequested.Trigger(this , owner)

    [<CLIEvent>]
    member this.ConfirmSellRequested = confirmSellRequested.Publish
    member this.ConfirmSell info = confirmSellRequested.Trigger(this , info)

    [<CLIEvent>]
    member this.ExecuteSellRequested = executeSellRequested.Publish
    member this.ExecuteSell info = executeSellRequested.Trigger(this , info)

Domain Types

The following are my domain types:

module Core.Entities

type StockInfo = {
    Symbol  : string
    Price   : decimal
    DayLow  : decimal
    DayHigh : decimal
}

type Shares = {
    AccountId : string
    Symbol    : string
    Qty       : int
}

type SharesInfo ={
    Shares        : Shares
    PricePerShare : decimal
    Total         : decimal
}

type Owner = { AccountId:string ; Symbol:string }

type RequestInfo = {
    AccountId : string
    Symbol    : string
    Quantity  : int
}

type InsufficientFunds = {
    PurchaseAttempt : RequestInfo
    Balance         : decimal
    StockPrice      : decimal
}    

type PurchaseResult =
    | PurchaseRequested of RequestInfo
    | UnknownSymbol     of RequestInfo
    | InvalidQuantity   of RequestInfo
    | InsufficientFunds of InsufficientFunds

type SellResult =
    | SellRequested        of RequestInfo
    | InsufficientQuantity of RequestInfo

Conclusion

The source code to my implementation can be found on GitHub.