About Me

My photo
Northglenn, Colorado, United States
I'm primarily a BI Developer on the Microsoft stack. I do sometimes touch upon other Microsoft stacks ( web development, application development, and sql server development).
Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

Saturday, October 11, 2014

Somewhat Dynamic Pivot in C#

I started working on a dynamic pivot to be used in Kendo UI, where the user could select the datapoints to be shown in the graph. Didn't quite finish, but here is some of the code, didn't want to waste/lose it; since, the concept was interesting.


Code:
public class StageDataPoints
    {
        public List<StageDataPoint> dataSeries { get; set; }

        public List<ExpandoObject> pivot()
        {
            var datapoints = dataSeries.Select(n => n.DataPoint).Distinct().ToList();

            var sdpGroup = from d in dataSeries
                           group d by new { d.DateTimeGrainValue, d.Stage, d.SubStage }
                               into grp
                               select new
                               {
                                   Key = grp.Key,
                                   Dict = grp.ToDictionary(n => n.DataPoint, n => n.DecimalValueAvg)
                               };

            List<ExpandoObject> defactoObjs = new List<ExpandoObject>();

            foreach (var row in sdpGroup)
            {
                dynamic r = new ExpandoObject();
                r.DateTime = row.Key.DateTimeGrainValue.ToString("M/d/yy h:mm");
                r.Stage = row.Key.Stage;
                r.SubStage = row.Key.SubStage;

                double value = double.NaN;
                string tempDP = "";

                foreach (var dp in datapoints)
                {
                    tempDP = dp;

                    foreach (var idp in row.Dict)
                    {
                        if (idp.Key == dp)
                        {
                            value = idp.Value;
                            break;
                        }
                    }
                    //Console.Write(dp + " " + value.ToString());
                    ((IDictionary<string, object>)r).Add(dp, value);
                }
                defactoObjs.Add(r);
            }
            return defactoObjs;
        }

        public List<StageDataPointMinify> rpt()
        {
            List<StageDataPointMinify> ret = new List<StageDataPointMinify>();
            foreach (var x in dataSeries)
            {
                ret.Add(new StageDataPointMinify()
                {
                    //Convert datetime to javascript verion
                    DateTimeGrainValueStr = x.DateTimeGrainValue.ToString("M/d/yy H:mm"),
                    DateTimeGrainValue = x.DateTimeGrainValue,
                    DataPoint = x.DataPoint,
                    DecimalValueAvg = x.DecimalValueAvg
                });
            }
            return ret;
        }
    }

    public class StageDataPoint
    {
        //public DateTime CalendarGrainValue { get; set; }
        //public string ClockGrainValue { get; set; }
        public DateTime DateTimeGrainValue { get; set; }
        public string Stage { get; set; }
        public string SubStage { get; set; }
        public string DataPoint { get; set; }
        //public Guid CJobGuid { get; set; }
        public string JobName { get; set; }
        public double DecimalValueAvg { get; set; }
        //public double DecimalValueMin { get; set; }
        //public double DecimalValueMax { get; set; }
    }
 

Friday, March 15, 2013

Just for kicks: Project Euler Problem #1

Just wanted to try a variety of methods to a solution. I wanted to do a variety of parallel, plinq, and straight forward logic test. I also wanted to implement a extension method and use func<> for better refactoring. As a test, I considered doing Euler's #1:
http://projecteuler.net/problem=1


