I start this time with a little disclaimer: This is, after all, a blog, and most blogs still fit the original definition, which is a public forum used for a person to state or explain their beliefs and/or feelings. So it is without further ado, that I proceed, unabashed:
The biggest problem with Mathematics today, particularly around people approaching, or new to the field, is the conventions of naming things.
Historically, and seemingly by convention, mathematical concepts are named after the first person to define or make serious contributions to that field. This is what is known as an eponym.
This is terrible practice, even tear-able! I am bitter about the amount of time I waste trying to find the 'name' of the mathmatical concept I wish to express or research, or when I have to derail my research to go define a term or concept I don't recognize, only to find out that I am already know what it was.
If people would just name stuff after what it actually fucking does, instead of some person's last name, we would all be a lot better off (except for maybe the aforementioned person).
In software development, we have this concept known as refactoring. This term includes fundamental re-structuring of the code, but also can be as simple as a bunch of renaming of everything to fit a more consistent, or holistic, view or concept. A similar thing needs to happen to the field of mathematics, and sooner rather than later!
No more eponyms in Mathematics!
Tags
C#
Math
Algorithm
Data
Error handling
Statistics
Cryptography
hack
Best practices
Architecture
CSV
DataTable
Encryption
SQL
Database
Humor
snippets
Entropy
ORM
Design Pattern
Dictionary
Jokes
Prime
Pseudorandom
Serialization
Code Generation
Compression
Coprime
Exception
Object Relational Mapping
Raspberry Pi
Reflection
Winform
Attributes
CodeDOM
Console
DataGrid
DataGridView
DataSet
Drawing
GCD
List
Mono
PropertyInfo
Sort
Static Analysis
Validation
XML
Benchmarking
Bugs
Bézier
Cellular automata
Chrome
Clipboard
Data Mapper
Designer
EULA
Extension Methods
Firefox
Games
Generics
GraphicsPath
HoneyPot
HowJSay
IComparer
IE
KeyedCollection
Luhn Algorithm
Parameter Sanitization
Query
Rogue-like
SortedDictionary
UnhandledExceptionHandler
Usercontrol
WIN32API
Sunday, June 12, 2016
Friday, January 22, 2016
Trick: How to mentally convert and calculate rate of pay
I have been real busy lately, so I will share only a short tip this week. However, I have some cool new projects/concepts I have been working on, such as a term rewriting system, so keep checking back.
I have been interviewing for a new job, its time to move up. Often I am quoted an annual salary, and I want to see how that compares with hourly wage. I do this calculation in my head, on the spot, and so can you. This technique leverages Estimation/Approximation.
Since 40hrs/week times 52wks/year = 40 * 52 = 2080 full-time work hours in a year.
We can use approximation by multiplying or dividing by 2000. Since we know that 2 * 1000 = 2000, multiplying/diving by 2000 is trivial. Remember, to multiply or divide by any power of ten, now matter how great, just count the zeros and just shift the decimal place once to the right, or towards a smaller quantity, that number of times. e.g. 43.50 * 1000 = 43,500
'So how large is the error from estimating?', One might ponder... Well ponder no more! Hark:
Estimation Error - From hourly to yearly-- $12/HR @ 40HR/WK $24,000/YR - Estimated $24,960/YR - Actual ------- -$960 - Difference $25/HR @ 40HR/WK $50,000/YR - Estimated $52,000/YR - Actual ------- $2,000/YR - Difference $50/HR @ 40HR/WK $100,000/YR - Estimated $104,000/YR - Actual -------- $4,000 - Difference Estimation Error - From yearly to hourly-- $25K/YR @ 40HR/WK $12.50/HR - Estimated $12.02/HR - Actual ------ -$0.48/HR - Difference $50K/YR @ 40HR/WK $25.00/HR - Estimated $24.04/HR - Actual ------ -$0.96/HR $100K/YR @ 40HR/WK $50.00/HR - Estimated $48.07/HR - Actual ------ -$1.92/HR
Thursday, December 24, 2015
Infix Notation Parser via Shunting-Yard Algorithm
Infix notation is the typical notation for writing equations in algebra.
An example would be: 7 - (2 * 5)
Parsing such an equation is not a trivial task, but I wanted one for my EquationFinder project, as I wanted to respect order of operations.
Strategies include substitution/replacement algorithms, recursion to parse into a tree and then tree traversal, or converting the infix notation to reverse polish notation (RPN), also known as post-fix notation, then using a stack based postfix notation evaluator. I choose the latter, as such algorithms are well defined in many places on the web.
My code consists of 3 classes, all static:
(Links go to the .cs file on GitHub)
- InfixNotation - this simply holds a few public variables and calls the public methods on the below two classes.
- ShuntingYardAlgorithm - this converts an equation in infix notation into postfix notation (aka RPN).
- PostfixNotation - this evaluates the equation in postfix notation and returns a numerical result value.
In order to implement the shunting-yard algorithm and the postfix evaluator, I simply wrote the steps to the algorithms as written on Wikipedia:
(Links go to the Wikipedia article)
Link to the Shunting-Yard Algorithm to convert Infix notation to Postfix notation.
Link to the Postfix Notation Evaluation Algorithm.
The code for this is pretty extensive, but I will prettify it and present it below. Alternatively, you can view and download the code from the MathNotationConverter project on my GitHub.
InfixNotationParser:
public static class InfixNotation
{
public static string Numbers = "0123456789";
public static string Operators = "+-*/^";
public static bool IsNumeric(string text)
{
return string.IsNullOrWhiteSpace(text) ? false : text.All(c => Numbers.Contains(c));
}
public static int Evaluate(string infixNotationString)
{
string postFixNotationString = ShuntingYardConverter.Convert(infixNotationString);
int result = PostfixNotation.Evaluate(postFixNotationString);
return result;
}
}
ShuntingYardConverter
(converts an equation from infix notation into postfix notation):
public static class ShuntingYardAlgorithm
{
private static string AllowedCharacters = InfixNotation.Numbers + InfixNotation.Operators + "()";
private enum Associativity
{
Left, Right
}
private static Dictionary<char, int> PrecedenceDictionary = new Dictionary<char, int>()
{
{'(', 0}, {')', 0},
{'+', 1}, {'-', 1},
{'*', 2}, {'/', 2},
{'^', 3}
};
private static Dictionary<char, Associativity> AssociativityDictionary = new Dictionary<char, Associativity>()
{
{'+', Associativity.Left},
{'-', Associativity.Left},
{'*', Associativity.Left},
{'/', Associativity.Left},
{'^', Associativity.Right}
};
private static void AddToOutput(List<char> output, params char[] chars)
{
if (chars != null && chars.Length > 0)
{
foreach (char c in chars)
{
output.Add(c);
}
output.Add(' ');
}
}
public static string Convert(string infixNotationString)
{
if (string.IsNullOrWhiteSpace(infixNotationString))
{
throw new ArgumentException("Argument infixNotationString must not be null, empty or whitespace.", "infixNotationString");
}
List<char> output = new List<char>();
Stack<char> operatorStack = new Stack<char>();
string sanitizedString = new string(infixNotationString.Where(c => AllowedCharacters.Contains(c)).ToArray());
string number = string.Empty;
List<string> enumerableInfixTokens = new List<string>();
foreach (char c in sanitizedString)
{
if (InfixNotation.Operators.Contains(c) || "()".Contains(c))
{
if (number.Length > 0)
{
enumerableInfixTokens.Add(number);
number = string.Empty;
}
enumerableInfixTokens.Add(c.ToString());
}
else if (InfixNotation.Numbers.Contains(c))
{
number += c.ToString();
}
else
{
throw new Exception(string.Format("Unexpected character '{0}'.", c));
}
}
if (number.Length > 0)
{
enumerableInfixTokens.Add(number);
number = string.Empty;
}
foreach (string token in enumerableInfixTokens)
{
if (InfixNotation.IsNumeric(token))
{
AddToOutput(output, token.ToArray());
}
else if (token.Length == 1)
{
char c = token[0];
if (InfixNotation.Numbers.Contains(c)) // Numbers (operands)
{
AddToOutput(output, c);
}
else if (InfixNotation.Operators.Contains(c)) // Operators
if (operatorStack.Count > 0)
{
char o = operatorStack.Peek();
if ((AssociativityDictionary[c] == Associativity.Left &&
PrecedenceDictionary[c] <= PrecedenceDictionary[o])
||
(AssociativityDictionary[c] == Associativity.Right &&
PrecedenceDictionary[c] < PrecedenceDictionary[o]))
{
AddToOutput(output, operatorStack.Pop());
}
}
operatorStack.Push(c);
}
else if (c == '(') // open brace
{
operatorStack.Push(c);
}
else if (c == ')') // close brace
{
bool leftParenthesisFound = false;
while (operatorStack.Count > 0 )
{
char o = operatorStack.Peek();
if (o != '(')
{
AddToOutput(output, operatorStack.Pop());
}
else
{
operatorStack.Pop();
leftParenthesisFound = true;
break;
}
}
if (!leftParenthesisFound)
{
throw new FormatException("The algebraic string contains mismatched parentheses (missing a left parenthesis).");
}
}
else // wtf?
{
throw new Exception(string.Format("Unrecognized character '{0}'.", c));
}
}
else
{
throw new Exception(string.Format("String '{0}' is not numeric and has a length greater than 1.", token));
}
} // end foreach
while (operatorStack.Count > 0)
{
char o = operatorStack.Pop();
if (o == '(')
{
throw new FormatException("The algebraic string contains mismatched parentheses (extra left parenthesis).");
}
else if (o == ')')
{
throw new FormatException("The algebraic string contains mismatched parentheses (extra right parenthesis).");
}
else
{
AddToOutput(output, o);
}
}
return new string(output.ToArray());
}
}
PostfixNotation
(evaluates the postfix notation and returns a numerical result):
public static class PostfixNotation
{
private static string AllowedCharacters = InfixNotation.Numbers + InfixNotation.Operators + " ";
public static int Evaluate(string postfixNotationString)
{
if (string.IsNullOrWhiteSpace(postfixNotationString))
{
throw new ArgumentException("Argument postfixNotationString must not be null, empty or whitespace.", "postfixNotationString");
}
Stack<string> stack = new Stack<string>();
string sanitizedString = new string(postfixNotationString.Where(c => AllowedCharacters.Contains(c)).ToArray());
List<string> enumerablePostfixTokens = sanitizedString.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).ToList();
foreach (string token in enumerablePostfixTokens)
{
if (token.Length > 0)
{
if (token.Length > 1)
{
if (InfixNotation.IsNumeric(token))
{
stack.Push(token);
}
else
{
throw new Exception("Operators and operands must be separated by a space.");
}
}
else
{
char tokenChar = token[0];
if (InfixNotation.Numbers.Contains(tokenChar))
{
stack.Push(tokenChar.ToString());
}
else if (InfixNotation.Operators.Contains(tokenChar))
{
if (stack.Count < 2)
{
throw new FormatException("The algebraic string has not sufficient values in the expression for the number of operators.");
}
string r = stack.Pop();
string l = stack.Pop();
int rhs = int.MinValue;
int lhs = int.MinValue;
bool parseSuccess = int.TryParse(r, out rhs);
parseSuccess &= int.TryParse(l, out lhs);
parseSuccess &= (rhs != int.MinValue && lhs != int.MinValue);
if (!parseSuccess)
{
throw new Exception("Unable to parse valueStack characters to Int32.");
}
int value = int.MinValue;
if (tokenChar == '+')
{
value = lhs + rhs;
}
else if (tokenChar == '-')
{
value = lhs - rhs;
}
else if (tokenChar == '*')
{
value = lhs * rhs;
}
else if (tokenChar == '/')
{
value = lhs / rhs;
}
else if (tokenChar == '^')
{
value = (int)Math.Pow(lhs, rhs);
}
if (value != int.MinValue)
{
stack.Push(value.ToString());
}
else
{
throw new Exception("Value never got set.");
}
}
else
{
throw new Exception(string.Format("Unrecognized character '{0}'.", tokenChar));
}
}
}
else
{
throw new Exception("Token length is less than one.");
}
}
if (stack.Count == 1)
{
int result = 0;
if (!int.TryParse(stack.Pop(), out result))
{
throw new Exception("Last value on stack could not be parsed into an integer.");
}
else
{
return result;
}
}
else
{
throw new Exception("The input has too many values for the number of operators.");
}
} // method
} // class
Another alternative technique is to using the Shunting-Yard Algorithm to turn infix notation into an abstract syntax tree (Linq.Expressions anyone?). I will likely post this technique later.
Other blog posts by me that are related to this article are the Threaded Equation Finder, a Mixed Radix System Calulator and Drawing Text Along a Bezier Spline.
Tuesday, December 1, 2015
Detailed Exception class
The C# StackTrace class can be useful for logging the source of errors, but when your assembly is built in Release mode, you lose valuable information in the StackFrame, like the line number, the column number or the file name.
Part of my error handling strategy involved setting an error string, and using StackTrace to log the function calling the setter and the location in the code the error occurred. Unfortionatly, as mentioned above, I was losing error information like line number, and that kind of information sure is nice to have. Thats why I invented the DetailedException class.
In .NET 4.5, one can get caller information by the use of default value parameters tagged with an special attribute, namely CallerFilePathAttribute, CallerMemberNameAttribute, CallerLineNumberAttribute.
How about a code example:
[Serializable]
public class DetailedException : Exception
{
public int SourceLineNumber { get; private set; }
public string SourceFilePath { get; private set; }
public string SourceMemberName { get; private set; }
public DetailedException(string message,
[CallerMemberName] string sourceMemberName = "",
[CallerFilePath] string sourceFilePath = "",
[CallerLineNumber] int sourceLineNumber = 0)
: base(message)
{
this.SourceMemberName = sourceMemberName;
this.SourceFilePath = sourceFilePath;
this.SourceLineNumber = sourceLineNumber;
}
Now if you have to throw an exception, throw new DetailedException("Testing DetailedException. WOW. SUCH DETAILS."); and you will gain information like SourceLineNumber!
If you decide to overload the constructor, be warned: You will be required to use named parameters when calling the DetailedException constructor
Labels:
.net,
Architecture,
Attributes,
Best practices,
Cool,
csharp,
Design Pattern,
Error handling,
Exception
A Simple Word Prediction Library
The word prediction feature on our phones are pretty handy and I've always and thought it would be fun to write one, and last night I decided to check that off my list. As usual, the whole project and all of its code is available to browse on GitHub. I talk more about the library and the design choices I made below the obnoxiously long image:
[Image of Windows Phone's Word Prediction feature]
Visit the project and view the code on my GitHub, right here.
(Project released under Creative Commons)
Overview:
One thing you might notice, if for no other reason than I bring it up, is that I favor composition over inheritance. That is, my classes use a Dictionary internally, but they do not inherit from Dictionary. My word prediction library is not a minor variation or different flavor of the Dictionary class, and while it might be cool to access the word predictions for a word via an indexer, my word prediction library should not be treated as a dictionary.
Under the hood:
There is a dictionary (a list of key/value pairs) of 'Word' objects. Each Word class has a value (the word), and its own dictionary of Word objects implemented as its own separate class (that does not inherit from Dictionary). This hidden dictionary inside each Word class keeps track of the probabilities of the the next word, for that given word. It does so by storing a Word as the key, and an integer counter value that gets incremented every time it tries to add a word to the dictionary that already exists (similar to my frequency dictionary, covered here).
The WordPredictionDictionary class doesn't grow exponentially, because each word is only represented once, by one Word class. The dictionaries inside the Word class only stores the references to the Word objects, not a copy of their values.
In order to begin using the WordPredictionDictionary to suggest words, one must train the WordPredictionDictionary on a representative body of text.
The WordPredictionDictionary class doesn't grow exponentially, because each word is only represented once, by one Word class. The dictionaries inside the Word class only stores the references to the Word objects, not a copy of their values.
In order to begin using the WordPredictionDictionary to suggest words, one must train the WordPredictionDictionary on a representative body of text.
TODO:
Write methods to serialize the trained data sets so they can be saved and reloaded.This has been implemented.- Write an intelli-sense-like word suggestion program that implements the WordPredictionDictionary in an end-user application.
Labels:
.net,
Architecture,
C#,
Cool,
csharp,
Data,
Dictionary,
Entropy,
Frequency,
Information,
Math,
Quantification,
Static Analysis,
Statistics,
Word Frequency
Thursday, October 29, 2015
Thinq - A Linq Experiment
Thinq - A Linq Experiment
View/Download the source code from the project's GitHub
So I wrote a program, just an experiment, where I was making a range class using IEnumerables (C#), and each element doesn't have to increment by one, but any amount. so I was creating ranges like 7 to 10 million, increment by 7, so upon enumeration it would yield multiples of 7. This is also called arithmetic progression.
Then I started combining different multiples with query operators like Where operator or Intersect like IEnumerable
So I began testing. After some playing, I decided to take the first 7 primes, and find any common multiples to them between 1 and 10 million. Much to my surprise, it found all the common multiples of the first 7 prime numbers under 10 million (there are only two of them, 4849845 & 9699690), and it did it in 500 milliseconds on some very modest hardware (1 core, 2.16GHz, 4GB ram).
I bumped up the ceiling to 50 million and I got an OutOfMemoryException because the IEnumerable holds on to every value it gets from the function MoveNext(). I threw in some metrics and discovered that it took about 3 seconds and some 32-million, 64-bit integers for my computer to declare 'out of memory'.
Well, at least it was fast, even if it did eat up all my ram in 3 seconds, it was still promising.
The solution was to create an IEnumerator that was aware of the arithmetic sequences that constrained the results set. When MoveNext() is called repeatedly during enumeration, I avoid the infinite memory requirement by restricting the result set returned from MoveNext(); it returns the next whole number that is divisible by every arithmetic sequence's 'common difference', or increment value. In this way, you have created a enumerable sequence that is the _intersection_ of all of the sequences.
The enumerator is prevented from running to infinity by obeying two limits: A maximum numeric value (cardinal) that GetNext() will return to ("results less than 50 million") and a maximum quantity of results (ordinal) that GetNext() yields ("the one millionth result"). If either of these limits are exceeded, the while loop will fail to evaluate to true. It is very common for my processor-intensive, long running or 'mathy' applications to employ a temporal limit (maximum time-to-live) or support cancellation, but this little experiment has been so performant that I have been able to get by without one.
So what kind of improvement did we get out of our custom enumerable? I can now find all the common factors for the first 8 prime numbers up to 1 billion in 25 seconds! I was impressed; the application used to max out around 50 million and run out of memory, and now it can investigate to one billion in a reasonable amount of time and the memory it uses is not much more than the 8 or so integers in the result set. 1 billion, however seems to be the sweet spot for my single 2.13 GHz laptop. I ran the same 8 primes to 2 billion and it took 1 minute, 12 seconds:
TIME ELAPSED: 01:12.38 LCM[3,5,7,11,13,17,19,23] (max 2,000,000,000) 17 FACTORS: 111546435 223092870 334639305 446185740 557732175 669278610 780825045 892371480 1003917915 1115464350 1227010785 1338557220 1450103655 1561650090 1673196525 1784742960 1896289395
Labels:
.net,
Algorithm,
C#,
Cool,
csharp,
Data Structure,
Greatest Common Divisor,
IEnumerable,
Math,
Prime
Tuesday, October 6, 2015
Mixed Radix Numeral System class and Counter
Mixed Radix Calculator
My 'Mixed Radix Calculator' creates a counting system of radices (plural of radix), such as base 12 or mixed radices such as Minutes/Hours/Days/Years: 365:24:60:60. I choose the left side to be the most significant side. This is merely a personal preference, and my MixedRadixSystem class supports displaying both alignments.
Of course you dont have to choose a mixed radix numeral system, you can count in an N-base numeral system, such as base 7 or a more familiar base 16. Another feature lies in my RadixNumeral class. Each numeral, or place value, supports having its own dictionary of symbols.
- View the code at its GitHub - https://github.com/AdamWhiteHat/MixedRadixCalculator
(Project released under Creative Commons)- 52:7:24:60:60:1000 -
A numeral system (or system of numeration) is a writing system for expressing numbers.
The most familiar one is of course the decimal numeral system. This is a 10-base numbering system. Computers use a binary numeral system. The base is sometimes called the radix or scale.
Not all numbering systems have just one base. Take for example, how we currently divide time: There are 60 seconds in a minute, 60 minutes in an hour, 24 hours in a day, and 365 days in a year. This is called a mixed radix numeral system, and one might express the above mixed radix system like: 365:24:60:60.
https://en.wikipedia.org/wiki/Mixed_radix
http://mathworld.wolfram.com/Base.html
Uses:
I haven't found a lot of use cases for it yet, but it is interesting. I originally built this because I wanted to experiment with numeral systems that uses increasing consecutive prime numbers for each radix, as well as experiment with some off-bases, such as base 3 or base 7.
In a single base, say base 7, then 'round numbers' with only one place value having a 1 and the rest having zeros, such as 1:0:0:0:0 (in base 7), such numbers are powers of 7, and ever other number except for the 1's place value is a multiple of 7.
A mixed radix numeral system can represent a polynomial, and possibly provide for a simpler way to visualize and reason about them.
Yet another possible use is to make a numeral system with a base that is larger than and co-prime to some other target number (say 256) to make a bijective map from every value in a byte to some other value exactly once by repeatedly adding the value of the co-prime, modulus 256. This can appear rather random (or sometimes not at all) but the mapping is easily determined given the co-prime. I have talked about this notion before on my blog
https://csharpcodewhisperer.blogspot.com/search/label/Coprime
If you like this project you would probably like my project EquationFinder, it finds equations given constraints
https://github.com/AdamWhiteHat/EquationFinder
Labels:
.net,
Algorithm,
C#,
Cool,
Coprime,
csharp,
CSV,
Data,
Greatest Common Divisor,
Math,
Prime,
Pseudorandom,
Radix,
Statistics
Tuesday, September 22, 2015
Threaded Equation Finder
Threaded Equation Finder
Find arithmetic equations that equates to a given 'target' value, number of terms, and operators.
Introduction
You should all be familiar with how a typical computer works; you give it some variables, describe some quantities of some resources you have, choose an algorithm, let it process, and it returns to you a result or outcome. Now imagine a computer if you could work with a computer that worked the other way around. I believe it was Douglas Adams that described the notion of an all-together different type of computer; That is, you tell the computer what you want the outcome to be, and it goes off figuring out how to get there and what you need to do it. Z3, the Theorem Prover, and the constraint satisfaction problem (CSP) solver (and probably others) in Microsoft's Solver Foundation do almost exactly that.There is also the idea of Backcasting, which is a similar, but different idea.
My program isn't as fancy as all that, but it does find equations that equates to a given 'target' value, albeit at random. You define constraints other than just the target value, such as what operators are allowed in the equation, the quantity of terms there, and the range or set of allowed terms.
For example, how many different ways can 9 nines equal 27, using only addition, subtraction, and multiplication, if evaluated left-to-right (ignore the order of operations)? Turns out there are only 67 ways.
(above) Application Screen Shot
How it works
The actual approach for finding equations that equate to an arbitrary target or 'goal' value is rather primitive. By way of Brute Force, several threads are launched asynchronously to generate thousands of random equations, evaluate them and keep the results that have not been found yet.This is something I wrote approx. 2 years ago. I dug it up and decided to publish it, because I thought it was interesting. As this was an 'experiment', I created different ways of storing and evaluating the expressions, and have made those different 'strategies' conform to a common interface so I could easily swap them out to compare the different strategies. I have refactored the code so that each class that implements IEquation is in its own project and creates its own assembly.
There are two fully-working strategies for representing equations: one that represented the equation as a list of 2-tuples (Term,Operator), did not perform order of operations, and was rather obtuse. The other strategy was to store the equation as a string and evaluate it using MSScriptControl.ScriptControl to Eval the string as a line of VBScript. This was unsurprisingly slower but allowed for much more robust equation evaluation. Order of operations is respected with the ScriptControl strategy, and opens the way to using using parenthesis.
The other idea for a strategy which I have not implemented but would like to, would be a left-recursive Linq.Expression builder. Also, maybe I could somehow use Microsoft Solver Foundation for a wiser equation generation strategy than at random.
Limitations
Today, however, there are better architectures. A concurrent system like this would benefit greatly from the Actor model. If you wanted to write complex queries against the stream of equations being generated or selected or solved, maybe reactive extensions would be a slam dunk.Although this project certainly is no Z3, it does provide an example of an interface... perhaps even a good one.
Running on Raspberry Pi 2
Microsoft's Managed Extensibility Framework (MEF) might be a good thing here, but I also wrote a console client that is designed to be ran with Mono on the Raspberry Pi 2. MEF is a proprietary Microsoft .NET technology that is not supported in Mono. The extra meta data in the assembly shouldn't be a problem, but having a dependency on the MEF assembly will be. Probing of the runtime environment and dynamically loading of assemblies is required here, which I have not had time to do, so at this time, there is no MEF.The reason the mono client is a console application is because mono and winforms on the Raspberry Pi 2 fails for some people. The problem has something to do with a hardware floating point vs a software float, and it happens to manifest itself when using a TextBox control. The only thing that I haven't tried, and that should presumably fix it, is to re-build mono from the latest source.
Labels:
.net,
Algorithm,
Architecture,
C#,
Console,
Cool,
csharp,
CSV,
Data,
Information,
Interface,
Math,
Mono,
Raspberry Pi,
Recursion,
Statistics,
Tuple
Sunday, August 2, 2015
Certificate Enumerator
Recently, my windows quit updating. Just prior to that, I had been messing around with my certificate store, so I suspected that to be the cause. Running Microsoft's troubleshooter reset the download, which I had a lot of hope of fixing the issue, but the download still continued to to fail. I decided to check the Windows Event Logs, and that's where I found an error message about a certificate in the chain failing. I knew it! However, I did not know whether a trusted certificate accidentally got put in the untrusted store, or whether an untrusted certificate was accidentally put in the trusted store. I needed a way to search all of my certificates' thumbprints or serial numbers against a know repository of trusted or untrusted certificates.
Microsoft's certificate snap-in for MMC does not allow you to view certificates in an efficient way. Opening them one at a time, manually, and then scrolling all the way down to where the thumbprint is displayed to compare it to a webpage is painful. Also, I was not satisfied with the way that Microsoft allows you to search the certificate store. The search is not very effective and you cant even search for thumbprints! Also I do not believe the search feature allows you anyway to copy any of that information to clipboard.
Most of what I needed to accomplish could simply be done if I could just export all of my computers certificates thumbprint or serial numbers to a text file, csv file, or other simple and searchable format. Then I thought to myself, I know how to do that! It was the great the lack of features of the MMC certificate snap-in, and the inability to search for certificate thumbprints that inspired me to write my own certificate utility, known simply as Certificate Enumerator.
CertificateEnumerator can list every certificate in your various certificate stores for your local machine and currently logged in user. It can then display that information to you either in a DataGridView or TextBox (as columnarized text), and provides the ability to persist that information to file as text, comma separated values (CSV), excel format or HTML table.
The Certificate Enumerator also has the ability to 'validate' each certificate against its CRL (certificate revocation list), if it supplied one.
The GUI could really use some love. In case you missed it, the project is on my GitHub, so feel free to download the source and play with it. If you come up with useful, submit a pull request.
Labels:
.net,
C#,
Certificates,
Cool,
Cryptography,
csharp,
CSV,
Data Structure,
Encryption,
Enumerator,
Error handling,
hack,
Information,
security,
X509
Wednesday, July 29, 2015
Finding a date range in SQL
At work, we use log4net, and we have the appender (or logging output location) set up to be AdoNetAppender, so thus it logs to a SQL database. In the Log table, there is a column called [Date], and it has the sql type of datetime.
Often, when querying the Log table, you only want to view the most recent dates. lets say within the last week. You could always ORDER BY [Date] DESC of course, but suppose we wanted more control than that, such as only last week's dates.
The SQL keywords (and functions) that are relevant here are BETWEEN, GETDATE and DATEADD.
Here is the SQL code:
SELECT
[ID],[Date],[Thread],[Level],[Logger],[Message],[Exception]
FROM
[DatabaseName].[dbo].[Log]
WHERE
[Date] BETWEEN
DATEADD(dd, -7, GETDATE())
AND
DATEADD(dd, 1, GETDATE())
ORDER BY
[Date] DESC
The BETWEEN keyword should be pretty self-explanatory, as should the GETDATE function. The secret sauce here lies within the DATEADD function.
The SQL function DATEADD has this signature: DATEADD (datepart, number, date)
The DATEADD function adds a number to a component of DATETIME, in this case, days. This number can be negative to subtract time from a DATETIME, as is the case with our example. The datepart parameter is what determines what component of the DATETIME we are adding to. You can add as much as a year, or as little as a nanosecond (what, no picoseconds? *laugh*). Microsoft's Transact-SQL MSDN page for DATEADD supplies the following table for datepart:
DATEPART | ABBREVIATIONS |
year | yy, yyyy |
quarter | qq, q |
month | mm, m |
dayofyear | dy, y |
day | dd, d |
week | wk, ww |
weekday | dw, w |
hour | hh |
minute | mi, n |
second | ss, s |
millisecond | ms |
microsecond | mcs |
nanosecond | ns |
In the example, I am subtracting 7 days from the current date. If you are making a stored procedure, this variable can be replaced with a parameter:
CREATE PROCEDURE [dbo].[sp_GetLogEntriesRange]
@RangeInDays int
AS
BEGIN
DECLARE @DaysToAdd int
SET @DaysToAdd = (0 - @RangeInDays)
SELECT
[ID],[Date],[Thread],[Level],[Logger],[Message],[Exception]
FROM
[DatabaseName].[dbo].[Log]
WHERE
[Date] BETWEEN
DATEADD(dd, @DaysToAdd, GETDATE())
AND
DATEADD(dd, 1, GETDATE())
ORDER BY
[Date] DESC
END
Enjoy, I hope this helps!
Subscribe to:
Posts (Atom)