diff --git a/DigitDisplay.sln b/DigitDisplay.sln index bd2b6a4..9842dc5 100644 --- a/DigitDisplay.sln +++ b/DigitDisplay.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25123.0 +# Visual Studio 15 +VisualStudioVersion = 15.0.27130.2010 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DigitDisplay", "DigitDisplay\DigitDisplay.csproj", "{8E1C0000-6DD5-42E0-8DAD-D75AF1FC249F}" EndProject @@ -13,6 +13,8 @@ Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FunctionalRecognizer", "Fun EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Recognizer", "Recognizer\Recognizer.csproj", "{F15E6F19-7B0D-48A5-B505-7C9658D208CC}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ObservationLoader", "ObservationLoader\ObservationLoader.csproj", "{301EC918-D5E6-4C89-9CD0-84C35FC7413C}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -39,8 +41,15 @@ Global {F15E6F19-7B0D-48A5-B505-7C9658D208CC}.Debug|Any CPU.Build.0 = Debug|Any CPU {F15E6F19-7B0D-48A5-B505-7C9658D208CC}.Release|Any CPU.ActiveCfg = Release|Any CPU {F15E6F19-7B0D-48A5-B505-7C9658D208CC}.Release|Any CPU.Build.0 = Release|Any CPU + {301EC918-D5E6-4C89-9CD0-84C35FC7413C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {301EC918-D5E6-4C89-9CD0-84C35FC7413C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {301EC918-D5E6-4C89-9CD0-84C35FC7413C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {301EC918-D5E6-4C89-9CD0-84C35FC7413C}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {FC5565F2-8C3B-4A75-97DA-2219CC4C2A83} + EndGlobalSection EndGlobal diff --git a/DigitDisplay/App.config b/DigitDisplay/App.config index b63f556..efa21db 100644 --- a/DigitDisplay/App.config +++ b/DigitDisplay/App.config @@ -1,7 +1,7 @@ - + - + @@ -9,4 +9,4 @@ - \ No newline at end of file + diff --git a/DigitDisplay/App.xaml.cs b/DigitDisplay/App.xaml.cs index 177f8df..9126f5c 100644 --- a/DigitDisplay/App.xaml.cs +++ b/DigitDisplay/App.xaml.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Configuration; -using System.Data; -using System.Linq; -using System.Threading.Tasks; -using System.Windows; +using System.Windows; namespace DigitDisplay { diff --git a/DigitDisplay/DigitDisplay.csproj b/DigitDisplay/DigitDisplay.csproj index 7c7af54..3c83bae 100644 --- a/DigitDisplay/DigitDisplay.csproj +++ b/DigitDisplay/DigitDisplay.csproj @@ -9,11 +9,12 @@ Properties DigitDisplay DigitDisplay - v4.5 + v4.6.1 512 {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 4 true + AnyCPU @@ -40,6 +41,9 @@ + + ..\packages\System.ValueTuple.4.4.0\lib\net461\System.ValueTuple.dll + @@ -57,11 +61,8 @@ MSBuild:Compile Designer - - ParallelRecognizerControl.xaml - - - RecognizerControl.xaml + + RecognizerUserControl.xaml MSBuild:Compile @@ -76,14 +77,10 @@ MainWindow.xaml Code - + MSBuild:Compile Designer - - Designer - MSBuild:Compile - @@ -103,6 +100,7 @@ ResXFileCodeGenerator Resources.Designer.cs + SettingsSingleFileGenerator Settings.Designer.cs @@ -123,6 +121,10 @@ {ff2cd045-8b57-422c-954a-ab2cbbe6c065} FunctionalRecognizer + + {301ec918-d5e6-4c89-9cd0-84c35fc7413c} + ObservationLoader + diff --git a/DigitDisplay/ImageHelper.cs b/DigitDisplay/ImageHelper.cs index 3333318..578e269 100644 --- a/DigitDisplay/ImageHelper.cs +++ b/DigitDisplay/ImageHelper.cs @@ -1,11 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Drawing; +using System.Drawing; using System.Drawing.Imaging; using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using System.Windows.Media.Imaging; namespace DigitDisplay diff --git a/DigitDisplay/MainWindow.xaml.cs b/DigitDisplay/MainWindow.xaml.cs index 23362db..f19079d 100644 --- a/DigitDisplay/MainWindow.xaml.cs +++ b/DigitDisplay/MainWindow.xaml.cs @@ -1,22 +1,15 @@ -using DigitLoader; -using Microsoft.FSharp.Core; -using System; +using System; +using DigitLoader; using System.Configuration; -using System.Drawing; -using System.Linq; using System.Threading; using System.Threading.Tasks; using System.Windows; -using System.Windows.Controls; -using System.Windows.Media; +using ObservationLoader; namespace DigitDisplay { - public partial class MainWindow : Window + public partial class MainWindow { - SolidColorBrush redBrush = new SolidColorBrush(System.Windows.Media.Color.FromRgb(255, 150, 150)); - SolidColorBrush whiteBrush = new SolidColorBrush(System.Windows.Media.Color.FromRgb(255, 255, 255)); - public MainWindow() { InitializeComponent(); @@ -29,32 +22,41 @@ private void GoButton_Click(object sender, RoutedEventArgs e) LeftPanel.Children.Clear(); RightPanel.Children.Clear(); - string[] rawData = FileLoader.LoadDataStrings(); + var rawData = FileLoader.LoadObservations(); - var parallelManhattanRecognizer = new ParallelRecognizerControl( - "Parallel Manhattan Classifier", Recognizer.manhattanClassifier, + var parallelManhattanRecognizer = new RecognizerUserControl( + "Parallel Manhattan Classifier", DispatchManhattanParallelForEach, rawData); LeftPanel.Children.Add(parallelManhattanRecognizer); - var manhattanRecognizer = new RecognizerControl( - "Manhattan Classifier", Recognizer.manhattanClassifier, + var manhattanRecognizer = new RecognizerUserControl( + "Manhattan Classifier", DispatchManhattanTasks, rawData); RightPanel.Children.Add(manhattanRecognizer); + } - //var euclideanRecognizer = new RecognizerControl( - // "Euclidean Classifier", Recognizer.euclideanClassifier, - // rawData); - //RightPanel.Children.Add(euclideanRecognizer); - - //var nullRecognizer = new RecognizerControl( - // "Null Classifier", (FSharpFunc)Recognizer.nullClassifier, - // rawData); - //RightPanel.Children.Add(nullRecognizer); + private static void DispatchManhattanParallelForEach((Observation observation, Action showResult)[] input) + { + var uiContext = SynchronizationContext.Current; + ThreadPool.QueueUserWorkItem(state => Parallel.ForEach(input, current => + { + var predicted = Recognizer.predict(current.observation.Pixels, Recognizer.manhattanClassifier); + uiContext.Post(_ => current.showResult(predicted), null); + })); + } - //var firstPixelRecognizer = new RecognizerControl( - // "FirstPixel Classifier", (FSharpFunc)Recognizer.firstPixelClassifier, - // rawData); - //LeftPanel.Children.Add(firstPixelRecognizer); + private static void DispatchManhattanTasks((Observation observation, Action showResult)[] input) + { + foreach (var current in input) + { + Task + .Run(() => Recognizer.predict(current.observation.Pixels, Recognizer.manhattanClassifier)) + .ContinueWith(t => + { + current.showResult(t.Result); + }, + TaskScheduler.FromCurrentSynchronizationContext()); + } } } } diff --git a/DigitDisplay/ParallelRecognizerControl.xaml b/DigitDisplay/ParallelRecognizerControl.xaml deleted file mode 100644 index bb27611..0000000 --- a/DigitDisplay/ParallelRecognizerControl.xaml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/DigitDisplay/ParallelRecognizerControl.xaml.cs b/DigitDisplay/ParallelRecognizerControl.xaml.cs deleted file mode 100644 index bb447ab..0000000 --- a/DigitDisplay/ParallelRecognizerControl.xaml.cs +++ /dev/null @@ -1,149 +0,0 @@ -using DigitLoader; -using Microsoft.FSharp.Core; -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Drawing; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Media; - -namespace DigitDisplay -{ - public partial class ParallelRecognizerControl : UserControl - { - string classifierName; - FSharpFunc classifier; - string[] rawData; - //ConcurrentQueue predictions = new ConcurrentQueue(); - - DateTimeOffset startTime; - SolidColorBrush redBrush = new SolidColorBrush(System.Windows.Media.Color.FromRgb(255, 150, 150)); - SolidColorBrush whiteBrush = new SolidColorBrush(System.Windows.Media.Color.FromRgb(255, 255, 255)); - int errors = 0; - - public ParallelRecognizerControl(string classifierName, FSharpFunc classifier, - string[] rawData) - { - InitializeComponent(); - this.classifierName = classifierName; - this.classifier = classifier; - this.rawData = rawData; - Loaded += RecognizerControl_Loaded; - } - - private void RecognizerControl_Loaded(object sender, RoutedEventArgs e) - { - - ClassifierText.Text = classifierName; - PopulatePanel(rawData); - } - - private struct PredictionData - { - public string prediction; - public string actual; - public string imageData; - } - - private void PopulatePanel(string[] rawData) - { - startTime = DateTime.Now; - - var options = new ParallelOptions(); - options.TaskScheduler = TaskScheduler.FromCurrentSynchronizationContext(); - - var loopResult = Parallel.ForEach(rawData, s => - { - int act = s.Split(',').Select(x => Convert.ToInt32(x)).First(); - int[] ints = s.Split(',').Select(x => Convert.ToInt32(x)).Skip(1).ToArray(); - var result = Recognizer.predict(ints, classifier); - - //predictions.Enqueue(new PredictionData() { - // prediction = result, actual = act.ToString(), imageData = s }); - - Task.Factory.StartNew(() => - CreateUIElements(result, act.ToString(), s, DigitsBox), - CancellationToken.None, - TaskCreationOptions.None, - options.TaskScheduler - ); - }); - - //Parallel.Invoke(options, () => - //{ - // PredictionData d; - // while (predictions.TryDequeue(out d)) - // { - // if (d.imageData != null) - // CreateUIElements(d.prediction, d.actual, d.imageData, DigitsBox); - // } - //}); - } - - private void CreateUIElements(string prediction, string actual, string imageData, - Panel panel) - { - Bitmap image = DigitBitmap.GetBitmapFromRawData(imageData); - - var multiplier = 1.5; - var imageControl = new System.Windows.Controls.Image(); - imageControl.Source = image.ToWpfBitmap(); - imageControl.Stretch = Stretch.UniformToFill; - imageControl.Width = imageControl.Source.Width * multiplier; - imageControl.Height = imageControl.Source.Height * multiplier; - - var textBlock = new TextBlock(); - textBlock.Height = imageControl.Height; - textBlock.Width = imageControl.Width; - textBlock.FontSize = 12; // * multiplier; - textBlock.TextAlignment = TextAlignment.Center; - textBlock.Text = prediction; - - var button = new Button(); - var backgroundBrush = whiteBrush; - button.Background = backgroundBrush; - button.Click += ToggleCorrectness; - - var buttonContent = new StackPanel(); - buttonContent.Orientation = Orientation.Horizontal; - button.Content = buttonContent; - - if (prediction != actual) - { - button.Background = redBrush; - errors++; - ErrorBlock.Text = $"Errors: {errors}"; - } - - buttonContent.Children.Add(imageControl); - buttonContent.Children.Add(textBlock); - - panel.Children.Add(button); - - TimeSpan duration = DateTimeOffset.Now - startTime; - TimingBlock.Text = $"Duration (seconds): {duration.TotalSeconds:0}"; - } - - private void ToggleCorrectness(object sender, RoutedEventArgs e) - { - var button = sender as Button; - if (button == null) return; - - if (button.Background == whiteBrush) - { - button.Background = redBrush; - errors++; - } - else - { - button.Background = whiteBrush; - errors--; - } - ErrorBlock.Text = $"Errors: {errors}"; - } - } -} diff --git a/DigitDisplay/Properties/AssemblyInfo.cs b/DigitDisplay/Properties/AssemblyInfo.cs index 5ffcb34..a82d524 100644 --- a/DigitDisplay/Properties/AssemblyInfo.cs +++ b/DigitDisplay/Properties/AssemblyInfo.cs @@ -1,6 +1,4 @@ using System.Reflection; -using System.Resources; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Windows; diff --git a/DigitDisplay/Properties/Resources.Designer.cs b/DigitDisplay/Properties/Resources.Designer.cs index d0f6630..ef490bc 100644 --- a/DigitDisplay/Properties/Resources.Designer.cs +++ b/DigitDisplay/Properties/Resources.Designer.cs @@ -1,17 +1,17 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.34014 +// Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ -namespace DigitDisplay.Properties -{ - - +namespace DigitDisplay.Properties { + using System; + + /// /// A strongly-typed resource class, for looking up localized strings, etc. /// @@ -19,51 +19,43 @@ namespace DigitDisplay.Properties // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources - { - + internal class Resources { + private static global::System.Resources.ResourceManager resourceMan; - + private static global::System.Globalization.CultureInfo resourceCulture; - + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() - { + internal Resources() { } - + /// /// Returns the cached ResourceManager instance used by this class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager - { - get - { - if ((resourceMan == null)) - { + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DigitDisplay.Properties.Resources", typeof(Resources).Assembly); resourceMan = temp; } return resourceMan; } } - + /// /// Overrides the current thread's CurrentUICulture property for all /// resource lookups using this strongly typed resource class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture - { - get - { + internal static global::System.Globalization.CultureInfo Culture { + get { return resourceCulture; } - set - { + set { resourceCulture = value; } } diff --git a/DigitDisplay/Properties/Settings.Designer.cs b/DigitDisplay/Properties/Settings.Designer.cs index fa5dec5..f2a0bc6 100644 --- a/DigitDisplay/Properties/Settings.Designer.cs +++ b/DigitDisplay/Properties/Settings.Designer.cs @@ -1,28 +1,24 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.34014 +// Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ -namespace DigitDisplay.Properties -{ - - +namespace DigitDisplay.Properties { + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] - internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase - { - + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.5.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); - - public static Settings Default - { - get - { + + public static Settings Default { + get { return defaultInstance; } } diff --git a/DigitDisplay/RecognizerControl.xaml.cs b/DigitDisplay/RecognizerControl.xaml.cs deleted file mode 100644 index 7a01256..0000000 --- a/DigitDisplay/RecognizerControl.xaml.cs +++ /dev/null @@ -1,127 +0,0 @@ -using DigitLoader; -using Microsoft.FSharp.Core; -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Linq; -using System.Threading.Tasks; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Media; - -namespace DigitDisplay -{ - public partial class RecognizerControl : UserControl - { - string classifierName; - FSharpFunc classifier; - string[] rawData; - - DateTimeOffset startTime; - SolidColorBrush redBrush = new SolidColorBrush(System.Windows.Media.Color.FromRgb(255, 150, 150)); - SolidColorBrush whiteBrush = new SolidColorBrush(System.Windows.Media.Color.FromRgb(255, 255, 255)); - int errors = 0; - - public RecognizerControl(string classifierName, FSharpFunc classifier, - string[] rawData) - { - InitializeComponent(); - this.classifierName = classifierName; - this.classifier = classifier; - this.rawData = rawData; - Loaded += RecognizerControl_Loaded; - } - - private void RecognizerControl_Loaded(object sender, RoutedEventArgs e) - { - - ClassifierText.Text = classifierName; - PopulatePanel(rawData); - } - - private void PopulatePanel(string[] rawData) - { - var tasks = new List>(); - foreach (var imageString in rawData) - { - int actual = imageString.Split(',').Select(x => Convert.ToInt32(x)).First(); - var task = Task.Run(() => - { - int[] ints = imageString.Split(',').Select(x => Convert.ToInt32(x)).Skip(1).ToArray(); - return Recognizer.predict(ints, classifier); - } - ); - tasks.Add(task); - task.ContinueWith(t => - { - CreateUIElements(t.Result, actual.ToString(), imageString, DigitsBox); - }, - TaskScheduler.FromCurrentSynchronizationContext() - ); - } - Task.WhenAny(tasks).ContinueWith(t => startTime = DateTime.Now); - } - - private void CreateUIElements(string prediction, string actual, string imageData, - Panel panel) - { - Bitmap image = DigitBitmap.GetBitmapFromRawData(imageData); - - var multiplier = 1.5; - var imageControl = new System.Windows.Controls.Image(); - imageControl.Source = image.ToWpfBitmap(); - imageControl.Stretch = Stretch.UniformToFill; - imageControl.Width = imageControl.Source.Width * multiplier; - imageControl.Height = imageControl.Source.Height * multiplier; - - var textBlock = new TextBlock(); - textBlock.Height = imageControl.Height; - textBlock.Width = imageControl.Width; - textBlock.FontSize = 12; // * multiplier; - textBlock.TextAlignment = TextAlignment.Center; - textBlock.Text = prediction; - - var button = new Button(); - var backgroundBrush = whiteBrush; - button.Background = backgroundBrush; - button.Click += ToggleCorrectness; - - var buttonContent = new StackPanel(); - buttonContent.Orientation = Orientation.Horizontal; - button.Content = buttonContent; - - if (prediction != actual) - { - button.Background = redBrush; - errors++; - ErrorBlock.Text = $"Errors: {errors}"; - } - - buttonContent.Children.Add(imageControl); - buttonContent.Children.Add(textBlock); - - panel.Children.Add(button); - - TimeSpan duration = DateTimeOffset.Now - startTime; - TimingBlock.Text = $"Duration (seconds): {duration.TotalSeconds:0}"; - } - - private void ToggleCorrectness(object sender, RoutedEventArgs e) - { - var button = sender as Button; - if (button == null) return; - - if (button.Background == whiteBrush) - { - button.Background = redBrush; - errors++; - } - else - { - button.Background = whiteBrush; - errors--; - } - ErrorBlock.Text = $"Errors: {errors}"; - } - } -} diff --git a/DigitDisplay/RecognizerControl.xaml b/DigitDisplay/RecognizerUserControl.xaml similarity index 91% rename from DigitDisplay/RecognizerControl.xaml rename to DigitDisplay/RecognizerUserControl.xaml index 590ab0d..22c08a5 100644 --- a/DigitDisplay/RecognizerControl.xaml +++ b/DigitDisplay/RecognizerUserControl.xaml @@ -1,9 +1,8 @@ - diff --git a/DigitDisplay/RecognizerUserControl.xaml.cs b/DigitDisplay/RecognizerUserControl.xaml.cs new file mode 100644 index 0000000..f753f59 --- /dev/null +++ b/DigitDisplay/RecognizerUserControl.xaml.cs @@ -0,0 +1,100 @@ +using DigitLoader; +using System; +using System.Linq; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Media; +using ObservationLoader; + +namespace DigitDisplay +{ + public partial class RecognizerUserControl + { + private static readonly SolidColorBrush RedBrush = new SolidColorBrush(Color.FromRgb(255, 150, 150)); + private static readonly SolidColorBrush WhiteBrush = new SolidColorBrush(Color.FromRgb(255, 255, 255)); + + private DateTimeOffset _startTime; + private int _errors; + public RecognizerUserControl(string classifierName, Action<(Observation, Action)[]> dispatcher, + Observation[] rawData) + { + InitializeComponent(); + ClassifierText.Text = classifierName; + + Loaded += (_, __) => PopulatePanel(rawData, dispatcher) ; + } + + private void PopulatePanel(Observation[] input, Action<(Observation, Action)[]> dispatcher) + { + (Observation, Action)[] toDispatch = input.Zip(input.Select(CreateButton), (observation, show) => (observation, show)).ToArray(); + _startTime = DateTimeOffset.Now; + dispatcher(toDispatch); + } + + private Action CreateButton(Observation observation) + { + var imageSource = DigitBitmap.GetBitmapFromRawData(observation.Pixels).ToWpfBitmap(); + var image = new Image + { + Source = imageSource, + Stretch = Stretch.UniformToFill, + Width = imageSource.Width * 1.5, + Height = imageSource.Height * 1.5 + }; + var textBlock = new TextBlock + { + Height = image.Height, + Width = image.Width, + FontSize = 12, + TextAlignment = TextAlignment.Center + }; + + var button = new Button(); + button.Click += ToggleCorrectness; + button.Background = WhiteBrush; + + var buttonContent = new StackPanel { Orientation = Orientation.Horizontal }; + buttonContent.Children.Add(image); + buttonContent.Children.Add(textBlock); + button.Content = buttonContent; + + void ShowButton(string predicted) + { + textBlock.Text = predicted; + if (predicted != observation.Label) + { + button.Background = RedBrush; + ChangeErrorsCount(1); + } + DigitsBox.Children.Add(button); + + TimingBlock.Text = "Duration (seconds): " + (DateTimeOffset.Now - _startTime).TotalSeconds.ToString("0"); + } + + return ShowButton; + } + + private void ToggleCorrectness(object sender, RoutedEventArgs e) + { + switch (sender) + { + case Button whiteButton when ReferenceEquals(whiteButton.Background, WhiteBrush): + whiteButton.Background = RedBrush; + ChangeErrorsCount(1); + break; + case Button redButton when ReferenceEquals(redButton.Background, RedBrush): + redButton.Background = WhiteBrush; + ChangeErrorsCount(-1); + break; + default: + return; + } + } + + private void ChangeErrorsCount(int errorDiff) + { + _errors += errorDiff; + ErrorBlock.Text = "Errors: " + _errors.ToString("0"); + } + } +} \ No newline at end of file diff --git a/DigitDisplay/packages.config b/DigitDisplay/packages.config new file mode 100644 index 0000000..61fc68c --- /dev/null +++ b/DigitDisplay/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/DigitLoader.Test/DigitBitmapTest.cs b/DigitLoader.Test/DigitBitmapTest.cs index 3874193..d15604f 100644 --- a/DigitLoader.Test/DigitBitmapTest.cs +++ b/DigitLoader.Test/DigitBitmapTest.cs @@ -1,5 +1,4 @@ -using System; -using Microsoft.VisualStudio.TestTools.UnitTesting; +using Microsoft.VisualStudio.TestTools.UnitTesting; namespace DigitLoader.Test { @@ -7,7 +6,7 @@ namespace DigitLoader.Test public class DigitBitmapTest { // Sample Record - string sample = "3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,21,130,190,254,254,250,175,135,96,96,16,4,0,0,0,0,0,0,0,0,0,0,0,0,0,26,102,186,254,254,248,222,222,225,254,254,254,254,254,206,112,4,0,0,0,0,0,0,0,0,0,0,0,207,254,254,177,117,39,0,0,56,248,102,48,48,103,192,254,135,0,0,0,0,0,0,0,0,0,0,0,91,111,36,0,0,0,0,0,72,92,0,0,0,0,12,224,210,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,50,139,240,254,66,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,121,220,254,244,194,15,0,0,0,0,0,0,0,0,0,0,0,0,0,8,107,112,112,112,87,112,141,218,248,177,68,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,77,221,254,254,254,254,254,225,104,39,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,32,32,32,32,130,215,195,47,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,111,231,174,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,47,18,0,0,0,0,0,0,0,0,0,40,228,205,35,0,0,0,0,0,0,0,0,0,0,0,0,22,234,42,0,0,0,0,0,0,0,0,0,0,56,212,226,38,0,0,0,0,0,0,0,0,0,0,0,96,157,0,0,0,0,0,0,0,0,0,0,0,0,30,215,188,9,0,0,0,0,0,0,0,0,0,0,96,142,0,0,0,0,0,0,0,0,0,0,0,0,0,86,254,68,0,0,0,0,0,0,0,0,0,0,71,202,15,0,0,0,0,0,0,0,0,0,0,0,0,6,214,151,0,0,0,0,0,0,0,0,0,0,10,231,86,2,0,0,0,0,0,0,0,0,0,0,0,0,191,207,0,0,0,0,0,0,0,0,0,0,0,93,248,129,7,0,0,0,0,0,0,0,0,0,0,117,238,112,0,0,0,0,0,0,0,0,0,0,0,0,94,248,209,73,12,0,0,0,0,0,0,42,147,252,136,9,0,0,0,0,0,0,0,0,0,0,0,0,0,48,160,215,230,158,74,64,94,153,223,250,214,105,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,129,189,234,224,255,194,134,75,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"; + int[] sample = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,21,130,190,254,254,250,175,135,96,96,16,4,0,0,0,0,0,0,0,0,0,0,0,0,0,26,102,186,254,254,248,222,222,225,254,254,254,254,254,206,112,4,0,0,0,0,0,0,0,0,0,0,0,207,254,254,177,117,39,0,0,56,248,102,48,48,103,192,254,135,0,0,0,0,0,0,0,0,0,0,0,91,111,36,0,0,0,0,0,72,92,0,0,0,0,12,224,210,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,50,139,240,254,66,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,121,220,254,244,194,15,0,0,0,0,0,0,0,0,0,0,0,0,0,8,107,112,112,112,87,112,141,218,248,177,68,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,77,221,254,254,254,254,254,225,104,39,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,32,32,32,32,130,215,195,47,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,111,231,174,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,47,18,0,0,0,0,0,0,0,0,0,40,228,205,35,0,0,0,0,0,0,0,0,0,0,0,0,22,234,42,0,0,0,0,0,0,0,0,0,0,56,212,226,38,0,0,0,0,0,0,0,0,0,0,0,96,157,0,0,0,0,0,0,0,0,0,0,0,0,30,215,188,9,0,0,0,0,0,0,0,0,0,0,96,142,0,0,0,0,0,0,0,0,0,0,0,0,0,86,254,68,0,0,0,0,0,0,0,0,0,0,71,202,15,0,0,0,0,0,0,0,0,0,0,0,0,6,214,151,0,0,0,0,0,0,0,0,0,0,10,231,86,2,0,0,0,0,0,0,0,0,0,0,0,0,191,207,0,0,0,0,0,0,0,0,0,0,0,93,248,129,7,0,0,0,0,0,0,0,0,0,0,117,238,112,0,0,0,0,0,0,0,0,0,0,0,0,94,248,209,73,12,0,0,0,0,0,0,42,147,252,136,9,0,0,0,0,0,0,0,0,0,0,0,0,0,48,160,215,230,158,74,64,94,153,223,250,214,105,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,129,189,234,224,255,194,134,75,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; int[] array0 = new int[28] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int[] array1 = new int[28] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; diff --git a/DigitLoader.Test/DigitLoader.Test.csproj b/DigitLoader.Test/DigitLoader.Test.csproj index 84b618d..9cfbb38 100644 --- a/DigitLoader.Test/DigitLoader.Test.csproj +++ b/DigitLoader.Test/DigitLoader.Test.csproj @@ -8,7 +8,7 @@ Properties DigitLoader.Test DigitLoader.Test - v4.5 + v4.6.1 512 {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 10.0 @@ -16,6 +16,7 @@ $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages False UnitTest + true diff --git a/DigitLoader.Test/Properties/AssemblyInfo.cs b/DigitLoader.Test/Properties/AssemblyInfo.cs index 38aa4cc..aa7d11e 100644 --- a/DigitLoader.Test/Properties/AssemblyInfo.cs +++ b/DigitLoader.Test/Properties/AssemblyInfo.cs @@ -1,5 +1,4 @@ using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following diff --git a/DigitLoader/DigitBitmap.cs b/DigitLoader/DigitBitmap.cs index 0f56629..a863624 100644 --- a/DigitLoader/DigitBitmap.cs +++ b/DigitLoader/DigitBitmap.cs @@ -1,20 +1,12 @@ -using System; -using System.Collections.Generic; -using System.Drawing; +using System.Drawing; using System.Linq; namespace DigitLoader { public class DigitBitmap { - public static int[][] GenerateDigitArray(string input) + public static int[][] GenerateDigitArray(int[] integerData) { - var rawData = input.Split(','); - var integerData = rawData - //.Skip(1) - .Select(x => Convert.ToInt32(x)) - .ToArray(); - var output = new int[28][]; for (int i = 0; i < 28; i++) { @@ -26,7 +18,7 @@ public static int[][] GenerateDigitArray(string input) return output; } - public static Bitmap GetBitmapFromRawData(string input) + public static Bitmap GetBitmapFromRawData(int[] input) { var digitArray = GenerateDigitArray(input); @@ -42,6 +34,5 @@ public static Bitmap GetBitmapFromRawData(string input) digitBitmap.MakeTransparent(Color.White); return digitBitmap; } - } } diff --git a/DigitLoader/DigitLoader.csproj b/DigitLoader/DigitLoader.csproj index 54ac029..84233c0 100644 --- a/DigitLoader/DigitLoader.csproj +++ b/DigitLoader/DigitLoader.csproj @@ -9,8 +9,9 @@ Properties DigitLoader DigitLoader - v4.5 + v4.6.1 512 + true @@ -45,6 +46,12 @@ + + + {301ec918-d5e6-4c89-9cd0-84c35fc7413c} + ObservationLoader + +