Here are the several methods I created:
Code Snippet
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using System.Threading;
  7.  
  8. namespace ProjectEuler
  9. {
  10.     /*
  11.      *   Q: If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.
  12.      *      Find the sum of all the multiples of 3 or 5 below 1000.
  13.      *
  14.      *   A: 233168
  15.      *   
  16.      *   Results:
  17.                     Method 1 Avg Time:  0.000007768
  18.                     Method 2a Avg Time: 0.000040169
  19.                     Method 2b Avg Time: 0.000029314
  20.                     Method 2c Avg Time: 0.000347431
  21.                     Method 2d Avg Time: 0.000175544
  22.                     Method 3a Avg Time: 0.00017445
  23.                     Method 3b Avg Time: 0.000144669
  24.                     Method 3c Avg Time: 0.002392947
  25.                     Method 3d Avg Time: 0.001309331
  26.      *   
  27.      */
  28.     class Problem1
  29.     {
  30.         int[] items = Enumerable.Range(1, 999).ToArray();
  31.         ReaderWriterLockSlim rw = new ReaderWriterLockSlim();
  32.         int sum = 0;
  33.  
  34.         //KISS Logic
  35.         public int RunMethod1()
  36.         {
  37.             sum = 0;
  38.  
  39.             foreach(int s in items)
  40.             {
  41.                 if (s % 3 == 0 || s % 5 == 0)
  42.                 {
  43.                     sum += s;
  44.                 }
  45.             };
  46.  
  47.             return sum;
  48.         }
  49.  
  50.         //Lazy Method
  51.         public int RunMethod2a()
  52.         {
  53.             return items.Where(n => n % 3 == 0 || n % 5 == 0).Sum();
  54.         }
  55.  
  56.         //Lazy Method on the fly
  57.         public int RunMethod2b()
  58.         {
  59.             return Enumerable.Range(1, 999).Where(n => n % 3 == 0 || n % 5 == 0).Sum();
  60.         }
  61.  
  62.         //Parallel Lazy Method
  63.         public int RunMethod2c()
  64.         {
  65.             return items.AsParallel().Where(n => n % 3 == 0 || n % 5 == 0).Sum();
  66.         }
  67.  
  68.         //Parallel Lazy Method on the fly
  69.         public int RunMethod2d()
  70.         {
  71.             return Enumerable.Range(1, 999).AsParallel().Where(n => n % 3 == 0 || n % 5 == 0).Sum();
  72.         }
  73.  
  74.         //Basic Parallel Method
  75.         public int RunMethod3a()
  76.         {
  77.             List<int> multOf3Or5 = new List<int>();
  78.  
  79.             Parallel.ForEach(items, s =>
  80.                 {
  81.                     if (s % 3 == 0 || s % 5 == 0)
  82.                     {
  83.                         lock (multOf3Or5)
  84.                         {
  85.                             multOf3Or5.Add(s);
  86.                         }
  87.                     }
  88.                 }
  89.             );
  90.  
  91.             return multOf3Or5.Sum();
  92.         }
  93.  
  94.         //Parallel it, but slice the work up
  95.         public int RunMethod3b()
  96.         {
  97.             List<int> multOf3Or5 = new List<int>();
  98.  
  99.             Parallel.ForEach(items.Slice(100), s =>
  100.             {
  101.                 foreach (int item in s)
  102.                 {
  103.                     if (item % 3 == 0 || item % 5 == 0)
  104.                     {
  105.                         lock (multOf3Or5)
  106.                         {
  107.                             multOf3Or5.Add(item);
  108.                         }
  109.                     }
  110.                 }
  111.             });
  112.  
  113.             return multOf3Or5.Sum();
  114.         }
  115.  
  116.  
  117.         //Basic Parallel Method just sum it
  118.         public int RunMethod3c()
  119.         {
  120.             sum = 0;
  121.  
  122.             Parallel.ForEach(items, s =>
  123.             {
  124.                 if (s % 3 == 0 || s % 5 == 0)
  125.                 {
  126.                     rw.EnterWriteLock();
  127.                     sum += s;
  128.                     rw.ExitWriteLock();
  129.                 }
  130.             });
  131.  
  132.             return sum;
  133.         }
  134.  
  135.         //Basic Parallel Method just slice & sum it
  136.         public int RunMethod3d()
  137.         {
  138.             sum = 0;
  139.             
  140.             Parallel.ForEach(items.Slice(100), s =>
  141.             {
  142.                 foreach (int item in s)
  143.                 {
  144.                     if (item % 3 == 0 || item % 5 == 0)
  145.                     {
  146.                         rw.EnterWriteLock();
  147.                         sum += item;
  148.                         rw.ExitWriteLock();
  149.                     }
  150.                 }
  151.             });
  152.  
  153.             return sum;
  154.         }
  155.     }
  156. }

