Add creation and modification timestamps to an Excel worksheet

February 19th, 2009 by exhuma.twn

Please, for the love of $deity do not hit me….. This is going to be a post about excel!

Excel is a horrid solution for data entry, and even worse for data archival. And yet, it’s one of the most commonly used solutions. One of the most useful information in any given data-set is the information about when the information was created and when it was last modified. This is something that any decent developer in charge of a data collection (let’s just call it that for now) will add to each data record.

Alas, a lot of non-it people manage and store their data in excel worksheets. And that is OK with me as long as they pay attention to data archival. In it’s most simple form, data archival can be achieved by storing the data as a CSV file and including the following metadata:

  • Which column represents which value (the name of the variable)
  • The data type (number, text, date, …) of each column
  • If a column is “coded”, please also include the meaning of each code.
    For example a “Yes”, “No”, “Maybe” column might be stored as “1”, “2” and “3”. Which means in it’s most basic nature it’s a numeric variable, but the different values have a meaning attached to them. So: Add this list in your metadata description.
  • If any computations or checks are performed on the values, please add them to the metadata document as well!

Even if the timestamp values might seem superflous at first, it will be of great help to anyone tracing errors in the data. Imagine that you would at some point need to fix some values that were entered/modified during a specific time period for whatever reason. Without this most basic bit of information you will be up for a treat. However, if it’s been rigurously implemented since the beginning, you’ll have the problem solved in no time.

Now, each halfway serious database system will offer you this kind of functionality out-of-the-box. But Excel is no database system (I intentionally left out the word “management” as this issue is a bit more general!). So it does not offer you a straight-forward way to solve this. But even if it’s not straight-forward, it’s simple enough for about anyone using Excel do add this bit of information.

Assuming that you use the first two columns (numbered 1 and 2 in excel) of your worksheet to add creation- and modification timestamps simply open up the Visual Basic editor (found in Tools->Macro or somesuch), next, in your project tree (in the top left of the screen) select your workbook (the .xls file), and in it’s sub-tree double-click the Worksheet that should have the timestamps set automatically.

Then copy/paste the following text into the just opened code editor and you’re done. I hope the comments will give some insight as to what happens. Note that in this case I will ignore the first row of the sheet, and obviously, the first two columns. If that does not suit your needs, feel free to change this script to your liking.

'
' Callback which is called when a cell in a workbook changes
' @param Target: The cell that changed it's value
'
Private Sub Worksheet_Change(ByVal Target As Range)
   ' We will ignore any changes in the first row, as it contains header labels
   If Target.Row = 1 Then Exit Sub
   
   ' As we set the values of column 1 and 2 we won't need to capture changes in these either
   If Target.Column = 1 Or Target.Column = 2 Then Exit Sub
   
   ' We will update the timestamp in column 2 *always* (last changed time)
   Cells(Target.Row, 2) = Now
   
   ' We will update the timestamp in column 1 only if it is empty (creation time)
   If IsEmpty(Cells(Target.Row, 1)) Then
     Cells(Target.Row, 1) = Now
   End If
End Sub

Posted in Coding Voodoo | No Comments »

Throwing standards out the window

September 24th, 2008 by exhuma.twn

This really seems to be a trend in software development. Especially on the Web. We have organisations like the W3C that continuously struggle to promote interoperability and standards.While developing I am trying to re-use as much of that knowledge as possible. Afterall, if someone already made the effort to solve a specific problem why should you rethink it again? And actively developing since the late ’90s I can safely say that I’ve seen my fair share of source code.

One thing I have realised is that in the past, developers seemed to care more about clean coding and standards.I have the impression that all this is seriously going down the drain since – let’s name it- the “Broadband Revolution”. Since then about everybody has an Internet connection at home and the number of wannabe web-developers skyrocketed. Now, if you google for JavaScript/HTML/whatever references you do not find one reference, you find hundreds. And about all of them seems to be written by somone who thinks to know better.

Why do these people re-invent the wheel by writing down on their web-space what’s already been written by domain-specialists? Are they trying to show the world just how “good” they really are? Are they looking for recognition on the web that they could not get in real life? Because, frankly, I would not have much respect for the work they do

Back to topic. About standards. Consider the following excerpt:

Note: The latest W3C method to connect an event handler to an event is to use the addEventListener method, similar to Java. However, this is not supported by Internet Explorer, and since Internet Explorer owns 96 percent of the browser market, we can ignore addEventListener.1

