Wednesday, February 24, 2016

My first hour with prolog (Prolog 101)

I started with prolog and it is hard. It really is!
Here I found a portable "IDE" http://portableapps.com/apps/development/swi-prolog_portable and here a video how to use it: https://www.youtube.com/watch?v=6Dh7eux76a8 .
I created a test project to summarize a list of numbers:
File > Edit > [select a file with following content: *.pl]

sumOfItems([], 0).
sumOfItems([H | T], Output) :-
    sumOfItems(T, OutputInner),
    Output is H + OutputInner.

File > Consult > [select same file]
1 ?- sumOfItems([1,2,3,4,5],X).
X = 15.
... from now on changes to the file are taken over if they were compiled.
To check that I added the following function and compiled:
avgOfItems([], 0).
avgOfItems([H], Result) :-
 Result is H.
avgOfItems([H|T], Result) :-
 avgOfItems(T, ResultInner),
 Result is (H + ResultInner)/2.
avgOfItems was callable...

kind regards,
Daniel

Tuesday, February 23, 2016

Filter DataGrid in C#/WPF using ICollectionView

Today I tried to find a bug in a ICollectionView-based WPF filtering action. The problem was fortunately easy to find, but I was shocked that I didn't find an easy example in our projects to explain my colleague the way how this all works... So, here is my easy example of a grid which can be filtered:

