20 Jan 2012 @ 5:52 AM 

I see this question semi-frequently on forums. It’s a reasonable question on the surface. However, the fact is that there is no “Best language for a beginner”. Truly, the very idea that a given computer language could be “better for beginners” than another is downright asinine.

Consider human languages. A person learns language over time, and there isn’t any more difficulty for different languages; the skill develops through practice. Chinese isn’t “harder” to learn than English, for example; but it is harder to learn when you know english.

So how does this extend into computer languages?

Well, the first computer language you learn won’t matter, just as the first Human language you learned doesn’t really matter.For Human languages, the big thing you are learning is how to express yourself to others. For Programming languages, the big thing you are learning is how to express yourself- to the computer.

Once you learn one imperative programming language, the others are easier to learn; same way with human languages. Once you know one germanic language, the others are typically easier to learn.

Of course, it’s harder to learn Chinese or Japanese when you are used to a latin alphabet; for programming languages, this “barrier” is typically found between imperative, Declarative, and functional languages. of course the actual difficulty is not quite at the same level; but functional languages are fundamentally different in many ways from imperative languages, enough that trying to take what you learned via programming in an imperative language and applying it to a functional one can do more harm than good to your learning process, just as trying to apply your understanding of English will harm attempts to learn most non-germanic languages, trying to apply an understanding of Chinese/Japanese/etc to learning English will harm attempts to learn it as well.

Additionally, one issue I find is that many people will say that “language X is easy to learn because it’s like plain english”. Which is a flawed perspective, since that brings with it a lot of language baggage; english is designed for communicating between people; a programming language is designed for communicating between a person and a computer (or rather, the interpreter/compiler which makes it into something the computer understands, but let’s not cloud the issue). So you end up with a psuedo-english language that tries to be declarative but at the same time isn’t english; SQL, for example, is english-like, but I’d be hard-pressed to say that “Select * from Customers Where CX>6″ is “plain english”. It’s easy to understand, but it’s restrictive; after all, in english the same concept could be expressed as “choose all fields from the customers table where the record in question has a CX field greater than 6″. But that is far from valid SQL, which has a far more restrictive grammar and syntax. (if it didn’t, parsing it would be a nightmare).

This is how I’ve always felt about it. What is important isn’t what specific language you learn but that you learn the concepts involved; for imperative languages this would be references, functions, recursion, variable allocations,object mutability, (and for OOP languages the various OOP concepts, such as polymorphism, aggregation, composition, delegation, etc). Functional languages, (and some imperative languages that integrate functional features) it’s things like lambdas, recursive definitions,Higher-order/First-class functions (Functions that take other functions as arguments), pure functions, strict versus non-strict evaluation, catamorphism, etc.

Once you learn the concepts, you can use pretty much learn any language with minimal effort, you just need to learn the syntax.(unless you are jumping across a declarative/imperative/functional divide, in which case you also need to learn and relearn other concepts as well). Overall, however, Learning a syntax is easy; the first programming language you learn is hardest no matter which one you choose simply because you have to learn the syntax at the same time you are learning all sorts of “new” concepts. It doesn’t matter what language you choose; it will always be “harder” to learn than later languages for you.

Update 04-15-2012

It has been mentioned that PASCAL, a fictitious language, apparently contradicts my points here. The argument being that languages that are easier to write functionality in will be easier to learn.

However, this misses the point. The ease of learning of a first programming language is absolutely pointless, because it isn’t the syntax or structure of a given language that gives you the tools to coalesce those language elements into algorithms, and therefore solutions, but rather your understanding of base concepts. The argument for PASCAL (again, a fictitious language that doesn’t exist, evidently they truly meant Pascal) was essentially that it needed less code to read and write to the console. For example:

  1.  
  2. var
  3.   Namevalue: String [255] ;
  4. end;
  5. begin
  6.     Writeln("Hello. Enter your name:");
  7.     Readln(Namevalue);
  8.  
  9.  
  10. end.
  11.  

is more “concise” and “easier to learn” than the equivalent java code:

  1.  
  2. import java.io.*;
  3. import java.util.*;
  4. public class testreader {
  5.  
  6.     private static Scanner scin = new Scanner(System.in);
  7.     public static void main(String []  args) {
  8.         System.out.println("Hello there. Enter your name:");
  9.         String readthis = scin.nextLine();
  10.     }
  11.  
  12. }
  13.  
  14.  

The argument essentially rests on the faulty premise that Writeln() is somehow “easier to learn” than java.out.println(). What such a perspective fails to take into account is the fact that Pascal and java are semantically quite different and based off of different programming models. Pascal is a structured programming language that divides it’s functions into units, but doesn’t (except in later incarnations such as Object Pascal and Delphi) support Object Oriented programming concepts.

