Benefits of form versioning

Picture a fully developed CRF.  The form layout is pristine, the validation rules are working exactly the way you want them to, and the field data maps directly to your database tables.

What more can you ask for?

Unfortunately, forms hardly ever stay the same throughout the course of a clinical trial or a research study.  Forms frequently need to adapt to new data points that were unforeseen during the protocol definition phase.  So how can we handle this?

We could go ahead and naively make the new changes, but what happens if the change asks for a field to be deleted?  Even if we just hide the field and keep the previous underlying data, how can we display the data that was captured now that the field is missing from the form?

One solution for this is form versioning.  The ability to load alternate versions of a form is a frequently overlooked feature when designing a system to handle CRFs for a clinical trial, forms for a research study, or generally any forms that tend to change.

Form versioning allows us to:

  • Retrieve and display data even if the field is no longer part of the current version of the form.
  • A dropdown list’s items can be added, removed, or changed and we’ll always be able to retrieve exactly what items were present before changes were made.
  • Keep the validation rules (edit checks) specific to a specific version of the form.
  • Tell customers that mid-study changes are a breeze because the form versioning technology keeps mid-study changes isolated from existing data.

Next time you’re designing a system that stores CRFs or basically stores form data, it may pay to integrate form versioning into your system.  It definitely saved me a lot of time.  Although I can’t say mid-study changes are my favorite thing in the world, I can say that form versioning makes mid-study changes a whole lot easier.

To receive updates on new articles, subscribe to CRF Design today!

Similar Posts:

MySQL increasing ID manually

Some times it’s necessary to assign a consecutively increasing ID field to a set of rows. Autoincrement is available, but you would need to leverage an INSERT in order to make use of MySQL’s autoincrement feature. Fortunately, it is possible to do this in place by using a separate counter variable in an UPDATE statement.

The solution given below is largely adapted for MySQL from Phil Haack’s SQL Server recipe. If you’re using MySQL Query Browser, you’ll need to make this a script by clicking File > New Script Tab.


SET @counter = your_starting_index;
UPDATE your_table_name
SET your_id_column_name=(@counter:=@counter+1);

Make sure to change your_starting_index, your_table_name, and your_id_column_name.

To receive updates on new articles, subscribe to CRF Design today!

Similar Posts:

Overload the array square bracket operator in C#

Although operator overloading is possible in C# (just like in C++), overloading the array square bracket operator is by definition not possible.  However, C# provides an alternative called indexers.  This is directly from the Microsoft C# Reference for the [] Operator:

The array indexing operator cannot be overloaded; however, types can define indexers, and properties that take one or more parameters. Indexer parameters are enclosed in square brackets, just like array indexes, but indexer parameters can be declared to be of any type, unlike array indexes, which must be integral.

The syntax for indexers resembles the C# syntax for properties rather than its syntax for operator overloading. Here’s a quick snippet for providing array-like access to a List you’d like to keep hidden within a class:


// overloads the square brackets to provide array-like access.
public T this[int i]
{
    get { return this.List[i]; }
    set { this.List[i] = value; }
}

Worked for me, and hopefully it works just as well for you!

UPDATE: As I do a quick search now, this Stack Overflow post just turned up.

To receive updates on new articles, subscribe to CRF Design today!

Similar Posts:

5 Common Mistakes for Tablet PC Development

Okay, so you’re sold on a Tablet PC, but what should you watch out for when developing a Tablet PC application in healthcare?

Below is a list of common mistakes for developing a Tablet PC application.  All are avoidable early in the project’s life-cycle. Some of these mistakes I own, and others I’ve seen from other project managers and developers. Hopefully, this list helps others avoid these common mistakes.

There are already plenty of re-hashed lists on the Internet describing how to address goal setting, client and stakeholder buy-in, or various software and management anti-patterns. This is not one of those lists.

Mistake 1 - I need to learn another operating system
Mistake 2 - It looks fine on my machine, so it’ll look fine on the tablet
Mistake 3 - It’s just Windows, so I don’t need to worry about fonts
Mistake 4 - It works in notebook mode, I don’t need to worry about slate mode
Mistake 5 - 3-hour battery life is more than enough
Bonus - I’ll think about security when it’s up and running