Method 1: is the straight forward logic I would have used, and seems to be the quickest.
Method 2s: is probably something I would use as well, and to clean code up.
Method 3s: using Parallel programming, doesn't always speed things up. Depends on how much work needs to be done. I used an Extension method called Slice which expands the use of enumerable. I mainly got the idea to do this after reading about extention methods from http://www.blackrabbitcoder.net/archive/2013/03/08/c.net-little-wonders-extension-methods-demystified.aspx

For the Slice Extension, I used this:
Code Snippet
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5.  
  6. namespace ProjectEuler
  7. {
  8.     public static class EnumerableExtensions
  9.     {
  10.         //Source and Inspiration: http://www.blackrabbitcoder.net/archive/2013/03/08/c.net-little-wonders-extension-methods-demystified.aspx
  11.  
  12.         public static IEnumerable<IEnumerable<T>> Slice<T>(this IEnumerable<T> source, int size)
  13.         {
  14.             // can't slice null sequence
  15.             if (source == null) throw new ArgumentNullException("source");
  16.             if (size < 1) throw new ArgumentOutOfRangeException("size", "The size must be positive.");
  17.  
  18.             // force into a list to take advantage of direct indexing. Could also force into an
  19.             // array, use LINQ grouping, do a Skip()/Take(), etc...
  20.             var sourceList = source.ToList();
  21.             int current = 0;
  22.      
  23.             // while there are still items to "slice" off, keep going
  24.             while (current < sourceList.Count)
  25.             {
  26.                 // return a sub-slice using an iterator for deferred execution
  27.                 yield return sourceList.GetRange(current, Math.Min(size, sourceList.Count - current));
  28.                 current += size;
  29.             }
  30.         }
  31.     }
  32. }

The Main program. I hate repeating myself, so after some refactoring I came up with this to use delegates.
Code Snippet
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Diagnostics;
  6.  
  7. namespace ProjectEuler
  8. {
  9.     class Program
  10.     {
  11.         public static Stopwatch sw = new Stopwatch();
  12.         public delegate int fPointer();
  13.  
  14.         static void Main(string[] args)
  15.         {
  16.             //Initialize Problem(s)
  17.             Problem1 p1 = new Problem1();
  18.  
  19.             Func<fPointer,int, double> timeIt = (d,runCount) =>
  20.             {
  21.                 List<double> times = new List<double>();
  22.  
  23.                 for (int i = 0; i < runCount; i++)
  24.                 {
  25.                     sw.Reset();
  26.                     sw.Start();
  27.                     d();
  28.                     sw.Stop();
  29.                     times.Add(sw.Elapsed.TotalSeconds);
  30.                 }
  31.                 return times.Average();
  32.             };
  33.  
  34.             //Get Times of Running Methods
  35.             Console.WriteLine("Method 1 Avg Time: " + timeIt(p1.RunMethod1,100));
  36.             Console.WriteLine("Method 2a Avg Time: " + timeIt(p1.RunMethod2a, 100));
  37.             Console.WriteLine("Method 2b Avg Time: " + timeIt(p1.RunMethod2b, 100));
  38.             Console.WriteLine("Method 2c Avg Time: " + timeIt(p1.RunMethod2c, 100));
  39.             Console.WriteLine("Method 2d Avg Time: " + timeIt(p1.RunMethod2d, 100));
  40.             Console.WriteLine("Method 3a Avg Time: " + timeIt(p1.RunMethod3a, 100));
  41.             Console.WriteLine("Method 3b Avg Time: " + timeIt(p1.RunMethod3b, 100));
  42.             Console.WriteLine("Method 3c Avg Time: " + timeIt(p1.RunMethod3c, 100));
  43.             Console.WriteLine("Method 3d Avg Time: " + timeIt(p1.RunMethod3d, 100));
  44.  
  45.             Console.ReadKey();
  46.         }
  47.     }
  48. }

Tuesday, March 05, 2013

Reminder: Setting up MVC4 Async Service in Controller

A quick reminder: I call a Json formatted file as a Service, that I placed in the App_Data folder. I then pull the contents needed using AsyncController.