It’s statements like these that drive me up the wall. And it’s one of the first links I got back from google when looking into the ins and outs of event handling in modern browsers. I am all for education and educating new (web-)developers about how things should be done. And this simply is not the way! Stating that you should throw out all the standards, simply because the market leader does not support it is just wrong. With this train of thought, the standards will never be adopted properly. Now this is the special case of Web-Browsers and JavaScript support, but this example easily spans over other areas as well.

Having a text like this in the top google hits surely gives newcomers the wrong idea.

I am honestly curious to see how the web evolves in the next few decades. But maybe I’m just too pessimistic and it will all turn out well. Time will tell!

1http://bucarotechelp.com/design/jseasy/96001603.asp?x=52&y=9&page=2

Posted in Babble | No Comments »

Demographics of Open Source projects

September 4th, 2008 by exhuma.twn

One thing I have been asking myself quite often lately: “Why do – even popular – open source projects often have mediocre coding standards?”

My first thought was: Ok, most likely many of the projects were written by non IT-professionals who only code “out of their head” without thinking things through at first. Curious as I am, I googled for the very title of this post. And I fell across an article on Linux Today about a study done by the Boston Consulting Group (Also quoted on slashdot). What I found particularly disturbing was the finding that the most part of the interviewees considered themselves as IT-Professionals. Granted, only interviewing less than 600 developers from only one source (sourceforge), is barely representative, and most likely highly biased as well. But it’s an interesting survey nonetheless.

So, why – in the love of $deity – do so many projects written by allegedly IT-Professionals present themselves with very poor coding style and more often than not very poorly designed database schemata? It’s becoming an increasing nuisance to work with these projects. If you want/need to make changes/extensions to the existing code you often need quite a while to get to grips with the logic behind all that exists.

Interestingly though, the stricter the rules of the used programming language/database the better the code, but the less common it is as well in open source projects. This does not mean though that it’s the fault of the programming language. Not at all. Even with a language as flexible as Perl you still can write very sexy code. But I haven’t seen a single Perl script that fit’s that description (though I haven’t inspected many Perl scripts yet in detail).

I would really like to see a study on the demographics of open source software that focusses it’s goal on coding style/standards rather than on the age group / motivations of coders. And it should also pick a representative sample of developers instead of going the lazy route and only querying sourceforge. This would certainly be an interesting project to do 😉

Posted in Babble | No Comments »

Bogged down in spam

August 22nd, 2008 by exhuma.twn

I just realized that we’ve got plenty of spam comments in our moderation queue. I did my best to clean it up. I appologize if any comments were lost in the process.

At least now We’ve got a nice collection of links to sites where I can buy cheap viagra, find adult friends, and even buy some designer luis vuitton purses! Good stuff….. -__-

Posted in Uncategorized | No Comments »

Python startup (command completion & history)

August 21st, 2008 by exhuma.twn

If you want command completion and a history in your python shell, export the PYTHONSTARTUP env var (export PYTHONSTARTUP=$HOME/.pystartup) in your bashrc and create a file ~/.pystartup with the following contents:

import atexit
import os
import readline
import rlcompleter

historyPath = os.path.expanduser("~/.pyhistory")

def save_history(historyPath=historyPath):
import readline
readline.write_history_file(historyPath)

if os.path.exists(historyPath):
readline.read_history_file(historyPath)

readline.parse_and_bind('tab: complete')

atexit.register(save_history)
del os, atexit, readline, rlcompleter, save_history, historyPath

Posted in Python | No Comments »

Martian Headsets

March 18th, 2008 by exhuma.twn

One link, lot’s of text 😉

http://www.joelonsoftware.com/items/2008/03/17.html

Posted in Babble, Links | 1 Comment »

Simplifying a polygon

February 10th, 2008 by exhuma.twn

As you may know, polygons are sensitive to the ordering in which vertices are put in. What is more, the normals of a polygon face depend on the direction of the face.

This usually is not a problem when the polygon is constructed by a graphics-savvy person. If, however (as in my case), the polygons are edited in a user frontend, and if the target audience for that UI may not be aware of the problem, you might run into trouble.