Mistake 1. I need to learn another operating system. Some programmers (and some clients) still think Tablet PCs use a special mobile operating system with its own set of SDKs and APIs. Currently, the majority of Tablet PCs run Windows XP (with Tablet PC enhancements) or Vista (which has the core Tablet PC functionality built-in). Although development tools specific to the Tablet PC such as Digital Ink and the Text Input Panel are available, no one says you have to use them. Most applications you use on your desktop or notebook will work just as well on a Tablet PC.

Bottomline: No new OS, just some added libraries for Windows.

Mistake 2. It looks fine on my machine, so it’ll look fine on the tablet. Okay, great!  It’s just a vanilla Windows machine with some extra bells and whistles. I can just develop my application on my workstation, and then deploy it when I’m done.

Almost — like any kind of development, it’s important to test in the environment where it will be used. Some times this isn’t possible, but hey, you’re developing for a tablet, it only makes sense to at least test it on a tablet. Microsoft does offer some emulation software (with limitations) that tries to duplicate a tablet environment, but nothing can replace testing it directly on your target system.

Probably the biggest time-saver is having a development environment that mirrors the screen resolution of the Tablet PC. If the monitor is the right size and it can rotate, you’ve got a winner! Tablet PCs often have an extra wide or extra tall screen, and they can change between notebook and slate mode. With the right monitor, you won’t need to deploy to a tablet every time you tweak something just to see if your application looks okay.

Bottomline: Make sure to test on your target system, and shell out the money for the right monitor.  The development time you save will be well worth the cost.

Mistake 3. It’s just Windows, so I don’t need to worry about fonts. This one is a killer.  Font size is probably the last thing I would worry about. Unfortunately, I’ve seen some good applications completely tank in front of the customers just because of font size.

Windows should keep the font size consistent whether it’s on a desktop, notebook, or Tablet PC.  And… it does. Tablet PCs, just like desktops and notebooks, come in a variety of resolutions. Imagine squeezing everything on your monitor into an 10-12″ screen at the same resolution. Changing the resolution fixes the situation in a way, but then those magnified resolutions don’t take advantage of the added width or height of a tablet PC. And the accessibility settings?  …the “Extra Large Fonts?” Another no-go.  Because you’re starting out with a smaller screen, the font size difference isn’t substantial enough to make much of an improvement to the user.  Try it, and you’ll see.

It really doesn’t seem like much of an issue, except when you’re working with an older user.  If they can’t read the text, forget all the Ink widgets and latest technology you implemented, because your application is now considered completely useless by the people who should be using it. Make sure to use larger fonts (18pt worked for me!) in your application, or better yet, allow the user to adjust the fonts within your application.

Bottomline: If they can’t read the application text, don’t let the door hit you on the way out.  Use larger fonts or let the user decide what font to use.

Mistake 4. It works in notebook mode, I don’t need to worry about slate mode. Most developers work on monitors that are wider than it is tall. So naturally, you’ll find yourself developing your Tablet PC applications in that environment. You’ll also find that you tend to work with the tablet in the notebook mode as well.

Not much harm in that, until you switch to slate mode. If your application GUI objects took advantage of the extra screen width, those objects will now either be off the screen or squeezed into about half the space. A number of techniques exist to leverage the added width or the added height, but I’ll leave that for another post.

Bottomline: Make sure your layout works in both notebook mode and slate mode.

Mistake 5. 3-hour battery life is more than enough. The battery is not so much a software development issue. However, if you’re taking ownership of developing a Tablet PC application, understanding whether the customer’s needs are met by the selected hardware is at the the top of your list. If the hardware doesn’t fit the customer’s needs, your application will never get used by anyone but you.

Learning how the customer uses the tablet is essential.  Will they be running around all day in the wards?  Are they traveling from site to site?  Will they require Wi-Fi (battery drainer!)? If any of these are true, you’ll need to get extra battery packs.  After getting the extra packs, either detail an SOP for swapping out the battery after hibernating the tablet, or better yet, start the project with tablets that have hot swappable batteries!

