For the last couple of days my Windows Phone have been very sick. It would not go to sleep when the power button was pressed. And when I unmuted the sound, I discovered that it was beeping incessantly.
This was happening only when the device was on battery power. When I plugged it in, it behaved correctly. At first I assumed that it has something to do with the battery. Rebooting the device and removing/reinserting the battery did not help, however.
The sound that it was making though was the same as the one for connecting the power. So I looked closely at the USB power connector in the phone, and discovered that the signal carrier was bent and was touching the walls of the adapter. I straightened it with a tiny screwdriver, and the problem disappeared.
Wednesday, December 28, 2011
Tuesday, December 20, 2011
Saturday, December 17, 2011
Sir Francis Bacon on Obama
"Hope is a good breakfast, but it is a bad supper."
http://www.brainyquote.com/quotes/quotes/f/francisbac125278.html
http://www.brainyquote.com/quotes/quotes/f/francisbac125278.html
Thursday, December 15, 2011
National Defense Authorization Act for Fiscal Year 2012 (it looks like this time of the year again)
"Göring: Why, of course, the people don't want war. Why would some poor slob on a farm want to risk his life in a war when the best that he can get out of it is to come back to his farm in one piece. Naturally, the common people don't want war; neither in Russia nor in England nor in America, nor for that matter in Germany. That is understood. But, after all, it is the leaders of the country who determine the policy and it is always a simple matter to drag the people along, whether it is a democracy or a fascist dictatorship or a Parliament or a Communist dictatorship.
Gilbert: There is one difference. In a democracy, the people have some say in the matter through their elected representatives, and in the United States only Congress can declare wars.
Göring: Oh, that is all well and good, but, voice or no voice, the people can always be brought to the bidding of the leaders. That is easy. All you have to do is tell them they are being attacked and denounce the pacifists for lack of patriotism and exposing the country to danger. It works the same way in any country.
In an interview with Gilbert in Göring's jail cell during the Nuremberg War Crimes Trials (18 April 1946)"
Why you should leave your vote for President (and most likely, Senator) blank next year
http://jonathanturley.org/2011/12/15/obama-breaks-promise-to-veto-bill-allowing-indefinite-detention-of-americans/
No matter what the Republican alternative is, the Democrats MUST be held accountable for this.
"Virtually all Democrats and Republicans voted to strip citizens of their rights in a vote of 93-7."
http://jonathanturley.org/2011/12/02/42285/
Here is the roll call.
http://www.govtrack.us/congress/vote.xpd?vote=s2011-218
The following people voted Nay:
Sanders, VT
Lee, UT
Wyden, OR
Merkley, OR
Coburn, OK
Paul, KY
Harkin, IA
Both WA senators voted for it. None of them will get my vote next election season, no matter what the alternative is.
No matter what the Republican alternative is, the Democrats MUST be held accountable for this.
"Virtually all Democrats and Republicans voted to strip citizens of their rights in a vote of 93-7."
http://jonathanturley.org/2011/12/02/42285/
Here is the roll call.
http://www.govtrack.us/congress/vote.xpd?vote=s2011-218
The following people voted Nay:
Sanders, VT
Lee, UT
Wyden, OR
Merkley, OR
Coburn, OK
Paul, KY
Harkin, IA
Both WA senators voted for it. None of them will get my vote next election season, no matter what the alternative is.
Wednesday, December 14, 2011
Tuesday, December 13, 2011
Generating random numbers with normal distribution
Question: Given a standard generator with uniform distribution, generate a normally distributed sequence of random numbers.
Answer: Box-Muller transform!
http://en.wikipedia.org/wiki/Box%E2%80%93Muller_transform
Source snippet:
class NormalRandom
{
private bool haveNextRandom = false;
private double nextRandom = 0;
private Random rnd = new Random();
return x1 * w;
Answer: Box-Muller transform!
http://en.wikipedia.org/wiki/Box%E2%80%93Muller_transform
Source snippet:
class NormalRandom
{
private bool haveNextRandom = false;
private double nextRandom = 0;
private Random rnd = new Random();
/// <summary>
/// Implements random number generator with normal distribution
/// Implements random number generator with normal distribution
/// based on the polar form of Box-Muller transform.
/// </summary>
/// <returns>A random number with normal distribution.</returns>
/// <returns>
public double NextDouble()
{
if (haveNextRandom)
{
haveNextRandom = false;
return nextRandom;
}
double x1, x2, w;
do
{
x1 = 2.0 * rnd.NextDouble() - 1.0;
x2 = 2.0 * rnd.NextDouble() - 1.0;
w = x1 * x1 + x2 * x2;
} while (w >= 1.0);
w = Math.Sqrt((-2.0 * Math.Log(w)) / w);
nextRandom = x2 * w;
haveNextRandom = true;
return x1 * w;
}
}
Monday, December 12, 2011
Graphics in console application
A long, long time ago when programming for Windows you had to make a choice - your application would have to be either console, or GUI, but not both. If you liked your app for the console subsystem, you could not create windows or dialog boxes, and the application did not have a message loop. If you were a GUI app, you could only use console if you created it yourself, and your app could not inherit its parent's console.
At some point down the line this got fixed, so a console application today can have UI elements - for example, it can call MessageBox(). Despite the weirdness - I am sure HCI purists/Apple would never approve of it - it can actually come quite handy. I, for one, quite often find myself in need of a graphic in the middle of a simple application (sometimes to just visualize something as part of a debug code path) - which I don't want to convert to fully-fledged GUI.
Unfortunately, there is precious little information on how to do do mixed mode console/GUI programming on the Internet, so I figured I'd fill the void :-).
First add references to System.Windows.Forms and System.Drawing (only if you are going to be drawing of course) to your app, as well as the corresponding "using"s.
Then you can create a dialog box that derives from Form:
using System.Windows.Forms;
class MyForm : Form
{
}
...and display it as follows:
MyForm f = new MyForm();
f.ShowDialog();
ShowDialog function is blocking - your console thread will not get control until user closes the window. Of course, standard console functions all work, you can print to the screen like so:
class MyForm : Form
{
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Console.WriteLine("Paint called!");
}
}
At some point down the line this got fixed, so a console application today can have UI elements - for example, it can call MessageBox(). Despite the weirdness - I am sure HCI purists/Apple would never approve of it - it can actually come quite handy. I, for one, quite often find myself in need of a graphic in the middle of a simple application (sometimes to just visualize something as part of a debug code path) - which I don't want to convert to fully-fledged GUI.
Unfortunately, there is precious little information on how to do do mixed mode console/GUI programming on the Internet, so I figured I'd fill the void :-).
First add references to System.Windows.Forms and System.Drawing (only if you are going to be drawing of course) to your app, as well as the corresponding "using"s.
Then you can create a dialog box that derives from Form:
using System.Windows.Forms;
class MyForm : Form
{
}
...and display it as follows:
MyForm f = new MyForm();
f.ShowDialog();
ShowDialog function is blocking - your console thread will not get control until user closes the window. Of course, standard console functions all work, you can print to the screen like so:
class MyForm : Form
{
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Console.WriteLine("Paint called!");
}
}
As an example, here is a very simple application that allows a user to plot simple functions from Math library:
//-----------------------------------------------------------------------
//
// Copyright (C) Sergey Solyanik.
//
// This file is subject to the terms and conditions of the Microsoft Public License (MS-PL).
// See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL for more details.
//
//-----------------------------------------------------------------------
using System;
using System.Drawing;
using System.Reflection;
using System.Windows.Forms;
namespace Graph
{
class Graph : Form
{
public delegate double Function(double x);
public Function F;
public double X1;
public double X2;
public double Y1;
public double Y2;
private double stretchX;
private double stretchY;
private int ToScreenX(double x)
{
return ClientRectangle.Left + (int)((x - X1) * stretchX);
}
private int ToScreenY(double y)
{
return ClientRectangle.Bottom + (int)((y - Y1) * stretchY);
}
private double ToPlaneX(int x)
{
return X1 + ((double)(x - ClientRectangle.Left)) / stretchX;
}
private double ToPlaneY(int y)
{
return Y1 + ((double)(y - ClientRectangle.Bottom)) / stretchY;
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
stretchX = (double)(ClientRectangle.Right - ClientRectangle.Left) /
(X2 - X1);
stretchY = (double)(ClientRectangle.Top - ClientRectangle.Bottom) /
(Y2 - Y1);
if (Math.Sign(X1) != Math.Sign(X2))
{
e.Graphics.DrawLine(
Pens.Black,
ToScreenX(0),
ClientRectangle.Bottom,
ToScreenX(0),
ClientRectangle.Top);
}
if (Math.Sign(Y1) != Math.Sign(Y2))
{
e.Graphics.DrawLine(
Pens.Black,
ClientRectangle.Left,
ToScreenY(0),
ClientRectangle.Right,
ToScreenY(0));
}
for (int x = ClientRectangle.Left; x < ClientRectangle.Right - 1; ++x)
{
e.Graphics.DrawLine(
Pens.Blue,
x,
ToScreenY(F(ToPlaneX(x))),
x + 1,
ToScreenY(F(ToPlaneX(x + 1))));
}
}
}
class Program
{
private static Graph.Function SelectFunction()
{
Console.WriteLine("Available functions:");
Type t = typeof(Math);
MethodInfo[] m = t.GetMethods();
for (int i = 0; i < m.Length; ++i)
{
if (m[i].IsPublic && m[i].IsStatic && m[i].ReturnType == typeof(double))
{
ParameterInfo[] p = m[i].GetParameters();
if (p.Length == 1 && p[0].ParameterType == typeof(double))
Console.WriteLine(" " + m[i].Name);
}
}
while (true)
{
Console.Write("Select a function to plot: ");
string response = Console.ReadLine();
for (int i = 0; i < m.Length; ++i)
{
if (m[i].IsPublic && m[i].IsStatic && m[i].ReturnType == typeof(double))
{
ParameterInfo[] p = m[i].GetParameters();
if (p.Length == 1 && p[0].ParameterType == typeof(double))
{
if (m[i].Name.Equals(response))
{
return (Graph.Function)
Delegate.CreateDelegate(typeof(Graph.Function), m[i]);
}
}
}
}
}
}
private static double GetNumber(string prompt)
{
for (; ; )
{
Console.Write(prompt);
string response = Console.ReadLine();
double result;
if (double.TryParse(response, out result))
return result;
}
}
static void Main(string[] args)
{
Console.CancelKeyPress += delegate
{
Console.WriteLine("Cancelled!");
Environment.Exit(1);
};
Console.WriteLine("Press Ctrl-C to quit.");
Console.WriteLine();
Graph g = new Graph();
g.F = SelectFunction();
g.X1 = GetNumber("Abscissa lower boundary: ");
g.X2 = GetNumber("Abscissa upper boundary: ");
g.Y1 = GetNumber("Ordinate lower boundary: ");
g.Y2 = GetNumber("Ordinate upper boundary: ");
g.ShowDialog();
}
}
}
Wednesday, December 7, 2011
Tuesday, December 6, 2011
WCF web services and a calculator implementation in one easy snippet!
I wanted to write a calculator that supported parentheses and operator precedence for a while, but never got to sit down and do it. Recently I was poking around WCF (yes, I know I am VERY late for that party!) and wanted something less trivial than "Hello, world" to explore it. Suddenly, it felt like a reasonable opportunity to kill two birds with one stone.
Below is an implementation of a calculator web service. A problem like this is most frequently dealt with using a parse tree, and this solution is no exception. A parse tree is a binary tree representation of an expression which makes the result very easy to calculate by recursive evaluation. Our service exposes two APIs: one takes a string and returns a computed result, the other returns the parse tree for the expression for educational purposes (and to give WCF something non-trivial to marshal).
A parse tree has operators such as +, -, *, and / stored in the nodes with the children of the nodes being the operands. For example, 2 + 2 would generate the following parse tree:
+
2 2
A more complex example, 3 * 4 + 2 will result in:
+
* 2
3 4
Once a parse tree is built, the evaluation is trivial: at every node, apply evaluation recursively to the children, then perform the arithmetic operator on the results. The trick here is to build it, as its construction must account for the operator precedence, parentheses, and such.
The data structure for the node contains an operator, its two children (only would of which will be set for unary operator and in other cases), the parent, and value field used for nodes that represent values. A parenthesized subexpression lives under the separate node rooted in its right child, as illustrated below:
2 * (3 + 5) =>
*
2 ()
+
3 5
The program moves alongside the expression and adds the nodes corresponding to the tokens it parses to the tree. For example, given the following expression: 2 + 2 + 2 it will:
1) Read 2, create a value node for 2, and remember it as its current node:
2 <=
2) Read +, create an operator node for +, set node for 2 as its left child:
+ <=
2
3) Read 2, create a value node for 2, and add it to the current (+) node as its right child;
+
2 2 <=
4) Read +, create an operator node for +, set node for 2 as its left child and hooking it in place of the value node under the earlier +:
+
2 + <=
2
5) Read 2, create a value node for 2, and add it to the current (+) node as its right child;
How does the operator precedence work in this scheme? It is encoded in the tree itself. Note that the tree for 3 * 4 + 2 must be built as follows:
+
* 2
3 4
//-----------------------------------------------------------------------
//
// Copyright (C) Sergey Solyanik.
//
// This file is subject to the terms and conditions of the Microsoft Public License (MS-PL).
// See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL for more details.
//
//-----------------------------------------------------------------------
using System;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.Runtime.Serialization;
namespace WCFCalc
{
[ServiceContract]
public interface IWCFCalc
{
[OperationContract]
int Calculate(string expr);
[OperationContract]
ExprNode Parse(string expr);
}
public enum Operator
{
PLUS,
MINUS,
MUL,
DIV,
VAL,
EXPR,
OPENPAREN,
ERROR
}
[DataContract]
public class ExprNode
{
[DataMember]
public ExprNode Left;
[DataMember]
public ExprNode Right;
// This is not exported because the
// serialization would take it as a
// circular reference.
public ExprNode Parent;
[DataMember]
public Operator Op;
[DataMember]
public int Value;
}
public class WCFCalcSvc : IWCFCalc
{
private void Err(string s)
{
Console.WriteLine(s);
throw new FaultException(
new InvalidOperationException(s), s);
}
private Operator ToOp(char c)
{
switch (c)
{
case '+': return Operator.PLUS;
case '-': return Operator.MINUS;
case '*': return Operator.MUL;
case '/': return Operator.DIV;
default: return Operator.ERROR;
}
}
private bool HigherPrecedence(Operator o1, Operator o2)
{
if ((o2 == Operator.PLUS || o2 == Operator.MINUS) &&
(o1 == Operator.MUL || o1 == Operator.DIV))
return true;
return false;
}
int Calculate(ExprNode expr)
{
if (expr.Op == Operator.VAL)
return expr.Value;
if (expr.Op == Operator.EXPR)
return Calculate(expr.Right);
if (expr.Op == Operator.PLUS)
return Calculate(expr.Left) + Calculate(expr.Right);
if (expr.Op == Operator.MINUS)
{
if (expr.Left == null)
return -Calculate(expr.Right);
return Calculate(expr.Left) - Calculate(expr.Right);
}
if (expr.Op == Operator.MUL)
return Calculate(expr.Left) * Calculate(expr.Right);
if (expr.Op == Operator.DIV)
return Calculate(expr.Left) / Calculate(expr.Right);
Err("Internal error: unknown operator!");
return 0;
}
public int Calculate(string expr)
{
return Calculate(Parse(expr));
}
public ExprNode Parse(string expr)
{
int x = 0;
ExprNode current = null;
while (x < expr.Length)
{
if (expr[x] == ' ')
{
++x;
continue;
}
if (expr[x] == '(')
{
++x;
ExprNode node = new ExprNode();
node.Op = Operator.OPENPAREN;
if (current == null)
{
current = node;
continue;
}
if ((current.Op == Operator.VAL) ||
(current.Right != null))
{
Err("Error @ " + x);
}
node.Parent = current;
current.Right = node;
current = node;
continue;
}
if (expr[x] == ')')
{
++x;
while (current != null && current.Op != Operator.OPENPAREN)
current = current.Parent;
if (current == null)
Err("Error @ " + x);
// Close the paren
current.Op = Operator.EXPR;
continue;
}
Operator op = ToOp(expr[x]);
if (op != Operator.ERROR)
{
++x;
ExprNode node = new ExprNode();
node.Op = op;
// currently no support for unary ops
if (current == null ||
(current.Op != Operator.VAL &&
current.Op != Operator.EXPR))
{
if (op == Operator.MINUS)
{
node.Parent = current;
if (current != null)
current.Right = node;
current = node;
continue;
}
Err("Error @ " + x);
}
// This ensures that the higher precedence
// operators are lower in the expression
// tree, and therefore execute before the
// lower precedence operators.
while (current.Parent != null &&
current.Parent.Op != Operator.OPENPAREN &&
!HigherPrecedence(op, current.Parent.Op))
{
current = current.Parent;
}
node.Parent = current.Parent;
if (current.Parent != null)
current.Parent.Right = node;
current.Parent = node;
node.Left = current;
current = node;
continue;
}
// value
if (expr[x] >= '0' && expr[x] <= '9')
{
int n = 0;
while (x < expr.Length && (expr[x] >= '0' && expr[x] <= '9'))
{
n = n * 10 + (expr[x] - '0');
++x;
}
ExprNode node = new ExprNode();
node.Op = Operator.VAL;
node.Value = n;
if (current == null)
{
current = node;
continue;
}
if (current.Op == Operator.VAL)
Err("Error @ " + x);
if (current.Right != null)
Err("Error @ " + x);
node.Parent = current;
current.Right = node;
current = node;
continue;
}
}
while (current != null && current.Parent != null)
{
if (current.Op == Operator.OPENPAREN)
Err("Not enough closed parens!");
current = current.Parent;
}
if (current != null && current.Op == Operator.OPENPAREN)
Err("Not enough closed parens!");
return current;
}
}
class Program
{
static void Main(string[] args)
{
Uri baseAddress = new Uri("http://localhost:8000/Calculator");
ServiceHost selfHost = new ServiceHost(typeof(WCFCalcSvc), baseAddress);
try
{
selfHost.AddServiceEndpoint(
typeof(IWCFCalc),
// DANGER! DO NOT CARRY SecurityMode.None
// INTO PRODUCTION SERVICE BY DEFAULT!!!
new WSHttpBinding(SecurityMode.None),
"Calculator");
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
selfHost.Description.Behaviors.Add(smb);
selfHost.Open();
Console.WriteLine("The service is ready.");
Console.WriteLine("Press to terminate service.");
Console.WriteLine();
Console.ReadLine();
selfHost.Close();
}
catch (CommunicationException ce)
{
Console.WriteLine("An exception occurred: {0}", ce.Message);
selfHost.Abort();
}
}
}
}
Below is an implementation of a calculator web service. A problem like this is most frequently dealt with using a parse tree, and this solution is no exception. A parse tree is a binary tree representation of an expression which makes the result very easy to calculate by recursive evaluation. Our service exposes two APIs: one takes a string and returns a computed result, the other returns the parse tree for the expression for educational purposes (and to give WCF something non-trivial to marshal).
A parse tree has operators such as +, -, *, and / stored in the nodes with the children of the nodes being the operands. For example, 2 + 2 would generate the following parse tree:
+
2 2
A more complex example, 3 * 4 + 2 will result in:
+
* 2
3 4
Once a parse tree is built, the evaluation is trivial: at every node, apply evaluation recursively to the children, then perform the arithmetic operator on the results. The trick here is to build it, as its construction must account for the operator precedence, parentheses, and such.
The data structure for the node contains an operator, its two children (only would of which will be set for unary operator and in other cases), the parent, and value field used for nodes that represent values. A parenthesized subexpression lives under the separate node rooted in its right child, as illustrated below:
2 * (3 + 5) =>
*
2 ()
+
3 5
The program moves alongside the expression and adds the nodes corresponding to the tokens it parses to the tree. For example, given the following expression: 2 + 2 + 2 it will:
1) Read 2, create a value node for 2, and remember it as its current node:
2 <=
2) Read +, create an operator node for +, set node for 2 as its left child:
+ <=
2
3) Read 2, create a value node for 2, and add it to the current (+) node as its right child;
+
2 2 <=
4) Read +, create an operator node for +, set node for 2 as its left child and hooking it in place of the value node under the earlier +:
+
2 + <=
2
5) Read 2, create a value node for 2, and add it to the current (+) node as its right child;
+
2 +
2 2 <=
2 +
2 2 <=
How does the operator precedence work in this scheme? It is encoded in the tree itself. Note that the tree for 3 * 4 + 2 must be built as follows:
+
* 2
3 4
and not like this:
*
3 +
4 2
3 +
4 2
The later would treat the expression as 3 * (4 + 2), which is, of course incorrect. However, this would be the tree that a naive algorithm that just reads the next token and stuffs it into a tree would build.
To account for operator precedence, before adding a new operator node, our algorithm would look at the parent nodes of its current position and if the operator at that node has a higher precedence than the operator we are about to add, it will move up the chain and hook the new node above all the higher-precedence operators, so the tree construction for 3 * 4 * 5 + 2 will proceed like this;
3<= => *<= => * => * => * => +
3 3 4<= 3 * <= 3 * * 2
4 4 5 <= 3 *
4 5
Once this concept is clear, the rest is pure accounting (as is most of the software development :-)). The code below implements it and publishes the results through a template implementation of WCF web service, which takes on the order of 7 functional lines of code (at the very end, in the main function).
//-----------------------------------------------------------------------
//
// Copyright (C) Sergey Solyanik.
//
// This file is subject to the terms and conditions of the Microsoft Public License (MS-PL).
// See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL for more details.
//
//-----------------------------------------------------------------------
using System;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.Runtime.Serialization;
namespace WCFCalc
{
[ServiceContract]
public interface IWCFCalc
{
[OperationContract]
int Calculate(string expr);
[OperationContract]
ExprNode Parse(string expr);
}
public enum Operator
{
PLUS,
MINUS,
MUL,
DIV,
VAL,
EXPR,
OPENPAREN,
ERROR
}
[DataContract]
public class ExprNode
{
[DataMember]
public ExprNode Left;
[DataMember]
public ExprNode Right;
// This is not exported because the
// serialization would take it as a
// circular reference.
public ExprNode Parent;
[DataMember]
public Operator Op;
[DataMember]
public int Value;
}
public class WCFCalcSvc : IWCFCalc
{
private void Err(string s)
{
Console.WriteLine(s);
throw new FaultException
new InvalidOperationException(s), s);
}
private Operator ToOp(char c)
{
switch (c)
{
case '+': return Operator.PLUS;
case '-': return Operator.MINUS;
case '*': return Operator.MUL;
case '/': return Operator.DIV;
default: return Operator.ERROR;
}
}
private bool HigherPrecedence(Operator o1, Operator o2)
{
if ((o2 == Operator.PLUS || o2 == Operator.MINUS) &&
(o1 == Operator.MUL || o1 == Operator.DIV))
return true;
return false;
}
int Calculate(ExprNode expr)
{
if (expr.Op == Operator.VAL)
return expr.Value;
if (expr.Op == Operator.EXPR)
return Calculate(expr.Right);
if (expr.Op == Operator.PLUS)
return Calculate(expr.Left) + Calculate(expr.Right);
if (expr.Op == Operator.MINUS)
{
if (expr.Left == null)
return -Calculate(expr.Right);
return Calculate(expr.Left) - Calculate(expr.Right);
}
if (expr.Op == Operator.MUL)
return Calculate(expr.Left) * Calculate(expr.Right);
if (expr.Op == Operator.DIV)
return Calculate(expr.Left) / Calculate(expr.Right);
Err("Internal error: unknown operator!");
return 0;
}
public int Calculate(string expr)
{
return Calculate(Parse(expr));
}
public ExprNode Parse(string expr)
{
int x = 0;
ExprNode current = null;
while (x < expr.Length)
{
if (expr[x] == ' ')
{
++x;
continue;
}
if (expr[x] == '(')
{
++x;
ExprNode node = new ExprNode();
node.Op = Operator.OPENPAREN;
if (current == null)
{
current = node;
continue;
}
if ((current.Op == Operator.VAL) ||
(current.Right != null))
{
Err("Error @ " + x);
}
node.Parent = current;
current.Right = node;
current = node;
continue;
}
if (expr[x] == ')')
{
++x;
while (current != null && current.Op != Operator.OPENPAREN)
current = current.Parent;
if (current == null)
Err("Error @ " + x);
// Close the paren
current.Op = Operator.EXPR;
continue;
}
Operator op = ToOp(expr[x]);
if (op != Operator.ERROR)
{
++x;
ExprNode node = new ExprNode();
node.Op = op;
// currently no support for unary ops
if (current == null ||
(current.Op != Operator.VAL &&
current.Op != Operator.EXPR))
{
if (op == Operator.MINUS)
{
node.Parent = current;
if (current != null)
current.Right = node;
current = node;
continue;
}
Err("Error @ " + x);
}
// This ensures that the higher precedence
// operators are lower in the expression
// tree, and therefore execute before the
// lower precedence operators.
while (current.Parent != null &&
current.Parent.Op != Operator.OPENPAREN &&
!HigherPrecedence(op, current.Parent.Op))
{
current = current.Parent;
}
node.Parent = current.Parent;
if (current.Parent != null)
current.Parent.Right = node;
current.Parent = node;
node.Left = current;
current = node;
continue;
}
// value
if (expr[x] >= '0' && expr[x] <= '9')
{
int n = 0;
while (x < expr.Length && (expr[x] >= '0' && expr[x] <= '9'))
{
n = n * 10 + (expr[x] - '0');
++x;
}
ExprNode node = new ExprNode();
node.Op = Operator.VAL;
node.Value = n;
if (current == null)
{
current = node;
continue;
}
if (current.Op == Operator.VAL)
Err("Error @ " + x);
if (current.Right != null)
Err("Error @ " + x);
node.Parent = current;
current.Right = node;
current = node;
continue;
}
}
while (current != null && current.Parent != null)
{
if (current.Op == Operator.OPENPAREN)
Err("Not enough closed parens!");
current = current.Parent;
}
if (current != null && current.Op == Operator.OPENPAREN)
Err("Not enough closed parens!");
return current;
}
}
class Program
{
static void Main(string[] args)
{
Uri baseAddress = new Uri("http://localhost:8000/Calculator");
ServiceHost selfHost = new ServiceHost(typeof(WCFCalcSvc), baseAddress);
try
{
selfHost.AddServiceEndpoint(
typeof(IWCFCalc),
// DANGER! DO NOT CARRY SecurityMode.None
// INTO PRODUCTION SERVICE BY DEFAULT!!!
new WSHttpBinding(SecurityMode.None),
"Calculator");
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
selfHost.Description.Behaviors.Add(smb);
selfHost.Open();
Console.WriteLine("The service is ready.");
Console.WriteLine("Press
Console.WriteLine();
Console.ReadLine();
selfHost.Close();
}
catch (CommunicationException ce)
{
Console.WriteLine("An exception occurred: {0}", ce.Message);
selfHost.Abort();
}
}
}
}
To compile the service, create an empty console project, add System.Runtime.Serialization and System.ServiceModel to the list of references, and copy the code into it.
To consume the service, create a client project with the following code:
//-----------------------------------------------------------------------
//
// Copyright (C) Sergey Solyanik.
//
// This file is subject to the terms and conditions of the Microsoft Public License (MS-PL).
// See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL for more details.
//
//-----------------------------------------------------------------------
using System;
using WCFTestClient.WCFCalc;
namespace WCFTestClient
{
class Program
{
static void Print(ExprNode n)
{
Console.Write("(" + n.Op + " ");
if (n.Left != null && n.Right != null)
{
Print(n.Left);
Console.Write(", ");
Print(n.Right);
Console.Write(")");
}
else if (n.Left != null || n.Right != null)
{
Print(n.Left != null ? n.Left : n.Right);
Console.Write(")");
}
else
{
Console.Write(n.Value + ")");
}
}
static void Main(string[] args)
{
WCFCalcClient svc = new WCFCalcClient();
for (; ; )
{
Console.Write("> ");
string s = Console.ReadLine();
if (s.Equals("exit", StringComparison.OrdinalIgnoreCase))
break;
try
{
if (s.StartsWith("p"))
{
s = s.Substring(1);
ExprNode n = svc.Parse(s);
Print(n);
Console.WriteLine();
}
else
{
Console.WriteLine(s + " = " + svc.Calculate(s));
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
}
}
As you can see, it only takes 1 line of code (!) to connect to our service. The rest constitutes the logic of the program itself.
Now run the service from a command line. Right-click on Service References, select "Add Service Reference", point it to http://localhost:8000/Calculator, set WCFCalc as a namespace, and click import. That's it - you are done. The service importer will create app.config with all the endpoint details, you can now just run the client.
Prefix your expression with p to display the parse tree for it, like so: p2+2, or type "exit" to leave.
Thursday, December 1, 2011
Pepper spray
"It is becoming more and more fashionable right now, this day and age, to use chemical on people who have an opinion. And that to me is a complete lack of leadership both in the police department and other people who cannot really deal with the root of the problem and they want to spray people to quiet them down. And it’s really not supposed to be that. It’s not a thing that solves any problem nor is it something that quiets people down.”
Kamran Loghman, inventor of modern pepper spray and developer of police procedures for its use
http://boingboing.net/2011/11/30/pepper-spray-inventor-its.html
Kamran Loghman, inventor of modern pepper spray and developer of police procedures for its use
http://boingboing.net/2011/11/30/pepper-spray-inventor-its.html
Subscribe to:
Posts (Atom)