Daily Archives: March 11, 2014

Lazy class (advanced)

OK, this is no joke. This class really exists.

Not many programmers come across this class. At first glance it seems to be useless. Let’s have a closer look!
Imagine the following situation. You are initializing objects. Each of them takes a lot of time and uses many resources. There is no load balancing. Some of them may be used simultaneously, so it is not one or the other. The problem is that you don’t know, which object will be needed. It could be that you don’t need any object at all. Nevertheless you want to provide each object to the system as if they were initialized already. That way you don’t have to deal with any initialization later during the running program.

I included a short example about Bill Gates. Let’s say he has too many cars, so he feels the agony of choice. Early in the morning Bill is standing in his garage. He needs a car to go to the beach, but there are simply too many cars to choose from. One of his many gardeners recommends the Porsche. Well, the final choice is at the whim of Bill Gates. Hypothetically he might also need a second car today. His new 19-year-old girl friend had an overnight stay … on the couch. Yeah, that’s life 😉

I am sure you are often using LINQ. It uses a similar concept. Linq does not execute until the point you access the query result. When the example program calls “… select x.GetSomething()”, then you do not see any output from the method GetSomething(), which would be “What about an ice cream?”. “Where is my lunch?” prints first. And when we call lYummy.First() to get the first object from the query (well, there is only one), only then you see GetSomething() executing.

Too Lazy or just right?

using System;
using System.Collections.Generic;
using System.Linq;

namespace DemoApp {
   public class VeryLazy {
      public class NotNow {
         public NotNow() { Console.WriteLine("executing constructor"); }
         public void DoSomething() { Console.WriteLine("Zzzzzz... Jeez, you woke me up!"); }
         public string GetSomething() {
            Console.WriteLine("What about an ice cream?");
            return "ice cream";
         }
      } // class      

      public class BillGatesGarage {
         Lazy<NotNow> Porsche = new Lazy<NotNow>();
         Lazy<NotNow> Ferrari = new Lazy<NotNow>();
         Lazy<NotNow> Maserati = new Lazy<NotNow>();
         Lazy<NotNow> Lamborghini = new Lazy<NotNow>();

         public enum eCoolness { eSmart, eShowOff, eFast, eFun }
         public NotNow getCar(eCoolness xCoolness) {
            Console.WriteLine();
            Console.WriteLine("Sleeping cars:");
            Console.WriteLine("Porsche " + !Porsche.IsValueCreated);
            Console.WriteLine("Ferrari " + !Ferrari.IsValueCreated);
            Console.WriteLine("Maserati " + !Maserati.IsValueCreated);
            Console.WriteLine("Lamborghini " + !Lamborghini.IsValueCreated);
            switch (xCoolness) {
               case eCoolness.eSmart: return Porsche.Value;
               case eCoolness.eShowOff: return Ferrari.Value;
               case eCoolness.eFast: return Maserati.Value;
               case eCoolness.eFun: return Lamborghini.Value;
            }
            return null;
         }
      } // class

      public static void test() {
         List<NotNow> lList = new List<NotNow>();
         lList.Add(new NotNow());         
         var lYummy = from x in lList select x.GetSomething();
         Console.WriteLine("Where is my lunch?");
         Console.WriteLine("I got an " + lYummy.First() + " for you!");

         Console.WriteLine();
         Lazy<NotNow> lLazy = new Lazy<NotNow>();
         Console.WriteLine("Object created already? " + lLazy.IsValueCreated);
         Console.WriteLine("No worries! Let's create an instance now:");
         NotNow lNotNow = lLazy.Value;
         Console.WriteLine("Object created already? " + lLazy.IsValueCreated);
         if (lLazy.IsValueCreated) lNotNow.DoSomething();

         Console.WriteLine();
         Console.WriteLine("All engines warmed up?");
         BillGatesGarage lGarage = new BillGatesGarage();
         NotNow lBrumBrum = lGarage.getCar(BillGatesGarage.eCoolness.eSmart);
         lBrumBrum.DoSomething();
         Console.WriteLine("Oh dear, he just changed his mind");
         NotNow lWhooosh = lGarage.getCar(BillGatesGarage.eCoolness.eFast);
         lWhooosh.DoSomething();

         // check cars
         lGarage.getCar(BillGatesGarage.eCoolness.eFast);
      } //

   } // class
} // namespace

