Making a login badge with font-awesome

On a new site I’m building I was looking for a way to include a nice login badge, similar to those on Google login pages. In fact I found some nice looking bootstrap login templates that actually included the Google login image below directly.

Google login guy

Turns out the image is actually a square, with a css border-radius applied, so given that the page already loads the whole set of font-awesome icons, I wondered if it was possible to replicate this without loading an image… and it is.

Font-awesome login guy

There were issues getting the user silhouette to sit nicely over a standard font awesome circle, so I went down the route of using the border radius. The colours don’t match exactly, but the advantage of this approach is the colours can be customised to match any theme very quickly. The complete code is pretty straight forward and the gist is below:

 

A cacophony of Canard and SQBL updates.

Late last month Canard version 0.2.2 was packaged up and released in time for the 2014 IASSIST conference. This new version changed the Canard Question Module Editor from running on Python 64-bit to 32-bit as was requested by a few people, as well as including import and export plugins for the new 3.2 release of the DDI-Lifecycle XML format.

The reason for the timing of this release the was due to me presenting Canard during the DDI tools session as well as the poster session. At both of these session, Canard was was well received, and there was interest in Canard in wide applications from teaching undergraduates about survey design and metadata management, researchers documenting surveys with lots of live feedback, and archivists recapturing questionnaire metadata.

Until recently, Canard (and its underlying data model SQBL) have been following a very ad hoc release and change process due to its ongoing development. However, given growing interest in the Canard tool, its in everyones interest for this to be made clearer. So first of all a proper release version of the Simple Questionnaire Building Language Schema is available on Github

New versions of SQBL will be released in a form that remains backwards compatible for minor and patch version numbers – in essence, this means the addition of no new or removal of old mandatory elements or attributes. Canard release versions will also be based to these version numbers, so starting from Canard v0.2.2, the Canard minor version number will be 1 greater than the SQBL version numbers it supports. Its likely that Canard will have more frequent releases than SQBL, however, given how patch versions may be released, its best to use the latest version of Canard to ensure compatibility with the applicable minor version family of SQBL.

In short – this guarantees that in future the latest Canard version 0.2 will open any SQBL v0.1 document made by a prior version of Canard in the 0.2 version family, which makes upgrading a safer option.

However, this doesn’t mean that SQBL is ‘fixed’ there are already certain issues that will need to be addressed – especially around describing calculated values in questionnaires – just that changes will be more predictable. Nor does it mean that the development of Canard will slow, as there are already issues which have been opened (and some closed) since the last release.

Its likely that patch level changes to SQBL will happen every 3 to 4 patch releases of Canard. This will give people time to adjust and find and identify any issues in the software or the schema, as well as give time to migrating import and export plugins.

As always, requests or bugs are more than wanted, so if you are using Canard, please feel free to raise an issue on Github, and likewise if there are missing features that require changes to the underlying data model, or deviations from similar standards like DDI, raise an issue with the SQBL schema, or join the SQBL mailing list and see if there are ways a problem can be captured in the current schema.

Why Linus Torvalds is wrong about XML

Linus Torvalds is one of the most revered figures in modern computer science and has made the kind of contributions to the world that I hope to achieve. However, given his global audience, his recent statements about XML give me pause for reflection.

I have worked with XML in a number of jobs, helped with the specification of international XML formats, written tutorials on their use, and even made my own XML format (with reason I might add). And I must say, in reply to Linus’s statement that

XML is the worst format ever designed

XML isn’t the problem, it is more that the problem is bad programmers. Computer Science is a broad field, not covering just the creation of programs, but also the correct specification of information for computation. The lack of appreciation for that second aspect has seen the recent rise of “Data Science” as a field – a mash of statistics, data management and programming.

While it is undenyable that many programmers write bad XML, this is because of poor understanding and discipline. One could equally say, people write bad code, lets stop them writing code. People will always make mistakes or cut corners, the solution is education, not reinventing the wheel.

Linus and the rest of the Subsurface team are well within their rights to use the data formats they choose, and I am eager to see what new formats he can design. But with that in mind, I will address some of the critiques of Linus and others about XML and point out their issues, followed by some handy tips for programmers looking at using XML.

XML should be human readable

I did the best that I could with XML, and I suspect the subsurface XML is about as pretty and human-readable as you can make that crap

CSV isn’t very readable, C, Perl and Python aren’t very human readable. What is “human-readable” is very subjective, as even English isn’t human-readable to non-English speakers.

Restricting ourselves to just technology, CSV isn’t very readable as for any non-trivial amount of data as the header will scroll off the top of the screen, and data will overflow onto the next line or outside the horizonal boundaries of the screen. One could argue that its possible in Excel, OpenOffice or using a VIm/Emacs plugin to lock the headers to the top of the screen – and now we have used a tool to overcome limitations in the format.

