<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Daily Morn by Raymond Li &#187; Programming</title>
	<atom:link href="http://rayli.net/blog/category/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://rayli.net/blog</link>
	<description></description>
	<lastBuildDate>Wed, 16 May 2012 05:07:29 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>PSHamcrest 0.1-alpha released!</title>
		<link>http://rayli.net/blog/2011/09/pshamcrest-0-1-alpha-released/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=pshamcrest-0-1-alpha-released</link>
		<comments>http://rayli.net/blog/2011/09/pshamcrest-0-1-alpha-released/#comments</comments>
		<pubDate>Thu, 01 Sep 2011 14:01:27 +0000</pubDate>
		<dc:creator>Raymond Li</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Powershell]]></category>

		<guid isPermaLink="false">http://rayli.net/blog/?p=929</guid>
		<description><![CDATA[PSHamcrest is released! PSHamcrest is a very basic Powershell unit test framework inspired by Hamcrest. It&#8217;s super easy to use &#8212; just dump it in the same directory and dot source it. I looked around on the Internet and didn&#8217;t find a simple, no frills unit test framework for PowerShell that leveraged Hamcrest matchers. So [...]]]></description>
			<content:encoded><![CDATA[<p>PSHamcrest is released! PSHamcrest is a very basic Powershell unit test framework inspired by Hamcrest. It&#8217;s super easy to use &#8212; just dump it in the same directory and dot source it.</p>
<p><span id="more-929"></span></p>
<p>I looked around on the Internet and didn&#8217;t find a simple, no frills unit test framework for PowerShell that leveraged Hamcrest matchers. So I wrote one! Being relatively new to PowerShell, I probably haven&#8217;t leveraged common PowerShell idioms. Hopefully, it&#8217;s easy enough to modify and tailor to your project. This is my first shot at it. Comments and suggestions are welcome!</p>
<p>Official PSHamcrest Page:<br />
<a title="PSHamcrest" href="http://rayli.net/blog/pshamcrest">http://rayli.net/blog/pshamcrest</a></p>
<p>Codeplex Page:<br />
<a title="PSHamcrest - Codeplex Page" href="http://pshamcrest.codeplex.com/">http://pshamcrest.codeplex.com/</a></p>
<p>Latest release:<br />
<a title="PSHamcrest Latest Release" href="http://pshamcrest.codeplex.com/releases">http://pshamcrest.codeplex.com/releases</a></p>
<p>Browse the latest source code:<br />
<a title="PSHamcrest Source Code" href="http://pshamcrest.codeplex.com/SourceControl/BrowseLatest">http://pshamcrest.codeplex.com/SourceControl/BrowseLatest</a></p>
]]></content:encoded>
			<wfw:commentRss>http://rayli.net/blog/2011/09/pshamcrest-0-1-alpha-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Binary serialization in C#</title>
		<link>http://rayli.net/blog/2011/03/binary-serialization-in-c-sharp/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=binary-serialization-in-c-sharp</link>
		<comments>http://rayli.net/blog/2011/03/binary-serialization-in-c-sharp/#comments</comments>
		<pubDate>Sun, 06 Mar 2011 02:20:22 +0000</pubDate>
		<dc:creator>Raymond Li</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[C#]]></category>

		<guid isPermaLink="false">http://rayli.net/blog/?p=748</guid>
		<description><![CDATA[Serializing an object into a binary file is an easy and fast way to persist your objects. If binary serialization is used to cache objects normally read from an XML file, a database or some other file format, you&#8217;ll get even more benefits. After incorporating binary serialization into a C# application that loaded data from [...]]]></description>
			<content:encoded><![CDATA[<p>Serializing an object into a binary file is an easy and fast way to persist your objects. If binary serialization is used to cache objects normally read from an XML file, a database or some other file format, you&#8217;ll get even more benefits.</p>
<p><span id="more-748"></span></p>
<p>After incorporating binary serialization into a C# application that loaded data from an Excel spreadsheet, I was able to get a 33% decrease in execution time by caching the generated object into a binary file. It&#8217;s a quick-and-dirty way to get a speed increase especially when you&#8217;re loading a lot of external data that changes, but doesn&#8217;t change frequently.</p>
<p>The first step for serializing a class into a binary file is to mark the class as <em>Serializable</em>.</p>
<pre class="brush: csharp; title: ; notranslate">
[Serializable]
public class YourClass
{
	// your class definition.
}
</pre>
<p>Now that your class is ready to be serialized, you can use <em>ObjectSerializer</em>. The <em>ObjectSerializer </em>class below allows anyone to serialize an object into a binary file. Serializing or de-serializing a class marked with the <em>[Serializable]</em> attribute takes no more than 3 lines of C# code.</p>
<pre class="brush: csharp; title: ; notranslate">
public class ObjectSerializer&lt;T&gt;
{
	protected IFormatter iformatter;

	public ObjectSerializer()
	{
		this.iformatter = new BinaryFormatter();
	}

	public T GetSerializedObject(string filename)
	{
		if (File.Exists(filename))
		{
			Stream inStream = new FileStream(
				filename,
				FileMode.Open,
				FileAccess.Read,
				FileShare.Read);
			T obj = (T)this.iformatter.Deserialize(inStream);
			inStream.Close();
			return obj;
		}
		return default(T);
	}

	public void SaveSerializedObject(T obj, string filename)
	{
		Stream outStream = new FileStream(
			filename,
			FileMode.Create,
			FileAccess.Write,
			FileShare.None);
		this.iformatter.Serialize(outStream, obj);
		outStream.Close();
	}
}
</pre>
<p>To serialize an object using <em>ObjectSerializer</em>, first instantiate the <em>ObjectSerializer </em>class. Then use the <em>SaveSerialziedObject()</em> method to serialize the object.</p>
<pre class="brush: csharp; title: ; notranslate">
YourClass yourObject = new YourClass();
ObjectSerializer&lt;YourClass&gt; objSerializer =
	new ObjectSerializer&lt;YourClass&gt;();

// serializes yourClass to SomeFilename.bin.
objSerializer.SaveSerializedObject(yourObject, &quot;SomeFilename.bin&quot;);
</pre>
<p>To deserialize the binary file generated from the previous operation, instantiate the <em>ObjectSerializer </em>class. Then use the <em>GetSerializedObject()</em> method to retrieve the original object.</p>
<pre class="brush: csharp; title: ; notranslate">
ObjectSerializer&lt;YourClass&gt; objSerializer =
	new ObjectSerializer&lt;YourClass&gt;();

// deserializes yourClass from SomeFilename.bin.
YourClass yourObjectFromFile =
	objSerializer.GetSerializedObject(&quot;SomeFilename.bin&quot;);
</pre>
<p>And there you have it&#8230; quick-and-dirty binary serialization in C#!</p>
]]></content:encoded>
			<wfw:commentRss>http://rayli.net/blog/2011/03/binary-serialization-in-c-sharp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>What are the benefits of a tracing JIT?</title>
		<link>http://rayli.net/blog/2010/04/what-are-the-benefits-of-a-tracing-jit/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=what-are-the-benefits-of-a-tracing-jit</link>
		<comments>http://rayli.net/blog/2010/04/what-are-the-benefits-of-a-tracing-jit/#comments</comments>
		<pubDate>Sat, 24 Apr 2010 02:54:25 +0000</pubDate>
		<dc:creator>Raymond Li</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://rayli.net/blog/?p=266</guid>
		<description><![CDATA[Firefox uses a tracing JIT.  Adobe&#8217;s been using it for a while.  A Python interpreter uses tracing.  Microsoft is also researching its possibilities.  So what&#8217;s the big deal? What is a tracing JIT? Although tracing JITs are a complex technology, the core concept is about optimizing execution of the hot paths in a program.  The [...]]]></description>
			<content:encoded><![CDATA[<p>Firefox <a title="TraceMonkey" href="http://en.wikipedia.org/wiki/TraceMonkey#TraceMonkey">uses a tracing JIT</a>.  Adobe&#8217;s been <a title="Tamarin" href="http://www.mozilla.org/projects/tamarin/">using it for a while</a>.  A Python interpreter <a title="PyPy Status Blog: Applying a Tracing JIT to an Interpreter" href="http://morepypy.blogspot.com/2009/03/applying-tracing-jit-to-interpreter.html">uses tracing</a>.  Microsoft is also <a title="SPUR: A Trace-Based JIT Compiler for CIL" href="http://research.microsoft.com/en-us/projects/spur/">researching its possibilities</a>.  So what&#8217;s the big deal?</p>
<p><span id="more-266"></span></p>
<p><em><strong>What is a tracing JIT?</strong></em></p>
<p>Although tracing JITs are a complex technology, the core concept is  about optimizing execution of the hot paths in a program.  The emphasis  is specifically on hot paths that return to the start of a path which sounds very  much like a loop.  However, the traditional definition of a programming  loop is only a subset of these hot paths.  The broader definition  includes code that spans methods and possibly even modules.  This  broader definition of a loop is what&#8217;s called a <em>trace</em>.</p>
<p><em><strong>Why use traces?</strong></em></p>
<p>By JIT compiling the traces, code that is executed frequently runs faster.  Code that isn&#8217;t included in traces isn&#8217;t compiled.  The claim is untraced code would not benefit as greatly from JIT compilation since it is not executed as frequently.  The basic trade-off is the time needed to JIT compile and cache the resulting code versus  the time needed to execute the code.</p>
<p><em><strong>When does tracing happen?</strong></em></p>
<p>Tracing takes place as instructions are interpreted.  Whether it&#8217;s Java, Python or Javascript, the code must be interpreted by a virtual machine.  It is during this stage that loops are detected and identified as traces.</p>
<p><em><strong>How is a tracing JIT different from other JITs?</strong></em></p>
<p>﻿﻿Run-time profiling for optimization and specific CPU and memory optimizations are done with most JITs to adapt the application for best performance.  However, non-tracing JIT implementations (Sun&#8217;s Java VM and Microsoft&#8217;s CLR) do this at the method level.  When code is determined to be &#8220;hot,&#8221; the entire method containing that code is JIT compiled and cached.  Tracing JITs do this at the trace level and may consist of a portion of a method (just a specific loop), multiple methods and even multiple methods from different modules.</p>
<p><em><strong>Who is using tracing JITs?</strong></em></p>
<p>The Mozilla Team uses a tracing JIT in the JavaScript engine for Firefox.  It&#8217;s codenamed <a title="TraceMonkey" href="https://wiki.mozilla.org/JavaScript:TraceMonkey">TraceMonkey</a> and is enabled by default in Firefox since version 3.5.  Adobe Labs has a tracing JIT called <a title="Tamarin" href="http://www.mozilla.org/projects/tamarin/">Tamarin</a>.  It&#8217;s basically a JavaScript engine as well.  Technically, it&#8217;s an implementation of ActionScript which is based on ECMAScript which JavaScript is based on.  Tamarin and TraceMonkey are so closely related that they both use the same backend: <a title="NanoJit" href="http://developer.mozilla.org/En/Nanojit">NanoJit</a>.</p>
<p>A Python interpreter called <a title="What is the purpose of PyPy?" href="http://rayli.net/blog/2010/04/what-is-the-purpose-of-pypy/">PyPy</a> recently <a title="PyPy JIT Overview" href="http://codespeak.net/pypy/dist/pypy/doc/jit/overview.html">switched</a> from being based on partial evaluation to a tracing JIT.  Microsoft is researching and prototyping a tracing JIT compiler (TJIT) for the common intermediate language (CIL) called <a title="SPUR: A Trace-Based JIT Compiler for CIL" href="http://research.microsoft.com/en-us/projects/spur/">SPUR</a>.</p>
<p><em><strong>Where can I find out more?</strong></em></p>
<p>This post only scratches the surface.  There&#8217;s plenty more about tracing JITs!</p>
<ul>
<li><a title="Andreas Gal" href="http://andreasgal.wordpress.com/">Andreas Gal&#8217;s blog</a></li>
<li><a title="Lambda the Ultimate | Have tracing JIT compilers won?" href="http://lambda-the-ultimate.org/node/3851">Lambda the Ultimate thread on tracing JITs (highly recommended)</a></li>
<li><a title="Hacker News | Have Tracing JIT Compilers Won?" href="http://news.ycombinator.com/item?id=1180517">Hacker News thread on tracing JITs</a></li>
<li><a title="Tracing JIT Notes" href="http://michael.bebenita.com/">Tracing JIT Notes</a></li>
<li><a title="Trace tree" href="http://en.wikipedia.org/wiki/Trace_tree">Wikipedia entry on trace trees</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://rayli.net/blog/2010/04/what-are-the-benefits-of-a-tracing-jit/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>What is the purpose of PyPy?</title>
		<link>http://rayli.net/blog/2010/04/what-is-the-purpose-of-pypy/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=what-is-the-purpose-of-pypy</link>
		<comments>http://rayli.net/blog/2010/04/what-is-the-purpose-of-pypy/#comments</comments>
		<pubDate>Wed, 07 Apr 2010 20:03:59 +0000</pubDate>
		<dc:creator>Raymond Li</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://rayli.net/blog/?p=189</guid>
		<description><![CDATA[PyPy is a Python interpreter written in Python.  It claims to be faster than CPython for certain benchmark tests.  How can Python &#8212; not particularly known for its speed &#8212; interpret Python source code faster than an interpreter written in C?  Also, an interpreter written in Python sounds like a neat exercise, but what&#8217;s the [...]]]></description>
			<content:encoded><![CDATA[<p><a title="PyPy" href="http://codespeak.net/pypy/">PyPy</a> is a Python interpreter written in Python.  It claims to be faster than CPython for certain benchmark tests.  How can Python &#8212; not particularly known for its speed &#8212; interpret Python source code faster than an interpreter written in C?  Also, an interpreter written in Python sounds like a neat exercise, but what&#8217;s the point of doing this?</p>
<p><span id="more-189"></span><strong><em>How can Python interpret Python source code faster than an interpreter written in C?</em></strong></p>
<p>The short answer is it can&#8217;t.  The long answer is that PyPy is actually two pieces of software:</p>
<ol>
<li>an interpreter</li>
<li>a translator</li>
</ol>
<p>The interpreter understands the full Python language.  The interpreter is written in <a title="Restricted Python" href="http://codespeak.net/pypy/dist/pypy/doc/coding-guide.html#restricted-python">RPython</a> (Restricted Python).  RPython is statically typed which makes it easier to compile into more efficient code.  This characteristic is very important for the next step.</p>
<p>The translator takes RPython code as its input and translates it to a lower language like C.  Although the interpreter was originally written in Python (specifically RPython), the translator translates it to C which can be compiled into a much faster interpreter that could rival or even surpass CPython.</p>
<p><strong><em>What&#8217;s the point of doing this in RPython?  Why not just code it in C like CPython?</em></strong></p>
<p>The difference boils down to the perceived difference between hacking away at an interpreter written in RPython (PyPy) versus an interpreter written in C (CPython).  The claim is that an interpreter coded in RPython allows for faster experimentation.</p>
<p><strong><em>Can a Python interpreter based on RPython code translated into C rival or exceed the performance of CPython?</em></strong></p>
<p>At this moment (April 7, 2010), the <a title="PyPy Speed Center" href="http://speed.pypy.org/">answer is no</a>.  Default CPython bests its PyPy-C equivalent on just about every benchmark.  On some benchmarks, the measurements are close.  On others, CPython is clearly the winner by far.</p>
<p><em><strong>This is false advertising!  If CPython does better on most benchmarks, how can PyPy claim to be faster?</strong></em></p>
<p>The answer is JIT!  The developers of PyPy <a title="PyPy JIT" href="http://codespeak.net/pypy/dist/pypy/doc/jit/overview.html">created a JIT compiler</a> for Python by adding a few hints to their RPython interpreter.  The PyPy JIT compiler just-in-time compiles RPython code to native code which is why it&#8217;s able to get such fantastic speed gains when compared to CPython.  PyPy-C-JIT crushes CPython on the majority of the speed tests at the <a title="PyPy Speed Center" href="http://speed.pypy.org/">PyPy Speed Center</a>.</p>
<p><em><strong>That doesn&#8217;t seem fair&#8230;  Of course native code will be faster than interpreted code.  What if CPython is coupled with JITting?<br />
</strong></em></p>
<p>Turns out PyPy still comes out ahead.  CPython can be coupled with <a title="Psyco" href="http://psyco.sourceforge.net/">Psyco</a>, a Python extension module that can JIT compile Python code.  The Psyco JIT approach differs from the PyPy approach, because the former focuses on partial evaluation and the latter on tracing.  I don&#8217;t know the difference yet (maybe another blog post?), but what we do know is this tracing JIT approach outperforms the Psyco approach.</p>
<p>So there it is&#8230;  PyPy in a nutshell.</p>
<p>UPDATE: It seems I&#8217;m not the only one interested in PyPy&#8217;s claims.  I came across a related thread on Stackoverflow: <a title="PyPy — How can it possibly beat CPython?" href="http://stackoverflow.com/questions/2591879/pypy-how-can-it-possibly-beat-cpython">PyPy — How can it possibly beat CPython?</a></p>
<p><em>DISCLAIMER: I have not used PyPy &#8212; just very curious about the problems it solves.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://rayli.net/blog/2010/04/what-is-the-purpose-of-pypy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PyCon 2010 Atlanta</title>
		<link>http://rayli.net/blog/2010/02/pycon-2010-atlanta/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=pycon-2010-atlanta</link>
		<comments>http://rayli.net/blog/2010/02/pycon-2010-atlanta/#comments</comments>
		<pubDate>Mon, 22 Feb 2010 14:54:15 +0000</pubDate>
		<dc:creator>Raymond Li</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://rayli.net/blog/?p=161</guid>
		<description><![CDATA[PyCon 2010 was in Atlanta this year.  It wasn&#8217;t quite as warm as I hoped it would be, but definitely an improvement over the 2-3 feet of snow we got in the DC region.  I do feel a little smarter after attending PyCon, but also infinitely humbled by the creativity, energy, and raw intelligence in [...]]]></description>
			<content:encoded><![CDATA[<p>PyCon 2010 was in Atlanta this year.  It wasn&#8217;t quite as warm as I hoped it would be, but definitely an improvement over the 2-3 feet of snow we got in the DC region.  I do feel a little smarter after attending PyCon, but also infinitely humbled by the creativity, energy, and raw intelligence in the Python community.  Here are some notes I took from the talks I attended&#8230;</p>
<p><span id="more-161"></span><em> </em></p>
<p><em>Python in the Browser</em>, Jimmy Schementi<br />
Using Python in the web browser leverages Microsoft&#8217;s Python implementation.  The goal is to use <a title="Silverlight" href="http://www.silverlight.net/">Silverlight</a>/<a title="Moonlight" href="http://www.mono-project.com/Moonlight">Moonlight</a> with <a title="IronPython" href="http://ironpython.net">IronPython</a> as a client-side browser language.</p>
<p><em>State of PyPy</em>, Maciej Fijalkowski<br />
<a title="PyPy" href="http://codespeak.net/pypy/">PyPy</a> is an implementation of Python written in Python.  But why?  (UPDATE:  <a title="http://rayli.net/blog/2010/04/what-is-the-purpose-of-pypy/" href="http://rayli.net/blog/2010/04/what-is-the-purpose-of-pypy/">What is the purpose of PyPy?</a>)</p>
<p><em>Python 3: Next Generation</em>, Wesley Chun<br />
This talk went through a laundry list of new features and bug fixes in Python 3.</p>
<p><em>Unladen Swallow: fewer coconuts, faster Python</em>, Collin Winter<br />
<a title="Unladen Swallow" href="http://code.google.com/p/unladen-swallow/">Unladen Swallow</a> is Google&#8217;s Python implementation branch of CPython.  It claims significant speed improvements.  Currently, the interpreter is a virtual machine with a JIT built using <a title="LLVM" href="http://llvm.org/">LLVM</a>.</p>
<p><em>Understanding the Python GIL</em>, David Beazly<br />
Discussed key issues with the global intepreter lock (GIL).  It seems improvements in Python 3 solve some problems associated with the GIL, but create new ones.  Beazly goes over how difficult the problem is, and how he feels it can be solved.</p>
<p><em>Easy command-line applications with cmd and cmd2</em>, Catherine Devlin (a.k.a. PyOraGeek)<br />
The talk title was a bit deceiving.  She prefaced the talk with a disclaimer, because the topic was actually command-line interpreters.  This is more along the lines of applications like the bash shell or Python&#8217;s REPL.  <a title="cmd" href="http://docs.python.org/library/cmd.html"><em>cmd</em></a> is Python&#8217;s class for line-oriented command interpreters.  <a title="cmd2" href="http://catherine.devlin.googlepages.com/cmd2.html"><em>cmd2</em></a> is Devlin&#8217;s enhancements to <em>cmd</em>.</p>
<p>The rest of the talks I attended were about <strong>software testing</strong>!</p>
<p><em>Why not run all your tests all the time?  A study of continuous integration systems</em>, C. Titus Brown<br />
Brown compared continuous integration systems: <a title="Hudson" href="http://hudson-ci.org/">Hudson</a>, <a title="Buildbot" href="http://buildbot.net/">Buildbot</a>, <a title="CruiseControl" href="http://cruisecontrol.sourceforge.net/">CruiseControl</a>, <a title="Bamboo" href="http://www.atlassian.com/software/bamboo/">Bamboo</a>, <a title="Bitten" href="http://bitten.edgewall.org/">Bitten</a>, <a title="Pony-build" href="http://wiki.github.com/ctb/pony-build/">Pony-build</a> (his project).  Despite this possible bias, a strong recommendation was give for <a title="Hudson" href="http://hudson-ci.org/">Hudson</a> (Java-based).</p>
<p><em>Tests and Testability</em>, Ned Batchelder<br />
Batchelder discussed testing lifecycle: test isolation, harvesting output, dependency injection and mocking.</p>
<p><em>Rapid Multi-purpose Testing</em>, Holger Krekel<br />
Krekel&#8217;s <a title="py.test" href="http://codespeak.net/py/dist/test/">py.test</a> is a command-line tool to collect, run and report about automated tests.  It supports test skipping, test running modes, parametric testing, test discovery, and multi-cpu testing.</p>
<p><em>New and Improved: Coming changes to unittest, the standard library test framework</em>, Michael Foord<br />
These changes will be new for Python 2.7:</p>
<ul>
<li>New assert methods.</li>
<li>No more fail methods, standardize on assert*.</li>
<li>Better multiline string testing.</li>
<li>Unit test discovery.</li>
<li><em>cleanup()</em> method cleans up in reverse order (improvement over current <em>tearDown()</em> method).</li>
</ul>
<p>Backported to Python 2.4, 2.5, and 2.6.  Check it out at <a title="unittest2" href="http://pypi.python.org/pypi/unittest2">unittest2</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://rayli.net/blog/2010/02/pycon-2010-atlanta/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Benefits of form versioning</title>
		<link>http://rayli.net/blog/2009/03/benefits-of-form-versioning/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=benefits-of-form-versioning</link>
		<comments>http://rayli.net/blog/2009/03/benefits-of-form-versioning/#comments</comments>
		<pubDate>Sat, 14 Mar 2009 12:22:12 +0000</pubDate>
		<dc:creator>Raymond Li</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[CRF Design]]></category>

		<guid isPermaLink="false">http://rayli.net/blog/?p=99</guid>
		<description><![CDATA[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 [...]]]></description>
			<content:encoded><![CDATA[<p>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.</p>
<p>What more can you ask for?</p>
<p>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?</p>
<p><span id="more-99"></span>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?</p>
<p>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.</p>
<p>Form versioning allows us to:</p>
<ul>
<li>Retrieve and display data even if the field is no longer part of the current version of the form.</li>
<li>A dropdown list&#8217;s items can be added, removed, or changed and we&#8217;ll always be able to retrieve exactly what items were present before changes were made.</li>
<li>Keep the validation rules (edit checks) specific to a specific version of the form.</li>
<li>Tell customers that mid-study changes are a breeze because the form versioning technology keeps mid-study changes isolated from existing data.</li>
</ul>
<p>Next time you&#8217;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&#8217;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.</p>
]]></content:encoded>
			<wfw:commentRss>http://rayli.net/blog/2009/03/benefits-of-form-versioning/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Overload the array square bracket operator in C#</title>
		<link>http://rayli.net/blog/2008/11/overload-the-array-square-bracket-operator-in-c/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=overload-the-array-square-bracket-operator-in-c</link>
		<comments>http://rayli.net/blog/2008/11/overload-the-array-square-bracket-operator-in-c/#comments</comments>
		<pubDate>Thu, 13 Nov 2008 10:35:02 +0000</pubDate>
		<dc:creator>Raymond Li</dc:creator>
				<category><![CDATA[Popular]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[C#]]></category>

		<guid isPermaLink="false">http://rayli.net/blog/?p=96</guid>
		<description><![CDATA[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 [...]]]></description>
			<content:encoded><![CDATA[<p>Although operator overloading is possible in C# (<a title="Operator   Overloading in C++" href="http://www.philosophicalgeek.com/2002/08/14/operator-overloading-in-c/">just like in C++</a>), overloading the array square bracket operator is by definition not possible.  However, C# provides an alternative called <a title="Indexers Tutorial" href="http://msdn.microsoft.com/en-us/library/aa288465(VS.71).aspx">indexers</a>.  This is directly from the Microsoft C# Reference for the <a title="[]   Operator (C# Reference)" href="http://msdn.microsoft.com/en-us/library/a3hd7ste.aspx">[] Operator</a>:</p>
<p><span id="more-96"></span></p>
<blockquote><p>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.</p></blockquote>
<p>The syntax for indexers resembles the C# syntax for properties rather than its syntax for operator overloading. Here&#8217;s a quick snippet for providing array-like access to a List you&#8217;d like to keep hidden within a class:</p>
<pre class="brush: csharp; title: ; notranslate">
// overloads the square brackets to provide array-like access.
public T this[int i]
{
    get { return this.List[i]; }
    set { this.List[i] = value; }
}
</pre>
<p>Worked for me, and hopefully it works just as well for you!</p>
<p>UPDATE: As I do a quick search now, this Stack Overflow <a title="How   do I overload the square-bracket operator in C#?" href="http://stackoverflow.com/questions/287928/how-do-i-overload-the-square-bracket-operator-in-c">post</a> just turned up.</p>
]]></content:encoded>
			<wfw:commentRss>http://rayli.net/blog/2008/11/overload-the-array-square-bracket-operator-in-c/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>5 common mistakes for tablet PC development</title>
		<link>http://rayli.net/blog/2008/10/5-common-mistakes-for-tablet-pc-development/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=5-common-mistakes-for-tablet-pc-development</link>
		<comments>http://rayli.net/blog/2008/10/5-common-mistakes-for-tablet-pc-development/#comments</comments>
		<pubDate>Fri, 10 Oct 2008 14:36:06 +0000</pubDate>
		<dc:creator>Raymond Li</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Health IT]]></category>
		<category><![CDATA[Tablet PC]]></category>

		<guid isPermaLink="false">http://rayli.net/blog/?p=84</guid>
		<description><![CDATA[Okay, so you&#8217;re sold on a Tablet PC, but what should you watch out for when developing a Tablet PC application in health care? Below is a list of common mistakes for developing a Tablet PC application.  All are avoidable early in the project&#8217;s life-cycle. Some of these mistakes I own, and others I&#8217;ve seen [...]]]></description>
			<content:encoded><![CDATA[<p>Okay, so you&#8217;re <a title="Future of notebooks, Dell Latitude XT   Tablet PC" href="http://rayli.net/blog/2008/04/future-of-notebooks-dell-latitude-xt-tablet-pc" target="_self">sold</a> on a Tablet PC, but what should you watch out for when developing a Tablet PC application in <a title="Tablet PC   Nursing" href="http://tabletpcnursing.blogspot.com/2008/03/motion-c5-mobile-clinical-assistant.html" target="_self">health care</a>?</p>
<p>Below is a list of common mistakes for developing a Tablet PC application.  All are avoidable early in the project&#8217;s life-cycle. Some of these mistakes I own, and others I&#8217;ve seen from other project managers and developers. Hopefully, this list helps others avoid these common mistakes.</p>
<p><span id="more-84"></span>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.</p>
<p><a href="#mistake1">Mistake 1 &#8211; I need to learn another operating system</a><br />
<a href="#mistake2">Mistake 2 &#8211; It looks fine on my machine, so it&#8217;ll look fine on the tablet</a><br />
<a href="#mistake3">Mistake 3 &#8211; It&#8217;s just Windows, so I don&#8217;t need to worry about fonts</a><br />
<a href="#mistake4">Mistake 4 &#8211; It works in notebook mode, I don&#8217;t need to worry about slate mode</a><br />
<a href="#mistake5">Mistake 5 &#8211; 3-hour battery life is more than enough</a><br />
<a href="#bonus">Bonus &#8211; I&#8217;ll think about security when it&#8217;s up and running</a></p>
<p><a name="mistake1"></a><strong>Mistake 1. I need to learn another operating system. </strong>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 <a title="Tablet PC Development   Guide" href="http://msdn.microsoft.com/en-us/library/ms704849(VS.85).aspx" target="_self">them</a>. Most applications you use on your desktop or notebook will work just as well on a Tablet PC.</p>
<p><em>Bottomline: No new OS, just some added libraries for Windows.</em></p>
<p><a name="mistake2"></a><strong>Mistake </strong><strong>2. It looks fine on my machine, so it&#8217;ll look fine on the tablet. </strong>Okay, great!  It&#8217;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&#8217;m done.</p>
<p>Almost &#8212; like any kind of development, it&#8217;s important to test in the environment where it will be used. Some times this isn&#8217;t possible, but hey, you&#8217;re developing for a tablet, it only makes sense to at least test it on a tablet. Microsoft does offer some <a title="The Development   Environment" href="http://msdn.microsoft.com/en-us/library/ms700652(VS.85).aspx" target="_self">emulation software</a> (with limitations) that tries to duplicate a tablet environment, but nothing can replace testing it directly on your target system.</p>
<p>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&#8217;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&#8217;t need to deploy to a tablet every time you tweak something just to see if your application looks okay.</p>
<p><em>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.</em></p>
<p><a name="mistake3"></a><strong>Mistake </strong><strong>3. It&#8217;s just Windows, so I don&#8217;t need to worry about fonts.</strong> This one is a killer.  Font size is probably the last thing I would worry about. Unfortunately, I&#8217;ve seen some good applications completely tank in front of the customers just because of font size.</p>
<p>Windows should keep the font size consistent whether it&#8217;s on a desktop, notebook, or Tablet PC.  And&#8230; 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&#8243; screen at the same resolution. Changing the resolution fixes the situation in a way, but then those magnified resolutions don&#8217;t take advantage of the added width or height of a tablet PC. And the accessibility settings?  &#8230;the &#8220;Extra Large Fonts?&#8221; Another no-go.  Because you&#8217;re starting out with a smaller screen, the font size difference isn&#8217;t substantial enough to make much of an improvement to the user.  Try it, and you&#8217;ll see.</p>
<p>It really doesn&#8217;t seem like much of an issue, except when you&#8217;re working with an older user.  If they can&#8217;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.</p>
<p><em>Bottomline: If they can&#8217;t read the application text, don&#8217;t let the door hit you on the way out.  Use larger fonts or let the user decide what font to use.</em></p>
<p><a name="mistake4"></a><strong>Mistake </strong><strong>4. It works in notebook mode, I don&#8217;t need to worry about slate mode.</strong> Most developers work on monitors that are wider than it is tall. So naturally, you&#8217;ll find yourself developing your Tablet PC applications in that environment. You&#8217;ll also find that you tend to work with the tablet in the notebook mode as well.</p>
<p>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&#8217;ll leave that for another post.</p>
<p><em>Bottomline: Make sure your layout works in both notebook mode and slate mode.</em></p>
<p><a name="mistake5"></a><strong>Mistake </strong><strong>5. 3-hour battery life is more than enough.</strong> The battery is not so much a software development issue. However, if you&#8217;re taking ownership of developing a Tablet PC application, understanding whether the customer&#8217;s needs are met by the selected hardware is at the the top of your list. If the hardware doesn&#8217;t fit the customer&#8217;s needs, your application will never get used by anyone but you.</p>
<p>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 <a title="Battery-conscious software development with .NET Framework 3.0 " href="http://blogs.technet.com/tabletpc/archive/2007/06/15/battery-conscious-software-development-with-net-framework-3-0.aspx" target="_self">true</a>, you&#8217;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!</p>
<p><em>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.</em></p>
<p><a name="bonus"></a><strong>Bonus: I&#8217;ll think about security when it&#8217;s up and running.</strong> I know, I know&#8230; I said 5, but I thought I&#8217;d throw in this one, since it&#8217;s a show-stopper. A tablet, just like a notebook, is meant to be portable. The price we pay for this convenience is it&#8217;s also a very good target for theft.</p>
<p>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&#8217;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&#8217;s just for starters! As a first step, I recommend full disk encryption.  TrueCrypt has worked well for me, and here&#8217;s list of <a title="Full Disk Encryption Providers" href="http://www.full-disk-encryption.net/Full_Disc_Encryption.html" target="_self">full disk encryption providers</a>.</p>
<p><em>Bottomline: Security, especially for tablets in a health care environment, cannot be an afterthought, it must be integrated into the design process.</em></p>
<p>So, there&#8217;s my 5.  Hopefully it&#8217;ll save you guys the need to find them out on your own.  Happy tablet hacking!</p>
]]></content:encoded>
			<wfw:commentRss>http://rayli.net/blog/2008/10/5-common-mistakes-for-tablet-pc-development/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Why does an abstract class need to implement interface methods?</title>
		<link>http://rayli.net/blog/2008/09/why-does-an-abstract-class-need-to-implement-interface-methods/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=why-does-an-abstract-class-need-to-implement-interface-methods</link>
		<comments>http://rayli.net/blog/2008/09/why-does-an-abstract-class-need-to-implement-interface-methods/#comments</comments>
		<pubDate>Sun, 28 Sep 2008 15:28:17 +0000</pubDate>
		<dc:creator>Raymond Li</dc:creator>
				<category><![CDATA[Popular]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://rayli.net/blog/?p=77</guid>
		<description><![CDATA[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 [...]]]></description>
			<content:encoded><![CDATA[<p>In a comment for a previous post (<a title="Top 10 differences between Java and C#" href="http://rayli.net/blog/2008/04/top-10-differences-between-java-and-c/">Top 10 differences between Java and C#</a>), John P. Wood wrote:</p>
<blockquote><p>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.</p>
<p><span id="more-77"></span>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.</p></blockquote>
<p>Like these 3 posts (<a title="Interfaces (C# Programming Guide)" href="http://msdn.microsoft.com/en-us/library/ms173156.aspx" target="_self">1</a> (bottom), <a title="Abstract/Interface question" href="http://social.msdn.microsoft.com/Forums/en-US/csharplanguage/thread/f1f8106c-d2e8-436c-9ee9-6b3e6731d185/" target="_self">2</a>, <a title="Why do abstract classes need to   implement interface members?" href="http://jelle.druyts.net/CommentView.aspx?guid=fe5e801e-71e5-474e-8235-01b2ad14ff68" target="_self">3</a>), 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?</p>
<p>I believe it&#8217;s a natural artifact of virtual and non-virtual methods in C# (<a title="Gotcha #2 - I can’t override!?" href="http://rayli.net/blog/2008/04/top-10-differences-between-java-and-c/#override">gotcha #2</a>).  In Java, methods are virtual by default (as far as I&#8217;m aware, Java doesn&#8217;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&#8217;s exactly what each options means:</p>
<ol>
<li><strong>abstract </strong>- No attempt at an implementation is made in the abstract class.  It&#8217;s up to the first concrete class to provide an implementation.  As a side note, defining a method as <em>abstract </em>implicitly defines it as <em>virtual</em>.  If this weren&#8217;t the case, you wouldn&#8217;t be able to override it in the child class which defeats the purpose of an abstract method.</li>
<li><strong>virtual </strong>- 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.</li>
<li><strong>non-virtual</strong> &#8211; 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 <em>non-virtual</em> method defined by the abstract class.</li>
</ol>
<p>Java can do options 1 and 2, but it lacks option 3.  Java could define the method as <em>final</em> to prevent it from being overriden, but this is slightly different than <em>non-virtual</em>.  The <em>final </em>keyword is more along the lines of <em>seal</em> 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 <em>virtual </em>by default.  However, this would be inconsistent with C# methods being <em>non-virtual</em> by default.</p>
<p>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&#8217;s my best guess&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://rayli.net/blog/2008/09/why-does-an-abstract-class-need-to-implement-interface-methods/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Portrait vs landscape, CRF design for a tablet PC</title>
		<link>http://rayli.net/blog/2008/08/portrait-vs-landscape-crf-design-for-a-tablet-pc/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=portrait-vs-landscape-crf-design-for-a-tablet-pc</link>
		<comments>http://rayli.net/blog/2008/08/portrait-vs-landscape-crf-design-for-a-tablet-pc/#comments</comments>
		<pubDate>Thu, 14 Aug 2008 16:18:21 +0000</pubDate>
		<dc:creator>Raymond Li</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[CRF Design]]></category>
		<category><![CDATA[Tablet PC]]></category>

		<guid isPermaLink="false">http://rayli.net/blog/?p=72</guid>
		<description><![CDATA[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 [...]]]></description>
			<content:encoded><![CDATA[<p><em><a href="http://rayli.net/ref/2008-08/hp_tablet_pc_tc1100.jpg"><img class="alignleft" title="HP Tablet PC (convertible)" src="/ref/2008-08/hp_tablet_pc_tc1100.jpg" alt="HP Tablet PC (convertible)" width="150" height="141" /></a>How do you systematically make use of the varied Tablet PC screen resolution dimensions using C#?</em></p>
<p>Designing a CRF specifically for a Tablet PC can be a challenging experience, but it can also be one of the most rewarding.</p>
<p>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&#8217;s Windows XP Tablet PC Edition or Vista (which has built-in support for Tablet PC specific functionality), you&#8217;re basically dealing with a Windows machine and you can pretty much treat it as such&#8230;  almost.</p>
<p><span id="more-72"></span>Maybe it&#8217;s not so much the variety.  One of my biggest obstacles was that the dimensions change.  They don&#8217;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!</p>
<p>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&#8217;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&#8217;s say you have a layout for making use of the added height or width, how do you know when to use which?</p>
<p>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:</p>
<pre class="brush: csharp; title: ; notranslate">
public bool IsPortrait()
{
    return Screen.PrimaryScreen.Bounds.Height &gt;
        Screen.PrimaryScreen.Bounds.Width;
}

public bool IsLandscape()
{
    return !this.IsPortrait();
}
</pre>
<p>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 <em>Form_Load()</em> method:</p>
<pre class="brush: csharp; title: ; notranslate">
Microsoft.Win32.SystemEvents.DisplaySettingsChanged +=
    new EventHandler(SystemEvents_DisplaySettingsChanged);
</pre>
<p>Now, define the event handler:</p>
<pre class="brush: csharp; title: ; notranslate">
void SystemEvents_DisplaySettingsChanged(object sender, EventArgs e)
{
    if (ScreenProperties.IsPortrait())
        // do portrait handling
    else
        // do landscape handling
}
</pre>
<p>And just like that, your form is now responding to screen resolution dimension changes!</p>
]]></content:encoded>
			<wfw:commentRss>http://rayli.net/blog/2008/08/portrait-vs-landscape-crf-design-for-a-tablet-pc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