example output:
executing constructor
Where is my lunch?
What about an ice cream?
I got an ice cream for you!

Object created already? False
No worries! Let’s create an instance now:
executing constructor
Object created already? True
Zzzzzz… Jeez, you woke me up!

All engines warmed up?

Sleeping cars:
Porsche True
Ferrari True
Maserati True
Lamborghini True
executing constructor
Zzzzzz… Jeez, you woke me up!
Oh dear, he just changed his mind

Sleeping cars:
Porsche False
Ferrari True
Maserati True
Lamborghini True
executing constructor
Zzzzzz… Jeez, you woke me up!

Sleeping cars:
Porsche False
Ferrari True
Maserati False
Lamborghini True

migration C#, Java, C++ (day 9b), TextIO, Tuples

logo

Some basic stuff today. Tuples are not well-known. They are very useful for returning multiple types within one method. Tuples are immutable in C#. C++ is more relaxed about this. Reading or writing text files is nothing special as well. Anyway, consider that C# uses Unicode whereas C++ mainly deals with ASCII. I do not see C++ as a standard developer language. It is used to gain extra speed. So I won’t even touch the idea of Unicode in my examples. What is the meaning of sitting in front of your PC for hours just to get a result that you could get in another language within minutes.
The right approach is to mix languages.

TextIO and Tuples

using System;
using System.IO;

namespace DemoApp.ToCpp {
   public class Day9 {

      public static void Test() {
         try {
            string lDesktopPath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + @"\";
            string lFile = lDesktopPath + "test.txt";
            string lText = "I see trees of green, red roses too.\nI see them bloom for me and you.\nAnd I think to myself what a wonderful world.\nI see skies of blue and clouds of white\n...";

            // write
            File.WriteAllText(lFile, lText);
            
            // read
            string lLoadResult = File.ReadAllText(lFile);
            Console.WriteLine(lLoadResult);

            // make trees blue
            lLoadResult = lLoadResult.Replace("green", "blue");
            Console.WriteLine("\nThe trees have just changed their colour:\n\n");
            Console.WriteLine(lLoadResult);

            // tuples
            Tuple<int, string, double> lTuple = new Tuple<int, string, double>(1, "2", 3.0);
            //lTuple.Item3 = 3.3; compiler error: readonly
            Console.WriteLine(lTuple.Item1 + " " + lTuple.Item2 + " " + lTuple.Item3);
         }
         catch (Exception ex) {
            Console.WriteLine(ex.Message);
         }

         Console.ReadLine();
      } //

   } // class
} // namespace

example output:
I see trees of green, red roses too.
I see them bloom for me and you.
And I think to myself what a wonderful world.
I see skies of blue and clouds of white

The trees have just changed their colour:

I see trees of blue, red roses too.
I see them bloom for me and you.
And I think to myself what a wonderful world.
I see skies of blue and clouds of white

1 2 3

#include <iostream>
#include <string>
#include <stdexcept>
#include <memory>
#include <sstream>
#include <fstream>
#include <algorithm>

using namespace std;

void StringToTextFile(const string &xFilename, const string &xText)  {
    ofstream lStream;
    lStream.open(xFilename.c_str());
    lStream << xText;
    lStream.close();
}

string TextFileToString(const string &xFilename)  {
    ostringstream lStringBuilder(ios::out | ios::binary);
    ifstream lStream(xFilename.c_str());
    string s;
    while (getline(lStream, s)) lStringBuilder << s << endl;
    return lStringBuilder.str();
}

int main() {
    try {
      string lDesktopPath = "C:\\Users\\YourUsername\\Desktop\\"; // no direct and portable C++ support
      string lFile = lDesktopPath + "test.txt";
      string lText = "I see trees of green, red roses too.\nI see them bloom for me and you.\nAnd I think to myself what a wonderful world.\nI see skies of blue and clouds of white\n...";

      // write
      StringToTextFile(lFile, lText);

      // read
      string lLoadResult = TextFileToString(lFile);
      cout << lLoadResult << endl;

      // make trees blue
      lLoadResult.replace(lLoadResult.find("green"), 5, "blue");
      cout << endl << "The trees have just changed their colour:" << endl << endl;
      cout << lLoadResult << endl;

      // tuples
      tuple<int, string, double> lTuple = make_tuple(1, "2", 3.0);
      cout << get<0>(lTuple) << " " << get<1>(lTuple) << " " << get<2>(lTuple) << endl;
      get<0, int, string, double>(lTuple) = 9;
      cout << get<0>(lTuple) << " " << get<1>(lTuple) << " " << get<2>(lTuple) << endl;

      int i;
      string s = "OOOPS";
      double d;
      tie (i, ignore, d) = lTuple; // unpack
      cout << i << " " << s << " " << d << endl;

      s = get<1>(lTuple);
      cout << s << endl;
    }
    catch (exception &ex) { cout << ex.what() << endl; }

    cin.get();
    return 0;
} //