I created a standard WPF project and installed the nuget-package mvvm-light (see: http://www.codeproject.com/Articles/321806/MVVMLight-Hello-World-in-10-Minutes if you don't know the nuget package). Long story short: it provides some base classes and some assets like a relay-command which is useful to start your work without the need of creating boiler-plate code again and again. The mvvmlight's viewmodel-locator is defined as a static resource in app.xaml so you can define view-models (and its instances) centrally using an "inversion of control"-container (called SimpleIoc). Here nothing has to be changed, because it creates a MainViewModel (as an example) we will use to create this sample.
I kept the MainWindow.xaml which was created by default and put the needed controls in there:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<Window x:Class="FilteringGrids.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:FilteringGrids"
        mc:Ignorable="d"
        Title="Filter-Test" Height="350" Width="525"
        DataContext="{Binding Main, Source={StaticResource Locator}}">
    <Grid Margin="10">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="1*" />
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="Auto" />
 
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="1*" />
        </Grid.RowDefinitions>
 
        <TextBox Grid.Row="0" Text="{Binding FilterText}" Margin="0,0,10,10"></TextBox>
        <Button Grid.Row="0" Grid.Column="1" Margin="0,0,10,10" Height="25" Width="50" Command="{Binding RefreshCommand}">Refresh</Button>
        <Button Grid.Row="0" Grid.Column="2" Margin="0,0,0,10" Height="25" Width="50"  Command="{Binding FilterCommand}">Filter</Button>
        <DataGrid Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="3" ItemsSource="{Binding Data}" />
    </Grid>
</Window>

As we can see in line 9: the datacontext is wired up with the viewmodel instance created in the ViewModelLocator, so we can use the paradigm of MVVM. In the following XAML code we bind the text to filter, the data and two buttons to the background viewmodel...


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.CommandWpf;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Data;
using System.Windows.Input;
namespace FilteringGrids.ViewModel
{
    /// <summary>
    /// This class contains properties that the main View can data bind to.
    /// <para>
    /// Use the <strong>mvvminpc</strong> snippet to add bindable properties to this ViewModel.
    /// </para>
    /// <para>
    /// You can also use Blend to data bind with the tool's support.
    /// </para>
    /// <para>
    /// See http://www.galasoft.ch/mvvm
    /// </para>
    /// </summary>
    public class MainViewModel : ViewModelBase
    {
        public class Model
        {
            public string Name { get; set; }
            public string Value1 { get; set; }
            public string Value2 { get; set; }
            public string Value3 { get; set; }
            public string Value4 { get; set; }
        }
        /// <summary>
        /// Initializes a new instance of the MainViewModel class.
        /// </summary>
        public MainViewModel()
        {
            #region Filter
            FilterText = "";
            Predicate<object> filterFunction = (object raw) =>
            {
                Model dataToFilter = raw as Model;
                return
                    dataToFilter.Name.Contains(FilterText) ||
                    dataToFilter.Value1.Contains(FilterText) ||
                    dataToFilter.Value2.Contains(FilterText) ||
                    dataToFilter.Value3.Contains(FilterText) ||
                    dataToFilter.Value4.Contains(FilterText);
            };
            FilterCommand = new RelayCommand(() => DataCollectionView.Refresh(),
                                             () => true);
            #endregion
            #region Init / Refresh
            RefreshCommand = new RelayCommand(() =>
            {
                Data = new List<Model> {
                    new Model() { Name="one",   Value1="1", Value2="1.0", Value3="1.00", Value4="1.000" },
                    new Model() { Name="two",   Value1="2", Value2="2.0", Value3="2.00", Value4="2.000" },
                    new Model() { Name="three", Value1="3", Value2="3.0", Value3="3.00", Value4="3.000" },
                    new Model() { Name="four",  Value1="4", Value2="4.0", Value3="4.00", Value4="4.000" },
                };
                DataCollectionView = CollectionViewSource.GetDefaultView(Data);
                DataCollectionView.Filter = filterFunction;
                this.RaisePropertyChanged("Data");
            }, () => true);
            // init data
            RefreshCommand.Execute(null);
            #endregion
        }
        public string FilterText { get; set; }
        public List<Model> Data { get; set; }
        private ICollectionView DataCollectionView { get; set; }
        public ICommand RefreshCommand { get; set; }
        public ICommand FilterCommand { get; set; }
    }
}


What we see here is that 99% of the magic happens in the constructor of the viewmodel. This is bad style, but keeps the things easy for the example, so please forgive me here. We see here that all members (defined at the end of the class) are bound by the xaml-code except the CollectionView which is used for the actual filtering.
Important here is:

  • if you change the reference of your data source then populate that to the UI (INPC -> RaisePropertyChanged)
  • Filtering over ICollectionView is easily achievable over a Predicate-function
  • recreate the ICollectionView if the original instance of the data changes (you probably don't need a reference to this)
  • if the filter-result might change call CollectionViewInstance.Refresh()

kind regards,
Daniel

Wednesday, February 17, 2016

TableVariables vs. TempTables

Hi,

in short:
- TableVariables don't change the schema, but are also executed in tempdb
- TempTables have statistics in comparison to TableVariables (query fast, costs after change)

I personally use TableVariables more often than TempTables, because I can't forget to drop them :-)


long version:

kind regards,
Daniel

get a random and unique id in a table

Today I created a random ID. The random ID must still be primary key what means that it must be unique. This is a code walk-through to solve this problem:

First of all I created a play-ground to make tests (with 4 test-entries).
declare @tbl TABLE(ID int)
insert into @tbl values (3), (7), (9), (10) 
Then I introduced a parameter to define the scope. Here we see 0 as an error case (no more IDs available) and start with ID 1 to @maxValue.
declare @maxValue int = 10
 Then we create a loop to test the development for example 20 times:
declare @i int = 0
while (@i < 20) begin
The idea now is to create a random value (=myRequestID) and to check whether the ID currently in use (if so, it will be copied to targetID).

    declare @myRequestID int = (cast(   (RAND()*(@maxValue-1))    as int) + 1)
    declare @myTargetID int = 0
    if not exists(select * from @tbl where ID = @myRequestID) begin
            set @myTargetID = @myRequestID
            insert into @tbl values (@myTargetID)
if we have already used this value (it exists in @tbl) then we need to search for an ID after the random value. Therefore we can choose all requested entries after the random value which have no next sibling and return the smallest id + 1
    end else begin      
        select @myTargetID = isnull(MIN(id) + 1, 0) from @tbl t
        where id between @myRequestID and (@maxValue - 1)
        and not exists(select * from @tbl innerT where innerT.ID = t.ID + 1)
if the targetID has a value we found a valid entry, else if the value is zero, we have not found an entry after the random value, so we jump over the maxValue border and restart at the beginning. Here we need to consider that the value 1 is a special case which needs to be handled extraordinary. 
        if @myTargetID <> 0 begin
            insert into @tbl values (@myTargetID)
        end else if not exists(select * from @tbl where ID = 1) begin
            set @myTargetID = 1;
            insert into @tbl values (@myTargetID)
Finally if 1 is already in use we can search for an ID hole from the start to the random value

        end else begin
            select @myTargetID = isnull(MIN(id) + 1, 0) from @tbl t
            where id < @myRequestID
            and not exists(select * from @tbl innerT where innerT.ID = t.ID + 1)
            if @myTargetID <> 0 begin
                insert into @tbl values (@myTargetID)
            end
        end

If no value was found in the end there is probably no hole available and we have no value to return.
        if @myTargetID = 0 begin
            print 'no value'
        end
    end
(end of the loop)
    set @i = @i + 1;
end

kr, Daniel

Tuesday, February 16, 2016

Closures in JavaScript and C#

Hi,

today I dug deeper into the world of javascript closures and found an interesting mozilla.org -page explaining the topic of closures perfectly. I started getting curious about how implementations like in https://jsfiddle.net/v7gjv/ as described in https://developer.mozilla.org/en/docs/Web/JavaScript/Closures#Creating_closures_in_loops_A_common_mistake could look like in C# and whether the same solutions lead to same success.

The problem depicted in the article referenced above is that a closure was used wrongly inside the method "setupHelp".

1
2
3
4
5
6
  for (var i = 0; i < helpText.length; i++) {
    var item = helpText[i];
    document.getElementById(item.id).onfocus = function() {
      showHelp(item.help);
    }
  }

The problem (quote taken over from the article):
The reason for this is that the functions assigned to onfocus are closures; they consist of the function definition and the captured environment from the setupHelp function's scope. Three closures have been created, but each one shares the same single environment. By the time the onfocus callbacks are executed, the loop has run its course and the item variable (shared by all three closures) has been left pointing to the last entry in the helpText list.
In the article a solution was provided. They used a function factory method, but I think the following solution is a bit better (even if it is possibly the same thing, but with less code and without the need of jumping around on the screen; the cleanliness of this solution might be doubted, but I do like this version the most):

1
2
3
4
5
6
7
8
9
  for (var i = 0; i < helpText.length; i++) {
    var item = helpText[i];
    document.getElementById(item.id).onfocus = function() {
      var myItem = item;
      return function() {
       showHelp(myItem.help);
      }
    }();
  }

... here we create an anonymous function on line 3 and call it instantly on line 8 to return an actual event handler (line 5). This function call brings us in a new scope in which we can access the variable from line 2 on line 4 and store it inside of our new scope to use it in line 6 from the event handler.

So... can we have such problems in C#?

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
    class Program
    {
        class MenuItem
        {
            public event EventHandler<EventArgs> onfocus;
            public void Call_onfocus()
            {
                onfocus(this, EventArgs.Empty);
            }
        }

        static void showHelp(string name, string help)
        {
            Console.WriteLine("{0,7}: {1}", name, help);
        }

        static void Main(string[] args)
        {
            var helpText = new List<Tuple<string, string>>{
                new Tuple<string, string>("email", "Your e-mail address"),
                new Tuple<string, string>("name", "Your full name"),
                new Tuple<string, string>("age", "Your age (you must be over 16)"),
            };

            var document = new Dictionary<string, MenuItem>();
            helpText.ForEach(x => document.Add(x.Item1, new MenuItem()));

            for (var i = 0; i < helpText.Count; i++)
            {
                var item = helpText[i];
                document[item.Item1].onfocus += (sender, e) =>
                {
                    showHelp(item.Item1, item.Item2);
                };
            }
            document.ToList().ForEach(x => x.Value.Call_onfocus());
        }
    }

Unfortunately the version that breaks in javascript works just fine in C#. So I needed to change a bit in the for-loop to demonstrate the problem...

1
2
3
4
5
6
7
            for (var i = 0; i < helpText.Count; i++)
            {
                document[helpText[i].Item1].onfocus += (sender, e) =>
                {
                    showHelp(helpText[i].Item1, helpText[i].Item2);
                };
            }

The for-loop now accesses the array directly and here we are... out-of-range-exception,.. boom... because i is 3 when the Call_onfocus (line 36 in the listing above) calls the event calling showHelp (line 5).

Now we know, that the problem is also a real-world problem in .NET environments. Can we now take over the way to fix the issue in javascript to the C# world? It would be helpful to know one working solution for two (or all kind of) different worlds.

I was able to do so, but I admit the solution is a bit ... let's say: different.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
            for (var i = 0; i < helpText.Count; i++)
            {
                document[helpText[i].Item1].onfocus += (
                    new Func<EventHandler<EventArgs>>(
                        () =>
                        {
                            var myItem = i;
                            return (sender, e) => {
                                showHelp(helpText[myItem].Item1, 
                                         helpText[myItem].Item2);
                            };
                        })());
            }

... as we can see here: I reused the solution of listing #2 and stored the changing value into a newly created scope I created by writing an ad-hoc function I instantly call.

The good things here are that we are not limited to pass in data through event args and minimize the lines of code/number of declared functions, but to be honest I would not recommend to use this kind of hoax too much...

kind regards,
Daniel

Wednesday, February 3, 2016

writing an executable in javascipt

Hi,

today I played around with javascript and its possibilities. To execute js in the browser was a quite non-innovative approach. That windows-8/10 apps can be written in js was also not new to me.The missing element to cover all kinds of applications was the desktop application. After 10 seconds of google-ing I found out that this works too. Even better, it works in combination with the .net framework which opens up a lot of possibilities.

The following code snippets show my test case. The resources I used were: http://www.phpied.com/make-your-javascript-a-windows-exe/ and additionally to check for the ability to use WPF components (yes that works too) https://social.msdn.microsoft.com/Forums/vstudio/en-US/bb41013f-e915-4743-81b0-8bea2d9acebb/jscriptnet-wpf?forum=netfxjscript .

make.bat
@echo off
del program.exe
"c:\Windows\Microsoft.NET\Framework\v4.0.30319\jsc" "program.js"
program.exe

program.js
import System;
import System.Windows.Forms;
function outputMessageBox(text) {
 MessageBox.Show(text, "output message");
};
 
function output(text) {
 Console.Write(text);
};
 
output('hello world');
outputMessageBox('hi');


I am looking forward to find a use case for it :-)

kind regards,
Daniel