This can be examined by merely looking at, say, the Writeln() function. It has more than one argument, and if the first of those arguments is a file handle, the output is written to that file. The requirements for creating and opening a file are less than easy- for example, a file is opened using the Rewrite() function, after you call Assign() to assign a file name to the file handle. Memorizing otherwise arbitrary function names and how they fit into a number of contexts is hardly easier to learn. Java, being Object Oriented bases it’s run-time library on Objects. the System class has a number of static fields that expose a number of System level objects; the “out” field represents the standard output stream, and is an output stream object, in fact; therefore in order to write to the standard output stream, things can be more verbose. In the case that a routine needs to repeatedly access and write to the output stream, it can easily be cached in a local variable- or really any variable at all. The point is that neither language makes it easier to learn the concepts required to implement algorithms. Java has a relatively basic implementation of Object Orientation (it is missing multiple Inheritance, proper generics, functions as objects, and metaclasses), and Pascal is a good implementation of the structured programming paradigm. Object Oriented concepts build upon structured programming concepts, and since you would have to learn the former first, one could argue that Pascal might be a better choice. However, there is still the crux of syntactic difference; additionally, being exposed to Object oriented syntax early on- even if one doesn’t understand it- could make it easier to absorb the concepts behind those peculiarities later on.

Of course, Pascal isn’t a modern language; it’s modern Equivalent, Delphi, fully supports Object Oriented Programming- even better than Java ever will, in fact- but that doesn’t mean it’s either a good or bad choice for a programming language to initially learn. I stick to my original perspective that it doesn’t really matter what language a person learns, what is far more important is they stop beating around a bush on some decision that they think is important and make it. It’s like debating over what type of cake a person should eat first to properly have the cake experience. Thing is- chocolate, spice, vanilla, fruit, etc. Whatever cake one chooses, it’s all cake and your experience is going to initially be coloured by that first cake. The only way to properly experience what a “cake” is is to have a variety of different cakes- the one you eat first is irrelevant. Same with programming languages; the only way to properly experience all the concepts and idioms involved is to learn a variety of different languages. The first one is going to always be a barrier because you have to become accustomed to the more strict grammars and syntax used with programming languages. Unlike a human language- such as english, where misspellings or grammatical ambiguities might confuse the reader or get you weird looks or a laugh here and there, with programming languages the interpreter or compiler is going to take everything you say literally and if it cannot understand what you are saying it will get very cross. Some compilers will put up with more ridiculous constructs- for example, C++ will happily compile code that makes absolutely no sense even to the most trained C++ programmer (and the result makes an equal amount of sense); others are restrictive, and will verbally assault you if you miss a single letter (Pascal, Delphi) others try to help you by doing stupid shit and inserting syntactic characters where it thinks you might need them (javascript). Anyway, my point is, such details aren’t important; the base concepts are there in all languages, just like all cakes are made with certain base ingredients and the unique flavour is added to the cake batter and supplemented (in most cases) with frosting.

4,084 total views, no views today

 12 Jan 2012 @ 3:11 PM 

In some of my recent posts, I’ve covered the topic of accessing and parsing an INI file for configuration data in a C# Application.

Some may wonder why. After all; the “norm” for C# and .NET applications is to use XML files for configuration information, isn’t it? Well, yes. But to be honest, XML files are a fucking pain in the ass. They aren’t human readable to your average person the same way an INI file is, and getting/setting values is tedious. Primarily, the reason I use INI files is that they are:

  1. Human Readable: Anybody can understand the basic structure of the sections and Name=Value syntax.
  2. Accessible: You don’t need a special editor
  3. Portable: since the entire thing is interpreted using Managed code, it will act the same on any platform (Mono or the MS CLR).

Mostly, I feel that XML, and in many ways other configuration options, are more or less driven by fad. Another option for configuration settings on Windows is the Registry, which is in fact often the recommended method; but this is anything but accessible to the user. Would you rather guide a user to edit a INI file or to fiddle with registry settings?

With that said, INI Files do have their own issues. For example, their data is typically typeless; or, more precisely, the Values are all strings. Whereas using a .NET XML Serializer, for example, you could easily(relatively speaking) serialize and deserialize a special configuration class to and from an XML file and preserve it’s format, with my INI file class there will typically be some work to parse the values.

It was with the idea of turning my string-only INIFile configuration settings into something that can be used for nearly any type that I created the INItemValueExtensions class, which is nothing more than a static class that provides some extension methods for the INIDataItem class. I covered this in my previous post.

The prototypes for the two static functions are:

  1.  
  2. public static T GetValue<T>(this INIDataItem dataitem, T DefaultValue);
  3.  
  4. //and
  5.  
  6. public static void SetValue<T>(this INIDataItem dataitem, T newvalue);
  7.  
  8.  

How would one use these extension methods? Well, here’s an Example:

  1.  
  2. public static void main(String []  args)
  3. {
  4.     INIFile loadini = new INIFile("D:\\testini.ini");
  5.     loadini ["Dates"]  ["TestDate"] .SetValue(DateTime.Now);
  6.     DateTime readvalue = loadini ["Dates"]  ["TestDate"] .GetValue <datetime> ();
  7.    
  8. }
  9.  </datetime>  

Woah, hold the phone! What’s going on here? We’re loading DateTime values directly from the INI File? How does that work?

All the “magic” happens in the getValue generic extension method. The first thing the routine does is check to see if the Type Parameter has a static TryParse() method; if it implements ISerializable and have a TryParse method, than the routine will read the string from the INI file, decode it via Base64, and throw it in a MemoryStream, and then try to deserialize the Object Graph for a Type T using that stream.

If it does implement a TryParse() routine, (like, for example, DateTime) it doesn’t try quite as hard. It takes the string from the INI file and hands it to the Type’s TryParse() routine, and then returns what that gives back. Naturally, the inverse function (setValue) does something somewhat opposite; it checks the Base64 logic, and if so it sets the value of the item to the Base64 encoded value of the serialized object. Otherwise, it just uses toString().

