<?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>Computer technology</title>
	<atom:link href="http://computer-tech.info/feed/" rel="self" type="application/rss+xml" />
	<link>http://computer-tech.info</link>
	<description>Turn computer became our best friend</description>
	<lastBuildDate>Fri, 18 Nov 2011 17:00:26 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Text and XML Configuration Files</title>
		<link>http://computer-tech.info/2011/11/text-and-xml-configuration-files/</link>
		<comments>http://computer-tech.info/2011/11/text-and-xml-configuration-files/#comments</comments>
		<pubDate>Fri, 18 Nov 2011 17:00:26 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Shortcuts]]></category>
		<category><![CDATA[Configuration]]></category>
		<category><![CDATA[Files]]></category>
		<category><![CDATA[text]]></category>

		<guid isPermaLink="false">http://computer-tech.info/2011/11/text-and-xml-configuration-files/</guid>
		<description><![CDATA[Text Configuration files and XML Configuration files are a problem for both operating systems and applications. Where do you keep them, how are they structured? Traditionally, Unix systems used text...]]></description>
			<content:encoded><![CDATA[<div style="float:right;width:300px;margin-left:8px;"> </div>
<h2>Text Configuration files and XML</h2>
<p>Configuration files are a problem for both operating systems and applications. Where do you keep them, how are they structured?</p>
<p>Traditionally, Unix systems used text files with wildly varying internal structures, and Windows used either binary data or &#8220;.ini&#8221; text files (in this sense, &#8220;binary&#8221; is used for anything that you can&#8217;t access directly with a simple text editor). More recently, Windows abandoned .ini files in favor of a binary central registry.</p>
<p>The benefits of using a simple text format for configuration files should be obvious: nothing to learn (assuming that you can figure out WHAT to edit), and far more robust &#8211; no internal pointers to get screwed up, etc. The downside is that reading these files is slower, but realistically that is almost insignificant. There is also the annoyance of converting any required binary values to and from text, but again, that shouldn&#8217;t be anything that really slows down the reading or writing.</p>
<p>However, the ease of editing can be seen as a disadvantage also: if a proprietary tool is necessary for accessing the files, you can impose consistency checks and possibly avoid the introduction of garbage.</p>
<p>I lean toward text files. It is possible to provide validation tools that CAN be used, and even SHOULD be used under ordinary circumstances, while leaving the ability to directly edit raw text when circumstances are not ordinary. A good example of that philosophy is the &#8220;visudoers&#8221; command (see http://aplawrence.com/Basics/sudo.html ). You should use visudoers ordinarily, but if for some reason you could not, you can edit the /etc/sudoers file directly. Some systems provide special editors for the /etc/passwd file for the same reasons, and of course your normal &#8220;editing&#8221; of that is through other tools like &#8220;useradd&#8221; etc.</p>
<p>However, the structure of text configuration files is still a problem. Everything has its own format: /etc/passwd is nothing like /etc/sudoers and neither have any resemblance to /etc/fstab. There&#8217;s no common structure. Unix generally ignored this problem, but Windows tried &#8220;.ini&#8221; files to impose some consistency. Unfortunately, the .ini format doesn&#8217;t really cut it, because it&#8217;s just too simplistic. There have been some attempts to extend .ini to allow nesting and other features, but most agree that it just doesn&#8217;t have legs and isn&#8217;t a good solution. Windows didn&#8217;t drop .ini files entirely (they couldn&#8217;t, simply because of legacy concerns) but they did strongly discourage their use and also provided some integration of .ini into the Registry: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnw98bk/html/inifilesversusregistry.asp With Mac OS X, Apple has taken a different approach and uses XML property lists for most configuration data. Using XML provides a consistent data format that is easily hand or program edited.</p>
<p>For example, here&#8217;s the start of my ~/Library/Preferences/com.apple.internetconfig.plist:</p>
<pre><font color="#006666" size=1 face=verdana>&lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt; &lt;plist version="1.0"&gt; &lt;dict&gt;</font></pre>
<p>If we look carefully, it&#8217;s easy enough to find the home page setting there:</p>
<pre><font color="#006666" size=1 face=verdana>&lt;key&gt;WWWHomePage&lt;/key&gt;                         &lt;dict&gt;                                 &lt;key&gt;ic-data&lt;/key&gt;                                 &lt;string&gt;http://www.pcunix.com/index.html&lt;/string&gt;                         &lt;/dict&gt;</font></pre>
<p>and, of course, many other settings and preferences. Every Mac OS X app uses XML property lists too; see http://aplawrence.com/MacOSX/twosafaris.html  for an example of those. Apple doesn&#8217;t suggest you edit plists directly, of course: there are tools for setting preferences and you should use these whenever possible. But knowing that I can edit these files easily gives me more confidence in my ability to diagnose and fix problems.</p>
]]></content:encoded>
			<wfw:commentRss>http://computer-tech.info/2011/11/text-and-xml-configuration-files/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Simple Image / Link Rollover in Javascript</title>
		<link>http://computer-tech.info/2011/11/a-simple-image-link-rollover-in-javascript/</link>
		<comments>http://computer-tech.info/2011/11/a-simple-image-link-rollover-in-javascript/#comments</comments>
		<pubDate>Thu, 17 Nov 2011 17:00:25 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Shortcuts]]></category>
		<category><![CDATA[Image]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[link]]></category>
		<category><![CDATA[Rollover]]></category>
		<category><![CDATA[Simple]]></category>

		<guid isPermaLink="false">http://computer-tech.info/2011/11/a-simple-image-link-rollover-in-javascript/</guid>
		<description><![CDATA[Image/Link Rollover in Javascript Your web site has been up and running for some time and while you are pleased with the results, you can&#8217;t help but think that it...]]></description>
			<content:encoded><![CDATA[<div style="float:right;width:300px;margin-left:8px;"> </div>
<h2>Image/Link Rollover in Javascript</h2>
<p>Your web site has been up and running for some time and while you are pleased with the results, you can&#8217;t help but think that it needs a little bit more &#8220;something&#8221;.</p>
<p>Maybe a tweak or two to make it stand out a little more. Nothing flashy or too complicated.</p>
<p>Maybe you want to do something with the links, like add some pictures or a &#8220;rollover effect&#8221;. Well, maybe not all the links; just one or two. There&#8217;s a fine line between classy and gaudy.</p>
<p>The problem is: you know nothing about Javascript. To you and a lot of people Javascript looks like ancient Vulcan. And yet there is a solution. Cut and paste comes to mind.</p>
<p>Just head on over to your friendly free Java source, find what you need and cut and paste it into your web page. Sounds simple enough. BUT. As the universe has shown us time and time again&#8230;nothing is simple.</p>
<p>Now a couple of hours have passed and you still haven&#8217;t found what you were looking for. It seems the Java codes you have been looking at, all deal with muliple images and a humoungus amount of code to place in the &#8220;head section&#8221; and nowhere does it give you instructions as to how to make the rest of the Java code fit into your web page. Forget about where you want to put it.</p>
<p>Believe it or not, there is a small compact Javascript that you can paste into your web page and put it where you want it. And the added bonus is: it&#8217;s a image link.</p>
<p>You will need three pictures in gif, jpg or bmp: your choice. Two of the three pictures must be the same.</p>
<p>Now here&#8217;s the Javascript:</p>
<p>&lt;SCRIPT LANGUAGE=&#8221;JavaScript&#8221;&gt;</p>
<p>Step one: Paste this code into the Head section of your HTML of your document.</p>
<p>&lt;Head&gt;</p>
<p>&lt;script&gt;</p>
<p>{!&#8211; Hide Script function move_in(img_name,img_src) { document[img_name].src=img_src; }</p>
<p>function move_out(img_name,img_src) { document[img_name].src=img_src; }</p>
<p>//End Hide Script&#8211;}</p>
<p>&lt;/script&gt;</p>
<p>&lt;/head?&gt;</p>
<p>Step two: Paste this code into the Body of your Html document</p>
<p>&lt;body&gt;</p>
<p>{a href=&#8221;anylink.html</p>
<p>OnMouseOver=&#8221;move_in(&#8216;image1&#8242;,&#8217;image_on.gif&#8217;)&#8221;</p>
<p>OnMouseOut=&#8221;move_out(&#8216;image1&#8242;,&#8217;image_out.gif&#8217;)&#8221;}</p>
<p>&lt;img src=&#8221;image_out.gif&#8221;&gt;</p>
<p>&lt;alt=&#8221;Move your mouse over here!&#8221; name=&#8221;image1&#8243;&gt;</p>
<p>&lt; /a&gt;</p>
<p>&lt;/body&gt;</p>
<p>&lt;/html&gt;</p>
<p>Now look down under the &#8220;body&#8221; tag and you will see: OnMouseOver=&#8221;move_in(&#8216;image1&#8242;,&#8217;image_on.gif&#8217;)&#8221;. Image_on.gif is the picture you want displayed. Image_out is what will be seen when you roll your mouse over the image.</p>
<p>So far that&#8217;s two images. The final image will go into the last peice of code which is &#8220;image_out.gif&#8221;. This should be your copy image. You can also change the information in the &#8220;alt&#8221; tag to whatever you like. Place any link you want in the &#8220;link&#8221; tag.</p>
<p>This little peice of Javascript code makes a great preview picture link for whatever site you want to link it to. Have fun with this. Experiment with different images or just use text and an image. It&#8217;s very versatile. I think it works best in tables and should be most effective in getting some attention for you web pages.</p>
]]></content:encoded>
			<wfw:commentRss>http://computer-tech.info/2011/11/a-simple-image-link-rollover-in-javascript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Pros and Cons of Business Blogging (Part 1)</title>
		<link>http://computer-tech.info/2011/11/the-pros-and-cons-of-business-blogging-part-1/</link>
		<comments>http://computer-tech.info/2011/11/the-pros-and-cons-of-business-blogging-part-1/#comments</comments>
		<pubDate>Wed, 16 Nov 2011 17:00:24 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Shortcuts]]></category>
		<category><![CDATA[Blogging]]></category>
		<category><![CDATA[Business]]></category>
		<category><![CDATA[Cons]]></category>
		<category><![CDATA[part]]></category>
		<category><![CDATA[Pros]]></category>

		<guid isPermaLink="false">http://computer-tech.info/2011/11/the-pros-and-cons-of-business-blogging-part-1/</guid>
		<description><![CDATA[From Dell to Intel, companies have started to put up their own blogs as a new way to communicate with their customers. A lot of smaller businesses are trying to...]]></description>
			<content:encoded><![CDATA[<div style="float:right;width:300px;margin-left:8px;"> </div>
<p>From Dell to Intel, companies have started to put up their own blogs as a new way to communicate with their customers. A lot of smaller businesses are trying to follow in their footsteps (with various levels of success). The question is: <em>“Is it really worth it?”</em></p>
<p><strong>The Good Stuff</strong></p>
<p>1. <strong>Getting Personal.</strong> Many businesses already publish newsletters for their clients, but blogging takes client communications to a higher plane. The key is interaction. Blogging is a two-way street, usually in an informal atmosphere. With it, one can create a strong personal relationship with customers, encouraging brand loyalty.</p>
<p>2. <strong>Reader-friendly.</strong> The basic blog format is clean and simple (unless cluttered up by ads). If you use any of the popular platforms such as WordPress, there are hundreds of great-looking free templates you can choose from. And, since people are used to blogs by this time, it’s easy for them to digest your content and navigate through your site.</p>
<p>3. <strong>Uncomplicated.</strong> You don’t have to be a very technical person to start a blog. Most can be set up in a matter of minutes. Enhancements like polls, podcast widgets and other plug-and-play add-ons are also available.</p>
<p>4. <strong>Low-cost.</strong> Blog setup can range from free, if you use a specialized blog host such as Blogger, to a few hundred dollars, depending on whether you plan to get your own webhost and use a personalized domain name. Of course, the latter will appear more professional.</p>
<p>5. <strong>Blog as portfolio.</strong> Aside from featuring the latest announcements from your company, your business blog can include articles on the latest trends in your industry, to show people that you are up-to-date and that your products and services reflect that. You can also post in-depth how-tos, reports, or opinion pieces that can build your credibility as an expert.</p>
]]></content:encoded>
			<wfw:commentRss>http://computer-tech.info/2011/11/the-pros-and-cons-of-business-blogging-part-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Floating Point Comparisons In PHP and Javascript</title>
		<link>http://computer-tech.info/2011/11/floating-point-comparisons-in-php-and-javascript/</link>
		<comments>http://computer-tech.info/2011/11/floating-point-comparisons-in-php-and-javascript/#comments</comments>
		<pubDate>Tue, 15 Nov 2011 17:00:30 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Shortcuts]]></category>
		<category><![CDATA[Comparisons]]></category>
		<category><![CDATA[Floating]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Point]]></category>

		<guid isPermaLink="false">http://computer-tech.info/2011/11/floating-point-comparisons-in-php-and-javascript/</guid>
		<description><![CDATA[Beware Comparing Floating Point Values Can Be Hazardous! The curse of the .0000000001 and .9999999999!” Here’s the problem. Say you’re comparing two floating point numbers a (71.00) and b (71.00)...]]></description>
			<content:encoded><![CDATA[<div style="float:right;width:300px;margin-left:8px;"> </div>
<h2>Beware Comparing Floating Point Values Can Be Hazardous!</h2>
<h3>The curse of the .0000000001 and .9999999999!”</h3>
<p>Here’s the problem. Say you’re comparing two floating point numbers<br /> a (71.00) and b (71.00) to see if they are the same. The problem is if<br /> you’ve done any calculations to arrive at these numbers they might<br /> actually be stored as 71.00000000001. Now if one of them is stored that<br /> way and the other isn’t and you compare the two to see if they are<br /> equal you’ll get a FALSE as the response, even though they should be<br /> the same.</p>
<p>This isn’t a bug, it’s how floating point comparisons are designed<br /> to work. It makes it so people writing complex software that requires<br /> floating point arithmetic can do what they need to. Unfortunately for<br /> the rest of us that usually are just using floating point numbers to<br /> represent things like currency (dollars in my case) it really makes<br /> life difficult!</p>
<h2>PHP Floating Point Comparison Made Easy</h2>
<p>Here’s my php function that compares floating point numbers:</p>
<pre style="clear: both;"><code>function moneycomp($a,$comp,$b,$decimals=2) {	$res = bccomp($a,$b,$decimals); // php function for comparing floating point numbers with a specified level of precision	switch ($comp) {		case &quot;&gt;&quot;:			return ($res==1);		case &quot;&gt;=&quot;:			return ($res==1 || $res==0);		case &quot;&lt;&quot;:			return ($res==-1);		case &quot;&lt;=&quot;:			return ($res==-1 || $res==0);		default:		case &quot;==&quot;:			return ($res==0);	}}  // example usage: if ($total &gt; $payments) ...if (moneycomp($total,'&gt;',$payments)) ...  // example usage: if ($debt &lt;= $income) ...if (moneycomp($debt,'&lt;=',$income) ...  // example usage: if ($cost == $price) ...if (moneycomp($cost,'==',$price) ...</code></pre>
<p>So that makes life really simple. You just write your comparisons wrapped in the moneycomp() function.</p>
<h2>Javascript Floating Point Comparison Made Easy</h2>
<p>And here’s my javascript function that compares floating point numbers:</p>
<pre style="clear: both;"><code>function moneycomp(a,comp,b,decimals) {	if (!decimals)		decimals = 2;	var multiplier = Math.pow(10,decimals);	a = Math.round(a * multiplier); // multiply to do integer comparison instead of floating point	b = Math.round(b * multiplier);	switch (comp) {		case &quot;&gt;&quot;:			return (a &gt; b);		case &quot;&gt;=&quot;:			return (a &gt;= b);		case &quot;&lt;&quot;:			return (a &lt; b);		case &quot;&lt;=&quot;:			return (a &lt;= b);		case &quot;==&quot;:			return (a == b);	}	return null;}  // example usage: if (total &gt; payments) ...if (moneycomp(total,'&gt;',payments)) ...  // example usage: if (debt &lt;= income) ...if (moneycomp(debt,'&lt;=',income) ...  // example usage: if (cost == price) ...if (moneycomp(cost,'==',price) ...</code></pre>
<h2>Resources And Further Reading</h2>
<ul class="unordered">
<li>PHP Floating Point Numbers </li>
<li>PHP Gotchas! </li>
<li>PHP Manual: bccomp() function </li>
<li>Javascript Math Functions </li>
<li>Mozilla Documentation &#8211; Javascript 1.5 Math Object </li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://computer-tech.info/2011/11/floating-point-comparisons-in-php-and-javascript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Flexible Method of Storing Control Data</title>
		<link>http://computer-tech.info/2011/11/a-flexible-method-of-storing-control-data/</link>
		<comments>http://computer-tech.info/2011/11/a-flexible-method-of-storing-control-data/#comments</comments>
		<pubDate>Tue, 15 Nov 2011 08:25:39 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Shortcuts]]></category>
		<category><![CDATA[control]]></category>
		<category><![CDATA[Data]]></category>
		<category><![CDATA[Flexible]]></category>
		<category><![CDATA[Method]]></category>
		<category><![CDATA[Storing]]></category>

		<guid isPermaLink="false">http://computer-tech.info/2011/11/a-flexible-method-of-storing-control-data/</guid>
		<description><![CDATA[Introduction Where an application requires certain values at runtime, and where these values may be changed at irregular intervals, it is common practice to hold these on a database record...]]></description>
			<content:encoded><![CDATA[<div style="float:right;width:300px;margin-left:8px;"> </div>
<h2>Introduction</h2>
<p>Where an application requires certain values at runtime, and where these values may be changed at irregular intervals, it is common practice to hold these on a database record rather than having them hard-coded into any program. This means that should any of these values ever change it is a simple matter of updating the database rather than changing, compiling and releasing individual program modules. This can be a problem, of course, if one of the modules is missed out.</p>
<p>The traditional approach is to have a single control record containing a separate field for each item of data. However, this has the following disadvantages:</p>
<ul>
<li>It can result in a very large record structure, which could be a problem as most database engines have a limit to the number of columns (fields) in a table.</li>
<li>Adding or removing items on the control record requires a change to the physical database structure. All components which reference this structure would then have to be recompiled.</li>
<li>Any component which updates any control data will have to lock the entire record. This may cause delays to other components which try to update the same record at the same time.</li>
</ul>
<h2>A flexible approach</h2>
<p>After encountering those disadvantages on more than one occasion I decided on a different and more flexible approach. Instead of a single record containing many values I have each value on its own record, which therefore results in many records. The trick is to store these values in separate records in the database, but to present them to the user in a single screen as if they were separate values on a single record. How is this possible? Read on and learn.</p>
<p>First, let us start with the database structure:</p>
<pre>CREATE TABLE `mnu_control` (  `record_id` varchar(16) NOT NULL default '',  `field_id` varchar(32) NOT NULL default '',  `field_value` varchar(255) default NULL,  PRIMARY KEY  (`record_id`,`field_id`));</pre>
<table width="100%" cellspacing="0" cellpadding="0" border="1">
<tr>
<th>Field ID</th>
<th>Description</th>
</tr>
<tr>
<td>RECORD_ID</td>
<p><td>is used to group various records into logical sets. The same table could be</p>
<p>used by multiple applications, so by setting RECORD_ID to the application name</p>
<p>each application&#8217;s data can be kept separate from the other, even if any</p>
<p>FIELD_IDs are the same.</td>
</tr>
<tr>
<td>FIELD_ID</td>
<p><td>is the name of the field, unqualified, in upper case.</td>
</tr>
<tr>
<td>FIELD_VALUE</td>
<p><td>is a string field as its holds any value in display format regardless of the interface definition (number, date, time, boolean, etc) of the source field on the screen.</td>
</tr>
</tbody>
</table>
<p><p>Second, build a screen where these records can be displayed and modified:</p>
<p><img src="http://c0004521.cdn2.cloudfiles.rackspacecloud.com/wp-content/uploads/2006/08/control-data.gif" /></p>
<p>As you can see this looks like a completely normal screen, which is the whole idea.</p>
<h2>Implementation</h2>
<p>Although I have previous implemented this design in a different language  this article shows my latest implementation in PHP  using my own development framework.</p>
<p><strong>Changing the table structure </strong></p>
<p>The first step is to update the internal table definition by replacing the physical database structure with the theoretical structure. The &quot;physical&quot; structure, as exported from the Data Dictionary, is as follows:</p>
<pre>    <span class="default">$fieldspec</span>[<span class="string">'record_id'</span>]                 = array(<span class="string">'type'</span> =&gt; <span class="string">'string'</span>,                                                    <span class="string">'size'</span> =&gt; <span class="string">16</span>,                                                    <span class="string">'pkey'</span> =&gt; <span class="string">'y'</span>,                                                    <span class="string">'required'</span> =&gt; <span class="string">'y'</span>,                                                    <span class="string">'uppercase'</span> =&gt; <span class="string">'y'</span>);      <span class="default">$fieldspec</span>[<span class="string">'field_id'</span>]                  = array(<span class="string">'type'</span> =&gt; <span class="string">'string'</span>,                                                    <span class="string">'size'</span> =&gt; <span class="string">32</span>,                                                    <span class="string">'pkey'</span> =&gt; <span class="string">'y'</span>,                                                    <span class="string">'required'</span> =&gt; <span class="string">'y'</span>,                                                    <span class="string">'uppercase'</span> =&gt; <span class="string">'y'</span>);      <span class="default">$fieldspec</span>[<span class="string">'field_value'</span>]               = array(<span class="string">'type'</span> =&gt; <span class="string">'string'</span>,                                                    <span class="string">'size'</span> =&gt;<span class="string"> 255</span>);</pre>
<p><p>This structure  can be replaced at runtime with</p>
<p>the following code:</p>
<pre>    function _cm_changeConfig (<span class="default">$where</span>, <span class="default">$fieldarray</span>)    <span class="comment">// Change the table configuration for the duration of this instance.</span>    {        <span class="comment">// default language code</span>        <span class="default">$fieldspec</span>[<span class="string">'default_language'</span>]      = array(<span class="string">'type'</span> =&gt; <span class="string">'string'</span>,                                                    <span class="string">'size'</span> =&gt; <span class="string">5</span>,                                                    <span class="string">'required'</span> =&gt; <span class="string">'y'</span>,                                                    <span class="string">'lowercase'</span> =&gt; <span class="string">'y'</span>,                                                    <span class="string">'control'</span> =&gt; <span class="string">'dropdown'</span>,                                                    <span class="string">'optionlist'</span> =&gt; <span class="string">'language_code'</span>);          <span class="comment">// how often must the user change his password?</span>        <span class="default">$fieldspec</span>[<span class="string">'pswd_change'</span>]           = array(<span class="string">'type'</span> =&gt; <span class="string">'string'</span>,                                                    <span class="string">'size'</span> =&gt; <span class="string">2</span>,                                                    <span class="string">'required'</span> =&gt; <span class="string">'y'</span>,                                                    <span class="string">'uppercase'</span> =&gt; <span class="string">'y'</span>,                                                    <span class="string">'control'</span> =&gt; <span class="string">'radiogroup'</span>,                                                    <span class="string">'optionlist'</span> =&gt; <span class="string">'pswd_change'</span>,                                                    <span class="string">'align_hv'</span> =&gt; <span class="string">'vertical'</span>);        <span class="comment">// change password after 'n' logons</span>        <span class="default">$fieldspec</span>[<span class="string">'pswd_count'</span>]            = array(<span class="string">'type'</span> =&gt; <span class="string">'integer'</span>,                                                    <span class="string">'size'</span> =&gt; <span class="string">3</span>,                                                    <span class="string">'unsigned'</span> =&gt; <span class="string">'y'</span>);        <span class="comment">// change password after 'n' days</span>        <span class="default">$fieldspec</span>[<span class="string">'pswd_days'</span>]             = array(<span class="string">'type'</span> =&gt; <span class="string">'integer'</span>,                                                    <span class="string">'size'</span> =&gt; <span class="string">3</span>,                                                    <span class="string">'unsigned'</span> =&gt; <span class="string">'y'</span>);        <span class="comment">// an invalid password can be tried 'n' times after which the user_id will be disabled</span>        <span class="default">$fieldspec</span>[<span class="string">'pswd_retries'</span>]          = array(<span class="string">'type'</span> =&gt; <span class="string">'integer'</span>,                                                    <span class="string">'size'</span> =&gt; <span class="string">3</span>,                                                    <span class="string">'unsigned'</span> =&gt; <span class="string">'y'</span>);        <span class="comment">// issue a &quot;password will expire in N days/logons&quot; warning</span>        <span class="default">$fieldspec</span>[<span class="string">'pswd_warning'</span>]          = array(<span class="string">'type'</span> =&gt; <span class="string">'integer'</span>,                                                    <span class="string">'size'</span> =&gt; <span class="string">3</span>,                                                    <span class="string">'unsigned'</span> =&gt; <span class="string">'y'</span>);        <span class="comment">// specify the format of user passwords</span>        <span class="default">$fieldspec</span>[<span class="string">'pswd_format_minlen'</span>]    = array(<span class="string">'type'</span> =&gt; <span class="string">'integer'</span>,                                                    <span class="string">'size'</span> =&gt; <span class="string">3</span>,                                                    <span class="string">'unsigned'</span> =&gt; <span class="string">'y'</span>,                                                    <span class="string">'required'</span> =&gt; <span class="string">'y'</span>,                                                    <span class="string">'minvalue'</span> =&gt; <span class="string">1</span>);        <span class="default">$fieldspec</span>[<span class="string">'pswd_format_upper'</span>]     = array(<span class="string">'type'</span> =&gt; <span class="string">'integer'</span>,                                                    <span class="string">'size'</span> =&gt; <span class="string">3</span>,                                                    <span class="string">'unsigned'</span> =&gt; <span class="string">'y'</span>);        <span class="default">$fieldspec</span>[<span class="string">'pswd_format_lower'</span>]     = array(<span class="string">'type'</span> =&gt; <span class="string">'integer'</span>,                                                    <span class="string">'size'</span> =&gt; <span class="string">3</span>,                                                    <span class="string">'unsigned'</span> =&gt; <span class="string">'y'</span>);        <span class="default">$fieldspec</span>[<span class="string">'pswd_format_digits'</span>]    = array(<span class="string">'type'</span> =&gt; <span class="string">'integer'</span>,                                                    <span class="string">'size'</span> =&gt; <span class="string">3</span>,                                                    <span class="string">'unsigned'</span> =&gt; <span class="string">'y'</span>);        <span class="comment">// are passwords to be encrypted on the database?</span>        <span class="default">$fieldspec</span>[<span class="string">'pswd_encrypt'</span>]          = array(<span class="string">'type'</span> =&gt; <span class="string">'boolean'</span>,                                                    <span class="string">'true'</span> =&gt; <span class="string">'Y'</span>,                                                    <span class="string">'false'</span> =&gt; <span class="string">'N'</span>);        <span class="comment">// are passwords to be visible in the update/enquiry screens?</span>        <span class="default">$fieldspec</span>[<span class="string">'pswd_hidden'</span>]           = array(<span class="string">'type'</span> =&gt; <span class="string">'boolean'</span>,                                                    <span class="string">'true'</span> =&gt; <span class="string">'Y'</span>,                                                    <span class="string">'false'</span> =&gt; <span class="string">'N'</span>);          <span class="comment">// define lockout times between which system is unavailable</span>        <span class="default">$fieldspec</span>[<span class="string">'shutdown_start'</span>]        = array(<span class="string">'type'</span> =&gt; <span class="string">'time'</span>,                                                    <span class="string">'size'</span> =&gt; <span class="string">5</span>);        <span class="default">$fieldspec</span>[<span class="string">'shutdown_end'</span>]          = array(<span class="string">'type'</span> =&gt; <span class="string">'time'</span>,                                                    <span class="string">'size'</span> =&gt; <span class="string">5</span>);        <span class="default">$fieldspec</span>[<span class="string">'shutdown_warning'</span>]      = array(<span class="string">'type'</span> =&gt; <span class="string">'time'</span>,                                                    <span class="string">'size'</span> =&gt; <span class="string">5</span>);          <span class="default">$day_names</span> = getLanguageArray(<span class="string">'day_names_short'</span>);          <span class="default">$fieldspec</span>[<span class="string">'shutdown_monday'</span>]       = array(<span class="string">'type'</span> =&gt; <span class="string">'boolean'</span>,                                                    <span class="string">'true'</span> =&gt; <span class="string">'Y'</span>,                                                    <span class="string">'false'</span> =&gt; <span class="string">'N'</span>,                                                    <span class="string">'control'</span> =&gt; <span class="string">'checkbox'</span>,                                                    <span class="string">'label'</span> =&gt; <span class="default">$day_names</span>[<span class="string">'mon'</span>],                                                    <span class="string">'align_lr'</span> =&gt; <span class="string">'left'</span>);          <span class="default">$fieldspec</span>[<span class="string">'shutdown_tuesday'</span>]      = array(<span class="string">'type'</span> =&gt; <span class="string">'boolean'</span>,                                                    <span class="string">'true'</span> =&gt; <span class="string">'Y'</span>,                                                    <span class="string">'false'</span> =&gt; <span class="string">'N'</span>,                                                    <span class="string">'control'</span> =&gt; <span class="string">'checkbox'</span>,                                                    <span class="string">'label'</span> =&gt; <span class="default">$day_names</span>[<span class="string">'tue'</span>],                                                    <span class="string">'align_lr'</span> =&gt; <span class="string">'left'</span>);        <span class="default">$fieldspec</span>[<span class="string">'shutdown_wednesday'</span>]    = array(<span class="string">'type'</span> =&gt; <span class="string">'boolean'</span>,                                                    <span class="string">'true'</span> =&gt; <span class="string">'Y'</span>,                                                    <span class="string">'false'</span> =&gt; <span class="string">'N'</span>,                                                    <span class="string">'control'</span> =&gt; <span class="string">'checkbox'</span>,                                                    <span class="string">'label'</span> =&gt; <span class="default">$day_names</span>[<span class="string">'wed'</span>],                                                    <span class="string">'align_lr'</span> =&gt; <span class="string">'left'</span>);        <span class="default">$fieldspec</span>[<span class="string">'shutdown_thursday'</span>]     = array(<span class="string">'type'</span> =&gt; <span class="string">'boolean'</span>,                                                    <span class="string">'true'</span> =&gt; <span class="string">'Y'</span>,                                                    <span class="string">'false'</span> =&gt; <span class="string">'N'</span>,                                                    <span class="string">'control'</span> =&gt; <span class="string">'checkbox'</span>,                                                    <span class="string">'label'</span> =&gt; <span class="default">$day_names</span>[<span class="string">'thu'</span>],                                                    <span class="string">'align_lr'</span> =&gt; <span class="string">'left'</span>);        <span class="default">$fieldspec</span>[<span class="string">'shutdown_friday'</span>]       = array(<span class="string">'type'</span> =&gt; <span class="string">'boolean'</span>,                                                    <span class="string">'true'</span> =&gt; <span class="string">'Y'</span>,                                                    <span class="string">'false'</span> =&gt; <span class="string">'N'</span>,                                                    <span class="string">'control'</span> =&gt; <span class="string">'checkbox'</span>,                                                    <span class="string">'label'</span> =&gt; <span class="default">$day_names</span>[<span class="string">'fri'</span>],                                                    <span class="string">'align_lr'</span> =&gt; <span class="string">'left'</span>);        <span class="default">$fieldspec</span>[<span class="string">'shutdown_saturday'</span>]     = array(<span class="string">'type'</span> =&gt; <span class="string">'boolean'</span>,                                                    <span class="string">'true'</span> =&gt; <span class="string">'Y'</span>,                                                    <span class="string">'false'</span> =&gt; <span class="string">'N'</span>,                                                    <span class="string">'control'</span> =&gt; <span class="string">'checkbox'</span>,                                                    <span class="string">'label'</span> =&gt; <span class="default">$day_names</span>[<span class="string">'sat'</span>],                                                    <span class="string">'align_lr'</span> =&gt; <span class="string">'left'</span>);        <span class="default">$fieldspec</span>[<span class="string">'shutdown_sunday'</span>]       = array(<span class="string">'type'</span> =&gt; <span class="string">'boolean'</span>,                                                    <span class="string">'true'</span> =&gt; <span class="string">'Y'</span>,                                                    <span class="string">'false'</span> =&gt; <span class="string">'N'</span>,                                                    <span class="string">'control'</span> =&gt; <span class="string">'checkbox'</span>,                                                    <span class="string">'label'</span> =&gt; <span class="default">$day_names</span>[<span class="string">'sun'</span>],                                                    <span class="string">'align_lr'</span> =&gt; <span class="string">'left'</span>);          <span class="default">$this</span>-&gt;fieldspec = <span class="default">$fieldspec</span>;          return <span class="default">$fieldarray</span>;      } <span class="comment">// _cm_changeConfig</span> </pre>
<p>This amended structure identifies the following:</p>
<ul class="compress">
<li>What fields need to be displayed on the screen.</li>
<li>How each field should be displayed (i.e. which HTML control to use).</li>
<li>How the user input for each field should be validated.</li>
</ul>
<h2>From database to screen</h2>
<p>The second step is to read multiple records from the database into an array using the following code:</p>
<pre><span class="default">$fieldarray</span> = <span class="default">$object</span>-&gt;getData(<span class="string">&quot;record_id='SYSTEM'&quot;</span>);</pre>
<p>At this point <code>$fieldarray</code> is a nested array &#8211; the first level is indexed by row number, and each row contains an associative array of <code>name=value</code> pairs. This looks like the following:</p>
<pre>$rowdata =&gt; Array(    [0] =&gt; Array        (            [record_id] =&gt; SYSTEM            [field_id] =&gt; DEFAULT_LANGUAGE            [field_value] =&gt; en        )      [1] =&gt; Array        (            [record_id] =&gt; SYSTEM            [field_id] =&gt; PSWD_CHANGE            [field_value] =&gt; AR        )      [2] =&gt; Array        (            [record_id] =&gt; SYSTEM            [field_id] =&gt; PSWD_COUNT            [field_value] =&gt;         )      [3] =&gt; Array        (            [record_id] =&gt; SYSTEM            [field_id] =&gt; PSWD_DAYS            [field_value] =&gt;         )      [4] =&gt; Array        (            [record_id] =&gt; SYSTEM            [field_id] =&gt; PSWD_ENCRYPT            [field_value] =&gt; Y        )      [5] =&gt; Array        (            [record_id] =&gt; SYSTEM            [field_id] =&gt; PSWD_FORMAT_DIGITS            [field_value] =&gt;         )      [6] =&gt; Array        (            [record_id] =&gt; SYSTEM            [field_id] =&gt; PSWD_FORMAT_LOWER            [field_value] =&gt;          )      [7] =&gt; Array        (            [record_id] =&gt; SYSTEM            [field_id] =&gt; PSWD_FORMAT_MINLEN            [field_value] =&gt; 4        )      [8] =&gt; Array        (            [record_id] =&gt; SYSTEM            [field_id] =&gt; PSWD_FORMAT_UPPER            [field_value] =&gt;          )      [9] =&gt; Array        (            [record_id] =&gt; SYSTEM            [field_id] =&gt; PSWD_HIDDEN            [field_value] =&gt; Y        )      [10] =&gt; Array        (            [record_id] =&gt; SYSTEM            [field_id] =&gt; PSWD_RETRIES            [field_value] =&gt; 3        )      [11] =&gt; Array        (            [record_id] =&gt; SYSTEM            [field_id] =&gt; PSWD_WARNING            [field_value] =&gt; 5        )      [12] =&gt; Array        (            [record_id] =&gt; SYSTEM            [field_id] =&gt; SHUTDOWN_END            [field_value] =&gt;         )      [13] =&gt; Array        (            [record_id] =&gt; SYSTEM            [field_id] =&gt; SHUTDOWN_FRIDAY            [field_value] =&gt;         )      [14] =&gt; Array        (            [record_id] =&gt; SYSTEM            [field_id] =&gt; SHUTDOWN_MONDAY            [field_value] =&gt;         )      [15] =&gt; Array        (            [record_id] =&gt; SYSTEM            [field_id] =&gt; SHUTDOWN_SATURDAY            [field_value] =&gt;         )      [16] =&gt; Array        (            [record_id] =&gt; SYSTEM            [field_id] =&gt; SHUTDOWN_START            [field_value] =&gt;         )      [17] =&gt; Array        (            [record_id] =&gt; SYSTEM            [field_id] =&gt; SHUTDOWN_SUNDAY            [field_value] =&gt;         )      [18] =&gt; Array        (            [record_id] =&gt; SYSTEM            [field_id] =&gt; SHUTDOWN_THURSDAY            [field_value] =&gt;         )      [19] =&gt; Array        (            [record_id] =&gt; SYSTEM            [field_id] =&gt; SHUTDOWN_TUESDAY            [field_value] =&gt;         )      [20] =&gt; Array        (            [record_id] =&gt; SYSTEM            [field_id] =&gt; SHUTDOWN_WARNING            [field_value] =&gt;         )      [21] =&gt; Array        (            [record_id] =&gt; SYSTEM            [field_id] =&gt; SHUTDOWN_WEDNESDAY            [field_value] =&gt;         ))</pre>
<p><p>This can be changed into a single row of data using the following code:</p>
<pre>    function _cm_post_getData (<span class="default">$rowdata</span>, &amp;<span class="default">$where</span>)    <span class="comment">// perform custom processing after database record(s) are retrieved.    // NOTE: $where is passed BY REFERENCE so that it may be modified.</span>    {        <span class="comment">// turn multiple rows into a single associative array</span>        foreach (<span class="default">$rowdata</span> as <span class="default">$row</span> =&gt; <span class="default">$data</span>) {            <span class="default">$fieldarray</span>[<span class="string">0</span>][strtolower(<span class="default">$data</span>[<span class="string">'field_id'</span>])] = <span class="default">$data</span>[<span class="string">'field_value'</span>];        } <span class="comment">// foreach</span>          <span class="comment">// get list of (virtual) fields in this table</span>        <span class="default">$fieldspec</span> = <span class="default">$this</span>-&gt;getFieldSpec();          <span class="comment">// insert any missing fields from $fieldspec</span>        foreach (<span class="default">$fieldspec</span> as <span class="default">$fieldname</span> =&gt; <span class="default">$spec</span>) {            if (!array_key_exists(strtolower(<span class="default">$fieldname</span>), <span class="default">$fieldarray</span>[<span class="string">0</span>])) {                <span class="default">$fieldarray</span>[<span class="string">0</span>][<span class="default">$fieldname</span>] = <span class="string">null</span>;            } <span class="comment">// if</span>        } <span class="comment">// foreach</span>          return <span class="default">$fieldarray</span>;      } <span class="comment">// _cm_post_getData</span> </pre>
<p>The new array looks like the following:</p>
<pre>$fieldarray =&gt; Array(    [0] =&gt; Array        (            [default_language] =&gt; en            [pswd_change] =&gt; AR            [pswd_count] =&gt;             [pswd_days] =&gt;             [pswd_encrypt] =&gt; Y            [pswd_format_digits] =&gt;             [pswd_format_lower] =&gt;             [pswd_format_minlen] =&gt; 4            [pswd_format_upper] =&gt;             [pswd_hidden] =&gt; Y            [pswd_retries] =&gt; 3            [pswd_warning] =&gt; 5            [shutdown_end] =&gt;             [shutdown_friday] =&gt;             [shutdown_monday] =&gt;             [shutdown_saturday] =&gt;             [shutdown_start] =&gt;             [shutdown_sunday] =&gt;             [shutdown_thursday] =&gt;             [shutdown_tuesday] =&gt;             [shutdown_warning] =&gt;             [shutdown_wednesday] =&gt;         ))</pre>
<p><p>This data is transferred to an XML document which is transformed into HTML by an XSL stylesheet. The information in the modified structure tells the stylesheet which HTML control to use for each field.</p>
<h2>From screen to database</h2>
<p>After the user has changed any values he presses the &quot;submit&quot; button to send those changes to the server for processing. Everyone knows that user input should never be trusted, and should be &quot;cleansed&quot; or &quot;filtered&quot; before being written to the database, and this common task can be performed automatically by the framework using the information contained with the modified structure. This will ensure that:</p>
<ul class="compress">
<li>Any field marked as &quot;required&quot; is not empty.</li>
<li>All string fields contain strings which do not exceed their maximum size.</li>
<li>All numeric fields contain numbers which do not exceed their maximum size, or fall below their minimum value.</li>
<li>All boolean fields contain a value which is either TRUE or FALSE.</li>
</ul>
<p><p>After this validation has been performed the data can be written to the database using the following code:</p>
<pre>    function _cm_updateSelection(<span class="default">$fieldarray</span>, <span class="default">$replace</span>)    <span class="comment">// update multiple rows in a single operation.</span>    {        <span class="default">$errors</span> = array();          <span class="comment">// set $fieldspec to the database view</span>        <span class="default">$this</span>-&gt;fieldspec = <span class="default">$this</span>-&gt;getFieldSpec_original();          <span class="comment">// get array of fieldnames in the primary key</span>        <span class="default">$pkeynames</span> = <span class="default">$this</span>-&gt;getPkeyNames();          <span class="comment">// now turn the array of columns into an array of rows</span>        <span class="default">$rowdata</span> = array();        <span class="default">$rownum</span> = <span class="string">0</span>;        foreach (<span class="default">$updatearray</span> as <span class="default">$fieldname</span> =&gt; <span class="default">$fieldvalue</span>) {            <span class="default">$rowdata</span>[<span class="default">$rownum</span>][<span class="string">'record_id'</span>]   = <span class="string">'system'</span>;            <span class="default">$rowdata</span>[<span class="default">$rownum</span>][<span class="string">'field_id'</span>]    = <span class="default">$fieldname</span>;            <span class="default">$rowdata</span>[<span class="default">$rownum</span>][<span class="string">'field_value'</span>] = <span class="default">$fieldvalue</span>;            <span class="comment">// construct 'where' clause from primary key</span>            <span class="default">$where</span> = array2where(<span class="default">$rowdata</span>[<span class="default">$rownum</span>], <span class="default">$pkeynames</span>);              <span class="comment">// find out if this record currently exists or not</span>            <span class="default">$count</span> = <span class="default">$this</span>-&gt;getCount(<span class="default">$where</span>);            if (<span class="default">$count</span> == <span class="string">0</span>) {                <span class="comment">// record does not exist, so create it</span>                <span class="default">$rowdata</span>[<span class="default">$rownum</span>] = <span class="default">$this</span>-&gt;insertRecord(<span class="default">$rowdata</span>[<span class="default">$rownum</span>]);            } else {                <span class="comment">// record already exists, so update it</span>                <span class="default">$rowdata</span>[<span class="default">$rownum</span>] = <span class="default">$this</span>-&gt;updateRecord(<span class="default">$rowdata</span>[<span class="default">$rownum</span>]);            } <span class="comment">// if</span>              if (!empty(<span class="default">$this</span>-&gt;errors)) {                <span class="comment">// ignore 'name' and extract 'value' from $this-&gt;errors                // as 'name' may not be the same as $fieldname</span>                <span class="default">$errors</span>[<span class="default">$fieldname</span>] = array_shift(<span class="default">$this</span>-&gt;errors);            } <span class="comment">// if</span>            <span class="default">$rownum</span> = <span class="default">$rownum</span> + <span class="string">1</span>;        } <span class="comment">// foreach</span>          <span class="default">$this</span>-&gt;errors = <span class="default">$errors</span>;          return <span class="default">$fieldarray</span>;      } <span class="comment">// _cm_updateSelection</span> </pre>
<p>The <code>getFieldSpec_original()</code> method is used to replace the modified structure with the original structure. It then steps through the</p>
<p>input array and extracts each field which it then treats as a separate database</p>
<p>row. This row is then inserted or updated, as appropriate.</p>
<h2>Summary</h2>
<p>This design has the following advantages:</p>
<ul>
<li>Values can be added to or removed from the control table without having to</p>
<p>alter the structure of the table. The structure of the table remains static</p>
<p>while it is only the contents which are varied.</li>
<li>Because individual values are held on totally separate records, individual
<p>values can be locked without affecting other values.</li>
<li>Because each value is held on a separate record it is easier for the table
<p>to hold 1000&#8242;s of records than it is for the table to contain 1000&#8242;s of fields.</li>
<li>By using a different value for <code>record_id</code> it is possible to use
<p>the same table for different sets of control data, such as for an individual</p>
<p>application instead of the whole system.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://computer-tech.info/2011/11/a-flexible-method-of-storing-control-data/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Zero in on your target audience with Google</title>
		<link>http://computer-tech.info/2011/11/zero-in-on-your-target-audience-with-google/</link>
		<comments>http://computer-tech.info/2011/11/zero-in-on-your-target-audience-with-google/#comments</comments>
		<pubDate>Sat, 05 Nov 2011 17:00:23 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Shortcuts]]></category>
		<category><![CDATA[audience]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[target]]></category>
		<category><![CDATA[Zero]]></category>

		<guid isPermaLink="false">http://computer-tech.info/2011/11/zero-in-on-your-target-audience-with-google/</guid>
		<description><![CDATA[While websites are great for gaining immediate global exposure (or notoriety, as the case may be), there are times when your product would benefit more from local search engine targeting....]]></description>
			<content:encoded><![CDATA[<div style="float:right;width:300px;margin-left:8px;"> </div>
<p>While websites are great for gaining immediate global exposure (or notoriety, as the case may be), there are times when your product would benefit more from local search engine targeting. For example, you have a pizzeria in Trieste, Italy. A person in Hawaii may accidentally stumble on your site and get a craving for your mouth-watering oven-hot thin crust Four Cheeses pizza&#8230; but he can&#8217;t order it anyway. It makes much more sense to concentrate your efforts on the people in and around your locality. For domains with a country code like .sg for Singapore and .jp for Japan, it’s automatically done, but if you’re using a neutral domain extension such as .com or .org, it has to be arranged manually. Here’s how to set it up using Google’s geographic targeting.<br /> <span id="more-178"></span><br /> 1. First of all, you must have a Google Account. If you don’t have one, just register for free.<br /> 2. Sign up on the Google Webmaster Tools main page.<br /> 3. On the dashboard, add the URL of your site. Verify by following the instructions given. If you’ve already done this before, then just select your site URL from the dashboard and proceed to the next step.<br /> 4. On the left column, click Tools from the menu.<br /> 5. On the Tools page, select Set geographic target.<br /> 6. Next, change the setting to “Associate a geographic location with this site”.<br /> 7. A dropdown box will appear and you’ll then be able to choose the country/region for your site&#8217;s target audience.<br /> 8. Save the changes and exit.</p>
<p>That’s it. Your site is targeted for your country. Note that this setting will only be in effect if the person searching chooses the &#8220;Search pages from [country]&#8221; option on the Google homepage. Otherwise, your site may still be found by users worldwide. Try it and see the results over time. If you want to revert to your previous settings, just log back in to Google and do some quick editing.</p>
]]></content:encoded>
			<wfw:commentRss>http://computer-tech.info/2011/11/zero-in-on-your-target-audience-with-google/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Designing and Coding a WordPress Theme From Scratch (Part 10)</title>
		<link>http://computer-tech.info/2011/11/designing-and-coding-a-wordpress-theme-from-scratch-part-10/</link>
		<comments>http://computer-tech.info/2011/11/designing-and-coding-a-wordpress-theme-from-scratch-part-10/#comments</comments>
		<pubDate>Fri, 04 Nov 2011 17:00:31 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Shortcuts]]></category>
		<category><![CDATA[Coding]]></category>
		<category><![CDATA[Designing]]></category>
		<category><![CDATA[From]]></category>
		<category><![CDATA[part]]></category>
		<category><![CDATA[Scratch]]></category>
		<category><![CDATA[Theme]]></category>
		<category><![CDATA[Wordpress]]></category>

		<guid isPermaLink="false">http://computer-tech.info/2011/11/designing-and-coding-a-wordpress-theme-from-scratch-part-10/</guid>
		<description><![CDATA[Part 3 &#8211; &#8220;Photoshop to XHTML in 24 Hours&#8221; Part 4 &#8211; &#8220;Cleaning Up Your XHTML&#8221; Part 5 &#8211; &#8220;Preloading Images with Javascript and CSS&#8221; Part 6 &#8211; &#8220;Marking Up...]]></description>
			<content:encoded><![CDATA[<div style="float:right;width:300px;margin-left:8px;"> </div>
<p>Part 3  &#8211; &#8220;Photoshop to XHTML in 24 Hours&#8221;<br /> Part 4  &#8211; &#8220;Cleaning Up Your XHTML&#8221;<br /> Part 5  &#8211; &#8220;Preloading Images with Javascript and CSS&#8221;<br /> Part 6  &#8211; &#8220;Marking Up is Hard to Do&#8221; and &#8220;The Anatomy of a WordPress Theme&#8221;<br /> Part 7  &#8211; &#8220;Beginning with PHP for WordPress&#8221;<br /> Part 8  &#8211; &#8220;Putting the Press in WordPress with PHP&#8221;<br /> Part 9  &#8211; &#8220;Marking Up Header.php, Footer.php and Sidebar.php&#8221;</p>
<p>So far we&#8217;ve made a ton of progress with our theme design.  We designed it  in Photoshop, we converted to XHTML  and then we began the somewhat tedious task of adding PHP .  Now that we&#8217;ve created index.php, header.php, footer.php and sidebar.php, we can move on to creating the rest of the theme.</p>
<p><span id="more-160"></span></p>
<p>In &#8220;The Anatomy of a WordPress Theme&#8221; we noted that WordPress needs certain files  for your theme to function properly.  Here&#8217;s that list again:</p>
<ol>
<li>404 Template = 404.php</li>
<li><strike>Archive Template</strike> = archive.php </li>
<li><strike>Archive Index Page</strike> = archives.php </li>
<li>Comments Template = comments.php </li>
<li><strong>Footer Template = footer.php</strong></li>
<li><strong>Header Template = header.php</strong></li>
<li>Links = links.php</li>
<li><strong>Main Template = index.php</strong></li>
<li>Page Template = page.php</li>
<li><strike>Popup Comments Template</strike> = comments-popup.php </li>
<li>Post Template = single.php</li>
<li><strike>Search Form</strike> = searchform.php </li>
<li><strike>Search Template</strike> = search.php </li>
<li><strong>Sidebar Template = sidebar.php</strong></li>
<li><strong>Stylesheet = style.css</strong></li>
</ol>
<p>As you may have noticed, the items listed in <strong>bold</strong> are the only items we&#8217;ve created in our lessons thus far and there is still a lot of work to be done!  Anything <strike>struck through</strike> is optional therefore this lesson won&#8217;t cover it but I have linked to pages where you can read about them on your own. While I can&#8217;t go into complete detail I will highlight some major points about each and then I&#8217;ll give you links to four sites that break the process down in detail and more thoroughly:</p>
<h2>single.php</h2>
<p>Single.php is the file referenced when someone clicks on the permalink for one of your posts.  Thus it is the template for displaying a single post on your blog.  On most blogs single.php an index.php are very similar except that in addition to querying <strong>&lt;? the content(); ?&gt;</strong> we also have to query the comments page. We do this just before we close the loop with:</p>
<pre> 	&lt;?php comments_template(); ?&gt; </pre>
<p><b>page.php</b></p>
<p>Page.php is the template for any page in your theme that doesn&#8217;t have it&#8217;s own .php template or that is not a blog entry.  This is also the template for the static &#8220;Pages&#8221; that you create within the WordPress Admin panel.  It is usually also just like index.php except that it doesn&#8217;t include <strong>the loop</strong> or <strong>the_content()</strong>.</p>
<p><b>links.php</b></p>
<p>Ignores Page content and instead displays your links using <strong>get_links_list</strong>.</p>
<h2>404.php</h2>
<p>Where you users land when they follow a bad link on your blog or click through to something that&#8217;s been removed. Codex  offers some advice&#8230;.</p>
<blockquote cite="http://codex.wordpress.org/Creating_an_Error_404_Page"><p> While you work hard to make sure that every link actually goes to a specific web page on your site, there is always a chance that a link clicked will slam dunk and become a famous 404 ERROR PAGE NOT FOUND. Some errors are avoidable, you should regularly check and double check all your links. Also, if you are deleting a popular but out-of-date post, consider deleting the body of the post, and replacing it with a link referring visitors to the new page.</p>
</blockquote>
<p>This concludes &#8220;Designing and Coding a WordPress theme from Scratch&#8221;  .  This guide was written as a starting point and a reference guide I can always be contacted at <strong>jongos [at] gmail</strong> if you are having trouble or need advice.  Alternatively I&#8217;ve compiled a list of resources that I often reference when creating themes below.</p>
<p>In this tutorial I mentioned a theme that I was developing quite a bit.  You can download it along with the PSD used to create it here .  Keep in mind that the version you&#8217;re downloading is an early beta release.  It&#8217;s bulky, clunky, not very pretty under the covers and has a mind of it&#8217;s own so I&#8217;m dubbing it the Rosie O Donnell release.  Feel free to give me feedback on it, use it to double check your own code, or modify it to suit your needs.</p>
<p><strong>DOWNLOAD THE AQUA MARINA  WORDPRESS THEME</strong></p>
<p><img src="http://farm3.static.flickr.com/2001/2449394258_676eb5ea2b_m.jpg"> </p>
<hr /> <b>Recommended Further Reading</b></p>
<p>Stepping_Into_Templates <br /> HTML to XHTML <br /> So You Want To Create WordPress Themes <br /> From XHTML/CSS to WordPress <br /> Tamba2&#8242;s Guide <br /> Slizing a WordPress Theme </p>
]]></content:encoded>
			<wfw:commentRss>http://computer-tech.info/2011/11/designing-and-coding-a-wordpress-theme-from-scratch-part-10/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Color Code Converter</title>
		<link>http://computer-tech.info/2011/11/color-code-converter/</link>
		<comments>http://computer-tech.info/2011/11/color-code-converter/#comments</comments>
		<pubDate>Thu, 03 Nov 2011 17:00:25 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Shortcuts]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[Color]]></category>
		<category><![CDATA[Converter]]></category>

		<guid isPermaLink="false">http://computer-tech.info/2011/11/color-code-converter/</guid>
		<description><![CDATA[Color Code Converter This article gives you a color code converter &#8212; RGB to hexadecimal, and the other way around. It is one of the easiest to use color code...]]></description>
			<content:encoded><![CDATA[<div style="float:right;width:300px;margin-left:8px;"> </div>
<h2>Color Code Converter</h2>
<p>This article gives you a color code converter &#8212; RGB to hexadecimal, and the other way around.</p>
<p>It is one of the easiest to use color code converters on the Internet.</p>
<p>This one has what many don&#8217;t, a color swatch representing the latest converted color code. And not just a swatch, but three swatches so colors can be visually compared with each other.</p>
<p>The demonstration and code download page is at http://willmaster.com/a/26t/pl.pl?art262</p>
<p>Give it a try. If you like it, download the code.</p>
<p>The Color Code Converter can be put on a web page for use by your site visitors.</p>
<p>If you prefer a private installation, you might put it into a popup linked from your personal portal page. (See http://willmaster.com/possibilities/wmptips/tip031014.shtml for a &#8220;Personal Portal Page&#8221; tip.)</p>
<p>Alternatively, bookmark the demonstration page and use it whenever you need a converter or to compare colors.</p>
<p>The converter has two buttons, one to convert to hexadecimal characters and one to convert to RGB.</p>
<p>There is also a checkbox that, when checked, will convert the codes as you type. It knows which code you&#8217;re typing and converts it to the other automatically.</p>
<p>The reason for both methods, manually clicking a button and the auto-convert checkbox, is that some browsers don&#8217;t do the auto-convert very well. The conversion is okay, but tabbing from one code field to another can require manual character selection and replacement instead of automatically replacing with whatever is typed. It has to do with the onkeyup() JavaScript command. On some browsers, the command intercepts tab and other non-printable/command keys as if they were normal keyboard printable character keys.</p>
<p>The form fields immediately below the color swatches are hexadecimal color codes for copying and pasting into documents, such as the aforementioned web page source code.</p>
<p>The hexadecimal code is not preceded with a &#8220;#&#8221; character. If you prefer to have the character for copying with the hexadecimal code, modify the JavaScript as below:</p>
<p>The last function in the demonstration JavaScript is ConvertASection(). Four lines from the bottom of that function&#8217;s source code is a line adding the &#8220;#&#8221; character to the hexadecimal code.</p>
<p>In order to print the &#8220;#&#8221; with the hexadecimal number in the form fields below the colors swatches, the line needs to be switched with the line immediately above it in the function&#8217;s source code. Unfortunately, the line above it is too long to print in this article. But I believe you&#8217;ll recognize it even with the ellipsis to indicate missing characters.</p>
<p>So what you do is switch these two lines:</p>
<pre><font color="#006666"> eval('document.ColorCodeConversionForm.hh ... hgbval + "'"); hgbval = '#' + hgbval;</font></pre>
<p>You&#8217;ll end up with:</p>
<pre><font color="#006666"> hgbval = '#' + hgbval; eval('document.ColorCodeConversionForm.hh ... hgbval + "'");</font></pre>
<p>A live implementation of the converter, with the above edits, is used at one of our affiliate text ad generators, http://willmaster.com/wmaf/AdCodeGenerator.shtml</p>
<p>If you wish to learn from the JavaScript, make a copy and play. Try this and that and see what happens.</p>
<p>Once you have a satisfactory modification, remember to test it on all the different browsers you have access to. IE5 for Mac OS 9 is especially cantankerous when it comes to certain JavaScript functions and constructs. That browser is one reason I rarely use regular expressions in JavaScript. It chokes on the code.</p>
<p>The color code convert can be used to convert from one format to another, to do trial and error until the correct color is displayed in the swatch, and to compare a swatch&#8217;s color with those in other swathes.</p>
]]></content:encoded>
			<wfw:commentRss>http://computer-tech.info/2011/11/color-code-converter/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cultured Perl: Genetic Algorithms Applied with Perl</title>
		<link>http://computer-tech.info/2011/11/cultured-perl-genetic-algorithms-applied-with-perl/</link>
		<comments>http://computer-tech.info/2011/11/cultured-perl-genetic-algorithms-applied-with-perl/#comments</comments>
		<pubDate>Wed, 02 Nov 2011 17:00:26 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Shortcuts]]></category>
		<category><![CDATA[Algorithms]]></category>
		<category><![CDATA[Applied]]></category>
		<category><![CDATA[Cultured]]></category>
		<category><![CDATA[Genetic]]></category>
		<category><![CDATA[Perl]]></category>

		<guid isPermaLink="false">http://computer-tech.info/2011/11/cultured-perl-genetic-algorithms-applied-with-perl/</guid>
		<description><![CDATA[Create Your Own Darwinian Breeding Grounds Based on the Darwinian principle of survival of the fittest, genetic programming uses mutation and replication to produce algorithms for creating ever-improving computer programs....]]></description>
			<content:encoded><![CDATA[<div style="float:right;width:300px;margin-left:8px;"> </div>
<h2>Create Your Own Darwinian Breeding Grounds</h2>
<p> Based on the Darwinian principle of survival of the fittest, genetic programming uses mutation and replication to produce algorithms for creating ever-improving computer programs. In this column, you&#8217;ll get to know the genetic algorithm in simple terms. Ted provides Perl implementations for some specific tasks, which you can adapt for generic use. To demonstrate the genetic algorithm, Ted breeds numbers for fitness to a formula, and letters to form English words.</p>
<p>You can run the examples in this article if you have Perl 5.005 or later installed on your system. Preferably, your system should be a recent (2000 or later) mainstream UNIX (Linux, Solaris, BSD) installation, but other types of operating systems may work as well. The examples may work with earlier versions of Perl and UNIX, and other operating systems, but their failure to function should be considered an exercise for the reader to solve.</p>
<h2>History</h2>
<p>The progress of genetics in the 20th century was rivaled in speed and reach only by the evolution of electronics and computer science. It is fitting that one of the most intriguing algorithms to come about in the 20 th century is the genetic algorithm.</p>
<p>Emerging in the early 1960s, the genetic algorithm (and evolutionary algorithms in general) took a place in computer science between deterministic and non-deterministic algorithms. The genetic algorithm, essentially, is as deterministic as you want to make it, meaning that the user can decide the number of iterations and termination criteria. It mimics Darwinian natural selection, making &#8220;fitness&#8221; (as determined by a formula applied to an individual) the chief selector of individuals for survival and procreation, together with mutation.</p>
<p>Other evolutionary algorithms attempt to mimic Lamarckian evolution, where behavior as a survival mechanism can be transferred between generations, and there are even evolutionary programs that write themselves for a particular purpose. All of those are beyond the scope of this article.</p>
<p>The main drawback of Perl for genetic algorithms is speed. Because of the computing needs of genetic algorithms, they are more efficiently implemented in C or other low-level pre-compiled languages. The Perl examples shown here are not as fast as their equivalents in C, but they will show you how the genetic algorithm works, and they are fast enough for some problems.</p>
<h2>Resources</h2>
<p> &#8226; Read Ted&#8217;s other Perl articles  in the &#8220;Cultured Perl&#8221; series on <em>developerWorks</em>.</p>
<p> &#8226; Thanks to Abigail, whose CPAN Sample module exhibits the sample() function I use in both examples. The Sample module and its documentation are wonderful tools for any Perl programmer at Sample .</p>
<p> &#8226; Visit CPAN  for all the Perl modules you ever wanted.</p>
<p> &#8226; Check out Perl.com  for Perl information and related resources.</p>
<p> &#8226;  Visit perldoc.com  for Perldoc information online.</p>
<p> &#8226; Programming Perl Third Edition&#8221; , by Larry Wall, Tom Christiansen, and Jon Orwant (O&#8217;Reilly &amp; Associates 2000) is the best guide to Perl today, up-to-date with 5.005 and 5.6.0.</p>
<p> &#8226; &#8220;Mastering Algorithms with Perl&#8221; , by Jon Orwant, Jarkko Hietaniemi, and John Macdonald (O&#8217;Reilly &amp; Associates 1999) is a great compendium of algorithms expressed in Perl. Chapter 14, &#8220;Probability,&#8221; shows how to do weighted and unweighted probability distributions with Perl.</p>
<p> &#8226;  The  Genetic Algorithms FAQ  is quite outdated, but it does point to useful suites of genetic algorithm software, both free and commercial.</p>
<p> &#8226; Related <em>developerWorks </em> articles by Teodor Zlatanov include:</p>
<p> &#8226; One-liners, 101 </p>
<p> &#8226; Small observations about the big picture </p>
<p> &#8226; Browse more Linux resources  on <em>developerWorks</em>.</p>
<p> &#8226;Browse more Open source resources  on <em>developerWorks</em>.</p>
<h2>So What is the Genetic Algorithm?</h2>
<p>The genetic algorithm is simple enough for anyone to understand, using biological terms taught in high school. Take a population of individuals, each with DNA of their own. Then measure each individual&#8217;s fitness (measured as a function applied to the individual&#8217;s DNA) and make the individual more likely to procreate if he is more fit. Extremely unfit individuals are killed off. Every survivor gets a chance to procreate (and it is important that procreation is never denied to a survivor, only made less likely if he is less fit). Merging the parents&#8217; DNA, and then applying a random mutation to the merged DNA simulates procreation. The new individual will, in theory, be as fit as the parents, plus or minus a small variance caused by the mutation. The cycle is then repeated.</p>
<p>There are, obviously, many variables that can affect the genetic algorithm, including population size, generations (iterations of the algorithm), merging method, fitness function, how fitness affects procreation chances, and how much mutation happens.</p>
<p>There are some drawbacks to the algorithm, as well. It works best if the fitness function is applied to the DNA as a series of bits. In other words, it&#8217;s best if the DNA is a series of binary options, yes or no. Blue eyes? Black eyes? Red hair? Black hair? Merging of parent DNA and subsequent mutation should not allow certain combinations of bits, because the resulting DNA will not be a valid solution to the original problem. Remember that the &#8220;DNA&#8221; is nothing more than a solution to a mathematical fitness formula. Some values used in that formula may be invalid &#8212; for instance, dividing by zero.</p>
<p>In addition, the genetic algorithm is not bound by time. You pick the number of generations. You can define some goal &#8212; for instance, &#8220;look for an individual with fitness of 0.99999&#8243; and stop there, but then the algorithm may never end because it hasn&#8217;t found that individual. That can be a problem if you set unrealistic goals or too few generations. Trial and error, and a good feel for the problem, are the best ways around this issue.</p>
<p>The fitness formula should return a floating point number between 0 and 1. Other ranges can be used, but in my experience floating point numbers work best. You may want a range between 0 and 32767, for instance, if you want the fitness to be a 7-bit integer for optimization.</p>
<p>Of course, delaying optimization until you know it&#8217;s needed is a good idea, so you should at least start with a simple fitness formula. The fitness formula is the most-used function in the genetic algorithm (it will be invoked (population size) x (generations times)), so you should make it as simple and as fast as possible.</p>
<p>There are three &#8220;good&#8221; ways to exit the genetic algorithm. First, you can decide to exit if there is no variety in the DNA pool anymore. This is a tricky test, actually, and a CPAN module for finding the distance of strings might be useful here, as long as you can represent the DNA as a string. Second, you can exit if you have reached a fitness goal. Unless you have a very good understanding of the fitness formula (in which case, you probably don&#8217;t need the genetic algorithm anyway), setting a fitness goal can result in either infinite loops, or an individual who is only &#8220;good enough.&#8221; Third, you can exit the algorithm after a set number of iterations, or &#8220;generations.&#8221;</p>
<p>In practice, all three ways (or at least the second and third one) are used to control the genetic algorithm. A few test runs, maybe 10 or 20, will give you a good feel for how quickly the algorithm converges, what kind of fitness you can expect.</p>
<p><strong>Genetic Algorithms FAQ </strong></p>
<p>See the Resources  section for the link to Genetic Algorithms FAQ. It also points to suites of genetic algorithm software, both free and commercial. See the Algorithm GA  that was obtained from the Genetic Algorithms FAQ.</p>
<h2>A Simple Example</h2>
<p>The code in Listing 1 uses a single byte as DNA (value between 0 and 255, 8 bits). The fitness formula is applied once to every new individual, taking the byte value of the DNA and dividing it by 256. This means that the fitness formula will always return a number between 0 and 255/256, so it can never reach 1. What do you think the fittest DNA will be?</p>
<p><pre><font color="#006666">numbers.pl source </font></pre>
<p>There are several interesting things about Listing 1. Its main loop is at the beginning, and you should understand all the pieces and how they work together on the population (and yet they are separate, so we can reuse them in the next example). You can execute Listing 1 with numbers.pl .</p>
<p>We build the weights array in the select_parents() function by stacking map() on top of grep(). While it could have been written as a loop, the one-line solution is much cleaner that way, and does not slow the program down significantly.</p>
<pre><font color="#006666">my @weights = map { $_-&gt;{fitness} } grep { $_-&gt;{survived} } @$population;</font></pre>
<p>The $population array reference is de-referenced. Then, only elements of the array with the &#8220;survived&#8221; field (set earlier by the survive() function) get through the grep. The survivors are then distilled to their fitness numbers, which get put in their places in the weights array.</p>
<p>The population size was chosen to be 256, because that way it was easy to initialize every individual to a number equal to its index. Feel free to start with different population sizes.</p>
<p>Mutation rates of more than 1% caused the maximum and minimum fitness to fluctuate wildly. The population never stabilized towards high fitness. Low mutation rates cause the population to reach high fitness as a whole much slower. In the end, 1% was about right for our population size.</p>
<p>The breeding selection algorithm picks one parent by looking at the weights &#8211; in effect, every individual gets a chance to be a parent, but the number of parent slots is finite. The second parent is picked at random from the parent population. Why? Well, we could have used weights to determine the second parent as well, but this way we ensure every parenting individual has a chance to participate in the breeding process.</p>
<p>The actual breeding is accomplished with a random 8-bit bitmask. We just AND the bitmask to the first parent&#8217;s DNA (remember, it&#8217;s just a byte) and AND the inverted bitmask to the second parent&#8217;s DNA. The effect is that we pick random bits from one parent, and then the rest of the bits come from the other parent.</p>
<p>The mutation is accomplished by AND and OR of individual DNA with random 8-bit bitmasks.</p>
<p>Oh, and by the way, the most fit DNA was 255, of course. You don&#8217;t need to wait 100,000 generations. Just hit Ctrl-C when you are done admiring the status line.</p>
<h2>Breeding words</h2>
<p>For this example, we will make the DNA 32 bits (5 bytes). Each byte will represent a letter or a space. We could have packed more information into each byte, but it would have obscured the purpose of the example. Every byte&#8217;s value (0-255, numerically) will be either A through Z (if the value is between 65 and 90, conveniently chosen to match the ASCII set), or a space (if the value is 0 to 64, or 91 to 255).</p>
<p>Note how much of the example is similar to the example in Listing 1. The dictionary of words follows the program.</p>
<p><pre><font color="#006666">words.pl source </font></pre>
<p>The main problem with this example was that DNA lengths greater than 32 bits were hard to manage. I started out trying to do my own bit operations, which were not only unwieldy, but also extremely slow. Then I tried the Math::BigInt package, which was extremely slow for this purpose. You can execute listing 3 with words.pl.</p>
<p>Finally, I settled on the vec() function &#8212; it is quite fast, and was the right choice for handling DNA (essentially, the DNA is a bit vector, a built-in Perl data structure). Use &#8220;perldoc -f vec&#8221; to find out more about the vec() function.</p>
<p>It is possible to end up with 1024 individuals with 0 fitness. That&#8217;s why this example has better safeguards against such an &#8220;accident&#8221; than the first example.</p>
<p>The init_population(), recombine(), and mutate() functions were changed to handle bit vectors instead of bytes.</p>
<p>The dna_to_words() function is somewhat inefficient, but is not invoked often enough to make a difference. The biggest slowdown comes from the fitness() function trying to match all the words in the dictionary, plus all the letters in the alphabet.</p>
<p>Fitness was calculated as: 2 for each letter in the DNA, plus the frequency of that letter in the dictionary, plus 2^N for every dictionary word of length N in the DNA. The dictionary array and letter frequencies hash were obtained only once (using a closure). Feel free to modify the fitness function and the dictionary to breed your own English words. The fitness formula shown is heavily biased towards letters, and takes a while to converge on English words (though &#8220;on&#8221; and &#8220;in&#8221; were pretty frequent visitors).</p>
<h2>Conclusion</h2>
<p>The evolutionary genetic algorithm is a fascinating topic that can hardly be exhausted in a single article. I hope you experiment with the examples and create your own Darwinian breeding grounds. It is especially entertaining to play with the fitness function in the second example, and watch English words appear out of noise.</p>
<p>The techniques shown in the examples range from beginner to advanced level, so try to understand them thoroughly. Often there is room for improvement. The vec() function is especially interesting. It is perfectly suited for long bit vectors such as DNA or other numeric data.</p>
<p>Write your own genetic algorithm implementation. Compare it with mine, and learn from the shortcomings (not necessarily yours, either). Implementing an algorithm is tricky business. There&#8217;s a lot you can do wrong, and only a few ways to get it right.</p>
]]></content:encoded>
			<wfw:commentRss>http://computer-tech.info/2011/11/cultured-perl-genetic-algorithms-applied-with-perl/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mondo Math Libs</title>
		<link>http://computer-tech.info/2011/11/mondo-math-libs/</link>
		<comments>http://computer-tech.info/2011/11/mondo-math-libs/#comments</comments>
		<pubDate>Tue, 01 Nov 2011 17:01:23 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Shortcuts]]></category>
		<category><![CDATA[Libs]]></category>
		<category><![CDATA[Math]]></category>
		<category><![CDATA[Mondo]]></category>

		<guid isPermaLink="false">http://computer-tech.info/2011/11/mondo-math-libs/</guid>
		<description><![CDATA[A look at some of the math libraries for Linux  Programmers generally fall into two groups when it comes to using math. One group doesn&#8217;t use floating point much, if...]]></description>
			<content:encoded><![CDATA[<div style="float:right;width:300px;margin-left:8px;"> </div>
<h2>A look at some of the math libraries for Linux</h2>
<p> Programmers generally fall into two groups when it comes to using math. One group doesn&#8217;t use floating point much, if at all, and typically needs integers only for the usual mundane purposes like loop control variables, counters, address arithmetic, and other simple calculations. This group&#8217;s math needs rarely require the use of anything more exotic than a 32-bit signed integer. They deal with floating point arithmetic only when necessary. And when floating point arithmetic cannot be avoided, they tend to head for the path of least resistance, using whichever FP format is handy or forced on them. This group includes most system programmers, as well as non-scientific and non-financial coders.</p>
<p>The second group includes the financial, scientific, and hobbyist programmers who don&#8217;t just crunch numbers but mercilessly grind them until their CPU glows cherry red. They use online handles like &quot;mantissaMan&quot; and &quot;sqrt-neg-one,&quot; and tell jokes with scientific notation punch lines. If you&#8217;re wondering whether you are in this second group, you probably aren&#8217;t.</p>
<p>This sort of thinking let me to write about multiple-precision math (hereafter MPM) libraries. The fact that there&#8217;s a seemingly endless list of implementations of MPM libs available on the net for Linux makes this topic valuable to both groups in our little programmer taxonomy.</p>
<h2>Ground rules</h2>
<p>Before I get into the specifics of various libraries and where to find them, let&#8217;s agree on some terminology.</p>
<p>The most widely quoted and used standard for floating point numbers is IEEE-754, which defines several data formats and exactly how various bit patterns in the fields are interpreted. (See Resources  later in this column for an online guide to IEEE-754.)</p>
<p>Mantissa and exponent refer to the two parts of binary-format floating point numbers as they are normally represented. The mantissa is the &quot;base&quot; part of the number, and the exponent is the power of ten (usually) the base is raised to. In decimal, the number 5.12e+3 has a mantissa of 5.12 and an exponent of 3.</p>
<p>Precision measures a number&#8217;s &quot;size&quot; in terms of the exact number of digits it can represent. This can be deceptive to the floating-point neophyte, however. Don&#8217;t think that because an IEEE-754 single precision number can store a maximum number of 3.40292347e+38 that it can represent every possible floating point number up to that value (or down to the negative of that value). An IEEE-754 single has a mantissa of only 23 bits, and you can&#8217;t possibly represent 38 decimal digits in only 23 bits. This is typical of binary floating point number representations: their exponents exceed their grasp. But precision doesn&#8217;t just refer to floating point values; it&#8217;s also applicable to integers.</p>
<p>I can&#8217;t stress enough that floating point is one area where you should pay attention to exactly how your data is represented, particularly when dealing with software-only implementations, such as MPM libs. In those cases, you&#8217;re using an artificial construct that was simply invented by a programmer, and not something supported in hardware.</p>
<h2>Binary vs. decimal</h2>
<p>This leads us to the next issue: binary vs. decimal representation of floating point numbers. The most commonly used floating point formats, whether IEEE-754 conforming or otherwise, are based on binary representations, just as integers are. Unfortunately, this leads to the endless discussion in newsgroups about unexpected results from some floating point operations. The explanation is simple &#8212; there are many fractional values that can be represented precisely in decimal notation yet have no exact form in binary. This most often surfaces after repeated calculations with one or more such numbers, leading the result to drift from the expected answer. Or it surfaces when you print a result at high precision, and instead of getting a nice round number like 74.00000, you get 73.99998. If you think this behavior is inconvenient in your astronomy or ray tracing program, imagine the headache it causes scientists or financial institutions, where even a small mistake can be catastrophic in more ways than one.</p>
<p>The most obvious solution to this problem is simply to represent floating point values in decimal form, as in the BCD (binary-coded decimal)/&quot;packed decimal&quot; numbers used in mainframes for decades, and countless other custom formats cooked up by inventive programmers. This will solve the representation problem, but usually at a cost in runtime performance, because the math operations are all carried out entirely in software (as in the MPM libraries discussed below), instead of in hardware in the form of a floating point unit (FPU).</p>
<p>By contrast, multiple-precision integers are almost universally represented as binary numbers, because there&#8217;s no benefit to going decimal, as there is with floating point values. Keeping the components in binary actually improves performance in most cases, because the most common approach is to represent each multiple-precision integer as an array of smaller integers, each of which is a format natively supported by the hardware.</p>
<h2>Some contenders</h2>
<p>So, you find that you need to use truly huge integers or floating point values in a Linux program. Where do you turn? In this section I&#8217;ll give you a brief overview of some of the more interesting and useful MPM library packages available on the Net. By no means an exhaustive list, or even a &quot;best of the Net&quot; list, this is just a good starting place.</p>
<p>If you find any math libraries for Linux that are worthy of mention, please e-mail me at the address at the start and end of this column, because this is one topic that I will likely return to in future installments.</p>
<p><span class="atitle3">apfloat</span> <br />This package includes support for arbitrary precision numbers in four forms: integers, floating point numbers, rational numbers, and complex numbers. The apfloat source code includes two archives: a common, base portion plus one tailored to various C++ compilers (including a generic ANSI C++ version), as well as versions optimized for 386/486 or Pentium systems. While the package&#8217;s author says apfloat should be usable with nearly every C++ compiler, it includes a makefile for gcc, which makes building the library under Linux very easy.</p>
<p>The supported math functions include the basic four arithmetic operations plus inverse root, trigonometric functions (normal, arc, hyperbolic, and inverse hyperbolic), power, exponentiation, a function to calculate pi to a desired precision, and more. There is also a stream output operator.</p>
<p>The package includes full source code plus several demonstration and test programs.</p>
<p><b xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">apfloat</b></p>
<ul xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<li>Main sites: www.jjj.de/mtommila/apfloat/ </li>
<li>Download page: http://www.jjj.de/mtommila/apfloat/1.51/ </li>
<li>Maximum precision: Limited only by memory (including disk space)</li>
<li>Language: C++</li>
<li>Licensing: Freeware, free for non-commercial use</li>
<li>Documentation: The apfloat manual is a 35-page PostScript file available from the downloads page. It provides a good introduction to the library, as well as several appendices on number theory and algorithms.</li>
</ul>
<p />
<p><span class="atitle3">gmp</span> <br />gmp stands for GNU Multiple Precision, and is, of course, the GNU entry in the field. It supports arbitrary precision operations on signed integers, rational numbers, and floating point numbers, and is, of course, quite at home with Linux.</p>
<p>One interesting facet of gmp is the degree to which it has been tailored to various hardware platforms. The manual points out that the package contains &quot;carefully optimized assembly code for these CPUs: DEC Alpha, Amd 29000, HPPA 1.0 and 1.1, Intel Pentium and generic x86, Intel i960, Motorola MC68000, MC68020, MC88100, and MC88110, Motorola/IBM PowerPC, National NS32000, IBM POWER, MIPS R3000, R4000, SPARCv7, SuperSPARC, generic SPARCv8, and DEC VAX. Some optimizations also for ARM, Clipper, IBM ROMP (RT), and Pyramid AP/XP.&quot;</p>
<p>Not surprisingly, the manual also points out that gmp places &quot;a general emphasis on speed (as opposed to simplicity or elegance).&quot; This is a fair statement; gmp is very fast, but because it is written in C, it provides a lower level interface than the other MPM libraries mentioned here. In particular, the lack of operator overloading places an additional burden on the programmer and anyone modifying his or her code in the future. The lack of destructors is more problematic, in that it opens the door for the all-too-familiar memory leak problems, because the gmp data types use dynamically allocated memory, which must be freed via explicit calls to _clear functions.</p>
<p>The gmp package is also pretty sparse in terms of provided math functions. It supports numerous variations of the basic functions, plus square roots, I/O, and random numbers, but little else.</p>
<p><b xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">gmp</b></p>
<ul xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<li>Main and download page: http://www.swox.com </li>
<li>Maximum precision: Limited by memory</li>
<li>Language: C (the main Web page mentions plans to design a C++ wrapper, but there doesn&#8217;t seem to be any progress on that front yet)</li>
<li>Licensing: GPL (GNU public license)</li>
<li>Documentation: The manual is online in HTML format at http://www.swox.com/gmp/manual/gmp_toc.html , or you can download it in DVI or PostScript format.</li>
</ul>
<p />
<p>If you experiment with gmp, be sure to download copies of the patches from the main site, because they fix some subtle bugs in the support for rational and floating point numbers.</p>
<p><span class="atitle3">hfloat</span> <br />hfloat is a floating-point-only library that was developed under Linux using gcc 2.7.x and also includes the author&#8217;s fxt-library, a collection of several FFT implementations. hfloat allows you to choose any number from 2 to 65536 for the radix used in number representations, giving it some notable flexibility. The supported operations include square root, n-th power, some trigonometric functions (not as many as apfloat), and logarithms.</p>
<p>hfloat has a few quirks to watch out for, including initialization syntax (described in &quot;Hints and tips&quot;  below), and the way it represents a number&#8217;s radix and precision. For example, for a base-10 number you use a radix of 10,000, not 10, and you measure precision in LIMBs, which are 16-bit unsigned integers. These aren&#8217;t major problems, particularly for programmers working with this sort of package, but I recommend you pay attention to the author&#8217;s descriptions and examples of these items in the manual.</p>
<p>The source code for hfloat is also somewhat unusual in that the author has broken it into several compilation units (the base class, one for the &quot;guts&quot;, one for functions, etc.). This will be visible to you only if you intend to modify the package, but it adds a bit to the learning curve as you figure out where everything is.</p>
<p><b xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">hfloat</b></p>
<ul xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<li>Main and download site: http://www.jjj.de/hfloat/hfloatpage.html </li>
<li>Maximum precision: Limited only by memory</li>
<li>Language: C++</li>
<li>Licensing: GPL (GNU Public License)</li>
<li>Documentation: The 15-page manual is available as a separate download, in DVI, PostScript, or Acrobat/PDF format. The manual is a bit terse, but it does cover basic usage of the package and its general layout.</li>
</ul>
<h2>Java&#8217;s BigInteger and BigDecimal</h2>
<p> </p>
<p>Java coders are probably familiar with the java.math package and two of its more interesting classes, BigInteger and BigDecimal. These are both arbitrary precision numeric classes, the first being binary, and the second being decimal, as you might have guessed from the names.</p>
<p>The good news is that these classes have been part of the standard Java implementation since JDK 1.1, so they&#8217;re &quot;free&quot; to programmers and require no extra work to distribute/install them on a user&#8217;s system (assuming Java itself is installed).</p>
<p>The primary drawback of these classes is that they&#8217;re pretty minimalist in comparison with some of the MPM libraries. They support the main four arithmetic operations and some other minor manipulations, but that&#8217;s it. There are no trigonometric, log, exponentiation, or other features available. As such, they make a good foundation for Java programmers, but they&#8217;re not enough to support many scientific or advanced applications.</p>
<p>One other interesting note is that IBM has made its own drop-in replacement for Sun&#8217;s BigDecimal class available. You can download it and documentation from IBM&#8217;s site (see Resources ). IBM&#8217;s and Sun&#8217;s BigDecimal classes differ in two areas. IBM improves in a couple of areas on the Sun version, such as making some conversions to less precise data types throw exceptions instead of simply returning bad data. IBM has also added a greater level of control over rounding, but without sacrificing backwards compatibility with existing code.</p>
<p><b xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">Java&#8217;s BigInteger and BigDecimal</b></p>
<ul xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<li>Main site (Sun): http://java.sun.com </li>
<li>Main site (IBM): http://www2.hursley.ibm.com/decimal/ </li>
<li>Sun&#8217;s documentation for BigInteger: http://java.sun.com/products/jdk/1.1/docs/api/java.math.BigInteger.html </li>
<li>Sun&#8217;s documentation for BigDecimal: http://java.sun.com/products/jdk/1.1/docs/api/java.math.BigDecimal.html </li>
<li>Maximum precision: Limited by memory</li>
<li>Language: Java</li>
<li>Licensing: See packages</li>
<li>Documentation: Sun and IBM both provide extensive online and downloadable documentation for their Java products. See the Web sites for more detail.</li>
</ul>
<p />
<p><span class="atitle2">Hints and tips</span> <br />You could write several sizable chapters or even an entire book on the benefits and pitfalls of MPM libraries, but here are a few things to watch out for as you experiment.</p>
<ul xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<li><b>Always remember that MPM libraries are quirky animals</b>: Every one has its own personality, and you should never assume you can pick one up, slap it into an existing project, and start coding away. At a minimum you should count on experimenting with the library at two levels: a very simple, naive one, in which you just exercise features to gain familiarity with the package, and also a more intense and application-specific one that should reveal the library&#8217;s oddities and give you a feel for its performance as you&#8217;ll use it. (And performance can be a particularly thorny issue, because in many cases the authors of some of these libraries have lavished attention on some parts and left others with minimal and slower implementations.)</li>
<li><b>Consider initialization issues</b>: Virtually all MPM libraries will let you initialize variables in their extended precision formats using as constants either the native environment&#8217;s numbers or string values. This makes sense; it would be silly if you couldn&#8217;t initialize a multiple-precision variable to anything larger than what a native number will hold. But you can run into trouble with decimal format multiple-precision floating point variables. For example, if you initialize such a variable with the literal constant 0.1, you&#8217;ll get a nasty surprise. Your compiler will normally convert 0.1 into a binary format, resulting in a repeating decimal value, which will be used to initialize your variable, so your variable won&#8217;t start off containing exactly 0.1. You can avoid this problem by using a string constant of &quot;0.1&quot; instead of a numeric constant. This will get the desired data into your variable and bypass your compiler&#8217;s translation efforts.</li>
<li><b>Be careful about semantics</b>: Some libraries, like hfloat, do some unusual things with what seems like &quot;normal&quot; statements. The hfloat manual explains that the line <code>hfloat a = 1234;</code> does not initialize the hfloat a to 1234, but instead sets a&#8217;s precision to 1234 digits and initializes it to 0. This is probably not what you would expect, and could lead to some spectacular bugs.</li>
<li><b>Know the package&#8217;s resource requirements</b>: Some libraries require a bit more tender loving care in order to work properly. In some cases you can simply use the library as provided or recompile it, and then drop it into your project as you would any other dynamically linked library. But some libraries require environment variables to be set or other libraries to be present. These details aren&#8217;t a concern for your own work, but if you plan to distribute a program that uses one of these libraries, it can quickly turn into more trouble than your users are willing to accept.</li>
<li>Another aspect of resource requirements is memory usage. Many of the MPM libraries will use all available memory in extreme circumstances, such as dealing with truly huge numbers, but they give you a way to limit the precision of the numbers and the memory used, or to decide when to stage values to disk instead of keeping them in memory. Depending on how widely distributable your application must be, these controls could mean the difference between a successful product rollout and a flop (no pun intended).</li>
<li><b>Handling exceptions, overflows, and underflows</b>: This is another area where MPM libraries vary greatly. Some ignore such issues completely, and others spend considerable effort to give you complete control over and information about how math operations are performed, and the results. Some packages use arbitrary precision representations, as opposed to a fixed precision, eliminating overflow/underflow problems.</li>
</ul>
<h2>Hints and tips</h2>
<p>You could write several sizable chapters or even an entire book on the benefits and pitfalls of MPM libraries, but here are a few things to watch out for as you experiment.</p>
<ul xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<li><b>Always remember that MPM libraries are quirky animals</b>: Every one has its own personality, and you should never assume you can pick one up, slap it into an existing project, and start coding away. At a minimum you should count on experimenting with the library at two levels: a very simple, naive one, in which you just exercise features to gain familiarity with the package, and also a more intense and application-specific one that should reveal the library&#8217;s oddities and give you a feel for its performance as you&#8217;ll use it. (And performance can be a particularly thorny issue, because in many cases the authors of some of these libraries have lavished attention on some parts and left others with minimal and slower implementations.)</li>
<li><b>Consider initialization issues</b>: Virtually all MPM libraries will let you initialize variables in their extended precision formats using as constants either the native environment&#8217;s numbers or string values. This makes sense; it would be silly if you couldn&#8217;t initialize a multiple-precision variable to anything larger than what a native number will hold. But you can run into trouble with decimal format multiple-precision floating point variables. For example, if you initialize such a variable with the literal constant 0.1, you&#8217;ll get a nasty surprise. Your compiler will normally convert 0.1 into a binary format, resulting in a repeating decimal value, which will be used to initialize your variable, so your variable won&#8217;t start off containing exactly 0.1. You can avoid this problem by using a string constant of &quot;0.1&quot; instead of a numeric constant. This will get the desired data into your variable and bypass your compiler&#8217;s translation efforts.</li>
<li><b>Be careful about semantics</b>: Some libraries, like hfloat, do some unusual things with what seems like &quot;normal&quot; statements. The hfloat manual explains that the line <code>hfloat a = 1234;</code> does not initialize the hfloat a to 1234, but instead sets a&#8217;s precision to 1234 digits and initializes it to 0. This is probably not what you would expect, and could lead to some spectacular bugs.</li>
<li><b>Know the package&#8217;s resource requirements</b>: Some libraries require a bit more tender loving care in order to work properly. In some cases you can simply use the library as provided or recompile it, and then drop it into your project as you would any other dynamically linked library. But some libraries require environment variables to be set or other libraries to be present. These details aren&#8217;t a concern for your own work, but if you plan to distribute a program that uses one of these libraries, it can quickly turn into more trouble than your users are willing to accept.</li>
<li>Another aspect of resource requirements is memory usage. Many of the MPM libraries will use all available memory in extreme circumstances, such as dealing with truly huge numbers, but they give you a way to limit the precision of the numbers and the memory used, or to decide when to stage values to disk instead of keeping them in memory. Depending on how widely distributable your application must be, these controls could mean the difference between a successful product rollout and a flop (no pun intended).</li>
<li><b>Handling exceptions, overflows, and underflows</b>: This is another area where MPM libraries vary greatly. Some ignore such issues completely, and others spend considerable effort to give you complete control over and information about how math operations are performed, and the results. Some packages use arbitrary precision representations, as opposed to a fixed precision, eliminating overflow/underflow problems.</li>
</ul>
<h2>Resources</h2>
<li>Sun&#8217;s Numerical Computation Guide  has an extensive introduction to floating point, the IEEE-754 spec, and Sun&#8217;s standard math libraries.</p>
</li>
<li>&quot;What Every Computer Scientist Should Know About Floating Point Arithmetic&quot;  is a 78-page article that contains more detail than you probably knew existed about floating point math.</li>
<li>Two ftp sites with numerous MPM libraries, papers, and related materials are:
<ul xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<li>ftp://ftp.nic.funet.fi/pub/sci/math/multiplePrecision/ </li>
<li>ftp://ripem.msu.edu/pub/bignum/ </li>
</ul>
</li>
<li>William Kahan is a professor at the University of Berkeley, and has several publications on his Web site  related to floating point issues. (In particular, see his paper &quot;How Java&#8217;s Floating-Point Hurts Everyone Everywhere&quot; for an interesting take on the subject.)</li>
]]></content:encoded>
			<wfw:commentRss>http://computer-tech.info/2011/11/mondo-math-libs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Page Caching using disk
Object Caching 644/763 objects using disk

Served from: computer-tech.info @ 2012-05-21 00:29:20 -->