I strongly believe, that details like this should be hidden from the less technically-inclined people, so they can get thei job done without swearing at the UI. And therefore be more productive. This piece of javascript allows you to “simplify”an array of 2D-Points by sorting it accordingly. The resulting array will construct a simple polygon with always outward-facing normals.

This uses the well-known paradigm of taking a reference point and then “swiping” counter-clockwise over the available points. Depending on the reference point (and the available vertices), the end-results may vary. So it may not really result in what the user expected. Having an undo ready at hand should prove useful. However, this algorithm assumes the most likely case, in which the reference point is set to the centroid of the polygon.

The entry-point function is this algorithm is “simplify_polygon”. Feel free to play around with it. Documentation is sparse, but if you know your trig you should figure it out by yourself. It’s fairly straightforward.

Note: The 4-way branch in the “angle” function could be simplified. It is as it is because my mind was locked in the 4 quadrants when writing it. Didn’t feel like changing it yet 😉

Read the rest of this entry »

Posted in Coding Voodoo | 1 Comment »

Vim script (mapping) to generate python getters and setters

December 31st, 2007 by exhuma.twn

Somethin that I need quite often is to create custom accessors and mutators for class-attributes. For example convert this:

class MyClass(object):
   
   def __init__(self):
      self.has_changes = False
      self.some_attribute = False

into this:

class MyClass(object):
   
   def __init__(self):
      self.__has_changes = False
      self.__some_attribute = False

   def get_some_attribute(self):
      "Accessor: some_attribute"
      return self.__some_attribute

   def set_some_attribute(self, input):
      "Mutator: some_attribute"
      self.__some_attribute = input
      self.__has_changes = True

   some_attribute = property(get_some_attribute, set_some_attribute)

   def get_has_changes(self):
      "Accessor: has_changes"
      return self.__has_changes

   has_changes = property(get_has_changes)

This particular example allows an easy tracking if a class contains changes. Without the need of calling myclass.get_some_attribute() or myclass.set_some_attribute(foo). You can simply do myclass.some_attribute = foo and the has_changes attribut will change accordingly.

If your class has many attributes, writing custom accessors and mutators can be tedious. So here’s a small Vim-mapping that get’s you started. Sure, you may still need to fine-tune some generated code, but the bulk is there.

<font color="#808bed">nmap</font> <font color="#c080d0">&lt;</font><font color="#c080d0">F6</font><font color="#c080d0">&gt;</font> yyP<font color="#c080d0">&lt;</font><font color="#c080d0">home</font><font color="#c080d0">&gt;</font>widef get_<font color="#c080d0">&lt;</font><font color="#c080d0">end</font><font color="#c080d0">&gt;</font>(self):<font color="#c080d0">&lt;</font><font color="#c080d0">esc</font><font color="#c080d0">&gt;&lt;</font><font color="#c080d0">down</font><font color="#c080d0">&gt;&lt;</font><font color="#c080d0">esc</font><font color="#c080d0">&gt;</font>yyP&gt;&gt;I&quot;Accessor: <font color="#c080d0">&lt;</font><font color="#c080d0">end</font><font color="#c080d0">&gt;</font>&quot;<font color="#c080d0">&lt;</font><font color="#c080d0">esc</font><font color="#c080d0">&gt;&lt;</font><font color="#c080d0">down</font><font color="#c080d0">&gt;</font>yyP&gt;&gt;Ireturn self.__<font color="#c080d0">&lt;</font><font color="#c080d0">esc</font><font color="#c080d0">&gt;</font>o<font color="#c080d0">&lt;</font><font color="#c080d0">esc</font><font color="#c080d0">&gt;&lt;</font><font color="#c080d0">down</font><font color="#c080d0">&gt;</font>yyPIdef set_<font color="#c080d0">&lt;</font><font color="#c080d0">end</font><font color="#c080d0">&gt;</font>(self, input):<font color="#c080d0">&lt;</font><font color="#c080d0">esc</font><font color="#c080d0">&gt;&lt;</font><font color="#c080d0">down</font><font color="#c080d0">&gt;</font>yyP&gt;&gt;I&quot;Mutator: <font color="#c080d0">&lt;</font><font color="#c080d0">end</font><font color="#c080d0">&gt;</font>&quot;<font color="#c080d0">&lt;</font><font color="#c080d0">esc</font><font color="#c080d0">&gt;&lt;</font><font color="#c080d0">down</font><font color="#c080d0">&gt;</font>yyP&gt;&gt;Iself.__<font color="#c080d0">&lt;</font><font color="#c080d0">end</font><font color="#c080d0">&gt;</font> = input<font color="#c080d0">&lt;</font><font color="#c080d0">esc</font><font color="#c080d0">&gt;</font>o<font color="#c080d0">&lt;</font><font color="#c080d0">esc</font><font color="#c080d0">&gt;&lt;</font><font color="#c080d0">down</font><font color="#c080d0">&gt;&lt;</font><font color="#c080d0">home</font><font color="#c080d0">&gt;</font>wveyA = property(get_<font color="#c080d0">&lt;</font><font color="#c080d0">esc</font><font color="#c080d0">&gt;</font>pA, set_<font color="#c080d0">&lt;</font><font color="#c080d0">esc</font><font color="#c080d0">&gt;</font>pA)<font color="#c080d0">&lt;</font><font color="#c080d0">esc</font><font color="#c080d0">&gt;</font>o<font color="#c080d0">&lt;</font><font color="#c080d0">esc</font><font color="#c080d0">&gt;</font>