This typically works, particularly with DateTime, because usually ToString() is the inverse of TryParse(). In the case of DateTime, this has a few edge cases with regards to locale, but usually it works quite well. And more importantly, the introduction of allowing any object that implements ISerializable to simply be thrown as an INI value via a Base64 encoded string is useful too, although with large objects it’s probably not a good idea for obvious reasons.

But… I still want to access other settings!

Of Course, an INIFile is only one of any number of ways to store/retrieve configuration settings. And while they don’t typically lend themselves to the same syntax provided by the INIFile class, it would be useful to have some sort of common denominator that can handle it all. That was the original intent of the relatively unassuming ISettingsStorage interface:

  1.  
  2.    public interface ISettingsStorage
  3.     {
  4.         void Save();
  5.         void Load();
  6.         void AddValue(String Category, String ValueName, String Value);
  7.         String GetValue(String Category, String ValueName);
  8.     }
  9.  

This uses a concept known as a “category” which is pretty much the same idea as an INI File section. What makes it different is that, for implementors that use other storage mechanisms, it could have additional meaning; for example, a fictitious XML implementation of ISettingsStorage could use the “Category” string as an XPath to an element; and the Value could be stored/retrieved as a Attribute. a Registry implementation might use it as a Registry path, and so on.

The problem is, even though the INIFile class implements this interface, it’s too basic, and doesn’t provide nearly the syntactic cleanliness that just using the INIFile does. Stemming from that, and because I wanted to try to get a way to store settings directly in a DB, I introduced two events to the INIFile class; one that fires when a Value is retrieved, and one when a value is saved. This way, the event could be hooked and the value saved elsewhere, If desired. Now, to be fair, this is mostly a shortcoming of my interface definition; as you can see above, there is no way to, for example, inspect category or Value names. I toyed with the idea of adding a “psuedo” category/value combination that would return a delimited string of category names, but that felt extremely silly. The creation of a generic interface- or abstract class- that provides all the conveniences I currently enjoy using my INIFile class but allowing me to also use XML, Registry, or nearly any other persistent storage for settings will be a long term goal. For now, I’m content with accessing INI files and having a unclean event to hack in my own behaviour.

My first test of the above feature- whereby it allows values to be TryParse’d and ToString’d back and forth from a given type on the fly- was the creation of a FormPositionSaver class.

The proper way to save and restore a window’s position on Windows is using the GetWindowPlacement() and SetWindowPlacement() API Functions. These use a structure, named, quite aptly, “WINDOWPLACEMENT” to retrieve and set the window position and various attributes. Therefore, our first task is to create the proper P/Invoke’s for these functions:

  1.  
  2.   [DllImport("user32.dll")]
  3.         private static extern int OffsetRect(ref RECT lpRect, int x, int y);
  4.  
  5.  [DllImport("user32.dll")]
  6.         private static extern int GetWindowPlacement(IntPtr hwnd, ref WINDOWPLACEMENT lpwndpl);
  7.  
  8.  [DllImport("user32.dll")]
  9.         private static extern int SetWindowPlacement(IntPtr hwnd, ref WINDOWPLACEMENT lpwndpl);
  10.  