Likewise, the same can be said for computer code, code-folding, auto-completion of long function and variable names and syntax highlighting are all software features to overcome failures in the format and make the output more “human-readable”. Plain-text supports none of the above, yet no one would recommend using Notepad to write code for the lack of features.

Likewise, I would never, ever recommend writing XML in a non-XML editor. Auto-adding of closing tags, checking schema as you type, easy access to the schema via hotlinks from elements and attributes, and XPath query and replace are all vital functions of a good XML editor. All of these make writing XML much easier and approachable, and compared to code or CSV, a programmer should spend only as much time in an XML editor to understand the format to make writing XML in code easier.

While it can be said that a poor craftsman blames his tools, a good craftsman knows when to use the right tools as well.

XML files should standalone

This is most visible in this bug raised in Subsurface where it is stated that:

Subsurface only ever stores metric units. But our goal is to create files that make sense and can be read and understood without additional information.

Now, examination of a sample of the XML from subsurface shows a glaring contradiction. There is nothing in this file that says that units are in metric. The distance ‘m’ could equally stand for ‘miles’, and while the order of magnitude would make misinterpretation for a human hard, a dive computer with an incorrect understanding may miscalculate the required oxygen pressure leading to potential death. To accurately understand this file, I need to find the documentation, i.e additional information. The reason for schema is to explicitly describe a data file.

Additionally, because data is stored as “human-readable” strings, I could validly put in “thirty metres” instead of “30.0 m” as a depth. At this point the program might fail, but as someone writing the data elsewhere I’d have no reason why. Apart from being a description of the data, schema exists as a contract. If you say the data is of this form, then these are the rules you must conform to. When you are looking at sharing data between programs or organisations this ability to lean on a technical enforcement is invaluable as making “bad” data is that much harder.

XML shouldn’t need other formats

This is a tricky one, as when people think of XML, even if they have made a schema their mid stops there. XML isn’t just a format, its more a suit of related formats that can make handing and manipulating information easier.

Its worth noting that people have raised databases within that thread as an alternative – SQL is only a query language, but requires the formal Database Definition Language to describe the data and an engine to query over it. Likewise, HTML without CSS, Javascript or any number of programming and templating languages that power the web would be much less useful to the general public.

Similarly, isolating XML from XML schemas, mean your data has no structure. Isolating XML from XQuery and XPath mean you have no way of querying your data. Without XSLT there is no easy, declarative way to transform XML, and having done this with traditional languages and XSLT, the latter makes using and transforming XML much easier. Ultimately, using XML without taking advantage of many of the technologies that exist in the entire XML landscape is not using technologies to its best.

Tips for good XML

With all of that aside, XML like all technologies can be used poorly. However, when done well and documented properly, a good XML format with an appropriate schema can reduce errors and give vital metadata that gives data context and longevity. So I present a few handy tips for using XML well.

  1. Only use XML when appropriateXML is best suited to complex data, especially hierarchical data. As Linus (and others) points out in the linked thread tabular data is much better suited to CSV or more structured tablular formats, simple key values can be stored in ini files, and markup text can be done in HTML, Markdown or any number of other formats.
  2. Look for other formats.If you are thinking of using XML for your tool – stop and see what others have already done. The world doesn’t need another format, so if you are thinking of doing so you should have a very, very good reason to do so.
  3. Use a schema or doctypeIf you are chosing to make your own format, this is the most important point. If you chose to use XML, make a schema. How you choose to capture this Doctype, XSD Schema, Schematron, Relax NG is largely irrelevant. What is important is that your data format is documented. There are even tools that can automate creating schema stubs from documents, so there is no excuse not to. As stated an XML schema is the formal contract about what your data is and lets others know that if the data doesn’t conform to this format then it is broken.
  4. Use XML datatypesXML already has specifications for text, numeric, datetime and identification data. Use these as a starting point for your data.
  5. Store one type of data per field.While the difference between <dive duration="30:00 mins"> and <dive duration="30" durationUnit="mins"> is minimal, the former uses a single string for two pieces of data, while the latter uses two fields, a number and an enumerable, each storing one piece of data. An even better solution is using the XML duration data type <dive duration="PT30M"> based on the existing ISO 8601 standard.

Book Review: H.G. Wells The Time Machine

After finishing the Harry Potter series (which doesn’t need another poorly written review), I decided for something older, shorter and a little more mature and decided to tackle some books I’ve been meaning to read for a long time – namely H.G. Wells more well known works.

I fortunately found an anthology – if two stories can be called so – of H.G. Wells “The Time Machine” and “The Invisible Man”. First of all, the story is thinly veiled critique of the aristocracy of Victorian Britain, the idea that the segmentation and stagnation of class would lead to the eventual dulling of the minds of the leisure class, while the underclasses become more violent and brutish.