Code Snippet
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Web;
  5. using System.Web.Mvc;
  6. using MadLibs.Models;
  7. using System.Net.Http;
  8. using Newtonsoft.Json;
  9.  
  10.  
  11. namespace MadLibs.Controllers
  12. {
  13.     public class MadLibController : AsyncController
  14.     {
  15.         //
  16.         // GET: /MadLib/
  17.  
  18.         public ActionResult StoryService()
  19.         {
  20.             return this.File("~/App_Data/StoriesDB.json", "application/json");
  21.         }
  22.  
  23.         public void IndexAsync()
  24.         {
  25.             String uri = Url.Action("StoryService", "MadLib", null, Request.Url.Scheme);
  26.             HttpClient client = new HttpClient();
  27.             var response = client.GetStringAsync(uri).Result;
  28.  
  29.             AsyncManager.Parameters["stories"] = JsonConvert.DeserializeObject<List<Story>>(response);
  30.         }
  31.  
  32.         public ActionResult IndexCompleted(List<Story> stories)
  33.         {
  34.             return View(stories);
  35.         }
  36.     }
  37. }

Tuesday, August 14, 2012

First StreamInsight attempt using Performance Counter

As my first attempt with StreamInsight, I decided to use the Performance Counter as my stream of data. Here is a brief overview of implementing the StreamInsight portion

3 important downloads to get started, with StreamInsight:

Download Reactive: http://www.microsoft.com/en-us/download/confirmation.aspx?id=28568
Download Examples: http://streaminsight.codeplex.com/releases/view/90143


First I created an class to represent the data I wanted to capture in my stream. Not all data types can be used with StreamInsight (ie: enum). Here is a list of supported data types: http://msdn.microsoft.com/en-us/library/ee378905.aspx

Code Snippet
  1. // Input events of CounterSample of supported data types
  2. public class StreamableCounterSample
  3. {
  4.     public float CpuUtilization { get; set; }
  5.     public long TimeStamp { get; set; }
  6. }


The main portion of the program.
Here starting on line 86, I create my StreamInsight server embedded in memory. The server name is the instance name that you give after installing StreamInsight. With StreamInsight 2.1, they added IQStreamable which allows you to query the stream. Lines 104 & 105 is when the stream will be queried for the results.
Code Snippet
  1. private float CalculatePerformance(BackgroundWorker worker, DoWorkEventArgs e)
  2. {
  3.     CreateCounters();
  4.  
  5.     //embedded (in-memory)
  6.     using (Server server = Server.Create("StreamInsight21"))
  7.     {
  8.         Microsoft.ComplexEventProcessing.Application application = server.CreateApplication("app");
  9.  
  10.         //A query for reading events from a stream
  11.         IQStreamable<StreamableCounterSample> inputStream = null;
  12.  
  13.         inputStream = CreateStream(application);
  14.  
  15.         while (true)
  16.         {
  17.             if (worker.CancellationPending)
  18.             {
  19.                 e.Cancel = true;
  20.                 break;
  21.             }
  22.             else
  23.             {
  24.                 perf = inputStream.ToObservable().ToEnumerable().Last().CpuUtilization;
  25.                 timestamp = DateTime.FromFileTime(inputStream.ToObservable().ToEnumerable().Last().TimeStamp);
  26.                 worker.ReportProgress((int)perf);
  27.             }
  28.         }
  29.  
  30.         return inputStream.ToObservable().ToEnumerable().Last().CpuUtilization;
  31.  
  32.     }
  33. }


When creating the stream in line 93, I'm setting up my observation. In this case CollectSamples is my source which is then converted to a temporal stream via ToPointStreamable, which inserts a single event instance with a datetime.

Code Snippet
  1. static IQStreamable<StreamableCounterSample> CreateStream(Microsoft.ComplexEventProcessing.Application application)
  2. {
  3.     // Live data uses IQbservable<>
  4.     return
  5.         application.DefineObservable(() => CollectSamples()).ToPointStreamable(
  6.         r => PointEvent<StreamableCounterSample>.CreateInsert(DateTime.Now, r),
  7.         AdvanceTimeSettings.StrictlyIncreasingStartTime);
  8. }


The collect samples, is where my data will be pulled. In this case I'm pulling my data from the performance counter, but returning an observable interval representing this temporal event that occurs every 1 second.
Code Snippet
  1. private static IObservable<StreamableCounterSample> CollectSamples()
  2. {
  3.     List<StreamableCounterSample> data = new List<StreamableCounterSample>();
  4.     
  5.     data.Add(new StreamableCounterSample
  6.     {
  7.         CpuUtilization = perfCounter.NextValue(),
  8.         TimeStamp = DateTime.Now.ToFileTime()
  9.     });
  10.  
  11.     return ToObservableInterval(data, TimeSpan.FromMilliseconds(1000), Scheduler.ThreadPool);
  12. }


Code Snippet
  1. private static IObservable ToObservableInterval(IEnumerable source, TimeSpan period, IScheduler scheduler)
  2. {
  3.     return Observable.Using(
  4.         () => source.GetEnumerator(),
  5.         it => Observable.Generate(
  6.             default(object),
  7.             _ => it.MoveNext(),
  8.             _ => _,
  9.             _ =>
  10.             {
  11.                 //Console.WriteLine("Input {0}", it.Current);
  12.                 return it.Current;
  13.             },
  14.             _ => period, scheduler));
  15. }


In the end, the final product is a simple winform showing the current CPU Utilization and the last time it ran.


The program can be downloaded from:

Thursday, January 12, 2012

SQL CLR Aggregate: Median

Since Sql Server doesn't have an aggregate for Median, I figured, that I'll create my first SQL CLR to handle this problem.

So, I created my intial project, using the .Net Framework 3.5 and C# SQL CLR aggregate template, and started coding:

Code Snippet
using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.Collections.Generic;


[Serializable]
[Microsoft.SqlServer.Server.SqlUserDefinedAggregate(
    Format.UserDefined,
    IsInvariantToDuplicates = false,
    IsInvariantToNulls = false,
    IsInvariantToOrder = false,
    MaxByteSize = 8000)]
public struct Median : IBinarySerialize
{
    //Variables to hold the values;
    private List<double> ld;

    public void Init()
    {
        ld = new List<double>();
    }

    public void Accumulate(SqlDouble Value)
    {
        if (!Value.IsNull)
        {
            ld.Add(Value.Value);
        }
    }

    ///
    /// Merge the partially computed aggregate with this aggregate.
    ///
    /// The other partial results to be merged
    public void Merge(Median Group)
    {
        this.ld.AddRange(Group.ld.ToArray());
    }

    ///
    /// Called at the end of aggregation, to return the results.
    ///
    /// The median of all inputted values
    public SqlDouble Terminate()
    {
        //debug: return (SqlDouble)ld.Count;

        //special case 0 values
        if (ld.Count == 0)
            return SqlDouble.Null;

        ld.Sort();
        int index = (int)ld.Count / 2;

        if (ld.Count % 2 == 0)
        {
            return (SqlDouble)(((double)ld[index] + (double)ld[index - 1]) / 2);
        }
        else
        {
            return (SqlDouble)((double)ld[index]);
        }
    }


    #region IBinarySerialize Members

    public void Read(System.IO.BinaryReader r)
    {
        int cnt = r.ReadInt32();
        this.ld = new List<double>(cnt);
        for(int i = 0; i < cnt; i++)
        {
            this.ld.Add(r.ReadDouble());
        }
    }

    public void Write(System.IO.BinaryWriter w)
    {
        w.Write(this.ld.Count);
        foreach (double d in this.ld)
        {
            w.Write(d);
        }
    }

    #endregion
}


Some of the intial changes that I've made from the default:
1) The SqlUserDefinedAggregate default was Format.Native. The problem with using the default Serializer is that I needed a way to store my values, preferably in a List. By changing the format to Format.UserDefined  -- I was able to create my own serializer. In this case I used the IBinarySerialize interface.

2) I also changed the default IsInvariant attributes.
  • IsInvariantToDuplicates - set to false since I want duplicates.
  • IsInvariantToNull - set to false since I will handle Null values in my code.
  • IsInvariantToOrder - set to false, I can do this in code.

Once the code is compiled, you will need to place the dll on the same machine as the SQL Server is located.

Using the following query to set the assembly and aggregate name:
Code Snippet
IF EXISTS (SELECT name FROM sysobjects WHERE name = 'Median')
   DROP AGGREGATE Median
go

IF EXISTS (SELECT name FROM sys.assemblies WHERE name = 'MyClrCode')
   DROP ASSEMBLY MyClrCode
go


CREATE ASSEMBLY MyClrCode
FROM 'C:\Median.dll'
WITH PERMISSION_SET = SAFE
GO

CREATE AGGREGATE dbo.Median
(@input float)
RETURNS float
EXTERNAL NAME MyClrCode.Median

Once done, time to do some testing. An example:
Code Snippet
--Test 1 value
select
dbo.Median(x.y)
from
(
    select 1 as y
)x
GO

--Test Accuracy
select
dbo.Median(x.y)
from
(
    select 1 as y
    union all
    select 2 as y
)x
GO

Monday, January 11, 2010

List Creator

This is one of my favorite pieces of code I've stolen borrowed from another site. I've had made some minor code changes and additions from the original, but basically I just need to send in a DataReader after running a sql command and it will return a list of objects of that type. (Very similar to Linq to Sql)

You just need to make sure that anything that is return through the query is defined in the object as a write property.

So here is the List Creator code, which does the creation via reflections:

Code Snippet
  1. public class ListCreator where T : new()
  2. {
  3.      public List FindAll(IDataReader iDataReader)
  4.      {
  5.          List returnList = new List();
  6.  
  7.          try
  8.          {
  9.              //need a Type and PropertyInfo object to set properties via reflection
  10.              Type tType = new T().GetType();
  11.              PropertyInfo pInfo;
  12.  
  13.              //x will hold the instance of until it is added to the list
  14.              T x;
  15.  
  16.              //use reader to populate list of objects
  17.              while (iDataReader.Read())
  18.              {
  19.                  x = new T();
  20.  
  21.                  //set property values
  22.                  //for this to work, command’s column names must match property names in object
  23.                  for (int i = 0; i < iDataReader.FieldCount; i++)
  24.                  {
  25.                      pInfo = tType.GetProperty(iDataReader.GetName(i));
  26.  
  27.                      pInfo.SetValue(x, (iDataReader[i] == DBNull.Value? null:iDataReader[i]), null);
  28.                  }
  29.  
  30.                  //once instance of is populated, add to list
  31.                  returnList.Add(x);
  32.              }
  33.          }
  34.          catch (Exception ex)
  35.          {
  36.              Logging.Logging.Error(ex.ToString());
  37.          }
  38.  
  39.          return returnList;
  40.      }
  41. }




So in my DAL I might have something like:

Code Snippet
  1. public List<PartsOrdering> GetAllPartsOrdering()
  2. {
  3.    List<PartsOrdering> li = new List<PartsOrdering>();
  4.    try
  5.    {
  6.       using (SqlConnection cn = new SqlConnection(connString))
  7.       {
  8.           ListCreator<PartsOrdering> PartsOrders = new ListCreator<PartsOrdering>();
  9.           SqlCommand cmd = new SqlCommand("dbo.selPartsOrdering", cn);
  10.           cmd.CommandType = CommandType.StoredProcedure;
  11.           cn.Open();
  12.           li = PartsOrders.FindAll(ExecuteReader(cmd));
  13.       }
  14.   }
  15.   catch (Exception ex)
  16.   {
  17.      Logging.Error(ex.ToString());
  18.   }
  19.   return li;
  20. }