I also include OffsetRect(), but I’ll get to that in a bit. Now the “big one” is the definition of the WINDOWPLACEMENT structure and it’s various aggregate structures. Why? well, in the interest of leveraging the INIFile’s static extensions, Why not define a static TryParse() and a toString() method on the structure that can set and retrieve the member values:

  1.  
  2.  
  3.          [StructLayout(LayoutKind.Sequential)]
  4.         private struct POINTAPI
  5.         {
  6.             internal int x;
  7.             internal int y;
  8.  
  9.  
  10.             public POINTAPI(int px, int py)
  11.             {
  12.                 x = px;
  13.                 y = py;
  14.             }
  15.  
  16.             public static void TryParse(String parseit, out POINTAPI result)
  17.             {
  18.                 //format: (X,Y)
  19.                 //strip out parens.
  20.                 String []  parsed = parseit.Replace("(", "").Replace(")", "").Split(new char []  {‘,’});
  21.                 int kx = int.Parse(parsed [0] );
  22.                 int ky = int.Parse(parsed [1] );
  23.  
  24.  
  25.                 result = new POINTAPI(kx, ky);
  26.             }
  27.  
  28.             public override string ToString()
  29.             {
  30.                 return "(" + x + "," + y + ")";
  31.             }
  32.         }
  33.  
  34.          [StructLayout(LayoutKind.Sequential)]
  35.         private struct RECT
  36.         {
  37.             internal int Left;
  38.             internal int Top;
  39.             internal int Right;
  40.             internal int Bottom;
  41.  
  42.             public override string ToString()
  43.             {
  44.                 return "{" + new POINTAPI(Left, Top).ToString() + "-" + new POINTAPI(Right, Bottom).ToString() + "}";
  45.             }
  46.  
  47.             public RECT(int pLeft, int pTop, int pRight, int pBottom)
  48.             {
  49.                 Left = pLeft;
  50.                 Top = pTop;
  51.                 Right = pRight;
  52.                 Bottom = pBottom;
  53.             }
  54.  
  55.             public static void TryParse(String parsestr, out RECT result)
  56.             {
  57.                 //strip out braces…
  58.                 parsestr = parsestr.Replace("{", "").Replace("}", "");
  59.                 //split at ")-("…
  60.                 String []  Pointstrings = parsestr.Split(new string []  {")-("}, StringSplitOptions.RemoveEmptyEntries);
  61.                 POINTAPI firstpoint, secondpoint;
  62.                 //parse the resulting values. re-add the parens that were removed by the split.
  63.                 POINTAPI.TryParse(Pointstrings [0]  + ")", out firstpoint);
  64.                 POINTAPI.TryParse("(" + Pointstrings [1] , out secondpoint);
  65.  
  66.  
  67.                 result = new RECT(firstpoint.y, firstpoint.y, secondpoint.x, secondpoint.y);
  68.             }
  69.         }
  70.  
  71.  
  72.   [StructLayout(LayoutKind.Sequential)]
  73.         private struct WINDOWPLACEMENT
  74.         {
  75.             internal int Length;
  76.             internal int flags;
  77.             internal int showCmd;
  78.             internal POINTAPI ptMinPosition;
  79.             internal POINTAPI ptMaxPosition;
  80.             internal RECT rcNormalPosition;
  81.  
  82.             public override string ToString()
  83.             {
  84.                 return String.Join(",", new string []
  85.                                             {
  86.                                                 flags.ToString(), showCmd.ToString(),
  87.                                                 ptMinPosition.x.ToString(), ptMinPosition.y.ToString(),
  88.                                                 ptMaxPosition.x.ToString(), ptMaxPosition.y.ToString(),
  89.                                                 rcNormalPosition.Left.ToString(), rcNormalPosition.Top.ToString(),
  90.                                                 rcNormalPosition.Right.ToString(), rcNormalPosition.Bottom.ToString()
  91.                                             });
  92.             }
  93.  
  94.             //parsed a string into a WINDOWPLACEMENT structure.
  95.             public static bool TryParse(String parseme, out WINDOWPLACEMENT result)
  96.             {
  97.                 try
  98.                 {
  99.                     String []  splitvalues = parseme.Split(‘,’);
  100.                     int []  parsedvalues = new int [splitvalues.Length] ;
  101.  
  102.  
  103.                     for (int i = 0; i < parsedvalues.Length; i++)
  104.                     {
  105.                         int.TryParse(splitvalues [i] , out parsedvalues [i] );
  106.                     }
  107.  
  108.                     result = new WINDOWPLACEMENT
  109.                                  {
  110.                                      flags = parsedvalues [0] ,
  111.                                      showCmd = parsedvalues [1] ,
  112.                                      ptMinPosition = new POINTAPI(parsedvalues [2] , parsedvalues [3] ),
  113.                                      ptMaxPosition = new POINTAPI(parsedvalues [4] , parsedvalues [5] ),
  114.                                      rcNormalPosition =
  115.                                          new RECT(parsedvalues [6] , parsedvalues [7] , parsedvalues [8] , parsedvalues [9] )
  116.                                  };
  117.  
  118.                     return true;
  119.                 }
  120.                 catch
  121.                 {
  122.                     result = new WINDOWPLACEMENT();
  123.                     return false;
  124.                 }
  125.             }
  126.         }
  127.  
  128.  

WHEW! that’s quite a bit of code for a structure definition, but we’ll make up for it with the brevity of the actual FormPositionSaver class itself. First, my design goal with this class was to make it basically do all the heavy lifting; it hooks both the Load and Unload event, and saves to and from a given INIFile Object in those events. Since the application I was working on at the time didn’t actually get a Valid INI object until during it’s main form’s Load event, and since there is no way to say “Invoke this event first no matter what” I also added a way for it to be told that hooking the load event would be pointless since it already occured, at which point it will not hook the event and instead set the form position immediately. Values are stored

  1.  
  2. public class FormPositionSaver
  3. {
  4.  
  5.   private Form FormObject = null;
  6.         private INIFile Configuration = null;
  7.         private static readonly String usesectionName = "WindowPositions";
  8.  
  9.  
  10.         ///  <summary>
  11.         /// Create the FormPositionSaver
  12.         ///  </summary>
  13.         ///  <param name="FormObj"> Form to deal with </param>
  14.         ///  <param name="configfile"> INIFile to load and save </param>
  15.         ///  <param name="alreadyloaded"> whether the Load event has fired. If true, will try to set the form position immediately. otherwise, it hooks the Load event and waits. </param>
  16.         public FormPositionSaver(Form FormObj, INIFile configfile, bool alreadyloaded)
  17.         {
  18.             Configuration = configfile;
  19.             FormObject = FormObj;
  20.  
  21.             FormObject.FormClosed += new FormClosedEventHandler(FormObject_FormClosed);
  22.  
  23.  
  24.             if (!alreadyloaded)
  25.                 FormObject.Load += new EventHandler(FormObject_Load);
  26.             else
  27.             {
  28.                 FormObject_Load(FormObject, new EventArgs());
  29.             }
  30.         }
  31.  
  32.         //save the placement...
  33.         private void FormObject_FormClosed(object sender, FormClosedEventArgs e)
  34.         {
  35.             //save placement.
  36.             //all the "tough work" is handled above, and by the INIDataItem Extension methods. Here we
  37.             //can simply use SetValue <>  and set the value. Nice and clean.
  38.             WINDOWPLACEMENT grabplacement = new WINDOWPLACEMENT();
  39.             GetWindowPlacement(FormObject.Handle, ref grabplacement);
  40.             Configuration [usesectionName]  [FormObject.Name] .SetValue(grabplacement);
  41.         }
  42.  
  43.         //Load event: load the form placement, if present, from the INI file we were given in our constructor.
  44.         private void FormObject_Load(object sender, EventArgs e)
  45.         {
  46.             WINDOWPLACEMENT currplacement = new WINDOWPLACEMENT();
  47.             GetWindowPlacement(FormObject.Handle, ref currplacement);
  48.                 //default is wherever it is now if there is a parse problem.
  49.  
  50.             WINDOWPLACEMENT getplacement =
  51.                 Configuration [usesectionName]  [FormObject.Name] .GetValue(currplacement);
  52.  
  53.             //check for previous instances, and offset if there are.
  54.             String thisproc = Process.GetCurrentProcess().ProcessName;
  55.             Process []  existing = Process.GetProcessesByName(thisproc);
  56.             if (existing.Length > 1)
  57.             {
  58.                 //more than one, so offset...
  59.                 OffsetRect(ref getplacement.rcNormalPosition, 16*existing.Length, 16*existing.Length);
  60.             }
  61.  
  62.  
  63.             SetWindowPlacement(FormObject.Handle, ref getplacement);
  64.  
  65.             //load placement...
  66.         }
  67.     }
  68.  