However, the one thing I did find interesting is the relationship between the unnamed Time Traveller, the Narrator and Weena – an Eloi woman of the future. The story can be broken into two sections, those where the Narrator introduces the cast at the start and closes the story at the end, each about a chapter or so each, while the bulk of the novel in-between is the Narrators recollection of the Time Travellers account of their travel. Here, I say their for a very important reason- by the Narrators account the Time Traveller is a man, while the Time Traveller does nothing to speak of their gender or race during the story.

The reason this is fascinating, is that during their travels the Time Traveller meets a meek, child-like Eloi woman who accompanies them on their future adventure. Reading the Time Traveller as intended as a man, presents a view of Victorian gender relations, where women were treated as child-like and in need of a man for protection. However, I found myself attempting to read the story and interpret it as though the Time Traveller could have been a woman and comparing the subtext. Reading the Time Traveller as a woman however, Weena becomes more like a child-like companion, and it reads less like a patriarchal reinforcement of a man overseeing the safety of a woman, but  more as a story of a woman managing their maternal instincts against their scientific drive and desire to return home – and funnily enough this reminded me of Aliens.

Given that people often lament the lack of female leads in fiction and movies, this seems to be one where the role could easily be played or read as a woman with very little change to the original text.

Next up, The Handmaids Tale and then The Invisible Man.

New release: Canard Question Module Editor v0.2.1

Its been a while since my last post, and while a few emails and updates to GitHub have happened, I haven’t written a formal announcement here. The big news of which two releases of the Canard Question Module Editor have been published and made available.

Version 0.2 went out on October 1st and Version 0.2.1 went out on the 9th. Normally, there’d be a larger gap between releases, however, very shortly after version 0.2 went out the door a handful of troublesome bugs were discovered regarding the handling of multilingual text. So a second version went out the door very shortly after that included some bug fixes and some new features tht made dealing with multiple languages easier.

Canard Screenshot

Additionally, the QFingerTabsWidget that was discussed in an earlier post, has seen a number of updates to allow for icons and a more responsive design of horizontal text in horizontally aligned tabs. This has become larger than just a gist and will in the coming weeks be spun of into its own GitHub repository.

Lastly, with Canard in a relatively stable state, and with the “plug-in architecture” in a usable state I’m going to focus on creating SQBL transformations for input, output and visualisation. So suggestions for target formats and languages, or updates or changes to existing plugins would be welcome in the comments.

If anyone is interested in following updates to SQBL or Canard, I’d strongly recommend following the SQBL Mailing lists to keep up to date with releases and new plugins as they are published.

Canard feature update: Bulk Question Editor

Just a nice and quick update to show off the latest addition to Canard. Post-IASSIST I’ve been working on getting a CS-Pro to SQBL converter. As a part of this I needed to actually install CSPro, and it turns out it has some pretty cool features. Not least of which was the ability to view and editor (in a simple way) all of the questions in a block.

In the words of Steves Jobs (and many, many others), Good Artists Borrow, Great Artists Steal, and I worked about implementing this in Canard. Below is a screenshot of the new Canard “Bulk Question Editor” accessible when you click on the “Flow Logic” of a module.

Screenshot of the new Canard Bulk Question Editor

Screenshot of the new Canard Bulk Question Editor

At this stage this change has been checked into the Canard GitHub for testing and will be rolled into the next release of Canard, which will be out… soon.

Book Review: Brave New World

So my latest literary outing was a re-read of Aldous Huxley’s “Brave New World”. While, there are tons of reviews that do a great job of comparing Huxley’s Brave New World with Orwells 1984 and our current surveillance state, there is one short passage from late in the book, that resonated with me this read through.

One of the principal functions of a friend is to suffer (in a milder and symbolic form) the punishments that we should like, but are unable, to inflict upon our enemies.

In the midst of a long essay on the dangers of giving ourselves over to technological advances, this quote is hidden and is, I think, one of the better, albeit more cynical, descriptions of friendship I have read.

Simple XML validation within PyQt TextEdit fields

As part of Canard, there is need for a very simple XML editor while the rich-text capabilities are finalised. So for the upcoming release, rather than work with a complex GUI, I’ve taken the easy option and will just allow the user to edit the very cut back rich text XML itself.

The complication with this is that a survey designer could write some invalid XML, which would be inserted into the rest of the document and break the entire file. The solution is to provide as-you-type validation of the XML to check that is valid. Fortunately, this is not as difficult as might be imagined, thanks to how easy to put together PyQt and Python are in general

Below is a screen shot of this little editor in action, with a very short code snippet that demonstrates how to do as-you-type XML validation inside of a PyQt application.

Simple PyQT XML Editor in action