Put this into your vimrc, or (like I do) into the ~/.vim/ftplugin/python.vim file so it get’s only loaded for python files. Then you only need to write the attribute name of the class, put your cursor on that line, be sure to be in normal mode (hit a few time <esc>) 😉 and hit F6

If you want to change the shortcut, simply change the first parameter to this mapping line.

Posted in Python | No Comments »

Schneiderman’s Golden Rules

October 19th, 2007 by exhuma.twn

NEVER forget these simple rules. Every computer application with a user interface will benefit from them.

It’s really worth it. People will love you for it. Trust me 😉

I personally find that using an ordered list is somewhat misleading. Every point should be considered with equal importance. That’s why I will change to “ol” tag to an “ul” tag now 😉

  • Strive for consistency. As we shall see below, it is important for a user interface to be consistent on many levels. For example, screen layouts should be consistent from one screen to another. In an environment using a graphical user interface (GUI), this also implies consistency from one application to another.
  • Enable frequent users to use shortcuts. Frequent users (or, power users) may be turned off by overly tedious procedures. Allow those users a less tedious procedure for accomplishing a given task.
  • Offer informative feedback. Users need to see the consequences of their actions. If a user enters a command but the computer does not show that it is either processing or has processed that command, this can leave the user confused and disoriented.
  • Design dialogues to yield closure. Interacting with a computer is somewhat like a dialogue or conversation. Every task should have a beginning, a middle and an end. It is important for the user to know when a task is at its end. The user needs to have the feeling that a task has reached closure.
  • Offer simple error handling. User errors should be designed into the system. Another way of stating this is that no user action should be considered an error that is beyond the ability of the system to manage. If the user makes a mistake, the user should receive useful, concise and clear information about the nature of the mistake. It should be easy for the user to undo his or her mistake.
  • Permit easy reversal of actions. More generally, users must be permitted to undo what they have done, whether it is in the nature of an error or not.
  • Support internal locus of control. User satisfaction is high when the user feels that he or she is in control and user satisfaction is low when the user feels that the computer is in control. Design interfaces to reinforce the feeling that the user is the focus of control in the human-computer interaction.
  • Reduce short-term memory load. Human short-term memory is remarkably limited. Psychologists often quote Miller’s law to the effect that short-term memory is limited to seven discrete pieces of information. Do everything possible to free the user’s memory burden. For example, instead of asking the user to type in the name of a file which is going to be retrieved, present the user with a list of files currently available.

See page 74-75 Scheiderman: Designing the User Interface, 3rd

Posted in Coding Voodoo | No Comments »

Why vim?

October 18th, 2007 by exhuma.twn
  • Misconception #1: modal editing
  • Misconception #2: it’s not all about regular expressions
  • Misconception #3: you gotta be nuts and/or a genius to use it
  • Misconception #4: hjkl to move around?
  • Misconception #5: since you are thinking 90% of the time, and editing 10%, the productivity gain might be there, but it’s useless anyway
  • Misconception #6: it’s just sticking to a disappearing past
  • Correct-conception #1: steep learning curve

Tickled your interest? Looky there!

Posted in Coding Voodoo | No Comments »

« Previous Entries Next Entries »

Pages

Recent Posts

Categories

Links


Archives

Meta