Alright, so maybe I lied a bit. It's not super short. Although a lot of it is comments. Some might note that I only sporadically add doc comments, even though I ought to be adding them everywhere. Well, sue me. I just add them when I feel like it. When I'm concentrating on function, I'm not one to give creedence to form.

This is where I explain OffsetRect(). Basically, if your application is run twice, and you load the form position twice, the second form will open over the first one, and the screen will look pretty much the same. So we detect previous instances and offset by an amount to make it's position different from any previous instances as necessary. That's pretty much the only purpose of OffsetRect.

I have packaged the current versions of cINIFile.cs and the new FormPositionSaver.cs in a zip file, it can be downloaded from here .

262 total views, no views today

Posted By: BC_Programming
Last Edit: 12 Jan 2012 @ 03:11 PM

EmailPermalinkComments (0)
Tags
 07 Jan 2012 @ 10:13 PM 

When speaking of browsers, Operating Systems, or various other pieces of technology, people will often speak of “market share”. I’ve always found it somewhat puzzling; the term Market share implies that the various selections are mutually exclusive. The thing is though, that simply isn’t the case

Take Linux “market share” for example. I use windows, as my primary OS, but I also use Linux on my laptop. Where do I fall? Who’s Market share do I increment? I use firefox usually as my browser, but I have Chrome, Opera, and IE installed. Does having them installed count towards market share? And if not, how often do I have to use them before they “count”, and who decides that?
Basically, once people start bleating about market share, they’d lost grip with the facts. There is no “market share” anymore; it’s all about Mind Share.

 

Anyway that’s a quick post from me. In other news I’ve got some additions to my INIFile.cs class (including a fix) that should make a juicy entry,too.

376 total views, no views today

Posted By: BC_Programming
Last Edit: 07 Jan 2012 @ 10:13 PM

EmailPermalinkComments (0)
Tags
 02 Jan 2012 @ 9:19 AM 

While I typically write about either computers, or nonsense crap here, It’s a personal blog and therefore I feel compelled to write about a recent event that I could only describe as emotionally traumatic.

What event? The death of one of our pet cats.

“PAH. It’s just a cat” you say. And, a day or two ago, I would have shared that perspective; after all, a cat is a cat, right? Cats, and other animals, die all the time due to being hit by cars, abuse, and neglect. I would have never expected the death of this cat to effect me as much as it did. After all, it’s just a cat, right? That is what I keep telling myself, everytime I start to feel sobs welling up, I think to myself “What the fuck man, she was just a fucking cat. get a fucking grip” .

I’m no stranger to the loss of pets, either; we had a family Dog that died a year or so  that we’d had since I was in fifth grade. In many ways I grew up with the dog. But when she was getting old and we put her down- I wasn’t sad, or angry, or anything; I was disappointed , but death is inevitable. And she had lived a long happy life. Same for various other pet s who have died from assorted causes. Shit happens, and you deal with it- no sense getting emotional over it, right? Even when family members have died, after the initial “holy shit they’re gone” period, I still have the memories of their life and (assuming we were at all close) various events and memories we had shared. And that is with human beings; somehow I feel that is fundamentally different; They were sentient people, with families and jobs; a pet is just an animal you keep as a companion; logic dictates that a pet dying should be no different than losing your favourite book. But emotion tells us that an animated, living object has more value than an inanimate object (with the possible exception of insects, bugs, and so forth). And up to now, my feelings about losing various pets has reflected that. But this instance has an overriding factor that makes it both more real and stronger.

So that brings about the question- what makes this one different?  There is one, blatant difference between the experience of losing this pet compared to all the others.

I watched her die, and it was anything but peaceful

