Saturday, October 22, 2016

Foreign Key constraint issue, hard to find cause

This hard to figure out issue has popped up from time to time

The DELETE statement conflicted with the REFERENCE constraint "FK_Order_Customer".
The conflict occurred in database "DATABASE", table "dbo.Order", column 'CustomerID'.

Not so much to do with the actual execution of your program, it works for most data but it seems that if a co-worker has manually edited data in the database with Sql Management Studio, there is a possibility that an extra line-break is introduced if the user confirms her edit with the return button.

To find the issue, copy the data and paste it to your favorite text-editor, in between two quotation marks.
Correct data:
'data'
Bad data:
'data
'
Remove the extra line break and you should be good to go.

Of course, good database design should prevent this from happening but sometimes you are stuck with legacy systems and it is good to know that this can happen, especially if you have people manually editing data in the database.

Hope this helps someone out there :)

Saturday, October 8, 2016

Reasoning in Open or Closed models


I've been thinking a lot on how to model knowledge and how to let a system work with it in a programmatic way.

Other articles in the AI Knowledge Based Reasoning series on this site:
Knowledge based reasoning in .net c#
Reasoning in Open or Closed models
Logic Expression evaluation with open-world assumption
Expression evaluation on object based models

Closed-world model

This is where I am at the moment in my thinking and in the coding of my current project. Mostly because it is quite stand forward to implement in code.

public bool Evaluate(expression);

In the closed-world model, everything that you do not find an answer for in your model is assumed to be false.
At first, this seems like a OK thing to do. Assuming that your model covers everything. For example in games, where the AI-engine has access to all information this is the way to go. But in an situation where the model does not cover everything I find it lacking. My current project tries to interface with the real world and when its reasoning returns False on everything that it does not know the end results are quite off the board.

Open-world assumption

So instead of just the boolean result of true or false. In the open-world assumption we introduce a third option, the NotSure result of an evaluation.
public EvaluationResult Evaluate(expression);
public enum EvaluationResult
{
 True,
 False,
 NotSure
}
So far quite easy, just convert your Evaluation method to return NotSure when its not sure.
But the question is, what to do when the system is not sure about something?
Options are:

  • Nothing, just wait until it is sure. Could be OK for systems that receive a lot of information. Just assume that the information missing will arrive at a later date.
  • Formulate a question regarding the missing piece of information. Break the evaluated expression into pieces and find out what was missing and ask a user or two to provide that input.
  • Figure out how much of an expression is unsure. Is it OK to still act on a result with 75% knowledge and 25% gaps? Maybe the AI should figure out the accepted level of certainty by trial and error. 

Conclusions

As I wrote in the beginning. I'm not sure how to implement this kind of reasoning myself. First step in converting the closed-world system that I have now to an open world one is to go by the Nothing approach. Basically just returning NotSure and then not acting on it for starters. Could not be worse than assuming a false falsehood that the system does now.

Sources

https://en.wikipedia.org/wiki/Closed-world_assumption
https://en.wikipedia.org/wiki/Open-world_assumption

WinForms RichTextBox Append Log and UIThread extensions

Turn any RichTextBox in winforms to a log view. Just call rtxt.AppendLog("someString"); and it will append that to a new line in the richtextbox. And scroll it to view.

public static void AppendLog(this RichTextBox rtxt, string s)
{
 rtxt.UIThread(() =>
 {
  rtxt.AppendText($"{s}{Environment.NewLine}");
  rtxt.SelectionLength = 0;
  if (rtxt.Lines.Length > 10000)
  {
   rtxt.Lines = rtxt.Lines.Skip(5000).ToArray();
  }
  rtxt.SelectionStart = rtxt.TextLength;
  rtxt.ScrollToCaret();
 });
}
The above snippet of code requires the following to function correctly.
static public void UIThread(this Control control, Action code)
{
 if (control.InvokeRequired)
 {
  control.BeginInvoke(code);
  return;
 }
 code.Invoke();
}
I can't take credit, found it years ago on some forum somewhere. But here it is anyway. It makes a call to a winforms control synschronize with the GUI thread so that no cross-threading exceptions is thrown. GUI items can only be modified from the GUI thread and this ensures just that.

The exception thrown if correct thread synchronization is not used is: 
System.InvalidOperationException was unhandled
  HResult=-2146233079
  Message=Cross-thread operation not valid: Control 'rtxtOutput' accessed from a thread other than the thread it was created on.
  Source=System.Windows.Forms
  StackTrace:
       at System.Windows.Forms.Control.get_Handle()
       at System.Windows.Forms.TextBoxBase.GetSelectionStartAndLength(Int32& start, Int32& length)
       at System.Windows.Forms.TextBoxBase.set_SelectionLength(Int32 value)
       at System.Windows.Forms.RichTextBox.set_SelectionLength(Int32 value)
       at ave.dev.winform.Form1.ticker_Tick(Object sender, EventArgs e) in C:\tfs\YYY\Form1.cs:line 54
       at ave.dev.winform.Form1._loggerHook_NewLogLine(String s) in C:\tfs\YYY\Form1.cs:line 38


Back to extensions list
Until next time: Work to Live, Don’t Live to Work

Friday, October 7, 2016

Transform string to and from camel case.

Small piece of code to transform a string to and from camel case form. For anyone who find that kind of things useful.

private static readonly char[] Delimeters = {' '}; 
public static string ToCamelCase(string input)
{
 var sb = new StringBuilder();
 input = input.ToLowerInvariant();
 var split = input.Split(Delimeters, StringSplitOptions.RemoveEmptyEntries);
 foreach (var s in split)
 {
  for(int i = 0; i < s.Length; i++)
  {
   var c = s[i];
   sb.Append(i == 0 ? char.ToUpperInvariant(c) : c);
  }
 }
 return sb.ToString().Trim();
}

public static string FromCamelCaseToNormal(string input)
{
 var sb = new StringBuilder();
 foreach (var c in input)
 {
  if (char.IsUpper(c) 
   || char.IsDigit(c))
   sb.Append(" ");
  sb.Append(c);
 }
 return sb.ToString().Trim();
}

Saturday, October 1, 2016

Get random item from a list extension


private static Random _random = new Random();
public static T GetRandom<T>(this List<T> list)
{
    if (list.Count == 0)
        return default(T);
    if (list.Count == 1)
        return list[0];
    return list[_random.Next(0, list.Count)];
}

Very useful in a broad range of scenarios when you want to get a random element from a list.
Just call myList.GetRandom()

Back to extensions list

Until next time: Work to Live, Don’t Live to Work