Bottomline: Understand in detail how the tablets will be used with regard to battery life.  If 3 hours is not enough, make sure the users understand how to swap in a fresh battery.

Bonus: I’ll think about security when it’s up and running. I know, I know… I said 5, but I thought I’d throw in this one, since it’s a show-stopper. A tablet, just like a notebook, is meant to be portable. The price we pay for this convenience is it’s also a very good target for theft.

If a tablet containing patient data is lost or stolen, the law requires those patients be notified. The healthcare professionals responsible for the loss will be in a world of hurt and paperwork, but it doesn’t stop there. Your application will also come under scrutiny. How do you secure the protected health information? Is the patient data de-identified?  How?  What data was lost? Who else has seen that data? And that’s just for starters! As a first step, I recommend full disk encryption.  TrueCrypt has worked well for me, and here’s list of full disk encryption providers.

Bottomline: Security, especially for tablets in a healthcare environment, cannot be an afterthought, it must be integrated into the design process.

So, there’s my 5.  Hopefully it’ll save you guys the need to find them out on your own.  Happy tablet hacking!

To receive updates on new articles, subscribe to CRF Design today!

Similar Posts:

Why does an abstract class need to implement interface methods?

In a comment for a previous post (Top 10 differences between Java and C#), John P. Wood wrote:

As a (primarily) Java developer, I’ve also noticed that C# handles abstract classes that implement interfaces differently. In Java, an abstract class can implement an interface, and not provide implementations of all of the interface’s methods.  It is the responsibility of the first concrete class that has that abstract class as an ancestor to implement all of the methods in the interface.

C# on the other hand seems to require that the abstract class provide implementations for all of the methods on the interface. Even if that implementation is just a method signature.

Like these 3 posts (1 (bottom), 2, 3), I am struggling with why the Microsoft Team chose to do this.  Why ask the developer to write a little stub for the interface method, when the abstract class has no intention of implementing it at all?

I believe it’s a natural artifact of virtual and non-virtual methods in C# (gotcha #2).  In Java, methods are virtual by default (as far as I’m aware, Java doesn’t support non-virtual methods).  However, C# (being derived from C++) does support non-virtual methods.  When an abstract class implements an interface in C#, you are given the chance to describe the interface methods as abstract, virtual or non-virtual.  Here’s exactly what each options means:

  1. abstract - No attempt at an implementation is made in the abstract class.  It’s up to the first concrete class to provide an implementation.  As a side note, defining a method as abstract implicitly defines it as virtual.  If this weren’t the case, you wouldn’t be able to override it in the child class which defeats the purpose of an abstract method.
  2. virtual - An attempt was made in the abstract class to implement this method, but the child class has the option of overriding it and providing its own implementation.
  3. non-virtual - Again, an attempt was made at an implementation in the abstract class.  However, the child class cannot override this method.  If a child class defines a method with the same name, the method will not be associated with the interface implemented in the abstract class.  The method associated with the interface is the non-virtual method defined by the abstract class.

Java can do options 1 and 2, but it lacks option 3.  Java could define the method as final to prevent it from being overriden, but this is slightly different than non-virtual.  The final keyword is more along the lines of seal in C#.  By allowing an option 3, C# provides finer control over how interfaces are inherited.  If C# went the route of Java and permitted abstract classes to put off interface method definitions, these methods would need to be virtual by default.  However, this would be inconsistent with C# methods being non-virtual by default.

In a nutshell, the C# developer is forced in the abstract class to decide exactly which of the three options to assign to the interface method.  Anyway, that’s my best guess…

To receive updates on new articles, subscribe to CRF Design today!

Similar Posts:

Portrait vs Landscape, CRF Design for a Tablet PC

HP Tablet PC (convertible)

HP Tablet PC (convertible)

How do you systematically make use of the varied Tablet PC screen resolution dimensions using C#?

Designing a CRF specifically for a Tablet PC can be a challenging experience, but it can also be one of the most rewarding.

The Tablet PC is very similar to a traditional desktop computer or a laptop.  As I write this entry, most Tablet PCs are running some variant of Windows.  Whether it’s Windows XP Tablet PC Edition or Vista (which has built-in support for Tablet PC specific functionality), you’re basically dealing with a Windows machine and you can pretty much treat it as such…  almost.

Maybe it’s not so much the variety.  One of my biggest obstacles was that the dimensions change.  They don’t change just once in a while (like when the resolution changes when you connect your laptop to a TV), they can change many times during a single session!

For example, convertible Tablet PCs (like the one in the image above) provide the ability to change from portrait to landscape and back again all in seconds.  In addition, most Tablet PCs come in screen dimensions that are either wider or taller depending on whether it’s in slate mode or the more traditional notebook mode.  Taking advantage of a taller or wider screen is going to be the topic of a future post, but let’s say you have a layout for making use of the added height or width, how do you know when to use which?

The first step is determining whether the screen dimensions are in portrait (slate) mode or landscape (notebook) mode.  Here are two straight-forward methods for determining which mode the Tablet PC is using:


public bool IsPortrait()
{
    return Screen.PrimaryScreen.Bounds.Height >
        Screen.PrimaryScreen.Bounds.Width;
}

public bool IsLandscape()
{
    return !this.IsPortrait();
}

We can setup a thread that calls one of these methods at specified intervals (polling solution), or we can leverage the .NET event architecture so that our application responds to dimension changes. Leveraging the event architecture is intuitively more efficient and more reliable, so add this to your Form_Load() method:


Microsoft.Win32.SystemEvents.DisplaySettingsChanged +=
    new EventHandler(SystemEvents_DisplaySettingsChanged);

Now, define the event handler:


void SystemEvents_DisplaySettingsChanged(
    object sender, EventArgs e)
{
        if (ScreenProperties.IsPortrait())
            // do portrait handling
        else
            // do landscape handling
}

And just like that, your form is now responding to screen resolution dimension changes!

To receive updates on new articles, subscribe to CRF Design today!

Similar Posts:

Quick and dirty “dirty checking” for Windows form, C#

While designing a CRF, little short-cuts can save you lots and lots of time.  This time-saver is straight-forward code-wise and should fit right into your C# code without much modification.

During CRF design time, I often have CRFs that have dozens and dozens of input controls (radio buttons, dropdowns, listboxes, textboxes…).  I’d like to add OnChange handlers to all of these input controls so that I know when a change has been made. Basically, what it comes down to is I want to know when the form is dirty, but I don’t want to add all the handlers by hand.  Fortunately, I didn’t have to and neither do you!

The code below is a recursive function which traverses the Control tree.  Whenever it locates a control that can be classified as an input control, it attaches an event handler.

void AddOnChangeHandlerToInputControls(Control ctrl)
{
    foreach (Control subctrl in ctrl.Controls)
    {
        if (subctrl is TextBox)
            ((TextBox)subctrl).TextChanged +=
            new EventHandler(InputControls_OnChange);
        else if(subctrl is CheckBox)
            ((CheckBox)subctrl).CheckedChanged +=
            new EventHandler(InputControls_OnChange);
        else if(subctrl is RadioButton)
            ((RadioButton)subctrl).CheckedChanged +=
            new EventHandler(InputControls_OnChange);
        else if(subctrl is ListBox)
            ((ListBox)subctrl).SelectedIndexChanged +=
            new EventHandler(InputControls_OnChange);
        else if(subctrl is ComboBox)
            ((ComboBox)subctrl).SelectedIndexChanged +=
            new EventHandler(InputControls_OnChange);
        else
        {
            if (subctrl.Controls.Count > 0)
                this.AddOnChangeHandlerToInputControls(subctrl);
        }
    }
}

Keep in mind the recursion is necessary, because the Controls property field only lists a control’s immediate children. Those immediate children may have children of their own. That’s right… exactly like a family tree! The use of recursion creates an elegant way to traverse the control’s control tree.

I’ve only picked up on the simplest input controls. It should be straight-forward to extend this for other controls like a DateTimePicker or a CheckedListBox (although the CheckedListBox is a little tricky because it uses a different type of event handler).

void InputControls_OnChange(object sender, ItemCheckEventArgs e)
{
    // Do something to indicate the form is dirty like:
    // this.formIsDirty = true;
}

All the event handler does is set a flag which indicates the form is dirty.  How you process the dirty flag is up to you, and there you have it! Hopefully, you’ve saved a few hours of manually adding event handlers!

To receive updates on new articles, subscribe to CRF Design today!

Similar Posts:

Top 10 differences between Java and C#

My latest transition from Java to C# left me scratching my head and scrambling to find the differences.  Don’t get me wrong — they are very similar, but some key syntax and philosophical differences set these two languages apart.  Below are my top 10 differences that I wish someone told me before I pulled out yet more hair.

Gotcha #10 - Give me my standard output!
Gotcha #9 - Namespaces == Freedom
Gotcha #8 - What happened to super?
Gotcha #7 - Chaining constructors to a base constructor
Gotcha #6 - Dagnabit, how do I inherit?
Gotcha #5 - Why don’t constants remain constant?
Gotcha #4 - Where is ArrayList, Vector or Hashtable?
Gotcha #3 - Of Accessors and Mutators (Getters and Setters)
Gotcha #2 - I can’t override!?
And the #1 gotcha…

Gotcha #10 - Give me my standard output!

This may not seem like a big deal, but when I’m first getting my head in a language, I want to be able to debug.  With everything so new and shiny, I don’t want to hear about the debugger yet, I don’t care about the fancy message boxes, just tell me how to get something on standard output!

In C#, the code looks like this:

Console.WriteLine("your string here");

Gotcha #9 - Namespaces ==  Freedom

In Java, the package hierarchical structure mirrored the directory hierarchical structure.  This made sense to a degree, but then why didn’t Sun just auto-derive the package structure?  Anyway, Microsoft has freed us from this constraint.  The C# package structure is defined using namespaces (just like Java), but the namespaces do NOT have to reflect the directory structure.

Gotcha #8 - What happened to super?

Slight renaming of keywords drives me bonkers!  Substitute Java’s super keyword with base.

Gotcha #7 - Chaining constructors to a base constructor

In Java, I often created a set of constructors with differing parameters that all reference a common all-powerful constructor.  In other words, I created a set of overloaded constructors that basically just called a constructor that did the bulk of the work.  This is called constructor chaining and normally leads to easier to maintain code.  In Java, the this(…) statement is used to call the constructor.  In C#, this is done right up in the method signature.

public MyConstructor(int i) : this(i, -1)
{
    ...
}

public MyConstructor(int i, int j)
{
    ...
}

Gotcha #6 - Dagnabit, how do I inherit?

In Java, the keyword extends is used to inherit from a parent class, and the keyword implements is used to inherit an interface.  In C#, the distinction does not exist and it’s all done in the method signature.

public class MyClass : MyParentClass
{
    ...
}

Gotcha #5 - Why don’t constants remain constant?

Well of course they do!  Just not among different languages.  In Java, I normally defined global constants using public static final.  In C#, the static keyword does exist (final does not), but you can define constants like this:

public const MyConstant = 101;

When the constant needs to be initialized at run-time (for example in a constructor), use the readonly keyword instead of const.

Gotcha #4 - Where is ArrayList, Vector or Hashtable?

In Java, these guys were my staples.  Pre-built dynamic arrays and look-up tables decrease development time and makes my life a whole lot easier, but where are they in C#? C# has an ArrayList, but it doesn’t make use of generics. Instead, I like to use:

System.Collections.Generic.List<>

Unfortunately, List<> is not thread-safe (C#’s ArrayList and Java’s Vector are thread-safe). C# also has a Hashtable; the generic version is:

System.Collections.Generic.Dictionary<>

Gotcha #3 - Of Accessors and Mutators (Getters and Setters)

As long as methods exist in classes, accessors and mutators will exist.  However, C# largely replaces them with class properties. Instead of the traditional getSomeInteger() and setSomeInteger(), we use properties!

public class SomeClass
{
    int someInteger = 42;

    public int SomeInteger
    {
        get { return this.someInteger; }
        set { this.someInteger = value; }
    }

    public void Main(string[] args)
    {
        SomeClass c = new SomeClass();
        Console.WriteLine(c.SomeInteger);
        c.SomeInteger = 420;
    }
}

this.someInteger is a class variable, and value is the new integer.

Gotcha #2 - I can’t override!?

At this point, we’ve transcended the syntax differences and we’ve entered into more philosophical choices that the Microsoft team made. In Java, all methods are by default virtual and you can override them. In C#, all methods are non-virtual. To override a method in the parent class, make sure the method of the parent class is defined as virtual using the virtual keyword.

class MyParentClass
{
    public virtual void MyMethod() { ... }
}

In the child class, the method must use the override keyword.

class MyChildClass : MyParentClass
{
    public override void MyMethod() { ... }
}

And the #1 gotcha…

I remember when I first learned Java, and everyone was saying how Java made everything an object. How Java forced you to make classes for everything. This turns out to be partially true. It is necessary to make classes.  However, primitives are not objects. In C#, even what were considered primitives in Java are objects in C#.  Absolutely everything descends from System.Object.  This choice by the C# team allows for greater consistency and for such things as a cleaner implementation of automatic boxing/unboxing.

To receive updates on new articles, subscribe to CRF Design today!

Similar Posts:

Dealing with mid-study changes (data model)

Whether you’re working on a big pharma clinical trial or a multi-site research study, changes will pop-up while the study is running. I have yet to find someone who enjoys changing electronic case report forms (CRFs), subject numbering schemes, or modifying user permissions in the middle of a study, but change requests will come and how you react to these changes defines the robustness of your design. It’s frustrating, and I’ve found that they are unfortunately a fact of life.

One of my favorite authors, David Allen, writes that how we react to change differentiates us from other people. Those who react quickly can respond efficiently, and then just as quickly move on. I view mid-study changes the same way. Because they will happen (and sometimes frequently!), it’s necessary to design a system that will make this process as painless as possible. For this post, I’ll focus on how a mid-study change to a CRF can be done quickly from the perspective of the data model.

The most common mid-study changes I’ve come across for a CRF are adding/removing items in a dropdown, adding/removing/modifying fields, changing the type of a field, and adding/removing/modifying what some call skip patterns or verification rules. Keep in mind, the data model must support these changes. The most difficult thing to satisfy without proper design is for the old data to be accessible. It’s messy and data conversion could be needed. Providing you’re not using some sort of star schema for your database, adding/removing/modifying columns in an existing database is something I like to avoid. Using a traditional relational database, I don’t see a clear way of avoid this.

One solution (the one I normally use) is to create a data table for the CRF where nothing is ever removed. Columns are permanent. The disadvantage of this approach is storage. For example, if a mid-study change requires removing a column, our approach means we do not remove it. Future records saved in this table would ignore this column which means there’s empty space in the table.

The advantage of this approach is that you never lose data. A permanent record always exists for the CRF and you only need to find ways to manipulate it. While we’re on the topic of manipulating the data, another advantage is all the CRF data is in one place! Yet another advantage is that you can re-use a lot of the older CRF. Normally, mid-study changes don’t require major protocol revisions, so you save time not having to re-code the unchanged portions of the CRF. If you utilize a persistence layer like Hibernate (which you should!), you’ll be able to leverage your existing code and only add methods or properties when needed.

In order to make all this possible, you will need to add an extra column to your data table that represents the revision/version/whatever you want to call it. This will make it possible to correctly display the right “view” on this model.

Although this will be the subject of another post, with the data model in place, we can then focus on how to retrieve and manipulate the data so that it displays properly in a CRF regardless of whether the CRF was saved before or after the mid-study change.

To receive updates on new articles, subscribe to CRF Design today!

Similar Posts: