Sunday, February 4, 2018

Sync over Async anti-pattern in C#

Problem
I was working on optimizing some code at work. This code was calling PostAsync to a web service. The problem was that Task.Wait() was used. This is called the Sync over Async anti-pattern, and causes a blocking wait. This basically means that thread is wasted, and could be causing unresponsiveness (like your UI freezing, depending on where you called it from)

Note: This also happens if you try to use the Task.Result right after the async call.

Here's an example:
        //Bad
        public string GetWeatherData_SyncOverAsync_Wait(string City)
        {
            var http = new HttpClient();
            var url = $"http://api.openweathermap.org/data/2.5/weather?q={City}&APPID={key}";

            var responseTask = http.GetAsync(url);
            responseTask.Wait();
            responseTask.Result.EnsureSuccessStatusCode();
            var contentTask = responseTask.Result.Content.ReadAsStringAsync();
            contentTask.Wait();
            string responseData = contentTask.Result;
            return responseData;
        }


Solution
await the Task. This releases the thread back to the threadpool until the task completes.

Step 1 - Put async in the method signature.

Step 2 - Make your method return a Task<T>.

Step 3 - await the async call

Step 4 - You will have to repeat these steps in the caller too, and that caller's callers. Basically you need async/await all the way up

        //Good
        public async Task<string> GetWeatherDataAsync(string City)
        {
            var http = new HttpClient();
            var url = $"http://api.openweathermap.org/data/2.5/weather?q={City}&APPID={key}";

            var responseTask = await http.GetAsync(url);
            responseTask.EnsureSuccessStatusCode();
            string responseData = await responseTask.Content.ReadAsStringAsync();
            return responseData;
        }


Sunday, January 21, 2018

Getting started with ReactJS

I followed a video tutorial about the basics of ReactJS. I created a Shopping List page where you can add items to the shopping list and remove them. Simple, yet an effective way to get introduced to using ReactJS.

Getting started
  1. Create a new pen on CodePen - https://codepen.io/ 
  2. Settings > Javascript > Quick-add
    1. React
    2. React-DOM
    3. Then add JavaScript Preprocessor = Babel

MUST GO IN THIS ORDER!!!! Do not put react-dom first

HTML and CSS

The div here is allows React to hook into the page.

The CSS here is optional

Create the component





Create a function that generates list items
This is called a stateless component. 

Set state in the ShoppingList component
I'm initializing the state to a list of items on the shopping list


Hooking the state up to the HTML
I'm looping through the shopping list items and creating HTML list items and wiring up an onClick handler. This onClick handler is going to remove items when you click them (the actual code for that part is shown in the next section)


Add OnClick function
Put the onClick function inside the Shopping List component



Add a button and textbox that allows us to add more items



Refs:
2. My code pen for this: https://codepen.io/Makolyte/pen/rpPzEy 



Friday, December 29, 2017

Calculator in C#

Problem: Create a calculator that can handle multiplication, division, subtraction, addition, power of, and parentheses. This does the proper order of operations (i.e. multiply before addition).
Important: operators/operands can be separated by ZERO or MORE spaces.

Approach: TDD. I solved Addition (+) first, then Subtraction (-). By working on just a few operators, I was able to expose and solve many hard problems using simple input (like "1-1").