Simple PyQT XML Editor in action

import sys
from lxml import etree
from PyQt4 import QtCore, QtGui

class editor(QtGui.QMainWindow):
    def __init__(self):
        super(editor, self).__init__()
        self.text = QtGui.QTextEdit()
        self.setCentralWidget(self.text)
        self.text.textChanged.connect(self.validate)
        
        self.statusBar()
        self.setWindowTitle('Simple XML editor')
        self.show() 
    def validate(self):
        try:
            root = etree.fromstring(str(self.text.toPlainText()))
            self.statusBar().showMessage("Valid XML")
        except etree.XMLSyntaxError, e:
            msg = e.error_log.last_error.message
            line=e.error_log.last_error.line
            col=e.error_log.last_error.column
            self.statusBar().showMessage("Invalid XML: Line %s, Col %s: %s"%(line,col,msg))
        except:
            self.statusBar().showMessage("Invalid XML: Unknown error")
        
def main():
    app = QtGui.QApplication(sys.argv)
    w = editor()
    sys.exit(app.exec_())
 
if __name__ == "__main__":
    main()

Practical XForms – Todo-list – Part 3: Adding bindings to collect the correct data

This is the third in an ongoing series that examines the practical uses of XForms by building a todo list. In this tutorial we are going to build on part 1 (where we built our data model) and part 2 (where we refined the data model to support looping). In this tutorial we will cover ways of using binds and inline schemas to correctly type the data model and use correct input types.

We left of from tutorial 2, with a user interface that looked like this:

A nearly completed XForm to-do list

A nearly completed XForm to-do list

The problem with this is that we are required to enter dates and state whether the task is complete manually. What would be preferred is if we could use a checkbox or date picker. A naive approach is to edit the interface directly, and alter the Xforms input into a checkbox. Below, we have code that generates a XForms select option that presents a series of checkboxes, however since we are dealing with binary information, we only need one item to select from:

1
2
3
4
5
<xf:select ref="@complete" appearance="full" >  
    <xf:item>
         <xf:value>true</xf:value> 
    </xf:item>
</select>
A task list with tick boxes

A task list with tick boxes

But the problem with this is that if the true value isn’t selected, rather than the value be false, it will instead be empty. Additionally there is no “date input” input type, so we’d have to make a custom date picker. We could again hack how we evaluate this value, and make custom handlers for different datatypes, or… we could type our data correctly.

Using XForms Binds to provide data-typing

XForms is very data-driven in how it operates, and conforms very strongly to the Model-View-Controller design pattern. We have already covered to View – the HTML/XForms code presented to the user – and the Model – the data model that we have designed to describe the information we hope to capture – now its time to look at the Controller aspect of XForms, the XForms bind. Binds have a lot of uses, dictating the connections between the model and the view,  they can be used to compute values, control when certain inputs are available and they can be used to provide explicit data-typing for elements in the model.

To demonstrate this we will revert the insert into our xf:model some bindings for our data:

1
2
3
4
5
6
7
<xf:bind nodeset="//task/@complete" type="xs:boolean"/>
<xf:bind nodeset="//task/@dueDate" type="xs:date"/>
<xf:bind nodeset="//task" type="xs:string" readonly="./@complete=true()"/>
<!-- later -->
<td><xf:input ref="."/></td>
<td><xf:input ref="@complete"/></td>
<td><xf:input ref="@dueDate" /></td>

Here we have reverted our complete entry field to a simple input, but have declare it to be an XML boolean datatype, similarly we have declared the due date to be an XML date and the task name to be a string. We have also demonstrated the ability to disable content based on the binding by saying that a task can only be edited if it has been completed. The end result of this simple and declarative change is shown below:

A more completed task list

A more completed task list

The above image shows several changes have taken place:

  • The complete field now has a tick-box (not shown is the fact that this will store a true or false value without further scripting required)
  • The due date field has a button with ellipses (…) that when pressed shows a date selector.
  • Although subtle, the first task and due date are grayed out indicating it has been disabled. Similarly, the button that would drop down the date selector for the first task is now gone.

So far we now have a fairly complete user interface for managing our tasks. You can see the full code for the task list on Github, or view all past code in the same repository. In the next tutorial we’ll look at an alternate way of providing datatyping  by linking to or including inline XML schemas, which can be useful when the data structure is known ahead of time. Then we’ll look at defining submission methods so we can save our data with a web server.

PyQt Interlude – Shift+Tab to de-indent text in QTextEdit

While searching for a solution to tabbing through QTableWidgets in PyQt, I found this old question on StackOverflow that needed help creating the code necessary to allow a QTextEdit to capture Shift-tab to deindent code.

Below is the thoroughly commented code that explains how all this works:

Soon another Canard update, and the next exciting installment in the XForms tutorial!