SlideShare a Scribd company logo
1 of 108
Download to read offline
MAINLY CONSOLE APPS AND MVC ENTITY FRAMEWORK ASP
February 1, 2016
Authored by: Chris
Chris Worledge Portfolio 2
A SELECTION OF EXAMPLES OF MORE RECENT WORK
1
ChrisWorledgePortfolio2|2/1/2016
Chris Worledge Portfolio 2
A selection of examples of more recent work
 Page 2 Measuring the Performance of Algorithms (C#)
 Page 36 Exploration of MongoDB using NodeJS
 Page 40 Temporal Data Store (Efficient use of C# Data Structures;
Lists, Dictionaries etc.)
 Page 53 Entity Framework with WebForms
 Page 57 Entity Framework with MVC
 Page 84 Web API with Angular JS
 Page 97 Bank Cash Machine Programme and Database
2
ChrisWorledgePortfolio2|2/1/2016
MEASURING THE PERFORMANCE OF ALGORITHMS
For comparison of different approaches to the same problem I have measured
the performance of two methods of measuring/calculating the digits within all
the numbers from one to any selected number. The problem was described to
me in terms of providing the numbers for doors where door numbers could
exceed 10^12! A less than likely scenario, but it indicated the leading zeros
would not be required.
The CountDigits method actually counts the digits within each number in turn
until the target number is reached. This is the brute force approach which is
ideal within small ranges, but does not scale up well.
The CalculateNumbers method actually adds the numbers of each digit as a
result of each digit in the target number.
A comparative unit test was employed to check they both produce the same
results:
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace CountDigitsUnitTests
{
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
ulong index = 1, next = 1;
for (ulong value = 1; value < 10000000; value = next)
{
ulong[] linear = new CountDigits.DigitCount().CountDigits(value);
ulong[] log = new CountDigits.CountDigits().CalculateNumbers(value);
CollectionAssert.AreEqual(linear, log);
index++;
next = next + index;
}
}
}
}
This test couldn’t cover the complete range of the methods as the time required
to run such a check was prohibitive.
3
ChrisWorledgePortfolio2|2/1/2016
Using 10^8 as a limit took 6 minutes over a whole day!
In Big O notation the first approach has O(n), a linear relationship which can
be ideal with very small number ranges, but has terrible performance with
large numbers, whilst the second has O(log(n)), which is much more scalable to
requirements in modern business environments.
We need System and System.Diagnostics (for the stopwatch class to measure
the execution times).
using System;
using System.Diagnostics;
namespace HotelApplication
{
class Program
{
public static void Main(string[] args)
{
4
ChrisWorledgePortfolio2|2/1/2016
ulong max = 10000000000 ;
//the upper number n in the range 1 to n
var timeTest = Stopwatch.StartNew();//set a stopwatch going
ulong[] digValues = new CountDigits().CalculateNumbers(max);
timeTest.Stop();//call the method, and stop the stopwatch
var elapsedValue = timeTest.Elapsed;
string longStringTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", elapsedValue.Hours,
elapsedValue.Minutes, elapsedValue.Seconds, elapsedValue.Milliseconds);//display the time
and the values
Console.WriteLine("Input: " + max.ToString());
Console.WriteLine("");
Console.WriteLine("Time in milliseconds = " + elapsedValue.TotalMilliseconds.ToString() +
" milliseconds");
Console.WriteLine("");
Console.WriteLine("Time = " + longStringTime);
Console.WriteLine("");
Console.WriteLine("0: " + digValues[0].ToString());
Console.WriteLine("1: " + digValues[1].ToString());
Console.WriteLine("2: " + digValues[2].ToString());
Console.WriteLine("3: " + digValues[3].ToString());
Console.WriteLine("4: " + digValues[4].ToString());
Console.WriteLine("5: " + digValues[5].ToString());
Console.WriteLine("6: " + digValues[6].ToString());
Console.WriteLine("7: " + digValues[7].ToString());
Console.WriteLine("8: " + digValues[8].ToString());
Console.WriteLine("9: " + digValues[9].ToString());
Console.WriteLine("");
//Do the same things again for the other method
var clock = Stopwatch.StartNew();
ulong[] digCount = new DigitCount().CountDigits(max);
clock.Stop();
var elapsedMillis = clock.ElapsedMilliseconds;
var timeelapsed = clock.Elapsed;
string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", timeelapsed.Hours,
timeelapsed.Minutes, timeelapsed.Seconds, timeelapsed.Milliseconds);
Console.WriteLine("Input: " + max.ToString());
Console.WriteLine("");
Console.WriteLine("Time in milliseconds = " + timeelapsed.TotalMilliseconds.ToString() +
" milliseconds");
Console.WriteLine("");
Console.WriteLine("Time = " + elapsedTime);
Console.WriteLine("");
Console.WriteLine("0: " + digCount[0].ToString());
Console.WriteLine("1: " + digCount[1].ToString());
Console.WriteLine("2: " + digCount[2].ToString());
Console.WriteLine("3: " + digCount[3].ToString());
Console.WriteLine("4: " + digCount[4].ToString());
Console.WriteLine("5: " + digCount[5].ToString());
Console.WriteLine("6: " + digCount[6].ToString());
Console.WriteLine("7: " + digCount[7].ToString());
Console.WriteLine("8: " + digCount[8].ToString());
Console.WriteLine("9: " + digCount[9].ToString());
Console.WriteLine("");
5
ChrisWorledgePortfolio2|2/1/2016
Console.WriteLine("Press enter to close...");
Console.ReadLine();
}
}
}
The anticipated outcome would be a linear time to logarithmic input for the
CalculateNumbers method; whilst the CountDigits method would remain linear
against input and become inpractical for large numbers.
The console display for 10^9:
6
ChrisWorledgePortfolio2|2/1/2016
The console display for 10^10:
7
ChrisWorledgePortfolio2|2/1/2016
The console display of 10^11:
An averaging technique was employed to reduce the impact of overhead, and
display the true trend of the underlying algorithm. This was only practical for
the Olog(n) algorithm due to the much increased run times of the O(n)
algorithm. This will have introduced error, but it’s impact would be small.
8
ChrisWorledgePortfolio2|2/1/2016
A table of results shows the performance of each algorithm in ms.
Input Input(scientific) Olog(n) O(n)
1 1.E+00 0.0005 0.3589
10 1.E+01 0.00052 0.0049
100 1.E+02 0.000748 0.0158
1000 1.E+03 0.00984 0.1433
10000 1.E+04 0.001136 1.272
100000 1.E+05 0.001343 18.056
1000000 1.E+06 0.001694 176.6585
10000000 1.E+07 0.001851 1820.4105
100000000 1.E+08 0.002001 19687.2353
1000000000 1.E+09 0.0022248 218771.4353
10000000000 1.E+10 0.002532 2427029.663
100000000000 1.E+11 0.002837 25599515.25
1000000000000 1E+12 0.003152
10000000000000 1E+13 0.003309
100000000000000 1E+14 0.003699
1000000000000000 1E+15 0.004099
10000000000000000 1E+16 0.004624
100000000000000000 1E+17 0.005271
1000000000000000000 1E+18 0.006046
10000000000000000000 1E+19 0.007024
18446744073709551615 1.84467E+19 0.0383061
The O(n) results stop at 10^11 as that took seven and a half hours, so it would
be reasonable to expect 10^12 to take around three days.
A linear comparison of both algorithms, demonstrates the limits of practical
use of the brute force approach.
9
ChrisWorledgePortfolio2|2/1/2016
If the mid point input value of 5 million were related to population, the linear
algorithm would demonstrate poor performance with most town and city
populations, but not cope at all with larger cities or counties, let alone
countries.
Independent charting against a logarithmic input shows the performance
comparison more fully.
0
5000000
10000000
15000000
20000000
25000000
30000000
O(n)
10
ChrisWorledgePortfolio2|2/1/2016
It should be noted that the y axis representing time in milliseconds is very
different on the two plots.
0
0.05
0.1
0.15
0.2
Olog(n)
11
ChrisWorledgePortfolio2|2/1/2016
A complete demo was devised which allowed any number ranges outputs to be
recorded in a text file, and a display of the results of successive powers of ten
finishing with 2^64 – 1.
using System;
using System.Diagnostics;
using System.IO;
namespace CleanDigitCounter
{
class Program
{
static void Main(string[] args)
{
consDemo();//runs a demo using the range of values from 10^0 to 10^19 and
2^64-1
}
private static void consDemo()
{
double[] times = new double[22] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0 };
int index = 0;
ulong max = 1;
while (index <= 19)
{
double totalMiliseconds = 0;
for (int i = 1; i <= 10; i++)
{
var avTest = Stopwatch.StartNew();
ulong[] alues = new CountDigits().CalculateNumbers(max);
avTest.Stop();
totalMiliseconds += avTest.Elapsed.TotalMilliseconds;
}
Console.WriteLine("");
Console.WriteLine("Input: " + max.ToString());
var avElapsedValue = totalMiliseconds / 10;
times[index] += avElapsedValue;
string avElapsed = avElapsedValue.ToString();
Console.WriteLine("Average Milliseconds for Value " + avElapsed);
Console.WriteLine("");
if (max == 1)
{
double totalMilis = 0;
for (int i = 1; i <= 10; i++)
{
var avTest = Stopwatch.StartNew();
ulong[] alues = new CountDigits().CalculateNumbers(max);
avTest.Stop();
totalMilis += avTest.Elapsed.TotalMilliseconds;
}
Console.WriteLine("");
12
ChrisWorledgePortfolio2|2/1/2016
Console.WriteLine("Input: " + max.ToString());
var avValue = totalMilis / 10;
times[index] += avValue;
string av = avValue.ToString();
Console.WriteLine("Average Milliseconds for Value " + av);
Console.WriteLine("");
}
var timeTest = Stopwatch.StartNew();
ulong[] digValues = new CountDigits().CalculateNumbers(max);
timeTest.Stop();
var elapsedValue = timeTest.Elapsed;
string longStringTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
elapsedValue.Hours, elapsedValue.Minutes, elapsedValue.Seconds,
elapsedValue.Milliseconds);
Console.WriteLine("Input: " + max.ToString());
Console.WriteLine("");
Console.WriteLine("Time in milliseconds = " +
elapsedValue.TotalMilliseconds.ToString() + " milliseconds");
Console.WriteLine("");
Console.WriteLine("Time = " + longStringTime);
Console.WriteLine("");
Console.WriteLine("0: " + digValues[0].ToString());
Console.WriteLine("1: " + digValues[1].ToString());
Console.WriteLine("2: " + digValues[2].ToString());
Console.WriteLine("3: " + digValues[3].ToString());
Console.WriteLine("4: " + digValues[4].ToString());
Console.WriteLine("5: " + digValues[5].ToString());
Console.WriteLine("6: " + digValues[6].ToString());
Console.WriteLine("7: " + digValues[7].ToString());
Console.WriteLine("8: " + digValues[8].ToString());
Console.WriteLine("9: " + digValues[9].ToString());
Console.WriteLine("");
if (index < 9)//just so the demo doesn't take weeks to run
{
var clock = Stopwatch.StartNew();
ulong[] digCount = new DigitCount().CountDigits(max);
clock.Stop();
var elapsedMillis = clock.ElapsedMilliseconds;
var timeelapsed = clock.Elapsed;
string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
timeelapsed.Hours, timeelapsed.Minutes, timeelapsed.Seconds, timeelapsed.Milliseconds);
Console.WriteLine("Input: " + max.ToString());
Console.WriteLine("");
Console.WriteLine("Time in milliseconds = " +
timeelapsed.TotalMilliseconds.ToString() + " milliseconds");
Console.WriteLine("");
Console.WriteLine("Time = " + elapsedTime);
13
ChrisWorledgePortfolio2|2/1/2016
Console.WriteLine("");
Console.WriteLine("0: " + digCount[0].ToString());
Console.WriteLine("1: " + digCount[1].ToString());
Console.WriteLine("2: " + digCount[2].ToString());
Console.WriteLine("3: " + digCount[3].ToString());
Console.WriteLine("4: " + digCount[4].ToString());
Console.WriteLine("5: " + digCount[5].ToString());
Console.WriteLine("6: " + digCount[6].ToString());
Console.WriteLine("7: " + digCount[7].ToString());
Console.WriteLine("8: " + digCount[8].ToString());
Console.WriteLine("9: " + digCount[9].ToString());
Console.WriteLine("");
}
max *= 10;
index++;
}
double miliseconds = 0;
ulong maxNumber = 18446744073709551615;
for (int k = 0; k < 10; k++)
{
for (int i = 1; i <= 10; i++)
{
var avTest = Stopwatch.StartNew();
ulong[] alues = new CountDigits().CalculateNumbers(maxNumber);
avTest.Stop();
miliseconds += avTest.Elapsed.TotalMilliseconds;
}
Console.WriteLine("");
Console.WriteLine("Input: " + maxNumber.ToString());
var average = miliseconds / 10;
times[20] += average;
}
double zero = times[0] / 20;
double one = times[1] / 10;
double two = times[2] / 10;
double three = times[3] / 10;
double four = times[4] / 10;
double five = times[5] / 10;
double six = times[6] / 10;
double seven = times[7] / 10;
double eight = times[8] / 10;
double nine = times[9] / 10;
double ten = times[10] / 10;
double eleven = times[11] / 10;
double twelve = times[12] / 10;
double thirteen = times[13] / 10;
double fourteen = times[14] / 10;
double fifteen = times[15] / 10;
double sixteen = times[16] / 10;
double seventeen = times[17] / 10;
double eighteen = times[18] / 10;
double nineteen = times[19] / 10;
double twenty = times[20] / 100;
14
ChrisWorledgePortfolio2|2/1/2016
Console.WriteLine("Average Milliseconds for Value 1 : " + zero.ToString());
Console.WriteLine("");
Console.WriteLine("Average Milliseconds for Value 10 : " + one.ToString());
Console.WriteLine("");
Console.WriteLine("Average Milliseconds for Value 100 : " +
two.ToString());
Console.WriteLine("");
Console.WriteLine("Average Milliseconds for Value 1,000 : " +
three.ToString());
Console.WriteLine("");
Console.WriteLine("Average Milliseconds for Value 10,000 : " +
four.ToString());
Console.WriteLine("");
Console.WriteLine("Average Milliseconds for Value 100,000 : " +
five.ToString());
Console.WriteLine("");
Console.WriteLine("Average Milliseconds for Value 1,000,000 : " +
six.ToString());
Console.WriteLine("");
Console.WriteLine("Average Milliseconds for Value 10,000,000 : " +
seven.ToString());
Console.WriteLine("");
Console.WriteLine("Average Milliseconds for Value 100,000,000 : " +
eight.ToString());
Console.WriteLine("");
Console.WriteLine("Average Milliseconds for Value 1000,000,000 : " +
nine.ToString());
Console.WriteLine("");
Console.WriteLine("Average Milliseconds for Value 10,000,000,000 : " +
ten.ToString());
Console.WriteLine("");
Console.WriteLine("Average Milliseconds for Value 100,000,000,000 : " +
eleven.ToString());
Console.WriteLine("");
Console.WriteLine("Average Milliseconds for Value 1,000,000,000,000 : " +
twelve.ToString());
Console.WriteLine("");
Console.WriteLine("Average Milliseconds for Value 10,000,000,000,000 : " +
thirteen.ToString());
Console.WriteLine("");
Console.WriteLine("Average Milliseconds for Value 100,000,000,000,000 : " +
fourteen.ToString());
Console.WriteLine("");
Console.WriteLine("Average Milliseconds for Value 1,000,000,000,000,000 : "
+ fifteen.ToString());
Console.WriteLine("");
Console.WriteLine("Average Milliseconds for Value 10,000,000,000,000,000 :
" + sixteen.ToString());
Console.WriteLine("");
Console.WriteLine("Average Milliseconds for Value 100,000,000,000,000,000 :
" + seventeen.ToString());
Console.WriteLine("");
Console.WriteLine("Average Milliseconds for Value 1,000,000,000,000,000,000
: " + eighteen.ToString());
Console.WriteLine("");
15
ChrisWorledgePortfolio2|2/1/2016
Console.WriteLine("Average Milliseconds for Value 10,000,000,000,000,000,000
: " + nineteen.ToString());
Console.WriteLine("");
Console.WriteLine("Average Milliseconds for Value 18446744073709551615 : "
+ twenty.ToString());
Console.WriteLine("");
Console.WriteLine("Press enter to close...");
Console.ReadLine();
}
private static void textFile(ulong start, ulong finish)
{
FileStream outstrm;
StreamWriter writer;
TextWriter oldOut = Console.Out;
try
{
outstrm = new FileStream("C:/Test/ConsoleOutput.txt",
FileMode.OpenOrCreate, FileAccess.Write);
writer = new StreamWriter(outstrm);
}
catch (Exception e)
{
Console.WriteLine("Cannot open ConsoleOutput.txt for writing");
Console.WriteLine(e.Message);
return;
}
Console.SetOut(writer);
ulong max;
for (max = start; max < finish; max++)
{
var timeTest = Stopwatch.StartNew();
ulong[] digValues = new CountDigits().CalculateNumbers(max);
timeTest.Stop();
var elapsedValue = timeTest.Elapsed;
string timeVal = elapsedValue.ToString();
string timeS = timeVal.Substring(5, 3);
string timeM = timeVal.Substring(9, 3);
string timeD = timeVal.Substring(12);
string longStringTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
elapsedValue.Hours, elapsedValue.Minutes, elapsedValue.Seconds,
elapsedValue.Milliseconds);
Console.WriteLine("Input: " + max.ToString());
Console.WriteLine("");
Console.WriteLine("Time in milliseconds = " +
elapsedValue.TotalMilliseconds.ToString() + " milliseconds");
Console.WriteLine("");
Console.WriteLine("Time = " + longStringTime);
Console.WriteLine("");
Console.WriteLine("0: " + digValues[0].ToString());
Console.WriteLine("1: " + digValues[1].ToString());
16
ChrisWorledgePortfolio2|2/1/2016
Console.WriteLine("2: " + digValues[2].ToString());
Console.WriteLine("3: " + digValues[3].ToString());
Console.WriteLine("4: " + digValues[4].ToString());
Console.WriteLine("5: " + digValues[5].ToString());
Console.WriteLine("6: " + digValues[6].ToString());
Console.WriteLine("7: " + digValues[7].ToString());
Console.WriteLine("8: " + digValues[8].ToString());
Console.WriteLine("9: " + digValues[9].ToString());
Console.WriteLine("");
var clock = Stopwatch.StartNew();
ulong[] digCount = new DigitCount().CountDigits(max);
clock.Stop();
var elapsedMillis = clock.ElapsedMilliseconds;
var timeelapsed = clock.Elapsed;
string timelapsed = timeelapsed.ToString();
string hrs = timelapsed.Substring(0, 2);
string mins = timelapsed.Substring(3, 2);
string secs = timelapsed.Substring(6, 2);
double milliseconds = 0;
int hours = 0;
int minutes = 0;
int seconds = 0;
int wholeMilis = 0;
int intdecMilis = 0;
double decMilis = 0.0;
int.TryParse(hrs, out hours);
int.TryParse(mins, out minutes);
int.TryParse(secs, out seconds);
string millis = timelapsed.Substring(9, 3);
int.TryParse(millis, out wholeMilis);
string afterDec = timelapsed.Substring(12);
int.TryParse(afterDec, out intdecMilis);
decMilis = (double)intdecMilis / 10000;
milliseconds = (hours * 60 * 60 * 1000) + (minutes * 60 * 1000) +
(seconds * 1000) + wholeMilis + decMilis;
string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
timeelapsed.Hours, timeelapsed.Minutes, timeelapsed.Seconds, timeelapsed.Milliseconds);
Console.WriteLine("Input: " + max.ToString());
Console.WriteLine("");
Console.WriteLine("Time in milliseconds = " +
timeelapsed.TotalMilliseconds.ToString() + " milliseconds");
Console.WriteLine("");
Console.WriteLine("Time = " + elapsedTime);
Console.WriteLine("");
Console.WriteLine("0: " + digCount[0].ToString());
Console.WriteLine("1: " + digCount[1].ToString());
Console.WriteLine("2: " + digCount[2].ToString());
Console.WriteLine("3: " + digCount[3].ToString());
Console.WriteLine("4: " + digCount[4].ToString());
Console.WriteLine("5: " + digCount[5].ToString());
Console.WriteLine("6: " + digCount[6].ToString());
Console.WriteLine("7: " + digCount[7].ToString());
17
ChrisWorledgePortfolio2|2/1/2016
Console.WriteLine("8: " + digCount[8].ToString());
Console.WriteLine("9: " + digCount[9].ToString());
Console.WriteLine("");
}
writer.Close();
outstrm.Close();
Console.SetOut(oldOut);
Console.WriteLine("Done");
Console.WriteLine("Press enter to close...");
Console.ReadLine();
}
}
}
The results:
Input: 1
Average Milliseconds for Value 0.07499
Input: 1
Average Milliseconds for Value 0.00022
Input: 1
Time in milliseconds = 0.0005 milliseconds
Time = 00:00:00.00
0: 0
1: 1
2: 0
3: 0
4: 0
5: 0
6: 0
7: 0
18
ChrisWorledgePortfolio2|2/1/2016
8: 0
9: 0
Input: 1
Time in milliseconds = 0.4146 milliseconds
Time = 00:00:00.00
0: 0
1: 1
2: 0
3: 0
4: 0
5: 0
6: 0
7: 0
8: 0
9: 0
Input: 10
Average Milliseconds for Value 0.00083
Input: 10
Time in milliseconds = 0.002 milliseconds
Time = 00:00:00.00
0: 1
1: 2
2: 1
3: 1
4: 1
5: 1
19
ChrisWorledgePortfolio2|2/1/2016
6: 1
7: 1
8: 1
9: 1
Input: 10
Time in milliseconds = 0.0046 milliseconds
Time = 00:00:00.00
0: 1
1: 2
2: 1
3: 1
4: 1
5: 1
6: 1
7: 1
8: 1
9: 1
Input: 100
Average Milliseconds for Value 0.002
Input: 100
Time in milliseconds = 0.0032 milliseconds
Time = 00:00:00.00
0: 11
1: 21
2: 20
20
ChrisWorledgePortfolio2|2/1/2016
3: 20
4: 20
5: 20
6: 20
7: 20
8: 20
9: 20
Input: 100
Time in milliseconds = 0.0146 milliseconds
Time = 00:00:00.00
0: 11
1: 21
2: 20
3: 20
4: 20
5: 20
6: 20
7: 20
8: 20
9: 20
Input: 1000
Average Milliseconds for Value 0.00142
Input: 1000
Time in milliseconds = 0.0032 milliseconds
21
ChrisWorledgePortfolio2|2/1/2016
Time = 00:00:00.00
0: 192
1: 301
2: 300
3: 300
4: 300
5: 300
6: 300
7: 300
8: 300
9: 300
Input: 1000
Time in milliseconds = 0.1345 milliseconds
Time = 00:00:00.00
0: 192
1: 301
2: 300
3: 300
4: 300
5: 300
6: 300
7: 300
8: 300
9: 300
Input: 10000
22
ChrisWorledgePortfolio2|2/1/2016
Average Milliseconds for Value 0.00167
Input: 10000
Time in milliseconds = 0.0029 milliseconds
Time = 00:00:00.00
0: 2893
1: 4001
2: 4000
3: 4000
4: 4000
5: 4000
6: 4000
7: 4000
8: 4000
9: 4000
Input: 10000
Time in milliseconds = 1.5072 milliseconds
Time = 00:00:00.01
0: 2893
1: 4001
2: 4000
3: 4000
4: 4000
5: 4000
6: 4000
7: 4000
8: 4000
23
ChrisWorledgePortfolio2|2/1/2016
9: 4000
Input: 100000
Average Milliseconds for Value 0.00193
Input: 100000
Time in milliseconds = 0.0029 milliseconds
Time = 00:00:00.00
0: 38894
1: 50001
2: 50000
3: 50000
4: 50000
5: 50000
6: 50000
7: 50000
8: 50000
9: 50000
Input: 100000
Time in milliseconds = 15.5442 milliseconds
Time = 00:00:00.15
0: 38894
1: 50001
2: 50000
3: 50000
4: 50000
5: 50000
24
ChrisWorledgePortfolio2|2/1/2016
6: 50000
7: 50000
8: 50000
9: 50000
Input: 1000000
Average Milliseconds for Value 0.00286
Input: 1000000
Time in milliseconds = 0.0029 milliseconds
Time = 00:00:00.00
0: 488895
1: 600001
2: 600000
3: 600000
4: 600000
5: 600000
6: 600000
7: 600000
8: 600000
9: 600000
Input: 1000000
Time in milliseconds = 171.8509 milliseconds
Time = 00:00:00.171
0: 488895
1: 600001
2: 600000
25
ChrisWorledgePortfolio2|2/1/2016
3: 600000
4: 600000
5: 600000
6: 600000
7: 600000
8: 600000
9: 600000
Input: 10000000
Average Milliseconds for Value 0.00262
Input: 10000000
Time in milliseconds = 0.0029 milliseconds
Time = 00:00:00.00
0: 5888896
1: 7000001
2: 7000000
3: 7000000
4: 7000000
5: 7000000
6: 7000000
7: 7000000
8: 7000000
9: 7000000
Input: 10000000
Time in milliseconds = 1903.8346 milliseconds
Time = 00:00:01.903
26
ChrisWorledgePortfolio2|2/1/2016
0: 5888896
1: 7000001
2: 7000000
3: 7000000
4: 7000000
5: 7000000
6: 7000000
7: 7000000
8: 7000000
9: 7000000
Input: 100000000
Average Milliseconds for Value 0.00182
Input: 100000000
Time in milliseconds = 0.0029 milliseconds
Time = 00:00:00.00
0: 68888897
1: 80000001
2: 80000000
3: 80000000
4: 80000000
5: 80000000
6: 80000000
7: 80000000
8: 80000000
9: 80000000
27
ChrisWorledgePortfolio2|2/1/2016
Input: 1000000000
Average Milliseconds for Value 0.00197
Input: 1000000000
Time in milliseconds = 0.0023 milliseconds
Time = 00:00:00.00
0: 788888898
1: 900000001
2: 900000000
3: 900000000
4: 900000000
5: 900000000
6: 900000000
7: 900000000
8: 900000000
9: 900000000
Input: 10000000000
Average Milliseconds for Value 0.00253
Input: 10000000000
Time in milliseconds = 0.0026 milliseconds
Time = 00:00:00.00
0: 8888888899
1: 10000000001
2: 10000000000
3: 10000000000
4: 10000000000
5: 10000000000
28
ChrisWorledgePortfolio2|2/1/2016
6: 10000000000
7: 10000000000
8: 10000000000
9: 10000000000
Input: 100000000000
Average Milliseconds for Value 0.00269
Input: 100000000000
Time in milliseconds = 0.0032 milliseconds
Time = 00:00:00.00
0: 98888888900
1: 110000000001
2: 110000000000
3: 110000000000
4: 110000000000
5: 110000000000
6: 110000000000
7: 110000000000
8: 110000000000
9: 110000000000
Input: 1000000000000
Average Milliseconds for Value 0.00296
Input: 1000000000000
Time in milliseconds = 0.0035 milliseconds
Time = 00:00:00.00
0: 1088888888901
1: 1200000000001
29
ChrisWorledgePortfolio2|2/1/2016
2: 1200000000000
3: 1200000000000
4: 1200000000000
5: 1200000000000
6: 1200000000000
7: 1200000000000
8: 1200000000000
9: 1200000000000
Input: 10000000000000
Average Milliseconds for Value 0.00475
Input: 10000000000000
Time in milliseconds = 0.0035 milliseconds
Time = 00:00:00.00
0: 11888888888902
1: 13000000000001
2: 13000000000000
3: 13000000000000
4: 13000000000000
5: 13000000000000
6: 13000000000000
7: 13000000000000
8: 13000000000000
9: 13000000000000
Input: 100000000000000
Average Milliseconds for Value 0.00391
30
ChrisWorledgePortfolio2|2/1/2016
Input: 100000000000000
Time in milliseconds = 0.0046 milliseconds
Time = 00:00:00.00
0: 128888888888903
1: 140000000000001
2: 140000000000000
3: 140000000000000
4: 140000000000000
5: 140000000000000
6: 140000000000000
7: 140000000000000
8: 140000000000000
9: 140000000000000
Input: 1000000000000000
Average Milliseconds for Value 0.00469
Input: 1000000000000000
Time in milliseconds = 0.0041 milliseconds
Time = 00:00:00.00
0: 1388888888888904
1: 1500000000000001
2: 1500000000000000
3: 1500000000000000
4: 1500000000000000
5: 1500000000000000
6: 1500000000000000
7: 1500000000000000
31
ChrisWorledgePortfolio2|2/1/2016
8: 1500000000000000
9: 1500000000000000
Input: 10000000000000000
Average Milliseconds for Value 0.00479
Input: 10000000000000000
Time in milliseconds = 0.0055 milliseconds
Time = 00:00:00.00
0: 14888888888888905
1: 16000000000000001
2: 16000000000000000
3: 16000000000000000
4: 16000000000000000
5: 16000000000000000
6: 16000000000000000
7: 16000000000000000
8: 16000000000000000
9: 16000000000000000
Input: 100000000000000000
Average Milliseconds for Value 0.00457
Input: 100000000000000000
Time in milliseconds = 0.0046 milliseconds
Time = 00:00:00.00
0: 158888888888888906
1: 170000000000000001
2: 170000000000000000
32
ChrisWorledgePortfolio2|2/1/2016
3: 170000000000000000
4: 170000000000000000
5: 170000000000000000
6: 170000000000000000
7: 170000000000000000
8: 170000000000000000
9: 170000000000000000
Input: 1000000000000000000
Average Milliseconds for Value 0.0049
Input: 1000000000000000000
Time in milliseconds = 0.0052 milliseconds
Time = 00:00:00.00
0: 1688888888888888907
1: 1800000000000000001
2: 1800000000000000000
3: 1800000000000000000
4: 1800000000000000000
5: 1800000000000000000
6: 1800000000000000000
7: 1800000000000000000
8: 1800000000000000000
9: 1800000000000000000
Input: 10000000000000000000
Average Milliseconds for Value 0.0055
Input: 10000000000000000000
33
ChrisWorledgePortfolio2|2/1/2016
Time in milliseconds = 0.0061 milliseconds
Time = 00:00:00.00
0: 17888888888888888908
1: 553255926290448385
2: 553255926290448384
3: 553255926290448384
4: 553255926290448384
5: 553255926290448384
6: 553255926290448384
7: 553255926290448384
8: 553255926290448384
9: 553255926290448384
Input: 18446744073709551615
Input: 18446744073709551615
Input: 18446744073709551615
Input: 18446744073709551615
Input: 18446744073709551615
Input: 18446744073709551615
Input: 18446744073709551615
Input: 18446744073709551615
Input: 18446744073709551615
Input: 18446744073709551615
Average Milliseconds for Value 1 : 0.0044365
Average Milliseconds for Value 10 : 8.3E-05
34
ChrisWorledgePortfolio2|2/1/2016
Average Milliseconds for Value 100 : 0.0002
Average Milliseconds for Value 1,000 : 0.000142
Average Milliseconds for Value 10,000 : 0.000167
Average Milliseconds for Value 100,000 : 0.000193
Average Milliseconds for Value 1,000,000 : 0.000286
Average Milliseconds for Value 10,000,000 : 0.000262
Average Milliseconds for Value 100,000,000 : 0.000182
Average Milliseconds for Value 1000,000,000 : 0.000197
Average Milliseconds for Value 10,000,000,000 : 0.000253
Average Milliseconds for Value 100,000,000,000 : 0.000269
Average Milliseconds for Value 1,000,000,000,000 : 0.000296
Average Milliseconds for Value 10,000,000,000,000 : 0.000475
Average Milliseconds for Value 100,000,000,000,000 : 0.000391
Average Milliseconds for Value 1,000,000,000,000,000 : 0.000469
35
ChrisWorledgePortfolio2|2/1/2016
Average Milliseconds for Value 10,000,000,000,000,000 : 0.000479
Average Milliseconds for Value 100,000,000,000,000,000 : 0.000457
Average Milliseconds for Value 1,000,000,000,000,000,000 : 0.00049
Average Milliseconds for Value 10,000,000,000,000,000,000 : 0.00055
Average Milliseconds for Value 18446744073709551615 : 0.0029604
Press enter to close...
36
ChrisWorledgePortfolio2|2/1/2016
EXPLORATION OF MONGODB USING NODEJS
This was achieved following a Microsoft Tutorial
Links the app to the database instance, we can then pass the database
instance to the MongoDB Client and populate and interrogate it as follows:
37
ChrisWorledgePortfolio2|2/1/2016
38
ChrisWorledgePortfolio2|2/1/2016
We perform CRUD operations out of sequence. Create; Update; Retrieve; and
Delete.
39
ChrisWorledgePortfolio2|2/1/2016
40
ChrisWorledgePortfolio2|2/1/2016
C# TEMPORAL DATA STORE
You will be implementing a read-biased in-memory temporal data store.
A temporal store allows point-in-time queries about data. An example would be
the price of an exchange traded security. We might capture the price of the
security once an hour throughout the trading day, and store the price in a
temporal store. We can then query the temporal store to determine at any given
time, what the most recent captured price was.
This example illustrates the following key terms, which will be used throughout
this document:
1. Identifier - a key (e.g. the security id), for which we want to store a
history of observations
2. History - the list of observations for a given identifier
3. Observation - a piece of data which is associated with a particular
identifier at a particular timestamp
4. Timestamp - a given point in time
The latest observation for an identifier at a timestamp is found by searching in
the identifier's history for the first observation whose timestamp is less than, or
equal to, the sought timestamp.
For the purposes of this scenario, you should assume the following:
1. Identifiers are integers in the inclusive range [0..2^31 - 1]
2. Timestamps are integers in the inclusive range [0..2^63 - 1]
3. Data is represented as a contiguous string of non-whitespace
characters. For example, "jiggawatt" is a valid piece of data. The string "great
scot" is not, owing to its whitespace.
4. Users may interact with the temporal store, as well as processes. you
should be strict in what data you accept, but should provide suitable error
messages where the user has erred.
5. Capacity; there is no requirement to restrict your store to a given size,
but you may assume that you will be provided with no more than 10,000
identifiers, each with no more than 1,000 history entries, and no data item will
be no more than 16 characters.
41
ChrisWorledgePortfolio2|2/1/2016
Your temporal data store will communicate with other processes via standard
input and output. A series of commands are read and applied to the data store
from standard input. The results of evaluating the commands should be
written to standard output. A command will only ever be one line; the result of
executing a command will be a single output line, except for the QUIT
command.
When there are no more lines to consume, your temporal data store should
exit. There is no need to persist data in the store between executions (this is an
in-memory temporal store).
class Program
{
static void Main(string[] args)
{
/*Holds the references to all the history stores, so we can find the required
history if it exists*/
List<DataDict> contain = new List<DataDict>();
//We make a few histories (from 0 - 4) and populate them with dummy data
for (int i = 0; i < 5; i++)
{
string j = "100";
string k = "1.1";
string dummy = "FirstCreate " + i + " " + j + " " + k;
new CommandHandler(dummy, contain);
}
for (int i = 0; i < 5; i++)
{
var p = 110;
var q = 1.2;
for (int l = 0; l < 10; l++)
{
string dummy = "FirstUpdate " + i.ToString() + " " + p.ToString() + "
" + q.ToString();
new CommandHandler(dummy, contain);
p = p + 10;
q = q + 0.1;
}
}
//Cue the console up, ready to receive user input
string line;
line = Console.ReadLine();
if (line != null)
{
new CommandHandler(line, contain);
}
}
}
42
ChrisWorledgePortfolio2|2/1/2016
The commands which can be executed against your data store are described
below. Note that:
- Items in <angle brackets> represent required arguments, but the angle
brackets themselves do not form part of the command
- Items in [square brackets] are optional arguments
- Successfully processed commands should always start their response with
"OK ", followed by the result of executing the command
- Commands which could not be executed should always start their response
with "ERR ", followed by a reasonable error message.
- Commands are not sensitive to whitespace; arguments must be separated by
at least one character of whitespace, but may be separated by more.
CREATE <id> <timestamp> <data>
- Creates a new history for the given identifier, if there is no existing
history. Adds an observation to the newly created history for the given
timestamp and data. CREATE should not be executed if the provided identifier
already has a history. Returns the data which was inserted, to confirm
insertion.
UPDATE <id> <timestamp> <data>
- Inserts an observation for the given identifier, timestamp and data.
Returns the data from the prior observation for that timestamp.
DELETE <id> [timestamp]
- If timestamp is provided, deletes all observations for the given identifier
from that timestamp forward. Returns the current observation at the given
timestamp, or an error if there is no available observation.
- If timestamp is not provided, deletes the history for the given identifier,
and returns the observation with the greatest timestamp from the history
which has been deleted.
43
ChrisWorledgePortfolio2|2/1/2016
GET <id> <timestamp>
- Returns the data from the observation for the given identifier at the given
timestamp, or an error if there is no available observation.
LATEST <id>
- Locates the observation with the greatest timestamp from the history for
the given identifier, and responds with its timestamp and data.
QUIT - Terminates the process immediately. No response should be written.
We use a List to store references to a series of Dictionaries, one for
each security.
class CommandHandler
{
string id = string.Empty;
string timeStamp = string.Empty;
string data = string.Empty;
string Command = string.Empty;
int ID;
long dateTime;
string line;
public CommandHandler(string command, List<DataDict> contain)
{
//separate out the different elements of the user input
char[] seperator = new char[] { ' ' };
string[] commands = command.Split(seperator,
StringSplitOptions.RemoveEmptyEntries);
Command = commands[0].Trim().ToLower();
if (commands.Count() > 1)
{
id = commands[1].Trim();
}
if (commands.Count() > 2)
{
timeStamp = commands[2].Trim();
}
if (commands.Count() > 3)
{
data = commands[3].Trim();
}
switch (Command)
{
case "create":
Create(contain);
44
ChrisWorledgePortfolio2|2/1/2016
break;
case "update":
Update(contain);
break;
case "delete":
Delete(contain);
break;
case "get":
Get(contain);
break;
case "latest":
Latest(contain);
break;
//These two are just to provide some intial values, so little comms with
user
case "firstcreate":
FirstCreate(contain);
break;
case "firstupdate":
FirstUpdate(contain);
break;
case "quit":
Environment.Exit(0);
break;
default:
Console.WriteLine("I am sorry, I do not understand that command.");
line = Console.ReadLine();
if (line != null)
{
new CommandHandler(line, contain);
}
break;
}
}
protected void Create(List<DataDict> contain)
{
if (int.TryParse(id, out ID))
{
int index = contain.FindIndex(e => e.Name == ID);
if (index >= 0)
{
Console.WriteLine("Error: The history already exists for ID '" + ID +
"'");
45
ChrisWorledgePortfolio2|2/1/2016
}
else
{
DataDict n = new DataDict(ID);
contain.Add(n);//adds the reference to the history store in the
container list
if (long.TryParse(timeStamp, out dateTime))
{
n.Add(dateTime, data);
Console.WriteLine("OK " + data.ToString());
}
else
{
Console.WriteLine("Error: The DateTime value provided is invalid.
Please ensure you provide a valid DateTime value.");
}
}
}
line = Console.ReadLine();
if (line != null)
{
new CommandHandler(line, contain);
}
}
protected void Update(List<DataDict> contain)
{
if (int.TryParse(id, out ID))
{
int index = -1;
index = contain.FindIndex(e => e.Name == ID);
if (index >= 0)
{
var n = (from DataList in contain
where DataList.Name == ID
select DataList).FirstOrDefault();
if (long.TryParse(timeStamp, out dateTime))
{
int exists = -1;
exists = n.DoesExist(dateTime);
string previous = string.Empty;
if (exists > 0)
{
previous = n.Update(dateTime, data);
}
else
{
previous = n.Add(dateTime, data);
}
Console.WriteLine("OK " + previous);
}
else
{
Console.WriteLine("Error: The DateTime value provided is invalid.
Please ensure you provide a valid DateTime value.");
}
46
ChrisWorledgePortfolio2|2/1/2016
}
else
{
Console.WriteLine("Error: No history exists for identifier '" +
ID.ToString() + "' ");
}
}
else
{
Console.WriteLine("Error: The ID provided is invalid. Please ensure it is
a number.");
}
line = Console.ReadLine();
if (line != null)
{
new CommandHandler(line, contain);
}
}
protected void Delete(List<DataDict> contain)
{
if (int.TryParse(id, out ID))
{
int index = contain.FindIndex(e => e.Name == ID);
if (index >= 0)
{
var n = (from DataList in contain
where DataList.Name == ID
select DataList).FirstOrDefault();
if (long.TryParse(timeStamp, out dateTime))
{
KeyValuePair<long, string> got = n.Specific(dateTime);
n.deleteAfter(dateTime);
Console.WriteLine("OK " + got.Value.ToString());
}
//if there is no timestamp, remove the whole list
else
{
string newestValue = n.Latest().Value;
contain.Remove(n);
Console.WriteLine("OK " + newestValue);
}
}
else
{
Console.WriteLine("Error: The ID provided [" + ID.ToString() + "] has
no history. Please ensure you provide a valid ID.");
}
}
else
{
Console.WriteLine("Error: The ID provided is Invalid. Please ensure it is
a number.");
}
line = Console.ReadLine();
if (line != null)
47
ChrisWorledgePortfolio2|2/1/2016
{
new CommandHandler(line, contain);
}
}
protected void Get(List<DataDict> contain)
{
if (int.TryParse(id, out ID))
{
int index = contain.FindIndex(e => e.Name == ID);
if (index >= 0)
{
var n = (from DataList in contain
where DataList.Name == ID
select DataList).FirstOrDefault();
if (long.TryParse(timeStamp, out dateTime))
{
if (n.ExistsOrLess(dateTime) > 0)
{
KeyValuePair<long, string> got = n.Specific(dateTime);
Console.WriteLine("OK " + got.Value.ToString());
}
else
{
Console.WriteLine("Error: The ID provided [" + ID.ToString()
+ "] has no history prior to the supplied DateTime value.");
}
}
else
{
Console.WriteLine("Error: The DateTime value provided is invalid.
Please ensure you provide a valid DateTime value.");
}
}
else
{
Console.WriteLine("Error: The ID provided [" + ID.ToString() + "] has
no history. Please ensure you provide a valid ID.");
}
}
else
{
Console.WriteLine("Error: The ID provided is Invalid. Please ensure it is
a number.");
}
line = Console.ReadLine();
if (line != null)
{
new CommandHandler(line, contain);
}
}
protected void Latest(List<DataDict> contain)
{
if (int.TryParse(id, out ID))
{
48
ChrisWorledgePortfolio2|2/1/2016
int index = contain.FindIndex(e => e.Name == ID);
if (index >= 0)
{
var n = (from DataList in contain
where DataList.Name == ID
select DataList).FirstOrDefault();
KeyValuePair<long, string> latest = n.Latest();
Console.WriteLine("OK " + latest.Key.ToString() + " " +
latest.Value.ToString());
}
else
{
Console.WriteLine("Error: No history exists for identifier '" +
ID.ToString() + "' ") ;
}
}
else
{
Console.WriteLine("Error: The ID provided is Invalid. Please ensure it is
a number.");
}
line = Console.ReadLine();
if (line != null)
{
new CommandHandler(line, contain);
}
}
protected void FirstCreate(List<DataDict> contain)
{
if (int.TryParse(id, out ID))
{
int index = contain.FindIndex(e => e.Name == ID);
if (index >= 0)
{
Console.WriteLine("Error: The id value " + ID.ToString() + " already
exists");
}
else
{
DataDict n = new DataDict(ID);
contain.Add(n);//adds the reference to the history store in the
container list
if (long.TryParse(timeStamp, out dateTime))
{
DataItem d = new DataItem(data, dateTime);
n.Add(dateTime, data);//the first record in the history
Console.WriteLine("OK " + data.ToString());
}
}
}
}
protected void FirstUpdate(List<DataDict> contain)
{
if (int.TryParse(id, out ID))
49
ChrisWorledgePortfolio2|2/1/2016
{
var n = (from DataList in contain
where DataList.Name == ID
select DataList).FirstOrDefault();
if (long.TryParse(timeStamp, out dateTime))
{
n.Add(dateTime, data);//additional records in the history
Console.WriteLine("OK " + data.ToString());
}
}
}
}
class DataDict
{
int name;
/*the Property only has an accessor to prevent accidental edit.
It allows multiple records to be stored and retrieved against the same ID
This structure allows you to access just the information relating to the ID
(Security) submitted
The alternative of putting all records in one list would mean selecting the
required ID from
the dictionary into a working dictionary each time, or working within the clutter
of many irrelevant records */
public int Name { get { return name; } }
public SortedDictionary<long, string> dataDict { get; set; }
public DataDict(int n)
{
name = n;
dataDict = new SortedDictionary<long, string>();
}
public string Add(long timePassed, string data)
{
string prev = string.Empty;
long prevKey = -1;
if (dataDict.Keys.Count > 0)
{
prevKey = dataDict.Keys.Max();
}
if (prevKey >= 0)
{
var previous = dataDict.Where(x => x.Key == prevKey).First();
prev = previous.Value;
}
else { prev = "not available"; }
dataDict.Add(timePassed, data);
return prev;
}
public int DoesExist(long dateTime)
50
ChrisWorledgePortfolio2|2/1/2016
{
if (dataDict.ContainsKey(dateTime))
{
return 1;
}
else
{
return 0;
}
}
public string Update(long timePassed, string data)
{
string prev = string.Empty;
var previous = dataDict.FirstOrDefault(e => e.Key == timePassed);
prev = previous.Value;
dataDict.Remove(timePassed);
dataDict.Add(timePassed, data);
return prev;
}
public string getBiggestData()
{
return dataDict.Values.Max().ToString();
}
public int ExistsOrLess(long dateTime)
{
var allUnder = dataDict.Where(e => e.Key <= dateTime);
if (allUnder.Count() > 0)
{
return 1;
}
else
{
return 0;
}
}
public KeyValuePair<long, string> Specific(long dateTime)
{
if (dataDict.ContainsKey(dateTime))
{
return dataDict.FirstOrDefault(e => e.Key == dateTime);
}
else
{
var allUnder = dataDict.Where(e => e.Key < dateTime);
return allUnder.Last();
}
}
51
ChrisWorledgePortfolio2|2/1/2016
public void deleteBefore(long dateTime)
{
SortedDictionary<long, string> tempDict = new SortedDictionary<long,
string>(dataDict.Where(e => e.Key >= dateTime).ToDictionary(e => e.Key, e => e.Value));
dataDict = tempDict;
}
public void deleteAfter(long dateTime)
{
SortedDictionary<long, string> tempDict = new SortedDictionary<long,
string>(dataDict.Where(e => e.Key <= dateTime).ToDictionary(e => e.Key, e => e.Value));
dataDict = tempDict;
}
public KeyValuePair<long, string> Latest()
{
long highest = dataDict.Keys.Max();
return dataDict.Where(x => x.Key == highest).First();
}
}
52
ChrisWorledgePortfolio2|2/1/2016Zero to four were used in the automated demo, so five and six have been used
in place of 0 & 1 in the manual demo.
53
ChrisWorledgePortfolio2|2/1/2016
ENTITY FRAMEWORK WITH WEBFORMS
An example of displaying the relationships between different staff from a
database using entity framework and web forms:
Data
ID ForeName SurName Manager
0 Lucy Atwell NULL
1 Carla Barns 0
2 Tara Crane 0
3 Freda Dunbarr 0
4 Patricia Edwards 1
5 Vicky Fox 1
6 Margaret Grant 2
7 Cindy Hall 2
8 Kirsty Irwin 3
10 Jane James 3
ID EmpID JobID
1 0 1
2 1 2
3 2 4
4 3 6
5 4 3
6 5 5
7 6 7
8 7 3
9 8 5
10 9 7
11 10 7
54
ChrisWorledgePortfolio2|2/1/2016
ID Job
1 Pharmacist
2 Physiotherapist
3 Cardiac Technician
4 Radiographer
5 Phlebotomist
6 Biomedical Scientist
7 Pharmacy Technician
Data Access Classes
public partial class Ldemo : DataContext
{
public Table<Emp> Emp;
public Table<EmpJob> EmpJob;
public Table<Job> Job;
public Ldemo(string connection) : base(connection) { }
}
public class Relationship
{
public String Forename { get; set; }
public String Surname { get; set; }
public String Job { get; set; }
public String Manager { get; set; }
public Relationship(String f, String s, String j, String m) {
Forename = f;
Surname = s;
Job = j;
Manager = m;
}
}
Form Code Behind
public partial class Page1 : System.Web.UI.Page
{
public List<Relationship> relations = new List<Relationship>();
protected void Page_Load(object sender, EventArgs e)
{
var conString =
System.Configuration.ConfigurationManager.ConnectionStrings["LinqDemoConnectionString"].T
oString();
Ldemo db = new Ldemo(conString);
relations = (from a in db.Emp
join b in db.Emp on new { Manager =
a.Manager.GetValueOrDefault(-1) } equals new { Manager = b.ID } into b_join
55
ChrisWorledgePortfolio2|2/1/2016
from b in b_join.DefaultIfEmpty()
join EmpJobs in db.EmpJob on new { ID = a.ID } equals new { ID =
EmpJobs.EmpID }
join Jobs in db.Job on new { JobID = EmpJobs.JobID } equals new
{ JobID = Jobs.ID }
select new Relationship(
a.ForeName,
a.SurName,
Jobs.Job1,
b.ForeName + " " + b.SurName
)).ToList();
}
}
The code creates a list called relations which holds all of the staff names with
their job and their manager. Since Lucy Atwell’s manager field contains null,
her manager field should be blank. All the other staff have a number
representing another member of staff is their manager.
Form aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Page1.aspx.cs"
Inherits="LinqDemo.Page1" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<table>
<tr>
<td><b>Forename</b></td>
<td><b>Surname</b></td>
<td><b>Job</b></td>
<td><b>Manager</b></td>
</tr>
<% foreach (var relation in relations) { %>
<tr><td><%= relation.Forename %></td>
<td><%= relation.Surname %></td>
<td><%= relation.Job %></td>
<td><%= relation.Manager %></td></tr>
<% } %>
</table>
</div>
</form>
</body>
</html>
56
ChrisWorledgePortfolio2|2/1/2016
The outcome:
57
ChrisWorledgePortfolio2|2/1/2016
ENTITY FRAMEWORK WITH MVC
This application demonstrates the use of entity framework 6 with an MVC5
asp.net (C#) 4.5 combination:
The purpose of the application is to store, retrieve, and display information
about shares.
It has different markets; shares; and share prices, so displays tables of these
allowing Create; Read; Update; and Delete functionality. It also allows display of
tables sorted by different parameters, and a view of just the most recent prices
for each share. The prices and shares table’s pages have a chart facility which
provides a line chart of the selected share price over time.
This is the Home page from the navigation bar along the top.
The subsequent shots follow along the navigation bar (List of stocks; List of
markets; List of prices; Sorted list of prices; Latest prices).
58
ChrisWorledgePortfolio2|2/1/2016
59
ChrisWorledgePortfolio2|2/1/2016
60
ChrisWorledgePortfolio2|2/1/2016
61
ChrisWorledgePortfolio2|2/1/2016
From the Prices list the chart button click for Jones gives:
62
ChrisWorledgePortfolio2|2/1/2016
From the Stocks page the charts link click for Browns gives:
Adding a new price:
The current date and time is inserted for you, and you select the stock from the
drop-down.
63
ChrisWorledgePortfolio2|2/1/2016
Models:
namespace MVC5ef6.Models
{
using System;
using System.Collections.Generic;
public partial class Stock
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage",
"CA2214:DoNotCallOverridableMethodsInConstructors")]
public Stock()
{
this.Prices = new HashSet<Price>();
}
public int stockID { get; set; }
public string stockName { get; set; }
public Nullable<int> marketID { get; set; }
public virtual Market Market { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage",
"CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Price> Prices { get; set; }
}
public partial class Market
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage",
"CA2214:DoNotCallOverridableMethodsInConstructors")]
public Market()
{
this.Stocks = new HashSet<Stock>();
}
public int marketID { get; set; }
public string marketName { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage",
"CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Stock> Stocks { get; set; }
}
public partial class Price
{
public int ID { get; set; }
public Nullable<int> stockID { get; set; }
public Nullable<System.DateTime> Stamp { get; set; }
public Nullable<decimal> Pence { get; set; }
public virtual Stock Stock { get; set; }
}
public partial class LatestPrice
{
64
ChrisWorledgePortfolio2|2/1/2016
public long ID { get; set; }
public string stockName { get; set; }
public string marketName { get; set; }
public Nullable<System.DateTime> Stamp { get; set; }
public Nullable<decimal> Pence { get; set; }
}
public partial class PriceListItem
{
public int ID { get; set; }
public Nullable<int> stockID { get; set; }
public Nullable<System.DateTime> Stamp { get; set; }
public Nullable<decimal> Pence { get; set; }
public string stockName { get; set; }
}
public class StockPriceModel
{
public int ID { get; set; }
public string ChartTitle { get; set; }
public string StampTitle { get; set; }
public string PenceTitle { get; set; }
public int stockID { get; set; }
public StockPrice PriceData { get; set; }
}
public class StockPrice
{
public int ID { get; set; }
public string Stamp { get; set; }
public decimal Pence { get; set; }
}
}
Views:
Shared: _Layout;
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>@ViewBag.Title - My ASP.NET Application</title>
@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/modernizr")
@Scripts.Render("~/bundles/jquery")
<script type="text/javascript"
src="https://www.gstatic.com/charts/loader.js"></script>
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
65
ChrisWorledgePortfolio2|2/1/2016
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-
target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
@Html.ActionLink("Share Prices", "Index", "Home", new { area = "" }, new
{ @class = "navbar-brand" })
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li>@Html.ActionLink("Home", "Index", "Home")</li>
<li>@Html.ActionLink("List of stocks", "Index", "Stocks")</li>
<li>@Html.ActionLink("List of markets", "Index", "Markets")</li>
<li>@Html.ActionLink("List of prices", "Index", "Prices")</li>
<li>@Html.ActionLink("Sorted List of prices", "Index",
"PriceListItems")</li>
<li>@Html.ActionLink("Latest Prices", "Index", "LatestPrices")</li>
</ul>
</div>
</div>
</div>
<div class="container body-content">
<h1></h1>
@RenderBody()
<!-- <hr /> -->
<footer>
<p>&copy; @DateTime.Now.Year - MVC5 with entity framework 6 application</p>
</footer>
</div>
@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/bootstrap")
@RenderSection("scripts", required: false)
</body>
</html>
Home: Index;
@{
ViewBag.Title = "Home Page";
}
<div class="jumbotron">
<h1>A short - cut to the latest prices</h1>
<h2>
Each stock's latest price, ordered by market.
<a>
@Html.ActionLink("Latest Prices", "Index", "LatestPrices", null, new { @class
= "btn btn-primary btn-lg actionLink" })
</a>
</h2>
</div>
<div>
66
ChrisWorledgePortfolio2|2/1/2016
<div class="spacer"></div>
</div>
<div class="row">
<div class="col-md-4">
<h2>See the Stocks</h2>
<a>@Html.ActionLink("List of stocks", "Index", "Stocks", null, new {@class= "btn
btn-primary btn-lg actionLink" }) </a>
</div>
<div class="col-md-4">
<h2>See the Markets</h2>
<a>@Html.ActionLink("List of markets", "Index", "Markets", null, new { @class =
"btn btn-primary btn-lg actionLink" })</a>
</div>
<div class="col-md-4">
<h2>See the Prices</h2>
<a>@Html.ActionLink("List of prices", "Index", "PriceListItems", null, new {
@class = "btn btn-primary btn-lg actionLink" }) </a>
</div>
<div class="spacer"></div>
<div class="spacer"></div>
<div class="spacer"></div>
<div class="spacer"></div>
</div>
Stocks: Index;
@model IEnumerable<MVC5ef6.Models.Stock>
@{
ViewBag.Title = "Index";
}
<div class="spacer"></div>
<h2>Table of Stocks</h2>
<p>
@Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
@Html.DisplayNameFor(model => model.stockName)
</th>
<th>
@Html.DisplayNameFor(model => model.Market.marketName)
</th>
<th></th>
</tr>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.stockName)
67
ChrisWorledgePortfolio2|2/1/2016
</td>
<td>
@Html.DisplayFor(modelItem => item.Market.marketName)
</td>
<td>
@Html.ActionLink("Chart", "Chart", new { id = item.stockID }, new { @class =
"actionLink" }) |
@Html.ActionLink("Edit", "Edit", new { id=item.stockID }, new { @class =
"actionLink" }) |
@Html.ActionLink("Details", "Details", new { id=item.stockID }, new { @class
= "actionLink" }) |
@Html.ActionLink("Delete", "Delete", new { id=item.stockID }, new { @class =
"actionLink" })
</td>
</tr>
}
</table>
Markets: Index;
@model IEnumerable<MVC5ef6.Models.Market>
@{
ViewBag.Title = "Index";
}
<div class="spacer"></div>
<h2>Table of Markets</h2>
<p>
@Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
@Html.DisplayNameFor(model => model.marketName)
</th>
<th></th>
</tr>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.marketName)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { id=item.marketID }, new { @class =
"actionLink" }) |
@Html.ActionLink("Details", "Details", new { id=item.marketID }, new { @class
= "actionLink" }) |
@Html.ActionLink("Delete", "Delete", new { id=item.marketID }, new { @class =
"actionLink" })
</td>
</tr>
}
68
ChrisWorledgePortfolio2|2/1/2016
</table>
Prices: Index;
@model IEnumerable<MVC5ef6.Models.Price>
@{
ViewBag.Title = "Prices";
}
<div class="spacer" ></div>
<h2>Table of Prices</h2>
<p>
@Html.ActionLink("Create New", "Create", null, new { @class = "actionLink" })
</p>
<table class="table">
<tr>
<th>
@Html.DisplayNameFor(model => model.Stamp)
</th>
<th>
@Html.DisplayNameFor(model => model.Pence)
</th>
<th>
@Html.DisplayNameFor(model => model.Stock.stockName)
</th>
<th></th>
</tr>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.Stamp)
</td>
<td>
@Html.DisplayFor(modelItem => item.Pence)
</td>
<td>
@Html.DisplayFor(modelItem => item.Stock.stockName)
</td>
<td>
@Html.ActionLink("Chart", "Chart", new { id = item.stockID }, new {
@class = "actionLink" }) |
@Html.ActionLink("Edit", "Edit", new { id = item.ID }, new { @class =
"actionLink" }) |
@Html.ActionLink("Details", "Details", new { id = item.ID }, new {
@class = "actionLink" }) |
@Html.ActionLink("Delete", "Delete", new { id = item.ID }, new {
@class = "actionLink" })
</td>
</tr>
}
</table>
69
ChrisWorledgePortfolio2|2/1/2016
PriceListItems (sorted list): Index;
@model IEnumerable<MVC5ef6.Models.PriceListItem>
@{
ViewBag.Title = "Sorted Prices";
}
<div class="spacer"></div>
<h2>Index</h2>
<p>
</p>
<table class="table">
<tr>
<th>
@Html.DisplayNameFor(model => model.stockName)
</th>
<th>
@Html.DisplayNameFor(model => model.Pence)
</th>
<th>
@Html.DisplayNameFor(model => model.Stamp)
</th>
<th></th>
</tr>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.stockName)
</td>
<td>
@Html.DisplayFor(modelItem => item.Pence)
</td>
<td>
@Html.DisplayFor(modelItem => item.Stamp)
</td>
</tr>
}
</table>
Latest Prices: Index;
<META HTTP-EQUIV="REFRESH" CONTENT="60">
@model IEnumerable<MVC5ef6.Models.LatestPrice>
@{
ViewBag.Title = "Index";
}
<div class="spacer"></div>
70
ChrisWorledgePortfolio2|2/1/2016
<h2>Table of Latest Prices</h2>
<table class="table">
<tr>
<th>
@Html.DisplayNameFor(model => model.marketName)
</th>
<th>
@Html.DisplayNameFor(model => model.stockName)
</th>
<th>
@Html.DisplayNameFor(model => model.Pence)
</th>
<th>
@Html.DisplayNameFor(model => model.Stamp)
</th>
<th></th>
</tr>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.marketName)
</td>
<td>
@Html.DisplayFor(modelItem => item.stockName)
</td>
<td>
@Html.DisplayFor(modelItem => item.Pence)
</td>
<td>
@Html.DisplayFor(modelItem => item.Stamp)
</td>
</tr>
}
</table>
Controllers:
namespace MVC5ef6.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult About()
{
ViewBag.Message = "Your application description page.";
71
ChrisWorledgePortfolio2|2/1/2016
return View();
}
public ActionResult Contact()
{
ViewBag.Message = "Your contact page.";
return View();
}
}
public class LatestPricesController : Controller
{
private MVC5demoEntities db = new MVC5demoEntities();
// GET: LatestPrices
public ActionResult Index()
{
return View(db.LatestPrices.OrderBy(l => l.marketName).ToList());
}
// GET: LatestPrices/Details/5
public ActionResult Details(long? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
LatestPrice latestPrice = db.LatestPrices.Find(id);
if (latestPrice == null)
{
return HttpNotFound();
}
return View(latestPrice);
}
// GET: LatestPrices/Create
public ActionResult Create()
{
return View();
}
// POST: LatestPrices/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include =
"ID,stockName,marketName,Pence,Stamp")] LatestPrice latestPrice)
{
if (ModelState.IsValid)
{
db.LatestPrices.Add(latestPrice);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(latestPrice);
72
ChrisWorledgePortfolio2|2/1/2016
}
// GET: LatestPrices/Edit/5
public ActionResult Edit(long? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
LatestPrice latestPrice = db.LatestPrices.Find(id);
if (latestPrice == null)
{
return HttpNotFound();
}
return View(latestPrice);
}
// POST: LatestPrices/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "ID,stockName,marketName,Pence,Stamp")]
LatestPrice latestPrice)
{
if (ModelState.IsValid)
{
db.Entry(latestPrice).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(latestPrice);
}
// GET: LatestPrices/Delete/5
public ActionResult Delete(long? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
LatestPrice latestPrice = db.LatestPrices.Find(id);
if (latestPrice == null)
{
return HttpNotFound();
}
return View(latestPrice);
}
// POST: LatestPrices/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(long id)
{
LatestPrice latestPrice = db.LatestPrices.Find(id);
db.LatestPrices.Remove(latestPrice);
db.SaveChanges();
return RedirectToAction("Index");
}
73
ChrisWorledgePortfolio2|2/1/2016
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
}
public class MarketsController : Controller
{
private MVC5demoEntities db = new MVC5demoEntities();
// GET: Markets
public ActionResult Index()
{
return View(db.Markets.ToList());
}
// GET: Markets/Details/5
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Market market = db.Markets.Find(id);
if (market == null)
{
return HttpNotFound();
}
return View(market);
}
// GET: Markets/Create
public ActionResult Create()
{
return View();
}
// POST: Markets/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "marketID,marketName")] Market market)
{
if (ModelState.IsValid)
{
db.Markets.Add(market);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(market);
}
74
ChrisWorledgePortfolio2|2/1/2016
// GET: Markets/Edit/5
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Market market = db.Markets.Find(id);
if (market == null)
{
return HttpNotFound();
}
return View(market);
}
// POST: Markets/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "marketID,marketName")] Market market)
{
if (ModelState.IsValid)
{
db.Entry(market).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(market);
}
// GET: Markets/Delete/5
public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Market market = db.Markets.Find(id);
if (market == null)
{
return HttpNotFound();
}
return View(market);
}
// POST: Markets/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
Market market = db.Markets.Find(id);
db.Markets.Remove(market);
db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
if (disposing)
75
ChrisWorledgePortfolio2|2/1/2016
{
db.Dispose();
}
base.Dispose(disposing);
}
}
public class NamedPrice
{
Models.Stock name { get; set; }
Models.Price price { get; set; }
}
public class PriceListItemsController : Controller
{
private MVC5demoEntities db = new MVC5demoEntities();
// GET: PriceListItems
public ActionResult Index()
{
var pricesForList = db.Prices.Join(db.Stocks, a => a.stockID, b => b.stockID,
(a, b) => new { a, b }).
Select(c => new PriceListItem { ID = c.a.ID, stockID = c.a.stockID, Stamp
= c.a.Stamp, Pence = c.a.Pence, stockName = c.b.stockName }).
OrderBy(q => q.Stamp).GroupBy(s => s.stockName);
IQueryable<IGrouping<string, PriceListItem>> ListedPrices =
pricesForList;/*We want to controll the display order,
but we don't need the grouping order as a seperate data attribute so we will
take the items into a list*/
List <PriceListItem> DisplayList = new List<PriceListItem>();
foreach (IGrouping<string, PriceListItem> item in ListedPrices)
{
foreach (PriceListItem listItem in item)
{
DisplayList.Add(listItem);
}
}
//now we can pass the list for display
return View(DisplayList);
}
// GET: PriceListItems/Details/5
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
PriceListItem priceListItem = db.PriceListItems.Find(id);
if (priceListItem == null)
{
return HttpNotFound();
}
76
ChrisWorledgePortfolio2|2/1/2016
return View(priceListItem);
}
// GET: PriceListItems/Create
public ActionResult Create()
{
return View();
}
// POST: PriceListItems/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "ID,stockID,Stamp,Pence,stockName")]
PriceListItem priceListItem)
{
if (ModelState.IsValid)
{
db.PriceListItems.Add(priceListItem);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(priceListItem);
}
// GET: PriceListItems/Edit/5
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
PriceListItem priceListItem = db.PriceListItems.Find(id);
if (priceListItem == null)
{
return HttpNotFound();
}
return View(priceListItem);
}
// POST: PriceListItems/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "ID,stockID,Stamp,Pence,stockName")]
PriceListItem priceListItem)
{
if (ModelState.IsValid)
{
db.Entry(priceListItem).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(priceListItem);
}
// GET: PriceListItems/Delete/5
public ActionResult Delete(int? id)
{
77
ChrisWorledgePortfolio2|2/1/2016
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
PriceListItem priceListItem = db.PriceListItems.Find(id);
if (priceListItem == null)
{
return HttpNotFound();
}
return View(priceListItem);
}
// POST: PriceListItems/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
PriceListItem priceListItem = db.PriceListItems.Find(id);
db.PriceListItems.Remove(priceListItem);
db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
}
public class PricesController : Controller
{
private MVC5demoEntities db = new MVC5demoEntities();
// GET: Prices
public ActionResult Index()
{
var prices = db.Prices.Include(p => p.Stock);
return View(prices.ToList());
}
// GET: Prices/Details/5
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Price price = db.Prices.Find(id);
if (price == null)
{
return HttpNotFound();
78
ChrisWorledgePortfolio2|2/1/2016
}
return View(price);
}
// GET: Prices/Create
public ActionResult Create()
{
ViewBag.stockID = new SelectList(db.Stocks, "stockID", "stockName");
return View();
}
// POST: Prices/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "ID,stockID,Stamp,Pence")] Price
price)
{
if (ModelState.IsValid)
{
db.Prices.Add(price);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.stockID = new SelectList(db.Stocks, "stockID", "stockName",
price.stockID);
return View(price);
}
// GET: Prices/Edit/5
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Price price = db.Prices.Find(id);
if (price == null)
{
return HttpNotFound();
}
ViewBag.stockID = new SelectList(db.Stocks, "stockID", "stockName",
price.stockID);
return View(price);
}
// POST: Prices/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "ID,stockID,Stamp,Pence")] Price price)
{
if (ModelState.IsValid)
{
db.Entry(price).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
79
ChrisWorledgePortfolio2|2/1/2016
ViewBag.stockID = new SelectList(db.Stocks, "stockID", "stockName",
price.stockID);
return View(price);
}
// POST: Prices/Chart/5
public ActionResult Chart(int? id)
{
if (id != null)
{
int stock;
int.TryParse(id.ToString(), out stock);//drag the int out of the ?int
string stockName = db.Stocks.Where(a => a.stockID == stock).Select(a =>
a.stockName).FirstOrDefault() ;
StockPriceModel SPModel = new StockPriceModel();
SPModel.ChartTitle = stockName;
SPModel.StampTitle = "DateTime";
SPModel.PenceTitle = "Pence";
SPModel.stockID = stock;
return View(SPModel);
}
else
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
}
public JsonResult GetChart(int stock)
{
var ChartData = db.Prices.Where(a => a.stockID.HasValue ? a.stockID == stock
: false)
.Select(p => new { Stamp = p.Stamp.HasValue ? p.Stamp.Value :
DateTime.Now, p.Pence }).
OrderBy(q => q.Stamp);//all the dates and prices in date order
List<StockPrice> CleanChartData = new List<StockPrice>();
CultureInfo culture = new CultureInfo("pt-BR");//so we get day before month!
int x = 0;
foreach (var t in ChartData)
{
string time = t.Stamp.ToString("G", culture);//give a date to display in
javascript
decimal price;
decimal.TryParse(t.Pence.ToString(), out price);//because t.pence is a
nullable decimal
StockPrice current = new StockPrice();
current.ID = x;
current.Stamp = time;
current.Pence = price;
CleanChartData.Add(current);
x++;
}
return Json(CleanChartData, JsonRequestBehavior.AllowGet);
80
ChrisWorledgePortfolio2|2/1/2016
}
// GET: Prices/Delete/5
public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Price price = db.Prices.Find(id);
if (price == null)
{
return HttpNotFound();
}
return View(price);
}
// POST: Prices/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
Price price = db.Prices.Find(id);
db.Prices.Remove(price);
db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
}
public class StocksController : Controller
{
private MVC5demoEntities db = new MVC5demoEntities();
// GET: Stocks
public ActionResult Index()
{
var stocks = db.Stocks.Include(s => s.Market);
return View(stocks.ToList());
}
// GET: Stocks/Details/5
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
81
ChrisWorledgePortfolio2|2/1/2016
}
Stock stock = db.Stocks.Find(id);
if (stock == null)
{
return HttpNotFound();
}
return View(stock);
}
// GET: Stocks/Create
public ActionResult Create()
{
ViewBag.marketID = new SelectList(db.Markets, "marketID", "marketName");
return View();
}
// POST: Stocks/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "stockID,stockName,marketID")] Stock
stock)
{
if (ModelState.IsValid)
{
db.Stocks.Add(stock);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.marketID = new SelectList(db.Markets, "marketID", "marketName",
stock.marketID);
return View(stock);
}
// GET: Stocks/Edit/5
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Stock stock = db.Stocks.Find(id);
if (stock == null)
{
return HttpNotFound();
}
ViewBag.marketID = new SelectList(db.Markets, "marketID", "marketName",
stock.marketID);
return View(stock);
}
// POST: Stocks/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "stockID,stockName,marketID")] Stock
stock)
{
82
ChrisWorledgePortfolio2|2/1/2016
if (ModelState.IsValid)
{
db.Entry(stock).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.marketID = new SelectList(db.Markets, "marketID", "marketName",
stock.marketID);
return View(stock);
}
// POST: Stocks/Chart/5
public ActionResult Chart(int? id)
{
if (id != null)
{
int stock;
int.TryParse(id.ToString(), out stock);//drag the int out of the ?int
string stockName = db.Stocks.Where(a => a.stockID == stock).Select(a =>
a.stockName).FirstOrDefault();
StockPriceModel SPModel = new StockPriceModel();
SPModel.ChartTitle = stockName;
SPModel.StampTitle = "DateTime";
SPModel.PenceTitle = "Pence";
SPModel.stockID = stock;
return View(SPModel);
}
else
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
}
public JsonResult GetChart(int stock)
{
var ChartData = db.Prices.Where(a => a.stockID.HasValue ? a.stockID == stock
: false)
.Select(p => new { Stamp = p.Stamp.HasValue ? p.Stamp.Value :
DateTime.Now, p.Pence }).
OrderBy(q => q.Stamp);//all the dates and prices in date order
List<StockPrice> CleanChartData = new List<StockPrice>();
CultureInfo culture = new CultureInfo("pt-BR");//so we get day before month!
int x = 0;
foreach (var t in ChartData)
{
string time = t.Stamp.ToString("d", culture);//give a date to display in
javascript
decimal price;
decimal.TryParse(t.Pence.ToString(), out price);//because t.pence is a
nullable decimal
StockPrice current = new StockPrice();
current.ID = x;
current.Stamp = time;
current.Pence = price;
CleanChartData.Add(current);
83
ChrisWorledgePortfolio2|2/1/2016
x++;
}
return Json(CleanChartData, JsonRequestBehavior.AllowGet);
}
// GET: Stocks/Delete/5
public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Stock stock = db.Stocks.Find(id);
if (stock == null)
{
return HttpNotFound();
}
return View(stock);
}
// POST: Stocks/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
Stock stock = db.Stocks.Find(id);
db.Stocks.Remove(stock);
db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
}
}
84
ChrisWorledgePortfolio2|2/1/2016
WEB API OF PREVIOUS EXAMPLE
Markets
85
ChrisWorledgePortfolio2|2/1/2016
Stocks
86
ChrisWorledgePortfolio2|2/1/2016
Prices
Latest Prices
87
ChrisWorledgePortfolio2|2/1/2016
88
ChrisWorledgePortfolio2|2/1/2016
89
ChrisWorledgePortfolio2|2/1/2016
var SPapp = angular.module('SPModule', ['ngResource']);
(function () {
var MarketsController = function ($scope, $http) {
$scope.markets = [];
var markets = function (serviceResp) {
$scope.markets = serviceResp.data;
};
var errorDetails = function (serviceResp) {
$scope.Error = "Something went wrong ??";
};
$http.get("http://localhost:63579/api/Markets")
.then(markets, errorDetails);
$scope.Title = "Markets Page";
};
SPapp.controller("MarketsController", MarketsController);
}());
(function () {
var StocksController = function ($scope, $http) {
$scope.stocks = [];
var target = 'Stocks'
var markets = function (serviceResp) {
$scope.stocks = serviceResp.data;
};
var errorDetails = function (serviceResp) {
$scope.Error = "Something went wrong ??";
};
$http.get("http://localhost:63579/api/Stocks")
.then(markets, errorDetails);
$scope.Title = "Stocks Page";
90
ChrisWorledgePortfolio2|2/1/2016
};
SPapp.controller("StocksController", StocksController);
}());
(function () {
var PricesController = function ($scope, $http) {
$scope.prices = [];
var markets = function (serviceResp) {
$scope.prices = serviceResp.data;
};
var errorDetails = function (serviceResp) {
$scope.Error = "Something went wrong ??";
};
$http.get("http://localhost:63579/api/PriceListItems")
.then(markets, errorDetails);
$scope.Title = "Prices Page";
};
SPapp.controller("PricesController", PricesController);
}());
SPapp.controller('latestPricesController', ['$scope', '$http',
function ($scope, $http) {
$scope.latestPrices = [];
$scope.loading = true;
$scope.addMode = false;
//Used to display the data
//Alternative ports old WebAPI 63579 new WebAPI1 54488
$http({
method: 'GET',
url: 'http://localhost:63579/api/latestPrices'
})
.then(function successCallback(response) {
console.log('success');
$scope.latestPrices = response.data;
$scope.loading = false;
}, function errorCallback(response) {
console.log('error');
$scope.errorMsg = response.status + ': ' + response.data;
$scope.error = "An Error has occured while loading 63579 prices! Status: " +
status + "statusText: ";// + statusText + "oops";
$scope.failstatus = status;
$scope.loading = false;
});
}]);
Home
<!DOCTYPE html>
<html lang="en" ng-app="SPModule">
<head>
<title>Share Prices Home Page</title>
<meta charset="utf-8" />
91
ChrisWorledgePortfolio2|2/1/2016
<script src="Scripts/jquery-2.1.4.min.js"></script>
<link href="Content/bootstrap.min.css" rel="stylesheet" />
<link href="Content/flatly.css" rel="stylesheet" />
<link href="Content/Site.css" rel="stylesheet" />
<script src="Scripts/bootstrap.min.js"></script>
<script src="Scripts/angular.min.js"></script>
<script src="Scripts/angular-resource.min.js"></script>
<script src="App/app.js"></script>
<script src="Services/latestPricesService.js"></script>
<script src="Services/TableService.js"></script>
<script src="Factories/latestPricesFactory.js"></script>
<script src="Factories/TableFactory.js"></script>
<script src="Factories/CrudFactory.js"></script>
<script src="Controllers/latestPricesController.js"></script>
<script src="Controllers/simlatestPricesController.js"></script>
</head>
<body ng-controller="latestPricesController">
<h1>&nbsp; Welcome To Share Prices Stock Market Website</h1>
<h1>&nbsp;<a href="Views/Markets.html">Markets</a>&nbsp;<a
href="Views/Stocks.html">Stocks</a>&nbsp;<a href="Views/Prices.html">All
Prices</a>&nbsp;<a href="Views/LatestPrices.html">Latest Prices</a></h1>
<h2>&nbsp; LatestPrices</h2>
<div class="container">
<strong class="error">{{ error }}</strong><br />
<strong class="error">{{ errorMsg }}</strong><br />
<strong class="error">{{ failstatus }}</strong>
<div id="mydiv" ng-show="loading">
<img src="images/ajax-loader.gif" class="ajax-loader" />
</div>
<table id="pricesTable" class="table table-bordered table-hover"
style="width:800px">
<thead>
<tr>
<th>ID</th>
<th>Stock Name</th>
<th>Market Name</th>
<th>Price</th>
<th>Stamp</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="latestPrice in latestPrices | orderBy: 'marketName'">
<td><strong>{{ latestPrice.id }}</strong></td>
<td>
<p>{{ latestPrice.stockName }}</p>
</td>
<td>
<p>{{ latestPrice.marketName }}</p>
</td>
<td>
<p>{{ latestPrice.pence }}</p>
</td>
<td>
<p>{{ latestPrice.stamp }}</p>
92
ChrisWorledgePortfolio2|2/1/2016
</td>
</tr>
</tbody>
<tfoot></tfoot>
</table>
<hr />
</div>
</body>
</html>
Markets
<!DOCTYPE html>
<html lang="en" ng-app="SPModule">
<head>
<title>Markets</title>
<meta charset="utf-8" />
<script src="../Scripts/jquery-2.1.4.min.js"></script>
<link href="../Content/bootstrap.min.css" rel="stylesheet" />
<link href="../Content/flatly.css" rel="stylesheet" />
<link href="../Content/Site.css" rel="stylesheet" />
<script src="../Scripts/bootstrap.min.js"></script>
<script src="../Scripts/angular.min.js"></script>
<script src="../App/app.js"></script>
<script src="../Controllers/MarketsController.js"></script>
</head>
<body ng-controller="MarketsController">
<h1>&nbsp; Welcome To Share Prices Stock Market Website</h1>
<h1>&nbsp;&nbsp;<a href="../Home.html">Home</a>&nbsp;<a
href="Stocks.html">Stocks</a>&nbsp;<a href="Prices.html">allPrices</a>&nbsp;<a
href="LatestPrices.html">LatestPrices</a></h1>
<h2>&nbsp; Market Names</h2>
<div class="container">
<strong class="error">{{ error }}</strong><br />
<strong class="error">{{ errorMsg }}</strong><br />
<strong class="error">{{ failstatus }}</strong>
<div id="mydiv" ng-show="loading">
<img src="../images/ajax-loader.gif" class="ajax-loader" />
</div>
<table id="pricesTable" class="table table-bordered table-hover"
style="width:800px">
<thead>
<tr>
<th>ID</th>
<th>Market Name</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="market in markets">
<td><strong>{{ market.marketID }}</strong></td>
<td>
<p>{{ market.marketName }}</p>
</td>
93
ChrisWorledgePortfolio2|2/1/2016
</tr>
</tbody>
<tfoot></tfoot>
</table>
<hr />
</div>
</body>
</html>
Stocks
<!DOCTYPE html>
<html lang="en" ng-app="SPModule">
<head>
<title>Markets</title>
<meta charset="utf-8" />
<script src="../Scripts/jquery-2.1.4.min.js"></script>
<link href="../Content/bootstrap.min.css" rel="stylesheet" />
<link href="../Content/flatly.css" rel="stylesheet" />
<link href="../Content/Site.css" rel="stylesheet" />
<script src="../Scripts/bootstrap.min.js"></script>
<script src="../Scripts/angular.min.js"></script>
<script src="../App/app.js"></script>
<script src="../Controllers/StocksController.js"></script>
</head>
<body ng-controller="StocksController">
<h1>&nbsp; Welcome To Share Prices Stock Market Website</h1>
<h1>&nbsp;&nbsp;<a href="../Home.html">Home</a>&nbsp;<a
href="Markets.html">Markets</a>&nbsp;<a href="Prices.html">allPrices</a>&nbsp;<a
href="LatestPrices.html">LatestPrices</a></h1>
<h2>&nbsp; Stock Names</h2>
<div class="container">
<strong class="error">{{ error }}</strong><br />
<strong class="error">{{ errorMsg }}</strong><br />
<strong class="error">{{ failstatus }}</strong>
<div id="mydiv" ng-show="loading">
<img src="../images/ajax-loader.gif" class="ajax-loader" />
</div>
<table id="pricesTable" class="table table-bordered table-hover"
style="width:800px">
<thead>
<tr>
<th>ID</th>
<th>Stock Name</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="stock in stocks">
<td><strong>{{ stock.stockID }}</strong></td>
<td>
<p>{{ stock.stockName }}</p>
</td>
94
ChrisWorledgePortfolio2|2/1/2016
</tr>
</tbody>
<tfoot></tfoot>
</table>
<hr />
</div>
</body>
</html>
Prices
<!DOCTYPE html>
<html lang="en" ng-app="SPModule">
<head>
<title>Markets</title>
<meta charset="utf-8" />
<script src="../Scripts/jquery-2.1.4.min.js"></script>
<link href="../Content/bootstrap.min.css" rel="stylesheet" />
<link href="../Content/flatly.css" rel="stylesheet" />
<link href="../Content/Site.css" rel="stylesheet" />
<script src="../Scripts/bootstrap.min.js"></script>
<script src="../Scripts/angular.min.js"></script>
<script src="../App/app.js"></script>
<script src="../Controllers/PricesController.js"></script>
</head>
<body ng-controller="PricesController">
<h1>&nbsp; Welcome To Share Prices Stock Market Website</h1>
<h1>&nbsp;&nbsp;<a href="../Home.html">Home</a>&nbsp;<a
href="Markets.html">Markets</a>&nbsp;<a href="Stocks.html">Stocks</a>&nbsp;<a
href="LatestPrices.html">LatestPrices</a></h1>
<h2>&nbsp; Stock Prices</h2>
<div class="container">
<strong class="error">{{ error }}</strong><br />
<strong class="error">{{ errorMsg }}</strong><br />
<strong class="error">{{ failstatus }}</strong>
<div id="mydiv" ng-show="loading">
<img src="../images/ajax-loader.gif" class="ajax-loader" />
</div>
<table id="pricesTable" class="table table-bordered table-hover"
style="width:800px">
<thead>
<tr>
<th>ID</th>
<th>Stock Name</th>
<th>Price</th>
<th>Date and Time</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="price in prices">
<td><strong>{{ price.id }}</strong></td>
95
ChrisWorledgePortfolio2|2/1/2016
<td>
<p>{{ price.stockName }}</p>
</td>
<td>
<p>{{ price.pence }}</p>
</td>
<td>
<p>{{ price.stamp }}</p>
</td>
</tr>
</tbody>
<tfoot></tfoot>
</table>
<hr />
</div>
</body>
</html>
Latest Prices
<!DOCTYPE html>
<html lang="en" ng-app="SPModule">
<head>
<title>Latest Prices</title>
<meta charset="utf-8" />
<script src="../Scripts/jquery-2.1.4.min.js"></script>
<link href="../Content/bootstrap.min.css" rel="stylesheet" />
<link href="../Content/flatly.css" rel="stylesheet" />
<link href="../Content/Site.css" rel="stylesheet" />
<script src="../Scripts/bootstrap.min.js"></script>
<script src="../Scripts/angular.min.js"></script>
<script src="../App/app.js"></script>
<script src="../Controllers/latestPricesController.js"></script>
<script src="../Controllers/simlatestPricesController.js"></script>
<script src="../Factories/latestPricesFactory.js"></script>
<script src="../Services/latestPricesService.js"></script>
</head>
<body ng-controller="latestPricesController">
<h1>&nbsp; Welcome To Share Prices Stock Market Website</h1>
<h1>&nbsp;&nbsp;<a href="../Home.html">Home</a>&nbsp;<a
href="Markets.html">Markets</a>&nbsp;<a href="Stocks.html">Stocks</a>&nbsp;<a
href="Prices.html">allPrices</a></h1>
<h2>&nbsp; LatestPrices</h2>
<div class="container">
<strong class="error">{{ error }}</strong><br />
<strong class="error">{{ errorMsg }}</strong><br />
<strong class="error">{{ failstatus }}</strong>
<div id="mydiv" ng-show="loading">
<img src="../images/ajax-loader.gif" class="ajax-loader" />
</div>
<table id="pricesTable" class="table table-bordered table-hover"
style="width:800px">
<thead>
<tr>
<th>ID</th>
96
ChrisWorledgePortfolio2|2/1/2016
<th>Stock Name</th>
<th>Market Name</th>
<th>Price</th>
<th>Stamp</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="latestPrice in latestPrices">
<td><strong>{{ latestPrice.id }}</strong></td>
<td>
<p>{{ latestPrice.stockName }}</p>
</td>
<td>
<p>{{ latestPrice.marketName }}</p>
</td>
<td>
<p>{{ latestPrice.pence }}</p>
</td>
<td>
<p>{{ latestPrice.stamp }}</p>
</td>
</tr>
</tbody>
<tfoot></tfoot>
</table>
<hr />
</div>>
</body>
</html>
97
ChrisWorledgePortfolio2|2/1/2016
AT HOME TASK
There is a special cash machine, without any security, that dispenses money
(notes and coins). The machine has a given initial state of what coins and notes
it has available.
The initial state is: 100x1p, 100x2p, 100x5p, 100x10p, 100x20p, 100x50p,
100x£1, 100x£2, 50x£5, 50x£10, 50x£20, 50x£50.
You should create a program that is given the value to withdraw as an input.
Program the cash machine, so it has 2 algorithms that can be swapped
(swapping can be done by rebuilding and rerunning the application):
1. Algorithm that returns least number of items (coins or notes)
2. Algorithm that returns the highest number of £20 notes possible
Output the number of coins and notes given for each withdrawal.
The machine should output the count and value of coins and notes dispensed
and the balance amount left.
The program should be extendible and written using .NET framework. Use the
best approach you can to implement the solution.
Examples
Algorithm 1
Input (Withdrawal amount)
120.00
Output
£50x2, £20x1
£X.XX balance
Algorithm 2
Input
120.00
Output
£20x6
£X.XX balance
98
ChrisWorledgePortfolio2|2/1/2016
First Algorithm:
99
ChrisWorledgePortfolio2|2/1/2016
Second Algorithm with £20 note bias:
Program:
namespace CashMachine
{
class Program
{
static void Main(string[] args)
{
Bank thisBank = new Bank();
thisBank.Algorithm = true;//allows the maximum twenties algorithm
while (true)
{
Console.WriteLine("Please enter required amount:");
string line = Console.ReadLine();
if (line != null)
{
Decimal debit;
if (Decimal.TryParse(line, out debit))
{
string response = thisBank.debit(debit);
Console.WriteLine(response);
}
100
ChrisWorledgePortfolio2|2/1/2016
else
{
Console.WriteLine("You have entered an invalid amount.");
}
}
}
}
}
}
Bank:
namespace CashMachine
{
class Bank
{
private Money[] Monies { get; set; }
public Boolean Algorithm { get; set; }
public Bank()
{
Monies = new Money[] {
new Money("£50", 50, 50 ),
new Money("£20", 20, 50 ),
new Money("£10", 10, 50 ),
new Money("£5", 5, 50 ),
new Money("£2", 2, 100 ),
new Money("£1", 1, 100 ),
new Money("50p", .5m, 100 ),//the appended m forces the Decimal type
new Money("20p", .2m, 100 ),
new Money("10p", .1m, 100 ),
new Money("5p", .05m, 100 ),
new Money("2p", .02m, 100 ),
new Money("1p", .01m, 100 )
};
Algorithm = false;//default to all denominations
}
public String debit(Decimal amount)
{
StringBuilder message = new StringBuilder();
Decimal debitvalue = amount;
if (amount <= getBalance())//check the money is available
{
debitAlgorithm(debitvalue, message);//takes the money by denomination
depending on the algorithm
message.Append("rnBalance remaining is £");
string balance = getBalance().ToString("#.##");
message.Append(balance);
return message.ToString();//tell them which notes and coins are being
supplied and how much is left in the machine.
}
else//we can't afford to service this request
101
ChrisWorledgePortfolio2|2/1/2016
{
return "The machine does not have sufficient funds to grant your
requestrn We are sorry for the inconvenience.";
}
}
private Decimal getBalance()
{
Decimal balance = 0;
foreach (Money money in Monies)
{
var value = money.value * money.quantity;
balance += value;
}
return balance;
}
private void debitAlgorithm(Decimal debitvalue, StringBuilder message)
{
int numberOfDenominations = Monies.Length;
int index = 0;//set the start point at fifties
Decimal requiredMoney = debitvalue;
Boolean messageAdded = false;
if (Algorithm)
{
index = 1;
requiredMoney = fullAlgorithm(index, messageAdded, requiredMoney,
message);//do the twenties first if set to that Algorithm
index = 0;
requiredMoney = fullAlgorithm(index, messageAdded, requiredMoney,
message);//do the fifties in case there weren't enough twenties left
index = 2;//carry on through the loop from £10 down
}
for (int i = index; i < numberOfDenominations; i++)
{
requiredMoney = fullAlgorithm(i, messageAdded, requiredMoney,
message);//we update the required amount each time
}
}
private Decimal fullAlgorithm(int i, Boolean messageAdded, Decimal debitvalue,
StringBuilder message)
{
Decimal requiredMoney = debitvalue;
int number = (int)(requiredMoney / Monies[i].value);//just the whole number
of this denomination
if (number > 0 && number < Monies[i].quantity)//We want some and that many
are available
{
requiredMoney = requiredMoney % Monies[i].value;//the leftover after the
above
Monies[i].quantity -= number;//debit the machine total for this
denomination
Portfolio2
Portfolio2
Portfolio2
Portfolio2
Portfolio2
Portfolio2

More Related Content

What's hot

Data Warehousing (December – 2015) [75:25 Pattern | Question Paper]
Data Warehousing (December – 2015) [75:25 Pattern | Question Paper]Data Warehousing (December – 2015) [75:25 Pattern | Question Paper]
Data Warehousing (December – 2015) [75:25 Pattern | Question Paper]Mumbai B.Sc.IT Study
 
Ch24 efficient algorithms
Ch24 efficient algorithmsCh24 efficient algorithms
Ch24 efficient algorithmsrajatmay1992
 
Porosity Calculation Using Techlog Softwares
Porosity Calculation Using Techlog SoftwaresPorosity Calculation Using Techlog Softwares
Porosity Calculation Using Techlog SoftwaresMohamed Qasim
 
Internet Technology (April – 2013) [Revised Syllabus | Question Paper]
Internet Technology (April  – 2013) [Revised Syllabus | Question Paper]Internet Technology (April  – 2013) [Revised Syllabus | Question Paper]
Internet Technology (April – 2013) [Revised Syllabus | Question Paper]Mumbai B.Sc.IT Study
 
Property-based Testing and Generators (Lua)
Property-based Testing and Generators (Lua)Property-based Testing and Generators (Lua)
Property-based Testing and Generators (Lua)Sumant Tambe
 
Internet Technologies (October – 2015) [Question Paper | CBSGS: 75:25 Pattern]
Internet Technologies (October – 2015) [Question Paper | CBSGS: 75:25 Pattern]Internet Technologies (October – 2015) [Question Paper | CBSGS: 75:25 Pattern]
Internet Technologies (October – 2015) [Question Paper | CBSGS: 75:25 Pattern]Mumbai B.Sc.IT Study
 
Analytical models of learning curves with variable processing time
Analytical models of learning curves with variable processing timeAnalytical models of learning curves with variable processing time
Analytical models of learning curves with variable processing timeSagarika Muthukumarana
 

What's hot (8)

Data Warehousing (December – 2015) [75:25 Pattern | Question Paper]
Data Warehousing (December – 2015) [75:25 Pattern | Question Paper]Data Warehousing (December – 2015) [75:25 Pattern | Question Paper]
Data Warehousing (December – 2015) [75:25 Pattern | Question Paper]
 
Ch24 efficient algorithms
Ch24 efficient algorithmsCh24 efficient algorithms
Ch24 efficient algorithms
 
Computer Network Assignment Help
Computer Network Assignment HelpComputer Network Assignment Help
Computer Network Assignment Help
 
Porosity Calculation Using Techlog Softwares
Porosity Calculation Using Techlog SoftwaresPorosity Calculation Using Techlog Softwares
Porosity Calculation Using Techlog Softwares
 
Internet Technology (April – 2013) [Revised Syllabus | Question Paper]
Internet Technology (April  – 2013) [Revised Syllabus | Question Paper]Internet Technology (April  – 2013) [Revised Syllabus | Question Paper]
Internet Technology (April – 2013) [Revised Syllabus | Question Paper]
 
Property-based Testing and Generators (Lua)
Property-based Testing and Generators (Lua)Property-based Testing and Generators (Lua)
Property-based Testing and Generators (Lua)
 
Internet Technologies (October – 2015) [Question Paper | CBSGS: 75:25 Pattern]
Internet Technologies (October – 2015) [Question Paper | CBSGS: 75:25 Pattern]Internet Technologies (October – 2015) [Question Paper | CBSGS: 75:25 Pattern]
Internet Technologies (October – 2015) [Question Paper | CBSGS: 75:25 Pattern]
 
Analytical models of learning curves with variable processing time
Analytical models of learning curves with variable processing timeAnalytical models of learning curves with variable processing time
Analytical models of learning curves with variable processing time
 

Similar to Portfolio2

Mid term sem 2 1415 sol
Mid term sem 2 1415 solMid term sem 2 1415 sol
Mid term sem 2 1415 solIIUM
 
HSc Computer Science Practical Slip for Class 12
HSc Computer Science Practical Slip for Class 12HSc Computer Science Practical Slip for Class 12
HSc Computer Science Practical Slip for Class 12Aditi Bhushan
 
Story of static code analyzer development
Story of static code analyzer developmentStory of static code analyzer development
Story of static code analyzer developmentAndrey Karpov
 
Summary Create an Object-Oriented program that creates a simulator an.pdf
 Summary Create an Object-Oriented program that creates a simulator an.pdf Summary Create an Object-Oriented program that creates a simulator an.pdf
Summary Create an Object-Oriented program that creates a simulator an.pdfallwinsupport
 
Name _______________________________ Class time __________.docx
Name _______________________________    Class time __________.docxName _______________________________    Class time __________.docx
Name _______________________________ Class time __________.docxrosemarybdodson23141
 
PVS-Studio features overview (2020)
PVS-Studio features overview (2020)PVS-Studio features overview (2020)
PVS-Studio features overview (2020)Andrey Karpov
 
Data Structures and Algorithms Lecture 2: Analysis of Algorithms, Asymptotic ...
Data Structures and Algorithms Lecture 2: Analysis of Algorithms, Asymptotic ...Data Structures and Algorithms Lecture 2: Analysis of Algorithms, Asymptotic ...
Data Structures and Algorithms Lecture 2: Analysis of Algorithms, Asymptotic ...TechVision8
 
maXbox Starter 43 Work with Code Metrics ISO Standard
maXbox Starter 43 Work with Code Metrics ISO StandardmaXbox Starter 43 Work with Code Metrics ISO Standard
maXbox Starter 43 Work with Code Metrics ISO StandardMax Kleiner
 
June 05 P2
June 05 P2June 05 P2
June 05 P2Samimvez
 
Net practicals lab mannual
Net practicals lab mannualNet practicals lab mannual
Net practicals lab mannualAbhishek Pathak
 
Final Exam Solutions Fall02
Final Exam Solutions Fall02Final Exam Solutions Fall02
Final Exam Solutions Fall02Radu_Negulescu
 
Microservices in Go_Dessi_Massimiliano_Codemotion_2017_Rome
Microservices in Go_Dessi_Massimiliano_Codemotion_2017_Rome Microservices in Go_Dessi_Massimiliano_Codemotion_2017_Rome
Microservices in Go_Dessi_Massimiliano_Codemotion_2017_Rome Massimiliano Dessì
 
Bis 311 final examination answers
Bis 311 final examination answersBis 311 final examination answers
Bis 311 final examination answersRandalHoffman
 

Similar to Portfolio2 (20)

Mid term sem 2 1415 sol
Mid term sem 2 1415 solMid term sem 2 1415 sol
Mid term sem 2 1415 sol
 
HSc Computer Science Practical Slip for Class 12
HSc Computer Science Practical Slip for Class 12HSc Computer Science Practical Slip for Class 12
HSc Computer Science Practical Slip for Class 12
 
Story of static code analyzer development
Story of static code analyzer developmentStory of static code analyzer development
Story of static code analyzer development
 
Summary Create an Object-Oriented program that creates a simulator an.pdf
 Summary Create an Object-Oriented program that creates a simulator an.pdf Summary Create an Object-Oriented program that creates a simulator an.pdf
Summary Create an Object-Oriented program that creates a simulator an.pdf
 
Xi practical file
Xi practical fileXi practical file
Xi practical file
 
Name _______________________________ Class time __________.docx
Name _______________________________    Class time __________.docxName _______________________________    Class time __________.docx
Name _______________________________ Class time __________.docx
 
I PUC CS Lab_programs
I PUC CS Lab_programsI PUC CS Lab_programs
I PUC CS Lab_programs
 
c++ referesher 1.pdf
c++ referesher 1.pdfc++ referesher 1.pdf
c++ referesher 1.pdf
 
PVS-Studio features overview (2020)
PVS-Studio features overview (2020)PVS-Studio features overview (2020)
PVS-Studio features overview (2020)
 
Data Structures and Algorithms Lecture 2: Analysis of Algorithms, Asymptotic ...
Data Structures and Algorithms Lecture 2: Analysis of Algorithms, Asymptotic ...Data Structures and Algorithms Lecture 2: Analysis of Algorithms, Asymptotic ...
Data Structures and Algorithms Lecture 2: Analysis of Algorithms, Asymptotic ...
 
maXbox Starter 43 Work with Code Metrics ISO Standard
maXbox Starter 43 Work with Code Metrics ISO StandardmaXbox Starter 43 Work with Code Metrics ISO Standard
maXbox Starter 43 Work with Code Metrics ISO Standard
 
June 05 P2
June 05 P2June 05 P2
June 05 P2
 
Net practicals lab mannual
Net practicals lab mannualNet practicals lab mannual
Net practicals lab mannual
 
3 algorithm-and-flowchart
3 algorithm-and-flowchart3 algorithm-and-flowchart
3 algorithm-and-flowchart
 
c programing
c programingc programing
c programing
 
Final Exam Solutions Fall02
Final Exam Solutions Fall02Final Exam Solutions Fall02
Final Exam Solutions Fall02
 
Microservices in Go_Dessi_Massimiliano_Codemotion_2017_Rome
Microservices in Go_Dessi_Massimiliano_Codemotion_2017_Rome Microservices in Go_Dessi_Massimiliano_Codemotion_2017_Rome
Microservices in Go_Dessi_Massimiliano_Codemotion_2017_Rome
 
Oct.22nd.Presentation.Final
Oct.22nd.Presentation.FinalOct.22nd.Presentation.Final
Oct.22nd.Presentation.Final
 
BDS_QA.pdf
BDS_QA.pdfBDS_QA.pdf
BDS_QA.pdf
 
Bis 311 final examination answers
Bis 311 final examination answersBis 311 final examination answers
Bis 311 final examination answers
 

Recently uploaded

Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024StefanoLambiase
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...soniya singh
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideChristina Lin
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio, Inc.
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...MyIntelliSource, Inc.
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Andreas Granig
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)OPEN KNOWLEDGE GmbH
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureDinusha Kumarasiri
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...Christina Lin
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样umasea
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaHanief Utama
 
The Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfThe Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfPower Karaoke
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsAhmed Mohamed
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWave PLM
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxTier1 app
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantAxelRicardoTrocheRiq
 
software engineering Chapter 5 System modeling.pptx
software engineering Chapter 5 System modeling.pptxsoftware engineering Chapter 5 System modeling.pptx
software engineering Chapter 5 System modeling.pptxnada99848
 
chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptkotipi9215
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...OnePlan Solutions
 

Recently uploaded (20)

Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
 
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort ServiceHot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with Azure
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief Utama
 
The Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfThe Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdf
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML Diagrams
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need It
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service Consultant
 
software engineering Chapter 5 System modeling.pptx
software engineering Chapter 5 System modeling.pptxsoftware engineering Chapter 5 System modeling.pptx
software engineering Chapter 5 System modeling.pptx
 
chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.ppt
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...
 

Portfolio2

  • 1. MAINLY CONSOLE APPS AND MVC ENTITY FRAMEWORK ASP February 1, 2016 Authored by: Chris Chris Worledge Portfolio 2 A SELECTION OF EXAMPLES OF MORE RECENT WORK
  • 2. 1 ChrisWorledgePortfolio2|2/1/2016 Chris Worledge Portfolio 2 A selection of examples of more recent work  Page 2 Measuring the Performance of Algorithms (C#)  Page 36 Exploration of MongoDB using NodeJS  Page 40 Temporal Data Store (Efficient use of C# Data Structures; Lists, Dictionaries etc.)  Page 53 Entity Framework with WebForms  Page 57 Entity Framework with MVC  Page 84 Web API with Angular JS  Page 97 Bank Cash Machine Programme and Database
  • 3. 2 ChrisWorledgePortfolio2|2/1/2016 MEASURING THE PERFORMANCE OF ALGORITHMS For comparison of different approaches to the same problem I have measured the performance of two methods of measuring/calculating the digits within all the numbers from one to any selected number. The problem was described to me in terms of providing the numbers for doors where door numbers could exceed 10^12! A less than likely scenario, but it indicated the leading zeros would not be required. The CountDigits method actually counts the digits within each number in turn until the target number is reached. This is the brute force approach which is ideal within small ranges, but does not scale up well. The CalculateNumbers method actually adds the numbers of each digit as a result of each digit in the target number. A comparative unit test was employed to check they both produce the same results: using Microsoft.VisualStudio.TestTools.UnitTesting; namespace CountDigitsUnitTests { [TestClass] public class UnitTest1 { [TestMethod] public void TestMethod1() { ulong index = 1, next = 1; for (ulong value = 1; value < 10000000; value = next) { ulong[] linear = new CountDigits.DigitCount().CountDigits(value); ulong[] log = new CountDigits.CountDigits().CalculateNumbers(value); CollectionAssert.AreEqual(linear, log); index++; next = next + index; } } } } This test couldn’t cover the complete range of the methods as the time required to run such a check was prohibitive.
  • 4. 3 ChrisWorledgePortfolio2|2/1/2016 Using 10^8 as a limit took 6 minutes over a whole day! In Big O notation the first approach has O(n), a linear relationship which can be ideal with very small number ranges, but has terrible performance with large numbers, whilst the second has O(log(n)), which is much more scalable to requirements in modern business environments. We need System and System.Diagnostics (for the stopwatch class to measure the execution times). using System; using System.Diagnostics; namespace HotelApplication { class Program { public static void Main(string[] args) {
  • 5. 4 ChrisWorledgePortfolio2|2/1/2016 ulong max = 10000000000 ; //the upper number n in the range 1 to n var timeTest = Stopwatch.StartNew();//set a stopwatch going ulong[] digValues = new CountDigits().CalculateNumbers(max); timeTest.Stop();//call the method, and stop the stopwatch var elapsedValue = timeTest.Elapsed; string longStringTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", elapsedValue.Hours, elapsedValue.Minutes, elapsedValue.Seconds, elapsedValue.Milliseconds);//display the time and the values Console.WriteLine("Input: " + max.ToString()); Console.WriteLine(""); Console.WriteLine("Time in milliseconds = " + elapsedValue.TotalMilliseconds.ToString() + " milliseconds"); Console.WriteLine(""); Console.WriteLine("Time = " + longStringTime); Console.WriteLine(""); Console.WriteLine("0: " + digValues[0].ToString()); Console.WriteLine("1: " + digValues[1].ToString()); Console.WriteLine("2: " + digValues[2].ToString()); Console.WriteLine("3: " + digValues[3].ToString()); Console.WriteLine("4: " + digValues[4].ToString()); Console.WriteLine("5: " + digValues[5].ToString()); Console.WriteLine("6: " + digValues[6].ToString()); Console.WriteLine("7: " + digValues[7].ToString()); Console.WriteLine("8: " + digValues[8].ToString()); Console.WriteLine("9: " + digValues[9].ToString()); Console.WriteLine(""); //Do the same things again for the other method var clock = Stopwatch.StartNew(); ulong[] digCount = new DigitCount().CountDigits(max); clock.Stop(); var elapsedMillis = clock.ElapsedMilliseconds; var timeelapsed = clock.Elapsed; string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", timeelapsed.Hours, timeelapsed.Minutes, timeelapsed.Seconds, timeelapsed.Milliseconds); Console.WriteLine("Input: " + max.ToString()); Console.WriteLine(""); Console.WriteLine("Time in milliseconds = " + timeelapsed.TotalMilliseconds.ToString() + " milliseconds"); Console.WriteLine(""); Console.WriteLine("Time = " + elapsedTime); Console.WriteLine(""); Console.WriteLine("0: " + digCount[0].ToString()); Console.WriteLine("1: " + digCount[1].ToString()); Console.WriteLine("2: " + digCount[2].ToString()); Console.WriteLine("3: " + digCount[3].ToString()); Console.WriteLine("4: " + digCount[4].ToString()); Console.WriteLine("5: " + digCount[5].ToString()); Console.WriteLine("6: " + digCount[6].ToString()); Console.WriteLine("7: " + digCount[7].ToString()); Console.WriteLine("8: " + digCount[8].ToString()); Console.WriteLine("9: " + digCount[9].ToString()); Console.WriteLine("");
  • 6. 5 ChrisWorledgePortfolio2|2/1/2016 Console.WriteLine("Press enter to close..."); Console.ReadLine(); } } } The anticipated outcome would be a linear time to logarithmic input for the CalculateNumbers method; whilst the CountDigits method would remain linear against input and become inpractical for large numbers. The console display for 10^9:
  • 8. 7 ChrisWorledgePortfolio2|2/1/2016 The console display of 10^11: An averaging technique was employed to reduce the impact of overhead, and display the true trend of the underlying algorithm. This was only practical for the Olog(n) algorithm due to the much increased run times of the O(n) algorithm. This will have introduced error, but it’s impact would be small.
  • 9. 8 ChrisWorledgePortfolio2|2/1/2016 A table of results shows the performance of each algorithm in ms. Input Input(scientific) Olog(n) O(n) 1 1.E+00 0.0005 0.3589 10 1.E+01 0.00052 0.0049 100 1.E+02 0.000748 0.0158 1000 1.E+03 0.00984 0.1433 10000 1.E+04 0.001136 1.272 100000 1.E+05 0.001343 18.056 1000000 1.E+06 0.001694 176.6585 10000000 1.E+07 0.001851 1820.4105 100000000 1.E+08 0.002001 19687.2353 1000000000 1.E+09 0.0022248 218771.4353 10000000000 1.E+10 0.002532 2427029.663 100000000000 1.E+11 0.002837 25599515.25 1000000000000 1E+12 0.003152 10000000000000 1E+13 0.003309 100000000000000 1E+14 0.003699 1000000000000000 1E+15 0.004099 10000000000000000 1E+16 0.004624 100000000000000000 1E+17 0.005271 1000000000000000000 1E+18 0.006046 10000000000000000000 1E+19 0.007024 18446744073709551615 1.84467E+19 0.0383061 The O(n) results stop at 10^11 as that took seven and a half hours, so it would be reasonable to expect 10^12 to take around three days. A linear comparison of both algorithms, demonstrates the limits of practical use of the brute force approach.
  • 10. 9 ChrisWorledgePortfolio2|2/1/2016 If the mid point input value of 5 million were related to population, the linear algorithm would demonstrate poor performance with most town and city populations, but not cope at all with larger cities or counties, let alone countries. Independent charting against a logarithmic input shows the performance comparison more fully. 0 5000000 10000000 15000000 20000000 25000000 30000000 O(n)
  • 11. 10 ChrisWorledgePortfolio2|2/1/2016 It should be noted that the y axis representing time in milliseconds is very different on the two plots. 0 0.05 0.1 0.15 0.2 Olog(n)
  • 12. 11 ChrisWorledgePortfolio2|2/1/2016 A complete demo was devised which allowed any number ranges outputs to be recorded in a text file, and a display of the results of successive powers of ten finishing with 2^64 – 1. using System; using System.Diagnostics; using System.IO; namespace CleanDigitCounter { class Program { static void Main(string[] args) { consDemo();//runs a demo using the range of values from 10^0 to 10^19 and 2^64-1 } private static void consDemo() { double[] times = new double[22] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int index = 0; ulong max = 1; while (index <= 19) { double totalMiliseconds = 0; for (int i = 1; i <= 10; i++) { var avTest = Stopwatch.StartNew(); ulong[] alues = new CountDigits().CalculateNumbers(max); avTest.Stop(); totalMiliseconds += avTest.Elapsed.TotalMilliseconds; } Console.WriteLine(""); Console.WriteLine("Input: " + max.ToString()); var avElapsedValue = totalMiliseconds / 10; times[index] += avElapsedValue; string avElapsed = avElapsedValue.ToString(); Console.WriteLine("Average Milliseconds for Value " + avElapsed); Console.WriteLine(""); if (max == 1) { double totalMilis = 0; for (int i = 1; i <= 10; i++) { var avTest = Stopwatch.StartNew(); ulong[] alues = new CountDigits().CalculateNumbers(max); avTest.Stop(); totalMilis += avTest.Elapsed.TotalMilliseconds; } Console.WriteLine("");
  • 13. 12 ChrisWorledgePortfolio2|2/1/2016 Console.WriteLine("Input: " + max.ToString()); var avValue = totalMilis / 10; times[index] += avValue; string av = avValue.ToString(); Console.WriteLine("Average Milliseconds for Value " + av); Console.WriteLine(""); } var timeTest = Stopwatch.StartNew(); ulong[] digValues = new CountDigits().CalculateNumbers(max); timeTest.Stop(); var elapsedValue = timeTest.Elapsed; string longStringTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", elapsedValue.Hours, elapsedValue.Minutes, elapsedValue.Seconds, elapsedValue.Milliseconds); Console.WriteLine("Input: " + max.ToString()); Console.WriteLine(""); Console.WriteLine("Time in milliseconds = " + elapsedValue.TotalMilliseconds.ToString() + " milliseconds"); Console.WriteLine(""); Console.WriteLine("Time = " + longStringTime); Console.WriteLine(""); Console.WriteLine("0: " + digValues[0].ToString()); Console.WriteLine("1: " + digValues[1].ToString()); Console.WriteLine("2: " + digValues[2].ToString()); Console.WriteLine("3: " + digValues[3].ToString()); Console.WriteLine("4: " + digValues[4].ToString()); Console.WriteLine("5: " + digValues[5].ToString()); Console.WriteLine("6: " + digValues[6].ToString()); Console.WriteLine("7: " + digValues[7].ToString()); Console.WriteLine("8: " + digValues[8].ToString()); Console.WriteLine("9: " + digValues[9].ToString()); Console.WriteLine(""); if (index < 9)//just so the demo doesn't take weeks to run { var clock = Stopwatch.StartNew(); ulong[] digCount = new DigitCount().CountDigits(max); clock.Stop(); var elapsedMillis = clock.ElapsedMilliseconds; var timeelapsed = clock.Elapsed; string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", timeelapsed.Hours, timeelapsed.Minutes, timeelapsed.Seconds, timeelapsed.Milliseconds); Console.WriteLine("Input: " + max.ToString()); Console.WriteLine(""); Console.WriteLine("Time in milliseconds = " + timeelapsed.TotalMilliseconds.ToString() + " milliseconds"); Console.WriteLine(""); Console.WriteLine("Time = " + elapsedTime);
  • 14. 13 ChrisWorledgePortfolio2|2/1/2016 Console.WriteLine(""); Console.WriteLine("0: " + digCount[0].ToString()); Console.WriteLine("1: " + digCount[1].ToString()); Console.WriteLine("2: " + digCount[2].ToString()); Console.WriteLine("3: " + digCount[3].ToString()); Console.WriteLine("4: " + digCount[4].ToString()); Console.WriteLine("5: " + digCount[5].ToString()); Console.WriteLine("6: " + digCount[6].ToString()); Console.WriteLine("7: " + digCount[7].ToString()); Console.WriteLine("8: " + digCount[8].ToString()); Console.WriteLine("9: " + digCount[9].ToString()); Console.WriteLine(""); } max *= 10; index++; } double miliseconds = 0; ulong maxNumber = 18446744073709551615; for (int k = 0; k < 10; k++) { for (int i = 1; i <= 10; i++) { var avTest = Stopwatch.StartNew(); ulong[] alues = new CountDigits().CalculateNumbers(maxNumber); avTest.Stop(); miliseconds += avTest.Elapsed.TotalMilliseconds; } Console.WriteLine(""); Console.WriteLine("Input: " + maxNumber.ToString()); var average = miliseconds / 10; times[20] += average; } double zero = times[0] / 20; double one = times[1] / 10; double two = times[2] / 10; double three = times[3] / 10; double four = times[4] / 10; double five = times[5] / 10; double six = times[6] / 10; double seven = times[7] / 10; double eight = times[8] / 10; double nine = times[9] / 10; double ten = times[10] / 10; double eleven = times[11] / 10; double twelve = times[12] / 10; double thirteen = times[13] / 10; double fourteen = times[14] / 10; double fifteen = times[15] / 10; double sixteen = times[16] / 10; double seventeen = times[17] / 10; double eighteen = times[18] / 10; double nineteen = times[19] / 10; double twenty = times[20] / 100;
  • 15. 14 ChrisWorledgePortfolio2|2/1/2016 Console.WriteLine("Average Milliseconds for Value 1 : " + zero.ToString()); Console.WriteLine(""); Console.WriteLine("Average Milliseconds for Value 10 : " + one.ToString()); Console.WriteLine(""); Console.WriteLine("Average Milliseconds for Value 100 : " + two.ToString()); Console.WriteLine(""); Console.WriteLine("Average Milliseconds for Value 1,000 : " + three.ToString()); Console.WriteLine(""); Console.WriteLine("Average Milliseconds for Value 10,000 : " + four.ToString()); Console.WriteLine(""); Console.WriteLine("Average Milliseconds for Value 100,000 : " + five.ToString()); Console.WriteLine(""); Console.WriteLine("Average Milliseconds for Value 1,000,000 : " + six.ToString()); Console.WriteLine(""); Console.WriteLine("Average Milliseconds for Value 10,000,000 : " + seven.ToString()); Console.WriteLine(""); Console.WriteLine("Average Milliseconds for Value 100,000,000 : " + eight.ToString()); Console.WriteLine(""); Console.WriteLine("Average Milliseconds for Value 1000,000,000 : " + nine.ToString()); Console.WriteLine(""); Console.WriteLine("Average Milliseconds for Value 10,000,000,000 : " + ten.ToString()); Console.WriteLine(""); Console.WriteLine("Average Milliseconds for Value 100,000,000,000 : " + eleven.ToString()); Console.WriteLine(""); Console.WriteLine("Average Milliseconds for Value 1,000,000,000,000 : " + twelve.ToString()); Console.WriteLine(""); Console.WriteLine("Average Milliseconds for Value 10,000,000,000,000 : " + thirteen.ToString()); Console.WriteLine(""); Console.WriteLine("Average Milliseconds for Value 100,000,000,000,000 : " + fourteen.ToString()); Console.WriteLine(""); Console.WriteLine("Average Milliseconds for Value 1,000,000,000,000,000 : " + fifteen.ToString()); Console.WriteLine(""); Console.WriteLine("Average Milliseconds for Value 10,000,000,000,000,000 : " + sixteen.ToString()); Console.WriteLine(""); Console.WriteLine("Average Milliseconds for Value 100,000,000,000,000,000 : " + seventeen.ToString()); Console.WriteLine(""); Console.WriteLine("Average Milliseconds for Value 1,000,000,000,000,000,000 : " + eighteen.ToString()); Console.WriteLine("");
  • 16. 15 ChrisWorledgePortfolio2|2/1/2016 Console.WriteLine("Average Milliseconds for Value 10,000,000,000,000,000,000 : " + nineteen.ToString()); Console.WriteLine(""); Console.WriteLine("Average Milliseconds for Value 18446744073709551615 : " + twenty.ToString()); Console.WriteLine(""); Console.WriteLine("Press enter to close..."); Console.ReadLine(); } private static void textFile(ulong start, ulong finish) { FileStream outstrm; StreamWriter writer; TextWriter oldOut = Console.Out; try { outstrm = new FileStream("C:/Test/ConsoleOutput.txt", FileMode.OpenOrCreate, FileAccess.Write); writer = new StreamWriter(outstrm); } catch (Exception e) { Console.WriteLine("Cannot open ConsoleOutput.txt for writing"); Console.WriteLine(e.Message); return; } Console.SetOut(writer); ulong max; for (max = start; max < finish; max++) { var timeTest = Stopwatch.StartNew(); ulong[] digValues = new CountDigits().CalculateNumbers(max); timeTest.Stop(); var elapsedValue = timeTest.Elapsed; string timeVal = elapsedValue.ToString(); string timeS = timeVal.Substring(5, 3); string timeM = timeVal.Substring(9, 3); string timeD = timeVal.Substring(12); string longStringTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", elapsedValue.Hours, elapsedValue.Minutes, elapsedValue.Seconds, elapsedValue.Milliseconds); Console.WriteLine("Input: " + max.ToString()); Console.WriteLine(""); Console.WriteLine("Time in milliseconds = " + elapsedValue.TotalMilliseconds.ToString() + " milliseconds"); Console.WriteLine(""); Console.WriteLine("Time = " + longStringTime); Console.WriteLine(""); Console.WriteLine("0: " + digValues[0].ToString()); Console.WriteLine("1: " + digValues[1].ToString());
  • 17. 16 ChrisWorledgePortfolio2|2/1/2016 Console.WriteLine("2: " + digValues[2].ToString()); Console.WriteLine("3: " + digValues[3].ToString()); Console.WriteLine("4: " + digValues[4].ToString()); Console.WriteLine("5: " + digValues[5].ToString()); Console.WriteLine("6: " + digValues[6].ToString()); Console.WriteLine("7: " + digValues[7].ToString()); Console.WriteLine("8: " + digValues[8].ToString()); Console.WriteLine("9: " + digValues[9].ToString()); Console.WriteLine(""); var clock = Stopwatch.StartNew(); ulong[] digCount = new DigitCount().CountDigits(max); clock.Stop(); var elapsedMillis = clock.ElapsedMilliseconds; var timeelapsed = clock.Elapsed; string timelapsed = timeelapsed.ToString(); string hrs = timelapsed.Substring(0, 2); string mins = timelapsed.Substring(3, 2); string secs = timelapsed.Substring(6, 2); double milliseconds = 0; int hours = 0; int minutes = 0; int seconds = 0; int wholeMilis = 0; int intdecMilis = 0; double decMilis = 0.0; int.TryParse(hrs, out hours); int.TryParse(mins, out minutes); int.TryParse(secs, out seconds); string millis = timelapsed.Substring(9, 3); int.TryParse(millis, out wholeMilis); string afterDec = timelapsed.Substring(12); int.TryParse(afterDec, out intdecMilis); decMilis = (double)intdecMilis / 10000; milliseconds = (hours * 60 * 60 * 1000) + (minutes * 60 * 1000) + (seconds * 1000) + wholeMilis + decMilis; string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", timeelapsed.Hours, timeelapsed.Minutes, timeelapsed.Seconds, timeelapsed.Milliseconds); Console.WriteLine("Input: " + max.ToString()); Console.WriteLine(""); Console.WriteLine("Time in milliseconds = " + timeelapsed.TotalMilliseconds.ToString() + " milliseconds"); Console.WriteLine(""); Console.WriteLine("Time = " + elapsedTime); Console.WriteLine(""); Console.WriteLine("0: " + digCount[0].ToString()); Console.WriteLine("1: " + digCount[1].ToString()); Console.WriteLine("2: " + digCount[2].ToString()); Console.WriteLine("3: " + digCount[3].ToString()); Console.WriteLine("4: " + digCount[4].ToString()); Console.WriteLine("5: " + digCount[5].ToString()); Console.WriteLine("6: " + digCount[6].ToString()); Console.WriteLine("7: " + digCount[7].ToString());
  • 18. 17 ChrisWorledgePortfolio2|2/1/2016 Console.WriteLine("8: " + digCount[8].ToString()); Console.WriteLine("9: " + digCount[9].ToString()); Console.WriteLine(""); } writer.Close(); outstrm.Close(); Console.SetOut(oldOut); Console.WriteLine("Done"); Console.WriteLine("Press enter to close..."); Console.ReadLine(); } } } The results: Input: 1 Average Milliseconds for Value 0.07499 Input: 1 Average Milliseconds for Value 0.00022 Input: 1 Time in milliseconds = 0.0005 milliseconds Time = 00:00:00.00 0: 0 1: 1 2: 0 3: 0 4: 0 5: 0 6: 0 7: 0
  • 19. 18 ChrisWorledgePortfolio2|2/1/2016 8: 0 9: 0 Input: 1 Time in milliseconds = 0.4146 milliseconds Time = 00:00:00.00 0: 0 1: 1 2: 0 3: 0 4: 0 5: 0 6: 0 7: 0 8: 0 9: 0 Input: 10 Average Milliseconds for Value 0.00083 Input: 10 Time in milliseconds = 0.002 milliseconds Time = 00:00:00.00 0: 1 1: 2 2: 1 3: 1 4: 1 5: 1
  • 20. 19 ChrisWorledgePortfolio2|2/1/2016 6: 1 7: 1 8: 1 9: 1 Input: 10 Time in milliseconds = 0.0046 milliseconds Time = 00:00:00.00 0: 1 1: 2 2: 1 3: 1 4: 1 5: 1 6: 1 7: 1 8: 1 9: 1 Input: 100 Average Milliseconds for Value 0.002 Input: 100 Time in milliseconds = 0.0032 milliseconds Time = 00:00:00.00 0: 11 1: 21 2: 20
  • 21. 20 ChrisWorledgePortfolio2|2/1/2016 3: 20 4: 20 5: 20 6: 20 7: 20 8: 20 9: 20 Input: 100 Time in milliseconds = 0.0146 milliseconds Time = 00:00:00.00 0: 11 1: 21 2: 20 3: 20 4: 20 5: 20 6: 20 7: 20 8: 20 9: 20 Input: 1000 Average Milliseconds for Value 0.00142 Input: 1000 Time in milliseconds = 0.0032 milliseconds
  • 22. 21 ChrisWorledgePortfolio2|2/1/2016 Time = 00:00:00.00 0: 192 1: 301 2: 300 3: 300 4: 300 5: 300 6: 300 7: 300 8: 300 9: 300 Input: 1000 Time in milliseconds = 0.1345 milliseconds Time = 00:00:00.00 0: 192 1: 301 2: 300 3: 300 4: 300 5: 300 6: 300 7: 300 8: 300 9: 300 Input: 10000
  • 23. 22 ChrisWorledgePortfolio2|2/1/2016 Average Milliseconds for Value 0.00167 Input: 10000 Time in milliseconds = 0.0029 milliseconds Time = 00:00:00.00 0: 2893 1: 4001 2: 4000 3: 4000 4: 4000 5: 4000 6: 4000 7: 4000 8: 4000 9: 4000 Input: 10000 Time in milliseconds = 1.5072 milliseconds Time = 00:00:00.01 0: 2893 1: 4001 2: 4000 3: 4000 4: 4000 5: 4000 6: 4000 7: 4000 8: 4000
  • 24. 23 ChrisWorledgePortfolio2|2/1/2016 9: 4000 Input: 100000 Average Milliseconds for Value 0.00193 Input: 100000 Time in milliseconds = 0.0029 milliseconds Time = 00:00:00.00 0: 38894 1: 50001 2: 50000 3: 50000 4: 50000 5: 50000 6: 50000 7: 50000 8: 50000 9: 50000 Input: 100000 Time in milliseconds = 15.5442 milliseconds Time = 00:00:00.15 0: 38894 1: 50001 2: 50000 3: 50000 4: 50000 5: 50000
  • 25. 24 ChrisWorledgePortfolio2|2/1/2016 6: 50000 7: 50000 8: 50000 9: 50000 Input: 1000000 Average Milliseconds for Value 0.00286 Input: 1000000 Time in milliseconds = 0.0029 milliseconds Time = 00:00:00.00 0: 488895 1: 600001 2: 600000 3: 600000 4: 600000 5: 600000 6: 600000 7: 600000 8: 600000 9: 600000 Input: 1000000 Time in milliseconds = 171.8509 milliseconds Time = 00:00:00.171 0: 488895 1: 600001 2: 600000
  • 26. 25 ChrisWorledgePortfolio2|2/1/2016 3: 600000 4: 600000 5: 600000 6: 600000 7: 600000 8: 600000 9: 600000 Input: 10000000 Average Milliseconds for Value 0.00262 Input: 10000000 Time in milliseconds = 0.0029 milliseconds Time = 00:00:00.00 0: 5888896 1: 7000001 2: 7000000 3: 7000000 4: 7000000 5: 7000000 6: 7000000 7: 7000000 8: 7000000 9: 7000000 Input: 10000000 Time in milliseconds = 1903.8346 milliseconds Time = 00:00:01.903
  • 27. 26 ChrisWorledgePortfolio2|2/1/2016 0: 5888896 1: 7000001 2: 7000000 3: 7000000 4: 7000000 5: 7000000 6: 7000000 7: 7000000 8: 7000000 9: 7000000 Input: 100000000 Average Milliseconds for Value 0.00182 Input: 100000000 Time in milliseconds = 0.0029 milliseconds Time = 00:00:00.00 0: 68888897 1: 80000001 2: 80000000 3: 80000000 4: 80000000 5: 80000000 6: 80000000 7: 80000000 8: 80000000 9: 80000000
  • 28. 27 ChrisWorledgePortfolio2|2/1/2016 Input: 1000000000 Average Milliseconds for Value 0.00197 Input: 1000000000 Time in milliseconds = 0.0023 milliseconds Time = 00:00:00.00 0: 788888898 1: 900000001 2: 900000000 3: 900000000 4: 900000000 5: 900000000 6: 900000000 7: 900000000 8: 900000000 9: 900000000 Input: 10000000000 Average Milliseconds for Value 0.00253 Input: 10000000000 Time in milliseconds = 0.0026 milliseconds Time = 00:00:00.00 0: 8888888899 1: 10000000001 2: 10000000000 3: 10000000000 4: 10000000000 5: 10000000000
  • 29. 28 ChrisWorledgePortfolio2|2/1/2016 6: 10000000000 7: 10000000000 8: 10000000000 9: 10000000000 Input: 100000000000 Average Milliseconds for Value 0.00269 Input: 100000000000 Time in milliseconds = 0.0032 milliseconds Time = 00:00:00.00 0: 98888888900 1: 110000000001 2: 110000000000 3: 110000000000 4: 110000000000 5: 110000000000 6: 110000000000 7: 110000000000 8: 110000000000 9: 110000000000 Input: 1000000000000 Average Milliseconds for Value 0.00296 Input: 1000000000000 Time in milliseconds = 0.0035 milliseconds Time = 00:00:00.00 0: 1088888888901 1: 1200000000001
  • 30. 29 ChrisWorledgePortfolio2|2/1/2016 2: 1200000000000 3: 1200000000000 4: 1200000000000 5: 1200000000000 6: 1200000000000 7: 1200000000000 8: 1200000000000 9: 1200000000000 Input: 10000000000000 Average Milliseconds for Value 0.00475 Input: 10000000000000 Time in milliseconds = 0.0035 milliseconds Time = 00:00:00.00 0: 11888888888902 1: 13000000000001 2: 13000000000000 3: 13000000000000 4: 13000000000000 5: 13000000000000 6: 13000000000000 7: 13000000000000 8: 13000000000000 9: 13000000000000 Input: 100000000000000 Average Milliseconds for Value 0.00391
  • 31. 30 ChrisWorledgePortfolio2|2/1/2016 Input: 100000000000000 Time in milliseconds = 0.0046 milliseconds Time = 00:00:00.00 0: 128888888888903 1: 140000000000001 2: 140000000000000 3: 140000000000000 4: 140000000000000 5: 140000000000000 6: 140000000000000 7: 140000000000000 8: 140000000000000 9: 140000000000000 Input: 1000000000000000 Average Milliseconds for Value 0.00469 Input: 1000000000000000 Time in milliseconds = 0.0041 milliseconds Time = 00:00:00.00 0: 1388888888888904 1: 1500000000000001 2: 1500000000000000 3: 1500000000000000 4: 1500000000000000 5: 1500000000000000 6: 1500000000000000 7: 1500000000000000
  • 32. 31 ChrisWorledgePortfolio2|2/1/2016 8: 1500000000000000 9: 1500000000000000 Input: 10000000000000000 Average Milliseconds for Value 0.00479 Input: 10000000000000000 Time in milliseconds = 0.0055 milliseconds Time = 00:00:00.00 0: 14888888888888905 1: 16000000000000001 2: 16000000000000000 3: 16000000000000000 4: 16000000000000000 5: 16000000000000000 6: 16000000000000000 7: 16000000000000000 8: 16000000000000000 9: 16000000000000000 Input: 100000000000000000 Average Milliseconds for Value 0.00457 Input: 100000000000000000 Time in milliseconds = 0.0046 milliseconds Time = 00:00:00.00 0: 158888888888888906 1: 170000000000000001 2: 170000000000000000
  • 33. 32 ChrisWorledgePortfolio2|2/1/2016 3: 170000000000000000 4: 170000000000000000 5: 170000000000000000 6: 170000000000000000 7: 170000000000000000 8: 170000000000000000 9: 170000000000000000 Input: 1000000000000000000 Average Milliseconds for Value 0.0049 Input: 1000000000000000000 Time in milliseconds = 0.0052 milliseconds Time = 00:00:00.00 0: 1688888888888888907 1: 1800000000000000001 2: 1800000000000000000 3: 1800000000000000000 4: 1800000000000000000 5: 1800000000000000000 6: 1800000000000000000 7: 1800000000000000000 8: 1800000000000000000 9: 1800000000000000000 Input: 10000000000000000000 Average Milliseconds for Value 0.0055 Input: 10000000000000000000
  • 34. 33 ChrisWorledgePortfolio2|2/1/2016 Time in milliseconds = 0.0061 milliseconds Time = 00:00:00.00 0: 17888888888888888908 1: 553255926290448385 2: 553255926290448384 3: 553255926290448384 4: 553255926290448384 5: 553255926290448384 6: 553255926290448384 7: 553255926290448384 8: 553255926290448384 9: 553255926290448384 Input: 18446744073709551615 Input: 18446744073709551615 Input: 18446744073709551615 Input: 18446744073709551615 Input: 18446744073709551615 Input: 18446744073709551615 Input: 18446744073709551615 Input: 18446744073709551615 Input: 18446744073709551615 Input: 18446744073709551615 Average Milliseconds for Value 1 : 0.0044365 Average Milliseconds for Value 10 : 8.3E-05
  • 35. 34 ChrisWorledgePortfolio2|2/1/2016 Average Milliseconds for Value 100 : 0.0002 Average Milliseconds for Value 1,000 : 0.000142 Average Milliseconds for Value 10,000 : 0.000167 Average Milliseconds for Value 100,000 : 0.000193 Average Milliseconds for Value 1,000,000 : 0.000286 Average Milliseconds for Value 10,000,000 : 0.000262 Average Milliseconds for Value 100,000,000 : 0.000182 Average Milliseconds for Value 1000,000,000 : 0.000197 Average Milliseconds for Value 10,000,000,000 : 0.000253 Average Milliseconds for Value 100,000,000,000 : 0.000269 Average Milliseconds for Value 1,000,000,000,000 : 0.000296 Average Milliseconds for Value 10,000,000,000,000 : 0.000475 Average Milliseconds for Value 100,000,000,000,000 : 0.000391 Average Milliseconds for Value 1,000,000,000,000,000 : 0.000469
  • 36. 35 ChrisWorledgePortfolio2|2/1/2016 Average Milliseconds for Value 10,000,000,000,000,000 : 0.000479 Average Milliseconds for Value 100,000,000,000,000,000 : 0.000457 Average Milliseconds for Value 1,000,000,000,000,000,000 : 0.00049 Average Milliseconds for Value 10,000,000,000,000,000,000 : 0.00055 Average Milliseconds for Value 18446744073709551615 : 0.0029604 Press enter to close...
  • 37. 36 ChrisWorledgePortfolio2|2/1/2016 EXPLORATION OF MONGODB USING NODEJS This was achieved following a Microsoft Tutorial Links the app to the database instance, we can then pass the database instance to the MongoDB Client and populate and interrogate it as follows:
  • 39. 38 ChrisWorledgePortfolio2|2/1/2016 We perform CRUD operations out of sequence. Create; Update; Retrieve; and Delete.
  • 41. 40 ChrisWorledgePortfolio2|2/1/2016 C# TEMPORAL DATA STORE You will be implementing a read-biased in-memory temporal data store. A temporal store allows point-in-time queries about data. An example would be the price of an exchange traded security. We might capture the price of the security once an hour throughout the trading day, and store the price in a temporal store. We can then query the temporal store to determine at any given time, what the most recent captured price was. This example illustrates the following key terms, which will be used throughout this document: 1. Identifier - a key (e.g. the security id), for which we want to store a history of observations 2. History - the list of observations for a given identifier 3. Observation - a piece of data which is associated with a particular identifier at a particular timestamp 4. Timestamp - a given point in time The latest observation for an identifier at a timestamp is found by searching in the identifier's history for the first observation whose timestamp is less than, or equal to, the sought timestamp. For the purposes of this scenario, you should assume the following: 1. Identifiers are integers in the inclusive range [0..2^31 - 1] 2. Timestamps are integers in the inclusive range [0..2^63 - 1] 3. Data is represented as a contiguous string of non-whitespace characters. For example, "jiggawatt" is a valid piece of data. The string "great scot" is not, owing to its whitespace. 4. Users may interact with the temporal store, as well as processes. you should be strict in what data you accept, but should provide suitable error messages where the user has erred. 5. Capacity; there is no requirement to restrict your store to a given size, but you may assume that you will be provided with no more than 10,000 identifiers, each with no more than 1,000 history entries, and no data item will be no more than 16 characters.
  • 42. 41 ChrisWorledgePortfolio2|2/1/2016 Your temporal data store will communicate with other processes via standard input and output. A series of commands are read and applied to the data store from standard input. The results of evaluating the commands should be written to standard output. A command will only ever be one line; the result of executing a command will be a single output line, except for the QUIT command. When there are no more lines to consume, your temporal data store should exit. There is no need to persist data in the store between executions (this is an in-memory temporal store). class Program { static void Main(string[] args) { /*Holds the references to all the history stores, so we can find the required history if it exists*/ List<DataDict> contain = new List<DataDict>(); //We make a few histories (from 0 - 4) and populate them with dummy data for (int i = 0; i < 5; i++) { string j = "100"; string k = "1.1"; string dummy = "FirstCreate " + i + " " + j + " " + k; new CommandHandler(dummy, contain); } for (int i = 0; i < 5; i++) { var p = 110; var q = 1.2; for (int l = 0; l < 10; l++) { string dummy = "FirstUpdate " + i.ToString() + " " + p.ToString() + " " + q.ToString(); new CommandHandler(dummy, contain); p = p + 10; q = q + 0.1; } } //Cue the console up, ready to receive user input string line; line = Console.ReadLine(); if (line != null) { new CommandHandler(line, contain); } } }
  • 43. 42 ChrisWorledgePortfolio2|2/1/2016 The commands which can be executed against your data store are described below. Note that: - Items in <angle brackets> represent required arguments, but the angle brackets themselves do not form part of the command - Items in [square brackets] are optional arguments - Successfully processed commands should always start their response with "OK ", followed by the result of executing the command - Commands which could not be executed should always start their response with "ERR ", followed by a reasonable error message. - Commands are not sensitive to whitespace; arguments must be separated by at least one character of whitespace, but may be separated by more. CREATE <id> <timestamp> <data> - Creates a new history for the given identifier, if there is no existing history. Adds an observation to the newly created history for the given timestamp and data. CREATE should not be executed if the provided identifier already has a history. Returns the data which was inserted, to confirm insertion. UPDATE <id> <timestamp> <data> - Inserts an observation for the given identifier, timestamp and data. Returns the data from the prior observation for that timestamp. DELETE <id> [timestamp] - If timestamp is provided, deletes all observations for the given identifier from that timestamp forward. Returns the current observation at the given timestamp, or an error if there is no available observation. - If timestamp is not provided, deletes the history for the given identifier, and returns the observation with the greatest timestamp from the history which has been deleted.
  • 44. 43 ChrisWorledgePortfolio2|2/1/2016 GET <id> <timestamp> - Returns the data from the observation for the given identifier at the given timestamp, or an error if there is no available observation. LATEST <id> - Locates the observation with the greatest timestamp from the history for the given identifier, and responds with its timestamp and data. QUIT - Terminates the process immediately. No response should be written. We use a List to store references to a series of Dictionaries, one for each security. class CommandHandler { string id = string.Empty; string timeStamp = string.Empty; string data = string.Empty; string Command = string.Empty; int ID; long dateTime; string line; public CommandHandler(string command, List<DataDict> contain) { //separate out the different elements of the user input char[] seperator = new char[] { ' ' }; string[] commands = command.Split(seperator, StringSplitOptions.RemoveEmptyEntries); Command = commands[0].Trim().ToLower(); if (commands.Count() > 1) { id = commands[1].Trim(); } if (commands.Count() > 2) { timeStamp = commands[2].Trim(); } if (commands.Count() > 3) { data = commands[3].Trim(); } switch (Command) { case "create": Create(contain);
  • 45. 44 ChrisWorledgePortfolio2|2/1/2016 break; case "update": Update(contain); break; case "delete": Delete(contain); break; case "get": Get(contain); break; case "latest": Latest(contain); break; //These two are just to provide some intial values, so little comms with user case "firstcreate": FirstCreate(contain); break; case "firstupdate": FirstUpdate(contain); break; case "quit": Environment.Exit(0); break; default: Console.WriteLine("I am sorry, I do not understand that command."); line = Console.ReadLine(); if (line != null) { new CommandHandler(line, contain); } break; } } protected void Create(List<DataDict> contain) { if (int.TryParse(id, out ID)) { int index = contain.FindIndex(e => e.Name == ID); if (index >= 0) { Console.WriteLine("Error: The history already exists for ID '" + ID + "'");
  • 46. 45 ChrisWorledgePortfolio2|2/1/2016 } else { DataDict n = new DataDict(ID); contain.Add(n);//adds the reference to the history store in the container list if (long.TryParse(timeStamp, out dateTime)) { n.Add(dateTime, data); Console.WriteLine("OK " + data.ToString()); } else { Console.WriteLine("Error: The DateTime value provided is invalid. Please ensure you provide a valid DateTime value."); } } } line = Console.ReadLine(); if (line != null) { new CommandHandler(line, contain); } } protected void Update(List<DataDict> contain) { if (int.TryParse(id, out ID)) { int index = -1; index = contain.FindIndex(e => e.Name == ID); if (index >= 0) { var n = (from DataList in contain where DataList.Name == ID select DataList).FirstOrDefault(); if (long.TryParse(timeStamp, out dateTime)) { int exists = -1; exists = n.DoesExist(dateTime); string previous = string.Empty; if (exists > 0) { previous = n.Update(dateTime, data); } else { previous = n.Add(dateTime, data); } Console.WriteLine("OK " + previous); } else { Console.WriteLine("Error: The DateTime value provided is invalid. Please ensure you provide a valid DateTime value."); }
  • 47. 46 ChrisWorledgePortfolio2|2/1/2016 } else { Console.WriteLine("Error: No history exists for identifier '" + ID.ToString() + "' "); } } else { Console.WriteLine("Error: The ID provided is invalid. Please ensure it is a number."); } line = Console.ReadLine(); if (line != null) { new CommandHandler(line, contain); } } protected void Delete(List<DataDict> contain) { if (int.TryParse(id, out ID)) { int index = contain.FindIndex(e => e.Name == ID); if (index >= 0) { var n = (from DataList in contain where DataList.Name == ID select DataList).FirstOrDefault(); if (long.TryParse(timeStamp, out dateTime)) { KeyValuePair<long, string> got = n.Specific(dateTime); n.deleteAfter(dateTime); Console.WriteLine("OK " + got.Value.ToString()); } //if there is no timestamp, remove the whole list else { string newestValue = n.Latest().Value; contain.Remove(n); Console.WriteLine("OK " + newestValue); } } else { Console.WriteLine("Error: The ID provided [" + ID.ToString() + "] has no history. Please ensure you provide a valid ID."); } } else { Console.WriteLine("Error: The ID provided is Invalid. Please ensure it is a number."); } line = Console.ReadLine(); if (line != null)
  • 48. 47 ChrisWorledgePortfolio2|2/1/2016 { new CommandHandler(line, contain); } } protected void Get(List<DataDict> contain) { if (int.TryParse(id, out ID)) { int index = contain.FindIndex(e => e.Name == ID); if (index >= 0) { var n = (from DataList in contain where DataList.Name == ID select DataList).FirstOrDefault(); if (long.TryParse(timeStamp, out dateTime)) { if (n.ExistsOrLess(dateTime) > 0) { KeyValuePair<long, string> got = n.Specific(dateTime); Console.WriteLine("OK " + got.Value.ToString()); } else { Console.WriteLine("Error: The ID provided [" + ID.ToString() + "] has no history prior to the supplied DateTime value."); } } else { Console.WriteLine("Error: The DateTime value provided is invalid. Please ensure you provide a valid DateTime value."); } } else { Console.WriteLine("Error: The ID provided [" + ID.ToString() + "] has no history. Please ensure you provide a valid ID."); } } else { Console.WriteLine("Error: The ID provided is Invalid. Please ensure it is a number."); } line = Console.ReadLine(); if (line != null) { new CommandHandler(line, contain); } } protected void Latest(List<DataDict> contain) { if (int.TryParse(id, out ID)) {
  • 49. 48 ChrisWorledgePortfolio2|2/1/2016 int index = contain.FindIndex(e => e.Name == ID); if (index >= 0) { var n = (from DataList in contain where DataList.Name == ID select DataList).FirstOrDefault(); KeyValuePair<long, string> latest = n.Latest(); Console.WriteLine("OK " + latest.Key.ToString() + " " + latest.Value.ToString()); } else { Console.WriteLine("Error: No history exists for identifier '" + ID.ToString() + "' ") ; } } else { Console.WriteLine("Error: The ID provided is Invalid. Please ensure it is a number."); } line = Console.ReadLine(); if (line != null) { new CommandHandler(line, contain); } } protected void FirstCreate(List<DataDict> contain) { if (int.TryParse(id, out ID)) { int index = contain.FindIndex(e => e.Name == ID); if (index >= 0) { Console.WriteLine("Error: The id value " + ID.ToString() + " already exists"); } else { DataDict n = new DataDict(ID); contain.Add(n);//adds the reference to the history store in the container list if (long.TryParse(timeStamp, out dateTime)) { DataItem d = new DataItem(data, dateTime); n.Add(dateTime, data);//the first record in the history Console.WriteLine("OK " + data.ToString()); } } } } protected void FirstUpdate(List<DataDict> contain) { if (int.TryParse(id, out ID))
  • 50. 49 ChrisWorledgePortfolio2|2/1/2016 { var n = (from DataList in contain where DataList.Name == ID select DataList).FirstOrDefault(); if (long.TryParse(timeStamp, out dateTime)) { n.Add(dateTime, data);//additional records in the history Console.WriteLine("OK " + data.ToString()); } } } } class DataDict { int name; /*the Property only has an accessor to prevent accidental edit. It allows multiple records to be stored and retrieved against the same ID This structure allows you to access just the information relating to the ID (Security) submitted The alternative of putting all records in one list would mean selecting the required ID from the dictionary into a working dictionary each time, or working within the clutter of many irrelevant records */ public int Name { get { return name; } } public SortedDictionary<long, string> dataDict { get; set; } public DataDict(int n) { name = n; dataDict = new SortedDictionary<long, string>(); } public string Add(long timePassed, string data) { string prev = string.Empty; long prevKey = -1; if (dataDict.Keys.Count > 0) { prevKey = dataDict.Keys.Max(); } if (prevKey >= 0) { var previous = dataDict.Where(x => x.Key == prevKey).First(); prev = previous.Value; } else { prev = "not available"; } dataDict.Add(timePassed, data); return prev; } public int DoesExist(long dateTime)
  • 51. 50 ChrisWorledgePortfolio2|2/1/2016 { if (dataDict.ContainsKey(dateTime)) { return 1; } else { return 0; } } public string Update(long timePassed, string data) { string prev = string.Empty; var previous = dataDict.FirstOrDefault(e => e.Key == timePassed); prev = previous.Value; dataDict.Remove(timePassed); dataDict.Add(timePassed, data); return prev; } public string getBiggestData() { return dataDict.Values.Max().ToString(); } public int ExistsOrLess(long dateTime) { var allUnder = dataDict.Where(e => e.Key <= dateTime); if (allUnder.Count() > 0) { return 1; } else { return 0; } } public KeyValuePair<long, string> Specific(long dateTime) { if (dataDict.ContainsKey(dateTime)) { return dataDict.FirstOrDefault(e => e.Key == dateTime); } else { var allUnder = dataDict.Where(e => e.Key < dateTime); return allUnder.Last(); } }
  • 52. 51 ChrisWorledgePortfolio2|2/1/2016 public void deleteBefore(long dateTime) { SortedDictionary<long, string> tempDict = new SortedDictionary<long, string>(dataDict.Where(e => e.Key >= dateTime).ToDictionary(e => e.Key, e => e.Value)); dataDict = tempDict; } public void deleteAfter(long dateTime) { SortedDictionary<long, string> tempDict = new SortedDictionary<long, string>(dataDict.Where(e => e.Key <= dateTime).ToDictionary(e => e.Key, e => e.Value)); dataDict = tempDict; } public KeyValuePair<long, string> Latest() { long highest = dataDict.Keys.Max(); return dataDict.Where(x => x.Key == highest).First(); } }
  • 53. 52 ChrisWorledgePortfolio2|2/1/2016Zero to four were used in the automated demo, so five and six have been used in place of 0 & 1 in the manual demo.
  • 54. 53 ChrisWorledgePortfolio2|2/1/2016 ENTITY FRAMEWORK WITH WEBFORMS An example of displaying the relationships between different staff from a database using entity framework and web forms: Data ID ForeName SurName Manager 0 Lucy Atwell NULL 1 Carla Barns 0 2 Tara Crane 0 3 Freda Dunbarr 0 4 Patricia Edwards 1 5 Vicky Fox 1 6 Margaret Grant 2 7 Cindy Hall 2 8 Kirsty Irwin 3 10 Jane James 3 ID EmpID JobID 1 0 1 2 1 2 3 2 4 4 3 6 5 4 3 6 5 5 7 6 7 8 7 3 9 8 5 10 9 7 11 10 7
  • 55. 54 ChrisWorledgePortfolio2|2/1/2016 ID Job 1 Pharmacist 2 Physiotherapist 3 Cardiac Technician 4 Radiographer 5 Phlebotomist 6 Biomedical Scientist 7 Pharmacy Technician Data Access Classes public partial class Ldemo : DataContext { public Table<Emp> Emp; public Table<EmpJob> EmpJob; public Table<Job> Job; public Ldemo(string connection) : base(connection) { } } public class Relationship { public String Forename { get; set; } public String Surname { get; set; } public String Job { get; set; } public String Manager { get; set; } public Relationship(String f, String s, String j, String m) { Forename = f; Surname = s; Job = j; Manager = m; } } Form Code Behind public partial class Page1 : System.Web.UI.Page { public List<Relationship> relations = new List<Relationship>(); protected void Page_Load(object sender, EventArgs e) { var conString = System.Configuration.ConfigurationManager.ConnectionStrings["LinqDemoConnectionString"].T oString(); Ldemo db = new Ldemo(conString); relations = (from a in db.Emp join b in db.Emp on new { Manager = a.Manager.GetValueOrDefault(-1) } equals new { Manager = b.ID } into b_join
  • 56. 55 ChrisWorledgePortfolio2|2/1/2016 from b in b_join.DefaultIfEmpty() join EmpJobs in db.EmpJob on new { ID = a.ID } equals new { ID = EmpJobs.EmpID } join Jobs in db.Job on new { JobID = EmpJobs.JobID } equals new { JobID = Jobs.ID } select new Relationship( a.ForeName, a.SurName, Jobs.Job1, b.ForeName + " " + b.SurName )).ToList(); } } The code creates a list called relations which holds all of the staff names with their job and their manager. Since Lucy Atwell’s manager field contains null, her manager field should be blank. All the other staff have a number representing another member of staff is their manager. Form aspx <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Page1.aspx.cs" Inherits="LinqDemo.Page1" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title></title> </head> <body> <form id="form1" runat="server"> <div> <table> <tr> <td><b>Forename</b></td> <td><b>Surname</b></td> <td><b>Job</b></td> <td><b>Manager</b></td> </tr> <% foreach (var relation in relations) { %> <tr><td><%= relation.Forename %></td> <td><%= relation.Surname %></td> <td><%= relation.Job %></td> <td><%= relation.Manager %></td></tr> <% } %> </table> </div> </form> </body> </html>
  • 58. 57 ChrisWorledgePortfolio2|2/1/2016 ENTITY FRAMEWORK WITH MVC This application demonstrates the use of entity framework 6 with an MVC5 asp.net (C#) 4.5 combination: The purpose of the application is to store, retrieve, and display information about shares. It has different markets; shares; and share prices, so displays tables of these allowing Create; Read; Update; and Delete functionality. It also allows display of tables sorted by different parameters, and a view of just the most recent prices for each share. The prices and shares table’s pages have a chart facility which provides a line chart of the selected share price over time. This is the Home page from the navigation bar along the top. The subsequent shots follow along the navigation bar (List of stocks; List of markets; List of prices; Sorted list of prices; Latest prices).
  • 62. 61 ChrisWorledgePortfolio2|2/1/2016 From the Prices list the chart button click for Jones gives:
  • 63. 62 ChrisWorledgePortfolio2|2/1/2016 From the Stocks page the charts link click for Browns gives: Adding a new price: The current date and time is inserted for you, and you select the stock from the drop-down.
  • 64. 63 ChrisWorledgePortfolio2|2/1/2016 Models: namespace MVC5ef6.Models { using System; using System.Collections.Generic; public partial class Stock { [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] public Stock() { this.Prices = new HashSet<Price>(); } public int stockID { get; set; } public string stockName { get; set; } public Nullable<int> marketID { get; set; } public virtual Market Market { get; set; } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] public virtual ICollection<Price> Prices { get; set; } } public partial class Market { [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] public Market() { this.Stocks = new HashSet<Stock>(); } public int marketID { get; set; } public string marketName { get; set; } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] public virtual ICollection<Stock> Stocks { get; set; } } public partial class Price { public int ID { get; set; } public Nullable<int> stockID { get; set; } public Nullable<System.DateTime> Stamp { get; set; } public Nullable<decimal> Pence { get; set; } public virtual Stock Stock { get; set; } } public partial class LatestPrice {
  • 65. 64 ChrisWorledgePortfolio2|2/1/2016 public long ID { get; set; } public string stockName { get; set; } public string marketName { get; set; } public Nullable<System.DateTime> Stamp { get; set; } public Nullable<decimal> Pence { get; set; } } public partial class PriceListItem { public int ID { get; set; } public Nullable<int> stockID { get; set; } public Nullable<System.DateTime> Stamp { get; set; } public Nullable<decimal> Pence { get; set; } public string stockName { get; set; } } public class StockPriceModel { public int ID { get; set; } public string ChartTitle { get; set; } public string StampTitle { get; set; } public string PenceTitle { get; set; } public int stockID { get; set; } public StockPrice PriceData { get; set; } } public class StockPrice { public int ID { get; set; } public string Stamp { get; set; } public decimal Pence { get; set; } } } Views: Shared: _Layout; <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>@ViewBag.Title - My ASP.NET Application</title> @Styles.Render("~/Content/css") @Scripts.Render("~/bundles/modernizr") @Scripts.Render("~/bundles/jquery") <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script> </head> <body> <div class="navbar navbar-inverse navbar-fixed-top"> <div class="container">
  • 66. 65 ChrisWorledgePortfolio2|2/1/2016 <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data- target=".navbar-collapse"> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> @Html.ActionLink("Share Prices", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" }) </div> <div class="navbar-collapse collapse"> <ul class="nav navbar-nav"> <li>@Html.ActionLink("Home", "Index", "Home")</li> <li>@Html.ActionLink("List of stocks", "Index", "Stocks")</li> <li>@Html.ActionLink("List of markets", "Index", "Markets")</li> <li>@Html.ActionLink("List of prices", "Index", "Prices")</li> <li>@Html.ActionLink("Sorted List of prices", "Index", "PriceListItems")</li> <li>@Html.ActionLink("Latest Prices", "Index", "LatestPrices")</li> </ul> </div> </div> </div> <div class="container body-content"> <h1></h1> @RenderBody() <!-- <hr /> --> <footer> <p>&copy; @DateTime.Now.Year - MVC5 with entity framework 6 application</p> </footer> </div> @Scripts.Render("~/bundles/jquery") @Scripts.Render("~/bundles/bootstrap") @RenderSection("scripts", required: false) </body> </html> Home: Index; @{ ViewBag.Title = "Home Page"; } <div class="jumbotron"> <h1>A short - cut to the latest prices</h1> <h2> Each stock's latest price, ordered by market. <a> @Html.ActionLink("Latest Prices", "Index", "LatestPrices", null, new { @class = "btn btn-primary btn-lg actionLink" }) </a> </h2> </div> <div>
  • 67. 66 ChrisWorledgePortfolio2|2/1/2016 <div class="spacer"></div> </div> <div class="row"> <div class="col-md-4"> <h2>See the Stocks</h2> <a>@Html.ActionLink("List of stocks", "Index", "Stocks", null, new {@class= "btn btn-primary btn-lg actionLink" }) </a> </div> <div class="col-md-4"> <h2>See the Markets</h2> <a>@Html.ActionLink("List of markets", "Index", "Markets", null, new { @class = "btn btn-primary btn-lg actionLink" })</a> </div> <div class="col-md-4"> <h2>See the Prices</h2> <a>@Html.ActionLink("List of prices", "Index", "PriceListItems", null, new { @class = "btn btn-primary btn-lg actionLink" }) </a> </div> <div class="spacer"></div> <div class="spacer"></div> <div class="spacer"></div> <div class="spacer"></div> </div> Stocks: Index; @model IEnumerable<MVC5ef6.Models.Stock> @{ ViewBag.Title = "Index"; } <div class="spacer"></div> <h2>Table of Stocks</h2> <p> @Html.ActionLink("Create New", "Create") </p> <table class="table"> <tr> <th> @Html.DisplayNameFor(model => model.stockName) </th> <th> @Html.DisplayNameFor(model => model.Market.marketName) </th> <th></th> </tr> @foreach (var item in Model) { <tr> <td> @Html.DisplayFor(modelItem => item.stockName)
  • 68. 67 ChrisWorledgePortfolio2|2/1/2016 </td> <td> @Html.DisplayFor(modelItem => item.Market.marketName) </td> <td> @Html.ActionLink("Chart", "Chart", new { id = item.stockID }, new { @class = "actionLink" }) | @Html.ActionLink("Edit", "Edit", new { id=item.stockID }, new { @class = "actionLink" }) | @Html.ActionLink("Details", "Details", new { id=item.stockID }, new { @class = "actionLink" }) | @Html.ActionLink("Delete", "Delete", new { id=item.stockID }, new { @class = "actionLink" }) </td> </tr> } </table> Markets: Index; @model IEnumerable<MVC5ef6.Models.Market> @{ ViewBag.Title = "Index"; } <div class="spacer"></div> <h2>Table of Markets</h2> <p> @Html.ActionLink("Create New", "Create") </p> <table class="table"> <tr> <th> @Html.DisplayNameFor(model => model.marketName) </th> <th></th> </tr> @foreach (var item in Model) { <tr> <td> @Html.DisplayFor(modelItem => item.marketName) </td> <td> @Html.ActionLink("Edit", "Edit", new { id=item.marketID }, new { @class = "actionLink" }) | @Html.ActionLink("Details", "Details", new { id=item.marketID }, new { @class = "actionLink" }) | @Html.ActionLink("Delete", "Delete", new { id=item.marketID }, new { @class = "actionLink" }) </td> </tr> }
  • 69. 68 ChrisWorledgePortfolio2|2/1/2016 </table> Prices: Index; @model IEnumerable<MVC5ef6.Models.Price> @{ ViewBag.Title = "Prices"; } <div class="spacer" ></div> <h2>Table of Prices</h2> <p> @Html.ActionLink("Create New", "Create", null, new { @class = "actionLink" }) </p> <table class="table"> <tr> <th> @Html.DisplayNameFor(model => model.Stamp) </th> <th> @Html.DisplayNameFor(model => model.Pence) </th> <th> @Html.DisplayNameFor(model => model.Stock.stockName) </th> <th></th> </tr> @foreach (var item in Model) { <tr> <td> @Html.DisplayFor(modelItem => item.Stamp) </td> <td> @Html.DisplayFor(modelItem => item.Pence) </td> <td> @Html.DisplayFor(modelItem => item.Stock.stockName) </td> <td> @Html.ActionLink("Chart", "Chart", new { id = item.stockID }, new { @class = "actionLink" }) | @Html.ActionLink("Edit", "Edit", new { id = item.ID }, new { @class = "actionLink" }) | @Html.ActionLink("Details", "Details", new { id = item.ID }, new { @class = "actionLink" }) | @Html.ActionLink("Delete", "Delete", new { id = item.ID }, new { @class = "actionLink" }) </td> </tr> } </table>
  • 70. 69 ChrisWorledgePortfolio2|2/1/2016 PriceListItems (sorted list): Index; @model IEnumerable<MVC5ef6.Models.PriceListItem> @{ ViewBag.Title = "Sorted Prices"; } <div class="spacer"></div> <h2>Index</h2> <p> </p> <table class="table"> <tr> <th> @Html.DisplayNameFor(model => model.stockName) </th> <th> @Html.DisplayNameFor(model => model.Pence) </th> <th> @Html.DisplayNameFor(model => model.Stamp) </th> <th></th> </tr> @foreach (var item in Model) { <tr> <td> @Html.DisplayFor(modelItem => item.stockName) </td> <td> @Html.DisplayFor(modelItem => item.Pence) </td> <td> @Html.DisplayFor(modelItem => item.Stamp) </td> </tr> } </table> Latest Prices: Index; <META HTTP-EQUIV="REFRESH" CONTENT="60"> @model IEnumerable<MVC5ef6.Models.LatestPrice> @{ ViewBag.Title = "Index"; } <div class="spacer"></div>
  • 71. 70 ChrisWorledgePortfolio2|2/1/2016 <h2>Table of Latest Prices</h2> <table class="table"> <tr> <th> @Html.DisplayNameFor(model => model.marketName) </th> <th> @Html.DisplayNameFor(model => model.stockName) </th> <th> @Html.DisplayNameFor(model => model.Pence) </th> <th> @Html.DisplayNameFor(model => model.Stamp) </th> <th></th> </tr> @foreach (var item in Model) { <tr> <td> @Html.DisplayFor(modelItem => item.marketName) </td> <td> @Html.DisplayFor(modelItem => item.stockName) </td> <td> @Html.DisplayFor(modelItem => item.Pence) </td> <td> @Html.DisplayFor(modelItem => item.Stamp) </td> </tr> } </table> Controllers: namespace MVC5ef6.Controllers { public class HomeController : Controller { public ActionResult Index() { return View(); } public ActionResult About() { ViewBag.Message = "Your application description page.";
  • 72. 71 ChrisWorledgePortfolio2|2/1/2016 return View(); } public ActionResult Contact() { ViewBag.Message = "Your contact page."; return View(); } } public class LatestPricesController : Controller { private MVC5demoEntities db = new MVC5demoEntities(); // GET: LatestPrices public ActionResult Index() { return View(db.LatestPrices.OrderBy(l => l.marketName).ToList()); } // GET: LatestPrices/Details/5 public ActionResult Details(long? id) { if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } LatestPrice latestPrice = db.LatestPrices.Find(id); if (latestPrice == null) { return HttpNotFound(); } return View(latestPrice); } // GET: LatestPrices/Create public ActionResult Create() { return View(); } // POST: LatestPrices/Create [HttpPost] [ValidateAntiForgeryToken] public ActionResult Create([Bind(Include = "ID,stockName,marketName,Pence,Stamp")] LatestPrice latestPrice) { if (ModelState.IsValid) { db.LatestPrices.Add(latestPrice); db.SaveChanges(); return RedirectToAction("Index"); } return View(latestPrice);
  • 73. 72 ChrisWorledgePortfolio2|2/1/2016 } // GET: LatestPrices/Edit/5 public ActionResult Edit(long? id) { if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } LatestPrice latestPrice = db.LatestPrices.Find(id); if (latestPrice == null) { return HttpNotFound(); } return View(latestPrice); } // POST: LatestPrices/Edit/5 [HttpPost] [ValidateAntiForgeryToken] public ActionResult Edit([Bind(Include = "ID,stockName,marketName,Pence,Stamp")] LatestPrice latestPrice) { if (ModelState.IsValid) { db.Entry(latestPrice).State = EntityState.Modified; db.SaveChanges(); return RedirectToAction("Index"); } return View(latestPrice); } // GET: LatestPrices/Delete/5 public ActionResult Delete(long? id) { if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } LatestPrice latestPrice = db.LatestPrices.Find(id); if (latestPrice == null) { return HttpNotFound(); } return View(latestPrice); } // POST: LatestPrices/Delete/5 [HttpPost, ActionName("Delete")] [ValidateAntiForgeryToken] public ActionResult DeleteConfirmed(long id) { LatestPrice latestPrice = db.LatestPrices.Find(id); db.LatestPrices.Remove(latestPrice); db.SaveChanges(); return RedirectToAction("Index"); }
  • 74. 73 ChrisWorledgePortfolio2|2/1/2016 protected override void Dispose(bool disposing) { if (disposing) { db.Dispose(); } base.Dispose(disposing); } } public class MarketsController : Controller { private MVC5demoEntities db = new MVC5demoEntities(); // GET: Markets public ActionResult Index() { return View(db.Markets.ToList()); } // GET: Markets/Details/5 public ActionResult Details(int? id) { if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } Market market = db.Markets.Find(id); if (market == null) { return HttpNotFound(); } return View(market); } // GET: Markets/Create public ActionResult Create() { return View(); } // POST: Markets/Create [HttpPost] [ValidateAntiForgeryToken] public ActionResult Create([Bind(Include = "marketID,marketName")] Market market) { if (ModelState.IsValid) { db.Markets.Add(market); db.SaveChanges(); return RedirectToAction("Index"); } return View(market); }
  • 75. 74 ChrisWorledgePortfolio2|2/1/2016 // GET: Markets/Edit/5 public ActionResult Edit(int? id) { if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } Market market = db.Markets.Find(id); if (market == null) { return HttpNotFound(); } return View(market); } // POST: Markets/Edit/5 [HttpPost] [ValidateAntiForgeryToken] public ActionResult Edit([Bind(Include = "marketID,marketName")] Market market) { if (ModelState.IsValid) { db.Entry(market).State = EntityState.Modified; db.SaveChanges(); return RedirectToAction("Index"); } return View(market); } // GET: Markets/Delete/5 public ActionResult Delete(int? id) { if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } Market market = db.Markets.Find(id); if (market == null) { return HttpNotFound(); } return View(market); } // POST: Markets/Delete/5 [HttpPost, ActionName("Delete")] [ValidateAntiForgeryToken] public ActionResult DeleteConfirmed(int id) { Market market = db.Markets.Find(id); db.Markets.Remove(market); db.SaveChanges(); return RedirectToAction("Index"); } protected override void Dispose(bool disposing) { if (disposing)
  • 76. 75 ChrisWorledgePortfolio2|2/1/2016 { db.Dispose(); } base.Dispose(disposing); } } public class NamedPrice { Models.Stock name { get; set; } Models.Price price { get; set; } } public class PriceListItemsController : Controller { private MVC5demoEntities db = new MVC5demoEntities(); // GET: PriceListItems public ActionResult Index() { var pricesForList = db.Prices.Join(db.Stocks, a => a.stockID, b => b.stockID, (a, b) => new { a, b }). Select(c => new PriceListItem { ID = c.a.ID, stockID = c.a.stockID, Stamp = c.a.Stamp, Pence = c.a.Pence, stockName = c.b.stockName }). OrderBy(q => q.Stamp).GroupBy(s => s.stockName); IQueryable<IGrouping<string, PriceListItem>> ListedPrices = pricesForList;/*We want to controll the display order, but we don't need the grouping order as a seperate data attribute so we will take the items into a list*/ List <PriceListItem> DisplayList = new List<PriceListItem>(); foreach (IGrouping<string, PriceListItem> item in ListedPrices) { foreach (PriceListItem listItem in item) { DisplayList.Add(listItem); } } //now we can pass the list for display return View(DisplayList); } // GET: PriceListItems/Details/5 public ActionResult Details(int? id) { if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } PriceListItem priceListItem = db.PriceListItems.Find(id); if (priceListItem == null) { return HttpNotFound(); }
  • 77. 76 ChrisWorledgePortfolio2|2/1/2016 return View(priceListItem); } // GET: PriceListItems/Create public ActionResult Create() { return View(); } // POST: PriceListItems/Create [HttpPost] [ValidateAntiForgeryToken] public ActionResult Create([Bind(Include = "ID,stockID,Stamp,Pence,stockName")] PriceListItem priceListItem) { if (ModelState.IsValid) { db.PriceListItems.Add(priceListItem); db.SaveChanges(); return RedirectToAction("Index"); } return View(priceListItem); } // GET: PriceListItems/Edit/5 public ActionResult Edit(int? id) { if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } PriceListItem priceListItem = db.PriceListItems.Find(id); if (priceListItem == null) { return HttpNotFound(); } return View(priceListItem); } // POST: PriceListItems/Edit/5 [HttpPost] [ValidateAntiForgeryToken] public ActionResult Edit([Bind(Include = "ID,stockID,Stamp,Pence,stockName")] PriceListItem priceListItem) { if (ModelState.IsValid) { db.Entry(priceListItem).State = EntityState.Modified; db.SaveChanges(); return RedirectToAction("Index"); } return View(priceListItem); } // GET: PriceListItems/Delete/5 public ActionResult Delete(int? id) {
  • 78. 77 ChrisWorledgePortfolio2|2/1/2016 if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } PriceListItem priceListItem = db.PriceListItems.Find(id); if (priceListItem == null) { return HttpNotFound(); } return View(priceListItem); } // POST: PriceListItems/Delete/5 [HttpPost, ActionName("Delete")] [ValidateAntiForgeryToken] public ActionResult DeleteConfirmed(int id) { PriceListItem priceListItem = db.PriceListItems.Find(id); db.PriceListItems.Remove(priceListItem); db.SaveChanges(); return RedirectToAction("Index"); } protected override void Dispose(bool disposing) { if (disposing) { db.Dispose(); } base.Dispose(disposing); } } public class PricesController : Controller { private MVC5demoEntities db = new MVC5demoEntities(); // GET: Prices public ActionResult Index() { var prices = db.Prices.Include(p => p.Stock); return View(prices.ToList()); } // GET: Prices/Details/5 public ActionResult Details(int? id) { if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } Price price = db.Prices.Find(id); if (price == null) { return HttpNotFound();
  • 79. 78 ChrisWorledgePortfolio2|2/1/2016 } return View(price); } // GET: Prices/Create public ActionResult Create() { ViewBag.stockID = new SelectList(db.Stocks, "stockID", "stockName"); return View(); } // POST: Prices/Create [HttpPost] [ValidateAntiForgeryToken] public ActionResult Create([Bind(Include = "ID,stockID,Stamp,Pence")] Price price) { if (ModelState.IsValid) { db.Prices.Add(price); db.SaveChanges(); return RedirectToAction("Index"); } ViewBag.stockID = new SelectList(db.Stocks, "stockID", "stockName", price.stockID); return View(price); } // GET: Prices/Edit/5 public ActionResult Edit(int? id) { if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } Price price = db.Prices.Find(id); if (price == null) { return HttpNotFound(); } ViewBag.stockID = new SelectList(db.Stocks, "stockID", "stockName", price.stockID); return View(price); } // POST: Prices/Edit/5 [HttpPost] [ValidateAntiForgeryToken] public ActionResult Edit([Bind(Include = "ID,stockID,Stamp,Pence")] Price price) { if (ModelState.IsValid) { db.Entry(price).State = EntityState.Modified; db.SaveChanges(); return RedirectToAction("Index"); }
  • 80. 79 ChrisWorledgePortfolio2|2/1/2016 ViewBag.stockID = new SelectList(db.Stocks, "stockID", "stockName", price.stockID); return View(price); } // POST: Prices/Chart/5 public ActionResult Chart(int? id) { if (id != null) { int stock; int.TryParse(id.ToString(), out stock);//drag the int out of the ?int string stockName = db.Stocks.Where(a => a.stockID == stock).Select(a => a.stockName).FirstOrDefault() ; StockPriceModel SPModel = new StockPriceModel(); SPModel.ChartTitle = stockName; SPModel.StampTitle = "DateTime"; SPModel.PenceTitle = "Pence"; SPModel.stockID = stock; return View(SPModel); } else { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } } public JsonResult GetChart(int stock) { var ChartData = db.Prices.Where(a => a.stockID.HasValue ? a.stockID == stock : false) .Select(p => new { Stamp = p.Stamp.HasValue ? p.Stamp.Value : DateTime.Now, p.Pence }). OrderBy(q => q.Stamp);//all the dates and prices in date order List<StockPrice> CleanChartData = new List<StockPrice>(); CultureInfo culture = new CultureInfo("pt-BR");//so we get day before month! int x = 0; foreach (var t in ChartData) { string time = t.Stamp.ToString("G", culture);//give a date to display in javascript decimal price; decimal.TryParse(t.Pence.ToString(), out price);//because t.pence is a nullable decimal StockPrice current = new StockPrice(); current.ID = x; current.Stamp = time; current.Pence = price; CleanChartData.Add(current); x++; } return Json(CleanChartData, JsonRequestBehavior.AllowGet);
  • 81. 80 ChrisWorledgePortfolio2|2/1/2016 } // GET: Prices/Delete/5 public ActionResult Delete(int? id) { if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } Price price = db.Prices.Find(id); if (price == null) { return HttpNotFound(); } return View(price); } // POST: Prices/Delete/5 [HttpPost, ActionName("Delete")] [ValidateAntiForgeryToken] public ActionResult DeleteConfirmed(int id) { Price price = db.Prices.Find(id); db.Prices.Remove(price); db.SaveChanges(); return RedirectToAction("Index"); } protected override void Dispose(bool disposing) { if (disposing) { db.Dispose(); } base.Dispose(disposing); } } public class StocksController : Controller { private MVC5demoEntities db = new MVC5demoEntities(); // GET: Stocks public ActionResult Index() { var stocks = db.Stocks.Include(s => s.Market); return View(stocks.ToList()); } // GET: Stocks/Details/5 public ActionResult Details(int? id) { if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
  • 82. 81 ChrisWorledgePortfolio2|2/1/2016 } Stock stock = db.Stocks.Find(id); if (stock == null) { return HttpNotFound(); } return View(stock); } // GET: Stocks/Create public ActionResult Create() { ViewBag.marketID = new SelectList(db.Markets, "marketID", "marketName"); return View(); } // POST: Stocks/Create [HttpPost] [ValidateAntiForgeryToken] public ActionResult Create([Bind(Include = "stockID,stockName,marketID")] Stock stock) { if (ModelState.IsValid) { db.Stocks.Add(stock); db.SaveChanges(); return RedirectToAction("Index"); } ViewBag.marketID = new SelectList(db.Markets, "marketID", "marketName", stock.marketID); return View(stock); } // GET: Stocks/Edit/5 public ActionResult Edit(int? id) { if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } Stock stock = db.Stocks.Find(id); if (stock == null) { return HttpNotFound(); } ViewBag.marketID = new SelectList(db.Markets, "marketID", "marketName", stock.marketID); return View(stock); } // POST: Stocks/Edit/5 [HttpPost] [ValidateAntiForgeryToken] public ActionResult Edit([Bind(Include = "stockID,stockName,marketID")] Stock stock) {
  • 83. 82 ChrisWorledgePortfolio2|2/1/2016 if (ModelState.IsValid) { db.Entry(stock).State = EntityState.Modified; db.SaveChanges(); return RedirectToAction("Index"); } ViewBag.marketID = new SelectList(db.Markets, "marketID", "marketName", stock.marketID); return View(stock); } // POST: Stocks/Chart/5 public ActionResult Chart(int? id) { if (id != null) { int stock; int.TryParse(id.ToString(), out stock);//drag the int out of the ?int string stockName = db.Stocks.Where(a => a.stockID == stock).Select(a => a.stockName).FirstOrDefault(); StockPriceModel SPModel = new StockPriceModel(); SPModel.ChartTitle = stockName; SPModel.StampTitle = "DateTime"; SPModel.PenceTitle = "Pence"; SPModel.stockID = stock; return View(SPModel); } else { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } } public JsonResult GetChart(int stock) { var ChartData = db.Prices.Where(a => a.stockID.HasValue ? a.stockID == stock : false) .Select(p => new { Stamp = p.Stamp.HasValue ? p.Stamp.Value : DateTime.Now, p.Pence }). OrderBy(q => q.Stamp);//all the dates and prices in date order List<StockPrice> CleanChartData = new List<StockPrice>(); CultureInfo culture = new CultureInfo("pt-BR");//so we get day before month! int x = 0; foreach (var t in ChartData) { string time = t.Stamp.ToString("d", culture);//give a date to display in javascript decimal price; decimal.TryParse(t.Pence.ToString(), out price);//because t.pence is a nullable decimal StockPrice current = new StockPrice(); current.ID = x; current.Stamp = time; current.Pence = price; CleanChartData.Add(current);
  • 84. 83 ChrisWorledgePortfolio2|2/1/2016 x++; } return Json(CleanChartData, JsonRequestBehavior.AllowGet); } // GET: Stocks/Delete/5 public ActionResult Delete(int? id) { if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } Stock stock = db.Stocks.Find(id); if (stock == null) { return HttpNotFound(); } return View(stock); } // POST: Stocks/Delete/5 [HttpPost, ActionName("Delete")] [ValidateAntiForgeryToken] public ActionResult DeleteConfirmed(int id) { Stock stock = db.Stocks.Find(id); db.Stocks.Remove(stock); db.SaveChanges(); return RedirectToAction("Index"); } protected override void Dispose(bool disposing) { if (disposing) { db.Dispose(); } base.Dispose(disposing); } } }
  • 90. 89 ChrisWorledgePortfolio2|2/1/2016 var SPapp = angular.module('SPModule', ['ngResource']); (function () { var MarketsController = function ($scope, $http) { $scope.markets = []; var markets = function (serviceResp) { $scope.markets = serviceResp.data; }; var errorDetails = function (serviceResp) { $scope.Error = "Something went wrong ??"; }; $http.get("http://localhost:63579/api/Markets") .then(markets, errorDetails); $scope.Title = "Markets Page"; }; SPapp.controller("MarketsController", MarketsController); }()); (function () { var StocksController = function ($scope, $http) { $scope.stocks = []; var target = 'Stocks' var markets = function (serviceResp) { $scope.stocks = serviceResp.data; }; var errorDetails = function (serviceResp) { $scope.Error = "Something went wrong ??"; }; $http.get("http://localhost:63579/api/Stocks") .then(markets, errorDetails); $scope.Title = "Stocks Page";
  • 91. 90 ChrisWorledgePortfolio2|2/1/2016 }; SPapp.controller("StocksController", StocksController); }()); (function () { var PricesController = function ($scope, $http) { $scope.prices = []; var markets = function (serviceResp) { $scope.prices = serviceResp.data; }; var errorDetails = function (serviceResp) { $scope.Error = "Something went wrong ??"; }; $http.get("http://localhost:63579/api/PriceListItems") .then(markets, errorDetails); $scope.Title = "Prices Page"; }; SPapp.controller("PricesController", PricesController); }()); SPapp.controller('latestPricesController', ['$scope', '$http', function ($scope, $http) { $scope.latestPrices = []; $scope.loading = true; $scope.addMode = false; //Used to display the data //Alternative ports old WebAPI 63579 new WebAPI1 54488 $http({ method: 'GET', url: 'http://localhost:63579/api/latestPrices' }) .then(function successCallback(response) { console.log('success'); $scope.latestPrices = response.data; $scope.loading = false; }, function errorCallback(response) { console.log('error'); $scope.errorMsg = response.status + ': ' + response.data; $scope.error = "An Error has occured while loading 63579 prices! Status: " + status + "statusText: ";// + statusText + "oops"; $scope.failstatus = status; $scope.loading = false; }); }]); Home <!DOCTYPE html> <html lang="en" ng-app="SPModule"> <head> <title>Share Prices Home Page</title> <meta charset="utf-8" />
  • 92. 91 ChrisWorledgePortfolio2|2/1/2016 <script src="Scripts/jquery-2.1.4.min.js"></script> <link href="Content/bootstrap.min.css" rel="stylesheet" /> <link href="Content/flatly.css" rel="stylesheet" /> <link href="Content/Site.css" rel="stylesheet" /> <script src="Scripts/bootstrap.min.js"></script> <script src="Scripts/angular.min.js"></script> <script src="Scripts/angular-resource.min.js"></script> <script src="App/app.js"></script> <script src="Services/latestPricesService.js"></script> <script src="Services/TableService.js"></script> <script src="Factories/latestPricesFactory.js"></script> <script src="Factories/TableFactory.js"></script> <script src="Factories/CrudFactory.js"></script> <script src="Controllers/latestPricesController.js"></script> <script src="Controllers/simlatestPricesController.js"></script> </head> <body ng-controller="latestPricesController"> <h1>&nbsp; Welcome To Share Prices Stock Market Website</h1> <h1>&nbsp;<a href="Views/Markets.html">Markets</a>&nbsp;<a href="Views/Stocks.html">Stocks</a>&nbsp;<a href="Views/Prices.html">All Prices</a>&nbsp;<a href="Views/LatestPrices.html">Latest Prices</a></h1> <h2>&nbsp; LatestPrices</h2> <div class="container"> <strong class="error">{{ error }}</strong><br /> <strong class="error">{{ errorMsg }}</strong><br /> <strong class="error">{{ failstatus }}</strong> <div id="mydiv" ng-show="loading"> <img src="images/ajax-loader.gif" class="ajax-loader" /> </div> <table id="pricesTable" class="table table-bordered table-hover" style="width:800px"> <thead> <tr> <th>ID</th> <th>Stock Name</th> <th>Market Name</th> <th>Price</th> <th>Stamp</th> </tr> </thead> <tbody> <tr ng-repeat="latestPrice in latestPrices | orderBy: 'marketName'"> <td><strong>{{ latestPrice.id }}</strong></td> <td> <p>{{ latestPrice.stockName }}</p> </td> <td> <p>{{ latestPrice.marketName }}</p> </td> <td> <p>{{ latestPrice.pence }}</p> </td> <td> <p>{{ latestPrice.stamp }}</p>
  • 93. 92 ChrisWorledgePortfolio2|2/1/2016 </td> </tr> </tbody> <tfoot></tfoot> </table> <hr /> </div> </body> </html> Markets <!DOCTYPE html> <html lang="en" ng-app="SPModule"> <head> <title>Markets</title> <meta charset="utf-8" /> <script src="../Scripts/jquery-2.1.4.min.js"></script> <link href="../Content/bootstrap.min.css" rel="stylesheet" /> <link href="../Content/flatly.css" rel="stylesheet" /> <link href="../Content/Site.css" rel="stylesheet" /> <script src="../Scripts/bootstrap.min.js"></script> <script src="../Scripts/angular.min.js"></script> <script src="../App/app.js"></script> <script src="../Controllers/MarketsController.js"></script> </head> <body ng-controller="MarketsController"> <h1>&nbsp; Welcome To Share Prices Stock Market Website</h1> <h1>&nbsp;&nbsp;<a href="../Home.html">Home</a>&nbsp;<a href="Stocks.html">Stocks</a>&nbsp;<a href="Prices.html">allPrices</a>&nbsp;<a href="LatestPrices.html">LatestPrices</a></h1> <h2>&nbsp; Market Names</h2> <div class="container"> <strong class="error">{{ error }}</strong><br /> <strong class="error">{{ errorMsg }}</strong><br /> <strong class="error">{{ failstatus }}</strong> <div id="mydiv" ng-show="loading"> <img src="../images/ajax-loader.gif" class="ajax-loader" /> </div> <table id="pricesTable" class="table table-bordered table-hover" style="width:800px"> <thead> <tr> <th>ID</th> <th>Market Name</th> </tr> </thead> <tbody> <tr ng-repeat="market in markets"> <td><strong>{{ market.marketID }}</strong></td> <td> <p>{{ market.marketName }}</p> </td>
  • 94. 93 ChrisWorledgePortfolio2|2/1/2016 </tr> </tbody> <tfoot></tfoot> </table> <hr /> </div> </body> </html> Stocks <!DOCTYPE html> <html lang="en" ng-app="SPModule"> <head> <title>Markets</title> <meta charset="utf-8" /> <script src="../Scripts/jquery-2.1.4.min.js"></script> <link href="../Content/bootstrap.min.css" rel="stylesheet" /> <link href="../Content/flatly.css" rel="stylesheet" /> <link href="../Content/Site.css" rel="stylesheet" /> <script src="../Scripts/bootstrap.min.js"></script> <script src="../Scripts/angular.min.js"></script> <script src="../App/app.js"></script> <script src="../Controllers/StocksController.js"></script> </head> <body ng-controller="StocksController"> <h1>&nbsp; Welcome To Share Prices Stock Market Website</h1> <h1>&nbsp;&nbsp;<a href="../Home.html">Home</a>&nbsp;<a href="Markets.html">Markets</a>&nbsp;<a href="Prices.html">allPrices</a>&nbsp;<a href="LatestPrices.html">LatestPrices</a></h1> <h2>&nbsp; Stock Names</h2> <div class="container"> <strong class="error">{{ error }}</strong><br /> <strong class="error">{{ errorMsg }}</strong><br /> <strong class="error">{{ failstatus }}</strong> <div id="mydiv" ng-show="loading"> <img src="../images/ajax-loader.gif" class="ajax-loader" /> </div> <table id="pricesTable" class="table table-bordered table-hover" style="width:800px"> <thead> <tr> <th>ID</th> <th>Stock Name</th> </tr> </thead> <tbody> <tr ng-repeat="stock in stocks"> <td><strong>{{ stock.stockID }}</strong></td> <td> <p>{{ stock.stockName }}</p> </td>
  • 95. 94 ChrisWorledgePortfolio2|2/1/2016 </tr> </tbody> <tfoot></tfoot> </table> <hr /> </div> </body> </html> Prices <!DOCTYPE html> <html lang="en" ng-app="SPModule"> <head> <title>Markets</title> <meta charset="utf-8" /> <script src="../Scripts/jquery-2.1.4.min.js"></script> <link href="../Content/bootstrap.min.css" rel="stylesheet" /> <link href="../Content/flatly.css" rel="stylesheet" /> <link href="../Content/Site.css" rel="stylesheet" /> <script src="../Scripts/bootstrap.min.js"></script> <script src="../Scripts/angular.min.js"></script> <script src="../App/app.js"></script> <script src="../Controllers/PricesController.js"></script> </head> <body ng-controller="PricesController"> <h1>&nbsp; Welcome To Share Prices Stock Market Website</h1> <h1>&nbsp;&nbsp;<a href="../Home.html">Home</a>&nbsp;<a href="Markets.html">Markets</a>&nbsp;<a href="Stocks.html">Stocks</a>&nbsp;<a href="LatestPrices.html">LatestPrices</a></h1> <h2>&nbsp; Stock Prices</h2> <div class="container"> <strong class="error">{{ error }}</strong><br /> <strong class="error">{{ errorMsg }}</strong><br /> <strong class="error">{{ failstatus }}</strong> <div id="mydiv" ng-show="loading"> <img src="../images/ajax-loader.gif" class="ajax-loader" /> </div> <table id="pricesTable" class="table table-bordered table-hover" style="width:800px"> <thead> <tr> <th>ID</th> <th>Stock Name</th> <th>Price</th> <th>Date and Time</th> </tr> </thead> <tbody> <tr ng-repeat="price in prices"> <td><strong>{{ price.id }}</strong></td>
  • 96. 95 ChrisWorledgePortfolio2|2/1/2016 <td> <p>{{ price.stockName }}</p> </td> <td> <p>{{ price.pence }}</p> </td> <td> <p>{{ price.stamp }}</p> </td> </tr> </tbody> <tfoot></tfoot> </table> <hr /> </div> </body> </html> Latest Prices <!DOCTYPE html> <html lang="en" ng-app="SPModule"> <head> <title>Latest Prices</title> <meta charset="utf-8" /> <script src="../Scripts/jquery-2.1.4.min.js"></script> <link href="../Content/bootstrap.min.css" rel="stylesheet" /> <link href="../Content/flatly.css" rel="stylesheet" /> <link href="../Content/Site.css" rel="stylesheet" /> <script src="../Scripts/bootstrap.min.js"></script> <script src="../Scripts/angular.min.js"></script> <script src="../App/app.js"></script> <script src="../Controllers/latestPricesController.js"></script> <script src="../Controllers/simlatestPricesController.js"></script> <script src="../Factories/latestPricesFactory.js"></script> <script src="../Services/latestPricesService.js"></script> </head> <body ng-controller="latestPricesController"> <h1>&nbsp; Welcome To Share Prices Stock Market Website</h1> <h1>&nbsp;&nbsp;<a href="../Home.html">Home</a>&nbsp;<a href="Markets.html">Markets</a>&nbsp;<a href="Stocks.html">Stocks</a>&nbsp;<a href="Prices.html">allPrices</a></h1> <h2>&nbsp; LatestPrices</h2> <div class="container"> <strong class="error">{{ error }}</strong><br /> <strong class="error">{{ errorMsg }}</strong><br /> <strong class="error">{{ failstatus }}</strong> <div id="mydiv" ng-show="loading"> <img src="../images/ajax-loader.gif" class="ajax-loader" /> </div> <table id="pricesTable" class="table table-bordered table-hover" style="width:800px"> <thead> <tr> <th>ID</th>
  • 97. 96 ChrisWorledgePortfolio2|2/1/2016 <th>Stock Name</th> <th>Market Name</th> <th>Price</th> <th>Stamp</th> </tr> </thead> <tbody> <tr ng-repeat="latestPrice in latestPrices"> <td><strong>{{ latestPrice.id }}</strong></td> <td> <p>{{ latestPrice.stockName }}</p> </td> <td> <p>{{ latestPrice.marketName }}</p> </td> <td> <p>{{ latestPrice.pence }}</p> </td> <td> <p>{{ latestPrice.stamp }}</p> </td> </tr> </tbody> <tfoot></tfoot> </table> <hr /> </div>> </body> </html>
  • 98. 97 ChrisWorledgePortfolio2|2/1/2016 AT HOME TASK There is a special cash machine, without any security, that dispenses money (notes and coins). The machine has a given initial state of what coins and notes it has available. The initial state is: 100x1p, 100x2p, 100x5p, 100x10p, 100x20p, 100x50p, 100x£1, 100x£2, 50x£5, 50x£10, 50x£20, 50x£50. You should create a program that is given the value to withdraw as an input. Program the cash machine, so it has 2 algorithms that can be swapped (swapping can be done by rebuilding and rerunning the application): 1. Algorithm that returns least number of items (coins or notes) 2. Algorithm that returns the highest number of £20 notes possible Output the number of coins and notes given for each withdrawal. The machine should output the count and value of coins and notes dispensed and the balance amount left. The program should be extendible and written using .NET framework. Use the best approach you can to implement the solution. Examples Algorithm 1 Input (Withdrawal amount) 120.00 Output £50x2, £20x1 £X.XX balance Algorithm 2 Input 120.00 Output £20x6 £X.XX balance
  • 100. 99 ChrisWorledgePortfolio2|2/1/2016 Second Algorithm with £20 note bias: Program: namespace CashMachine { class Program { static void Main(string[] args) { Bank thisBank = new Bank(); thisBank.Algorithm = true;//allows the maximum twenties algorithm while (true) { Console.WriteLine("Please enter required amount:"); string line = Console.ReadLine(); if (line != null) { Decimal debit; if (Decimal.TryParse(line, out debit)) { string response = thisBank.debit(debit); Console.WriteLine(response); }
  • 101. 100 ChrisWorledgePortfolio2|2/1/2016 else { Console.WriteLine("You have entered an invalid amount."); } } } } } } Bank: namespace CashMachine { class Bank { private Money[] Monies { get; set; } public Boolean Algorithm { get; set; } public Bank() { Monies = new Money[] { new Money("£50", 50, 50 ), new Money("£20", 20, 50 ), new Money("£10", 10, 50 ), new Money("£5", 5, 50 ), new Money("£2", 2, 100 ), new Money("£1", 1, 100 ), new Money("50p", .5m, 100 ),//the appended m forces the Decimal type new Money("20p", .2m, 100 ), new Money("10p", .1m, 100 ), new Money("5p", .05m, 100 ), new Money("2p", .02m, 100 ), new Money("1p", .01m, 100 ) }; Algorithm = false;//default to all denominations } public String debit(Decimal amount) { StringBuilder message = new StringBuilder(); Decimal debitvalue = amount; if (amount <= getBalance())//check the money is available { debitAlgorithm(debitvalue, message);//takes the money by denomination depending on the algorithm message.Append("rnBalance remaining is £"); string balance = getBalance().ToString("#.##"); message.Append(balance); return message.ToString();//tell them which notes and coins are being supplied and how much is left in the machine. } else//we can't afford to service this request
  • 102. 101 ChrisWorledgePortfolio2|2/1/2016 { return "The machine does not have sufficient funds to grant your requestrn We are sorry for the inconvenience."; } } private Decimal getBalance() { Decimal balance = 0; foreach (Money money in Monies) { var value = money.value * money.quantity; balance += value; } return balance; } private void debitAlgorithm(Decimal debitvalue, StringBuilder message) { int numberOfDenominations = Monies.Length; int index = 0;//set the start point at fifties Decimal requiredMoney = debitvalue; Boolean messageAdded = false; if (Algorithm) { index = 1; requiredMoney = fullAlgorithm(index, messageAdded, requiredMoney, message);//do the twenties first if set to that Algorithm index = 0; requiredMoney = fullAlgorithm(index, messageAdded, requiredMoney, message);//do the fifties in case there weren't enough twenties left index = 2;//carry on through the loop from £10 down } for (int i = index; i < numberOfDenominations; i++) { requiredMoney = fullAlgorithm(i, messageAdded, requiredMoney, message);//we update the required amount each time } } private Decimal fullAlgorithm(int i, Boolean messageAdded, Decimal debitvalue, StringBuilder message) { Decimal requiredMoney = debitvalue; int number = (int)(requiredMoney / Monies[i].value);//just the whole number of this denomination if (number > 0 && number < Monies[i].quantity)//We want some and that many are available { requiredMoney = requiredMoney % Monies[i].value;//the leftover after the above Monies[i].quantity -= number;//debit the machine total for this denomination