//Code using System; using System.Collections.Generic; using System.Text; using System.Text.RegularExpressions; using System.Linq; namespace Solution { public static class Kata { private static bool isNumeric(string s) { double tmp = 0; return Double.TryParse(s, out tmp); } private static bool needToSplitNegative(string token, List<string> tokens) { //check for the case where we have like 1-1 //the regex will split this into 1 and -1 //so we need to split it if (isNumeric(token) && token.StartsWith("-") && tokens.Count > 0 && isNumeric(tokens.Last())) return true; return false; } public static List<string> Tokenizer(string s) { List<string> tokens = new List<string>(); //matches: //number //operator //or outer parentheses with stuff inside //for outer parens, i got it wrong at first. //then i found this: https://stackoverflow.com/a/35271017/1538717 foreach (Match match in Regex.Matches(s.Replace(" ", ""), @"([-]{0,1}[\d]*[\.]{0,1}[\d]+)|([\/\*\+\-\^])|\((?>\((?<c>)|[^()]+|\)(?<-c>))*(?(c)(?!))\)")) { string token = match.Value; if(needToSplitNegative(match.Value, tokens)) { tokens.Add("-"); tokens.Add(token.Substring(1)); } else tokens.Add(match.Value); } return tokens; } private static double doOp(double left, double right, string op) { switch (op) { case "+": return left + right; case "-": return left - right; case "*": return left * right; case "/": return left / right; case "^": return Math.Pow(left, right); default: return 0; } } private static int getSmallest(List<string> tokens, string op1, string op2) { int useIndex = -1; int addIndex = tokens.IndexOf(op1); int subIndex = tokens.IndexOf(op2); if (addIndex > -1 && subIndex > -1) { useIndex = Math.Min(addIndex, subIndex); } else if (addIndex > -1) useIndex = addIndex; else if (subIndex > -1) useIndex = subIndex; else useIndex = -1; return useIndex; } public static double calculate(string s) { if (string.IsNullOrEmpty(s)) throw new ArgumentException("Please send proper input!"); var tokens = Tokenizer(s); Console.WriteLine(string.Join(" ", tokens)); if (!tokens.Any()) throw new ArgumentException("There are no numbers or operators!"); while (true) { int useIndex = tokens.FindIndex(t=>t.StartsWith("(")); if(useIndex != -1) { tokens[useIndex] = calculate(tokens[useIndex].Substring(1, tokens[useIndex].Length - 2)).ToString(); continue; } useIndex = tokens.IndexOf("^"); if(useIndex == -1) useIndex = getSmallest(tokens, "*", "/"); if (useIndex == -1) useIndex = getSmallest(tokens, "+", "-"); //there are no operators if (useIndex == -1) break; double left = Convert.ToDouble(tokens[useIndex - 1]); double right = Convert.ToDouble(tokens[useIndex + 1]); double result = doOp(left, right, tokens[useIndex]); tokens[useIndex + 1] = result.ToString(); tokens.RemoveRange(useIndex - 1, 2); } return Convert.ToDouble(tokens[0]); } } } //Tests using NUnit.Framework; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text.RegularExpressions; //TODO: Replace examples and use TDD development by writing your own tests namespace Solution { [TestFixture] public class CalculatorTest { public bool close(double a, double b) { if (Math.Abs(a - b) < 0.000000001) return true; return false; } [TestCase("1 + 1", 2)] [TestCase("1+1", 2, Description="Deals with spaces")] [TestCase("1+1+1", 3, Description ="More than 2 operands")] [TestCase("1+1+1+1", 4, Description ="Duplicate expression")] [TestCase("1.05+0.95", 2, Description ="Deals with decimals")] [TestCase("-1.05+-0.95", -2, Description = "Deals with negatives")] public void AddTest(string input, double expected) { Assert.AreEqual(expected, Kata.calculate(input), 0.000000001); } [TestCase("1 - 1", 0)] [TestCase("1-1", 0, Description = "Deals with spaces")] [TestCase("1-1-1", -1, Description = "More than 2 operands")] [TestCase("1-1-1-1", -2, Description = "Duplicate expression")] [TestCase("1.05-0.05", 1, Description = "Deals with decimals")] [TestCase("-1.05--0.95", -0.1, Description = "Deals with negatives")] public void SubtractTest(string input, double expected) { Assert.AreEqual(expected, Kata.calculate(input), 0.000000001); } [TestCase("1 * 1", 1)] [TestCase("1+4*2", 9, Description ="Testing precedence")] public void MultiplyTest(string input, double expected) { Assert.AreEqual(expected, Kata.calculate(input), 0.000000001); } [TestCase("1 / 1", 1)] [TestCase("1/4*2", 0.5, Description = "Testing precedence")] public void DivideTest(string input, double expected) { Assert.AreEqual(expected, Kata.calculate(input), 0.000000001); } [TestCase("1 ^ 1", 1)] [TestCase("1/4*2^2",1, Description = "Testing precedence")] public void PowerTest(string input, double expected) { Assert.AreEqual(expected, Kata.calculate(input), 0.000000001); } [TestCase("(1 ^ 1)", 1)] [TestCase("1/4*2^(1+1)", 1, Description = "Testing precedence")] public void ParensTest(string input, double expected) { Assert.AreEqual(expected, Kata.calculate(input), 0.000000001); } [TestCase("1 + 1", new string[] { "1", "+", "1" })] [TestCase("1 * 1", new string[] { "1", "*", "1" })] [TestCase("1 / 1", new string[] { "1", "/", "1" })] [TestCase("1 ^ 1", new string[] { "1", "^", "1" })] [TestCase("1 - 1", new string[] { "1", "-", "1" })] [TestCase("-1 - -1", new string[] { "-1", "-", "-1" })] [TestCase("-1 - (-1 + 1)", new string[] { "-1", "-", "(-1+1)" })] [TestCase("1-1", new string[] { "1", "-", "1" })] [TestCase("(3-1)(3-2)", new string[] { "(3-1)","(3-2)" })] public void TokenizerTest(string input, string[] expectedArr) { List<string> expected = expectedArr.ToList<string>(); List<string> actual = new List<string>(); foreach(string s in Kata.Tokenizer(input)) { actual.Add(s); } CollectionAssert.AreEqual(expected, actual); } } }

Friday, December 15, 2017

Sum two big numbers without using BigInteger

Problem
You're given two large integers represented by strings a and b. Sum them without using BigInteger.

Approach
Do it like how you sum numbers on paper

Code
using System; using System.Text; public static class Kata { public static string sumStrings(string a, string b) { int maxLen = Math.Max(a.Length, b.Length); a = PadLeft(a, maxLen); b = PadLeft(b, maxLen); int[] digits = new int[maxLen]; bool carry = false; for(int i = a.Length - 1; i >= 0; i--) { int sum = AddChars(a[i], b[i]); if(carry) { sum++; carry = false; } if(sum > 9) { digits[i] = sum - 10; carry = true; } else { digits[i] = sum; } } string result = string.Join("", digits); if(carry) result = "1" + result; return result.TrimStart('0'); } public static int AddChars(char a, char b) { return (a - '0') + (b - '0'); } public static string PadLeft(string a, int len) { return a.PadLeft(len, '0'); } }

Thursday, December 14, 2017

Convert json to a dynamic anonymous object - using Newtonsoft


//This takes JSON and deserializes it into a dynamic object. //This means i don't have to declare the type anywhere string json = GetJsonFile(); var converter = new ExpandoObjectConverter(); dynamic storeConfig = JsonConvert.DeserializeObject<ExpandoObject>(json, converter);
var activePipelines = ((IEnumerable<dynamic>)storeConfig.Pipelines).Where(m => Convert.ToBoolean(m.IsActive));

//do stuff with the active pipelines








Saturday, December 9, 2017

Points earned per kata in CodeWars

How many points is each kata worth?







See your points earned per challenge here: https://www.codewars.com/users/<put your username here>/site-events



Ref:
1. https://airtable.com/embed/shrDt7USqZ7GStRb0/tbly10FthXIRqbd7L/viwJf0lpHrvPCKNfb

Count number of set bits in a 32-bit int




using System; public class Kata { public static int CountBits(int n) { int count = 0; int mask = 1; for(int i = 0; i < 32; i++) { if((mask & n) == mask) count++; mask = mask << 1; } return count; } }
There was an error in this gadget