That changes the entire thing for me. While I can remember her, as a cat, I don’t think I can ever remember her without also remembering the way she died. In those brief few seconds where I watched the life drain from her, as she fought for every last breath, every lasting second of her dwindling life being only the result of a fierce determination to hang on, the memory burned itself  into me, overshadowing at least in part all other memories about her, so that when I think of her, the first thing that pops into my head is her death. With my other pets, I wasn’t there for their death’s so my memories are typically about their life; not their death. You know, you remember the various fiobles that set them apart from each other and other pets. Thinking about it now, I can’t remember any of those when I think of her. All I remember is the 10 second period where I was half awake, hearing the struggling sounds that in my idiotic naivety perceived to be her playing; the 5 seconds after being fully awakened and suddenly growing concerned at the violence of her activity. Then the smell, which told me something was critically wrong. Grabbing a nearby flashlight and peering underneath the bed. And not within 10 seconds of that, watching her last half dozen breaths, as she stared at me, with an expression that essentially asked me if she could give up yet, which I of course responded with a look of perplexity as I let the situation sink in. watching one last violent thrash as her last breaths were acquiesced only through a dogged refusal to accept the inevitable. And then, she was still.

I will never forget those few seconds where I strained to see her chest moving to indicate she was breathing, certain that I simply wasn’t looking hard enough, She was still alive, she wouldn’t die , would she? Certainly there is a logical explanation for her behaviour. But there was nothing. Her body was still.

I will never forget my puzzled utterance of “Squeak?”, which came out more as an exclamation and affirmation that what I was seeing was in fact being seen with my own two eyes and was not in fact some sort of backwards nightmare.

I will never forget my frantic attempt to move the furniture in such a way to get to her, or my cursing of the nearby chair and desk for having the audacity to obstruct me from easily performing that task.

I will never forget having my hope that she was just breathing lightly dashed, as I moved the bed and exposed her head, and had two unblinking, and clearly lifeless eyes staring back at me, as her tongue hung out in what would in other circumstances be considered a comical fashion.

You know how people talk about “seeing the life in their eyes”? I always thought that was a phrase. I now know it’s not.

 

398 total views, no views today

Posted By: BC_Programming
Last Edit: 02 Jan 2012 @ 09:21 AM

EmailPermalinkComments (2)
Tags
Tags: , , , ,
Categories: Personal
 01 Jan 2012 @ 5:20 PM 

HAHA! How’s that for a clever title?

Oh… well… ahem… nevermind.

As a avid user of my own INIFile class, which I first write about- at least it’s C# implementation- in my parsing INI files posting , I am always looking for ways to improve it’s usage make it more “accessible”.