example output:
I see trees of green, red roses too.
I see them bloom for me and you.
And I think to myself what a wonderful world.
I see skies of blue and clouds of white

The trees have just changed their colour:

I see trees of blue, red roses too.
I see them bloom for me and you.
And I think to myself what a wonderful world.
I see skies of blue and clouds of white

1 2 3
9 2 3
9 OOOPS 3
2

package DemoApp.ToCpp;

public final class Tuple<T, U, V> {

  // tuples are not supported by the standard libraries
  // this is a quick and dirty way to replicate a Triplet
  private final T _value0;
  private final U _value1;
  private final V _value2;

  public Tuple(T xValue0, U xValue1, V xValue2) {
    _value0 = xValue0;
    _value1 = xValue1;
    _value2 = xValue2;
  } // constructor

  public T get0() { return _value0; }
  public U get1() { return _value1; }
  public V get2() { return _value2; }
} // class
//-----------------------------------------------------------------------------
package DemoApp.ToCpp;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;

public class Day9 {  

  public static void main(String[] args) {
    try {
      String lDesktopPath = null;

      try {
        lDesktopPath = System.getProperty("user.home") + "/Desktop";
        lDesktopPath = lDesktopPath.replace("\\", "/");
        System.out.println("Desktop path: " + lDesktopPath);
      } catch (Exception e) {
        System.out.println("Exception caught =" + e.getMessage());
      }

      String lFile = lDesktopPath + "/test.txt";
      String lNewLine = System.getProperty("line.separator");
      String lText = "I see trees of green, red roses too." + lNewLine + "I see them bloom for me and you." + lNewLine + "And I think to myself what a wonderful world." + lNewLine + "I see skies of blue and clouds of white" + lNewLine + "...";

      // write  (try-with-resources statement, http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html)
      try (BufferedWriter lWriter = new BufferedWriter(new FileWriter(lFile))) {
        lWriter.write(lText);
      } catch (IOException ex) {
        System.out.println("IOException =" + ex.getMessage());
      }

      // read (all in one shot)
      StringBuilder lStringBuilder = new StringBuilder();
      String lLoadResult = null;
      try {
        Path lPath = Paths.get(lFile);
        List<String> lList = Files.readAllLines(lPath, StandardCharsets.UTF_8);
        for (String lLine : lList) { lStringBuilder.append(lLine); lStringBuilder.append(lNewLine); }
        lLoadResult = lStringBuilder.toString();        
        System.out.println(lLoadResult);
      } catch (IOException ex) {
        System.out.println("IOException =" + ex.getMessage());
      }

      // make trees blue
      if (lLoadResult != null) {
        lLoadResult = lLoadResult.replace("green", "blue");
        System.out.println("The trees have just changed their colour:\n");
        System.out.println(lLoadResult);
      }

      // tuples      
      Tuple<Integer, String, Double> lTuple = new Tuple<>(1, "2", 3.0);
      //lTuple.Item3 = 3.3; compiler error: readonly
      System.out.println(lTuple.get0() + " " + lTuple.get1() + " " + lTuple.get2());
    } catch (RuntimeException ex) {
      System.out.println(ex.getMessage());
    }

    new Scanner(System.in).nextLine();
  }

} // class

example output:
Desktop path: C:/Users/LvAdmin/Desktop
I see trees of green, red roses too.
I see them bloom for me and you.
And I think to myself what a wonderful world.
I see skies of blue and clouds of white

The trees have just changed their colour:

I see trees of blue, red roses too.
I see them bloom for me and you.
And I think to myself what a wonderful world.
I see skies of blue and clouds of white

1 2 3.0