Code Snippet
  1. [Serializable]
  2. public class PartsOrdering : IFormattable
  3. {
  4.     #region Properties
  5.     [DefaultValue(-1)]
  6.     public int PartsOrderingID
  7.     {
  8.         get;
  9.         set;
  10.     }
  11.     [DefaultValue("")]
  12.     public string ToolID
  13.     {
  14.         get;
  15.         set;
  16.     }
  17.     [DefaultValue("")]
  18.     public string PartNumber
  19.     {
  20.         get;
  21.         set;
  22.     }
  23.     [DefaultValue("")]
  24.     public string Description
  25.     {
  26.         get;
  27.         set;
  28.     }
  29.     [DefaultValue(0)]
  30.     public int Quantity
  31.     {
  32.         get;
  33.         set;
  34.     }
  35.     [DefaultValue(1)]
  36.     public int PartsOrderingLocationID
  37.     {
  38.         get;
  39.         set;
  40.     }
  41.     [DefaultValue(1)]
  42.     public int PartsOrderingUrgencyID
  43.     {
  44.         get;
  45.         set;
  46.     }
  47.     [DefaultValue("")]
  48.     public string Comment
  49.     {
  50.         get;
  51.         set;
  52.     }
  53.     public DateTime RequestedDateTime
  54.     {
  55.         get;
  56.         set;
  57.     }
  58.     [DefaultValue("")]
  59.     public string RequestedUser
  60.     {
  61.         get;
  62.         set;
  63.     }
  64.     public string LocationName
  65.     {
  66.         get
  67.          {
  68.              List&lt;PartsOrderingLocation&gt; locations = new PartsOrderingLocation().List();
  69.              return locations.Where(n =&gt; n.PartsOrderingLocationID.Equals(this.PartsOrderingLocationID)).Select(n =&gt; n.Name).First();
  70.          }
  71.         set
  72.          {
  73.              List&lt;PartsOrderingLocation&gt; locations = new PartsOrderingLocation().List();
  74.              this.PartsOrderingLocationID = locations.Where(n =&gt; n.Name.Equals(value)).Select(n =&gt; n.PartsOrderingLocationID).First();
  75.          }
  76.  
  77.     }
  78.     public string UrgencyName
  79.     {
  80.         get
  81.          {
  82.              List&lt;PartsOrderingUrgency&gt; locations = new PartsOrderingUrgency().List();
  83.              return locations.Where(n =&gt; n.PartsOrderingUrgencyID.Equals(this.PartsOrderingUrgencyID)).Select(n =&gt; n.Name).First();
  84.          }
  85.         set
  86.          {
  87.              List&lt;PartsOrderingUrgency&gt; locations = new PartsOrderingUrgency().List();
  88.              this.PartsOrderingUrgencyID = locations.Where(n =&gt; n.Name.Equals(value)).Select(n =&gt; n.PartsOrderingUrgencyID).First();
  89.          }
  90.     }
  91.     public int UrgencyRank
  92.     {
  93.         get
  94.          {
  95.              List&lt;PartsOrderingUrgency&gt; locations = new PartsOrderingUrgency().List();
  96.              return locations.Where(n =&gt; n.PartsOrderingUrgencyID.Equals(this.PartsOrderingUrgencyID)).Select(n =&gt; n.Rank).First();
  97.          }
  98.     }
  99.     [DefaultValue(-1)]
  100.     public int PartsOrderingGroupID
  101.     {
  102.         get;
  103.         set;
  104.     }
  105.     [DefaultValue(true)]
  106.     public bool IsActive
  107.     {
  108.         get;
  109.         set;
  110.     }
  111. }







Friday, July 31, 2009

Project Euler Problem 1 (C# vs F#)

The problem:

If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.

Find the sum of all the multiples of 3 or 5 below 1000.


C#

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Diagnostics;

namespace Euler

{

class Program

{

//Add all the natural numbers below one thousand that are multiples of 3 or 5.

//0.001 seconds

static void Main(string[] args)

{

Stopwatch sw = new Stopwatch();

sw.Start();

int total = 0;

for (int i = 1; i <>

{

if (i % 3 == 0 || i % 5 == 0)

{

total += i;

}

}

Console.WriteLine("Answer: " + total);

sw.Stop();

Console.WriteLine(sw.Elapsed);

Console.WriteLine(sw.ElapsedTicks);

Console.ReadLine();

}

}

}


The F# solution:

F#

#light

//0096404 milliseconds

open System.Diagnostics

let stopWatch = new Stopwatch()

stopWatch.Start()

printfn "%A" (List.sum(List.filter (fun n-> (n % 3) = 0 or (n % 5) = 0) [1 .. 999]))

stopWatch.Stop();

printfn "%A"stopWatch.Elapsed

printfn "%A"stopWatch.ElapsedTicks

open System

Console.ReadKey(true)




C# does it in

0.001 seconds

3606 ticks


F# does it in

0.0096404 seconds

24380 ticks


There is probably some more efficient way of doing the F#, this was however my first attempt at learning the language. Will have to see how it can do the more tougher problems.