Recently, I have been tasked (by way of my new title of “freelance consultant”) with creating several LOB (Line of Business) Type applications. Applications, naturally, have a tendency to lend their implementations to the creation and reading of settings. Being something of a fan of the simplicity of INI Files, I chose to use my INIFile class in the application. It works well, however, I have noticed that I have a lot of duplicate code. More specifically, I typically have to implement a “wrapper” class, which manages configuration information and reads/writes values to and from the INIFile as its own properties are accessed. For example:

  1. public bool PopulateUserOrderDropdown
  2. {
  3.    get {
  4.     bool tparse;
  5.     if(bool.TryParse(OurINI ["Admin.Settings"]  ["PopulateUserOrderDropDown","false"] .Value,out tparse)
  6.         return tparse;
  7.     return false;
  8.    }
  9.    set { OurINI ["Admin.Settings"]  ["PopulateUserOrderDropDown"] .Value;}
  10. }

Nothing too dreadful, but imagine having nearly the exact same thing repeated a number of times! The code is repeated and as Larry Wall says, one of the traits of a good programmer is sloth. I don’t like having to write this same code over and over again! The INIFile is supposed to make it easy!

The trouble here stems from the fact that the INIFile values are only strings; and typically, many settings are represented in the application itself as integers and booleans, dates, and so forth. My first attempt to mitigate the clutter was a static method, which I called xParse:

  1. public static class boolEx
  2. {
  3.     public static bool xParse(String Value, bool Default)
  4.     {
  5.         bool parseresult;
  6.         if(bool.TryParse(Value,out parseresult))
  7.             return parseresult;
  8.         else
  9.             return Default;
  10.  
  11.     }
  12. }

relatively straightforward- basically it’s a shell of what I had repeated over and over again. This mitigated the issue somewhat, so my properties in the wrapper looked like this:

  1. public bool PopulateUserOrderDropdown
  2. {
  3.    get { return boolEx.xParse(OurINI ["Admin.Settings"]  ["PopulateUserOrderDropDown", "false"] .Value); }
  4.    set { OurINI ["Admin.Settings"]  ["PopulateUserOrderDropDown"] .Value;}
  5. }

much more managable, but still, could we not make this more concise? My first thought, was that perhaps I could eliminate the necessity of having the wrapper at all; I recalled two interfaces from my old COM programming days, specifically, IDispatch and IDispatchEx. Surely, I could do something similar?

Unfortunately, the interfaces are for COM, and C# doesn’t have dynamics until Version 4.

So, I fired up Visual Studio 2010 express to see if I couldn’t add the dynamic language constructs to the INIFile class; additionally, since I still need to work with .NET 3.5, I’ll add the new code as a conditional compilation.

The first step was deciding exactly what I wanted to happen. Imagine code like this:

  1. INIFile useINI = new INIFile("settings.ini");
  2. String ConnectionString = (String)useINI.General.ConnectionString;

The holy grail of the INIFile simplicity! Naturally, the .NET framework does provide the facility with which to add this functionality, as part of the System.Dynamic namespace.

The first step was deciding on the method by which to conditional compile. Since projects copy the source of a file to your project folder when you add them, it seemed reasonable to simply add it as a #define right inside the INIFile class itself.

 #define CS4 

And now, I just need to enclose all my new happy stuff in a conditional directive, and I’ll get the best of both worlds- C# 4.0 consumers who keep the #define will be able to use the suave new feature, and older consumers will still be able to work without ripping apart the classes. The code to add this was surprisingly simple; as it stands now the longest method (An implementation of TryDeleteMember, which is never called from C#/VB.NET consumers, so is excessive for my usage). First, obviously we enclose the import statement in the conditional compile; the class headers are conditionally compiled as well, only deriving from DynamicObject with CS4 set.

The core of the new functionality is in the overrides to the Dynamic Object’s TryGetMember.

For the INISection:

  1. public override bool TryGetMember(GetMemberBinder binder,out object result)
  2. {
  3.     result = this [binder.Name] ;
  4.     return true;
  5. }

And for the INIFile…

  1. public override bool TryGetMember(GetMemberBinder binder,out object result)
  2. {
  3.     result = this [binder.Name] ;
  4.     return true;
  5. }

Exactly the same, in fact. This works because of the indexer I added; the indexer will add the item if it doesn’t exist and return the new value, so even if the member name doesn’t exist, the INIFile will simply have that section added.

That’s for the retrieval of erements; to allow the assignment to them in the same fashion, we need to override TrySetMember(). In my case, this was a bit more involved, for flexibility purposes.

For example, code like INIFile.MainSection=”hello” should work, and change the name of the section. And why allow things like assignments from a Dictionary<String, String>, or maybe even a list (assigning a numbered id to set values)? And of course allow setting the Value directly, which will likely use the indexer much as I did for the TryGet… Implementations.

  1.         public override bool TrySetMember(SetMemberBinder binder, object value)
  2.         {
  3.  
  4.             //if it is a dataitem, set it directly.
  5.             if (value is INIDataItem)
  6.             {
  7.                 this [binder.Name]  = (INIDataItem)value;
  8.                 return true;
  9.             }
  10.             else if (value is Tuple<, Object>)
  11.             {
  12.                 Tuple<, Object> theTuple = (Tuple<, Object>)value;
  13.                 INIDataItem getitem = this [binder.Name] ;
  14.                 getitem.Name = theTuple.Item1;
  15.                 getitem.Value = theTuple.Item2.ToString();
  16.                 return true;
  17.  
  18.             }
  19.             else if (value is Tuple<, String>)
  20.             {
  21.                 Tuple<, Object> theTuple = (Tuple<, Object>)value;
  22.                 INIDataItem getitem = this [binder.Name] ;
  23.                 getitem.Name = theTuple.Item1;
  24.                 getitem.Value = theTuple.Item2.ToString();
  25.                 return true;
  26.             }
  27.  
  28.             else if (value is KeyValuePair<, Object>)
  29.             {
  30.  
  31.                 //Allow a KeyValuePair<,Object> to be passed to set Name and Value.
  32.                 KeyValuePair<, Object> castedval = (KeyValuePair<, Object>)value;
  33.                 INIDataItem getitem = this [binder.Name] ;
  34.                 getitem.Name = castedval.Key;
  35.                 getitem.Value = castedval.Value.ToString();
  36.  
  37.                 return true;
  38.             }
  39.             else if (value is KeyValuePair<, String>)
  40.             {
  41.                 //Allow a KeyValuePair<,String> to be passed to set Name and Value.
  42.                 KeyValuePair<, String> castedval = (KeyValuePair<, String>)value;
  43.                 INIDataItem getitem = this [binder.Name] ;
  44.                 getitem.Name = castedval.Key;
  45.                 getitem.Value = castedval.Value;
  46.  
  47.                 return true;
  48.  
  49.             }
  50.  
  51.             else
  52.             {
  53.                 this [binder.Name] .Value = value.ToString();
  54.                 return true;
  55.             }
  56.         }

setting the Value should be equally flexible; since we can, why not?
for example, why not make the following “legal”?

  1. INIFile.Section.Value="newvalue";
  2. INIFile.Section.Value=DateTime.Now;
  3. INIFile.Section.Value=Tuple.Create("NewName","Chicken");
  4. INIFile.Section.Value=Tuple.Create("NewName",DateTime.Now);

The first example sets the Value to a string, the second sets it to a DateTime that is silently casted to a String (using toString(), and the last two use the new C# 4.0 tuples, to set both the name of the value and the value simultaneously.

A more elegant solution would be to add this code to the Indexer, and merely call the indexer with the name and the value and return true if no exception occurs and false otherwise. However, I’m reluctant to go that route since some of the types are C# 4 types (Tuples).

  1.         public override bool TrySetMember(SetMemberBinder binder, object value)
  2.         {
  3.  
  4.             if (value is String)
  5.             {
  6.                 this [binder.Name] .Name = (String)value;
  7.                 return true;
  8.  
  9.             }
  10.             else if (value is List<INIItem>)
  11.             {
  12.                 INISection getsection = this [binder.Name] ;
  13.                 getsection.INIItems = (List<INIItem>)value;
  14.                 return true;
  15.  
  16.             }
  17.             else
  18.             {
  19.                 return false;
  20.  
  21.             }
  22.  
  23.         }

So Now, I’ve got an INI File implementation that supports Dynamic invocation. Well, that’s great… except that the application I first found it clumsy in is using .NET 3.5, so I can’t use the dynamic features. Back at square one.

In C# 2008/3, we might not be able to leverage the power of dynamics, but we do have generics and Extension methods at our disposal. a feasible alternative could be to add a extension method to the INIDataItem class that has a generic type parameter that it will attempt to convert it’s string Value into. First, using ChangeType, second, it can try to invoke a static TryParse on the given Type to parse the “value” string. And if none of that works, it can return a passed in default. This is still more verbose than the dynamic solution, but it has two distinct advantages- first, it’s type-safe, so you get all the intellisense goodness, and second, it’s still shorter than the alternative.

Here is the code, which can be found in the cINIFile.cs file attached to this posting as well.

  1.     public static class INItemValueExtensions
  2.     {
  3.         //extensions for INIDataItem
  4.  
  5.         //normally, INIDataItem is a Name/Value Pair; More Specifically, because of the way INI files are, they are
  6.         //naturally typeless. However, most configuration options are mapped to a different type by the application.
  7.         //and I’ve found it to be a gigantic pain to have to write the same TryParse() handling code over and over.
  8.         //so I added these handy extensions to the INIDataItem class, which provide some functions for setting.
  9.         //I keep them out of the main code simply because that way it doesn’t clutter it up. It’s already cluttered enough as-is.
  10.  
  11.         /// <summary>
  12.         /// Attempts to use Convert.ChangeType() to change the Value of this INIDataItem to the specified type parameter.
  13.         /// If this fails, it will attempt to call a static "TryParse(String, out T)" method on the generic type parameter.
  14.         /// If THAT fails, it will return the passed in DefaultValue parameter.
  15.         /// </summary>
  16.         /// <typeparam name="T">Parameter Type to retrieve and act on in Static context.</typeparam>
  17.         /// <param name="dataitem">INIDataItem instance whose value is to be parsed to the given type.</param>
  18.         /// <param name="DefaultValue">Default value to return</param>
  19.         /// <returns>Result of the parse/Conversion, or the passed in DefaultValue</returns>
  20.         public static T GetValue<T>(this INIDataItem dataitem, T DefaultValue)
  21.         {
  22.  
  23.             //Generic method, attempts to call a static "TryParse" argument on the given class type, passing in the dataitem’s value.
  24.             try
  25.             {
  26.                 return (T)Convert.ChangeType(dataitem.Value, typeof(T));
  27.             }
  28.             catch (InvalidCastException ece)
  29.             {
  30.                 //attempt to call TryParse. on the static class type.
  31.                 //TryParse(String, out T)
  32.  
  33.                 Type usetype = typeof(T);
  34.                 T result = default(T);
  35.                 Object []  passparams = new object []  { dataitem.Value, result };
  36.                 try
  37.                 {
  38.                     bool tpresult = (bool)usetype.InvokeMember("TryParse", BindingFlags.Static, null, null, passparams);
  39.                     if (tpresult)
  40.                     {
  41.                         //tryparse succeeded!
  42.                         return (T)passparams [1] ; //second index was out parameter…
  43.                     }
  44.                 }
  45.                 catch (Exception xx)
  46.                 {
  47.                     //curses…
  48.                     return DefaultValue;
  49.  
  50.                 }
  51.  
  52.             }
  53.             return DefaultValue;
  54.  
  55.         }
  56.         /// <summary>
  57.         /// Logical inverse of the getValue routine… a bit faster to implement…
  58.         /// </summary>
  59.         /// <typeparam name="T"></typeparam>
  60.         /// <param name="dataitem"></param>
  61.         /// <param name="newvalue"></param>
  62.  
  63.         public static void setValue<T>(this INIDataItem dataitem, T newvalue)
  64.         {
  65.             dataitem.Value = newvalue.ToString();
  66.  
  67.         }
  68.  
  69.         private static void GetTypeDefault<T>(out T result)
  70.         {
  71.             Type tt = typeof(T);
  72.  
  73.             //basic idea: call default, empty constructor using reflection.
  74.             ConstructorInfo defaultconstructor = tt.GetConstructor(new Type []  { });
  75.  
  76.             result = (T)defaultconstructor.Invoke(null);
  77.  
  78.         }
  79.  
  80.     }
  81.  
  82.  
  83.  

And there you have it, a bunch of awesome additions. INI files are often thought of as deprecated, but that’s only the INIFile functions. This class was designed because working with the registry makes it difficult to test properly, and because JSON,YAML, and many other formats are excessively complicated. when you just need a few basic settings, all you need is the clean, simple format of a INI file. And now, with these additions, code for reading from those INI files is clean and simple as well!

The Source- cINIFile.cs

480 total views, no views today

Posted By: BC_Programming
Last Edit: 01 Jan 2012 @ 05:27 PM

EmailPermalinkComments (0)
Tags

 Last 50 Posts
 Back
Change Theme...
  • Users » 858
  • Posts/Pages » 192
  • Comments » 67
Change Theme...
  • VoidVoid « Default
  • LifeLife
  • EarthEarth
  • WindWind
  • WaterWater
  • FireFire
  • LightLight

PP



    No Child Pages.

Windows optimization tips



    No Child Pages.