September 6, 2005

Open source OCR

Thanks John-Paul.

Orcad (
Clara (

Posted by torque at 11:45 PM | Comments (0) | TrackBack

Slurping files in Perl

Uri Guttman wrote just what I was looking for: a careful exposition of how to read files fast in Perl. Kudos.

Posted by torque at 10:55 PM | Comments (0) | TrackBack

September 5, 2005

Regular expressions and .NET

I enjoy Perl and PHP in large part because of support for regular expressions. Much can be done in a short amount of code. Guess what? It is firmly embedded in Microsoft .NET Framework. I had no idea. The classes are located in System.Text.RegularExpressions. A nice tutorial is can be found at Nice.

Posted by torque at 4:42 PM | Comments (1) | TrackBack

August 30, 2005

Converting OST to PST

There is no clear answer, but the MS Exchange Blog has a nice thread which might end up being of use.

Posted by torque at 7:13 AM | Comments (0) | TrackBack

April 8, 2005

emf + paperposition

I wasted a lot of brain cells stressing out aobut this one. A .emf is an enhanced metafile, typically used for storing vector graphics in Windows. In Matlab, PaperPosition sets the size of both printouts and exported graphics. Here's what I was trying to do:

set(gcf,'PaperPosition',[0 0 6 3]);
On my old slow computer, this produces a 6" by 3" graphic. On the new fast computer it produces a graphic similar in size to the on-screen figure and completely ignores PaperPosition. When exporting.png, .gif or .jpg, there was no problem. I could not figure out how to reconcile the difference. I ended up having to use the fast computer for numerical work and then the slow computer to print the charts.

This worked well until I had to produce a very graphic insensive chart. The slow computer choked... and I had a draft due. Not a pretty scene. So, how do we fix this? I found the solution by accident, it is under File, Preferences, Figure Copy Template. then Copy Options. There you will see:


Match figure screen size should be unchecked. On my new computer it was checked. After unchecking, PaperPosition should work for .emfs.

Posted by torque at 1:46 PM | Comments (2) | TrackBack

March 11, 2005

A few helpful tips on plotting in Matlab

Every few months I find myself having the same questions on plotting in Matlab. It's time to stop being so unproductive. Here are a few tips for my future reference and yours.

Automating "Fill page". How many times have you clicked "fill page" under Page Setup. If you are like me, the answer is many times too many. To automate this, you need to set the PagePosition property of the current figure.

set(gcf, 'PaperPositionMode', 'manual');
set(gcf, 'PaperUnits', 'inches');
set(gcf, 'PaperPosition', [.25 .25 8 10.5]);
If you need to switch to landscape (the default is portrait), you will want to edit the Paper Orientation property.
set(gcf, 'PaperPositionMode', 'manual');
set(gcf, 'PaperUnits', 'inches');
set(gcf, 'PaperOrientation', 'landscape');
set(gcf, 'PaperPosition', [.25 .25 10.5 8]);
If you are exporting the figure for other purposes, you will want to remove the border from PaperPosition. See Ben Hinkle's Exporting Figures for Publication for more details (and exportfig.m).

Changing plot color and linestyles. If you are tired of the standard plot colors and linestyles, and don't really want to specify them for every line, you can edit DefaultAxesColorOrder and DefaultAxesLineStyleOrder. Matlab cycles through all colors before moving to the next linestyle. This seems to be unchangeable. Colors are specify in a 3 by n matrix, where n is the number of colors. Linestyles are specified in a string using the standard linestyle characters, separated by "|", e.g., "-|--|:". As an example,
set(gcf,'DefaultAxesColorOrder',[0 0 0 ; 0 .1 .9]) set(gcf,'DefaultAxesLineStyleOrder','-|:')
cycles through black and dark blue solid then black and dark blue dotted.

Annotating the plot. From time to time, you may want to write data or comments on to the plot, or perhaps next to the plot. I used to try to cram information into xlabel, ylabel and title. No more. The appropriate command is annotation, which itself is quite rich. I will be illustrating the textbox annotation.

An issue with textbox annotation is that coordinates are specified with respect to percentages of the figure. To make the placement neat, leverage subplots. I wanted to make a page with four rows of two plots each with a box to the right detailing, well, the details. Here's how I did it:

% setup first plot %
% setup second plot %
What's going on. After switching to the target subplot, I used get(gca,'Position') to fetch the dimensions of the subplot in percentages of the figure. This way I don't have to guess where the textbox should be. LineStyle is set to 'none' to eliminate the default border. For formatting, I found the section on the String to be quite helpful. To enter a multiline string, separate the lines using cells, e.g.,
mystring = {sprintf('[%s]',EEG.tu.label)...
  ,sprintf('wC4-dT6: %.1f%%',100*dryrate)...
  ,sprintf('wC4-wT6: %.1f%%',100*wetrate)...
  ,sprintf('nTest = %d',EEG.chanlocs(1).nTest)}

Posted by torque at 4:49 PM | Comments (0) | TrackBack

February 18, 2005

Keyhole API

Keyhole is beautiful... but is this beauty tapable? Incidentally, TerraServer USA offers a webservices API which might be a good alternative.

Posted by torque at 11:02 AM | Comments (1) | TrackBack

February 4, 2005

Visual Studio 2005 beta

It is always nice to get "free" software from Microsoft. For a limited time, Microsoft is offering free downloads of Visual Studio 2005 - Visual Basic, Visual J#, Visual C++, Visual C#, SQL and Visual Web Developer. I find it facinating that they threw C++ back in with C#. What is the difference between C# and C++? I for one am still using my old Visual C++ 6.0 in lieu of C# or C++ .NET. That said, I have a feeling, despite Scott McNealy's rhetoric, that .NET will win in the end. The other day, after avoiding it for two years, I was finally coerced into installing .NET Framework 1.1 into my laptop in order to use Kinko's direct print software. The annoying thing is that the printout didn't even look right... sigh.

Posted by torque at 3:10 PM | Comments (0) | TrackBack

January 26, 2005

MySQL 4.1+ reports "Client does not support authentication protocol"

Here's a solution. The issue, as you might guess, is that MySQL 4.1+ employs a new authentication protocl. Old clients, including MyODBC 3.51 will report this error. There are a variety of fixes, here's what I used.

Reset the password to pre-4.1 style for each user that needs to use a pre-4.1 client program. This can be done using the SET PASSWORD statement and the OLD_PASSWORD() function:

-> 'some_user'@'some_host' = OLD_PASSWORD('newpwd');

I had to do it using the root account.

Posted by torque at 3:09 PM | Comments (1) | TrackBack

January 10, 2005

Freelance programming and design

This is a test of the Scriptlance javascript facility. The problem, of course, is that the code is javascript, which means that Google probably won't parse it.

Posted by torque at 9:54 AM | Comments (0) | TrackBack

January 4, 2005

So you want to write a BHO?

External toolbars, e.g., Google toolbar, as well as many spyware installs are browser helper objects (BHOs). They extend the functionality of Internet Explorer (IE) and can be quite powerful (in positive and negative ways). You can get a list of keys to BHOs installed in your computer by running regedit and browsing to HKEY_LOCAL_MACHINE\ Software\ Microsoft\ Windows\ CurrentVersion\ Explorer\ Browser Helper Objects. I found three keys

  1. {06849E9F-C8D7-4D59-B87D-784B7D6BE0B3}
  2. {AA58ED58-01DD-4d91-8333-CF10577473F7}, and
  3. {FDD3B846-8D59-4ffb-8758-209B6AD74ACC}
You can easily look up BHO keys at SpywareData. I was relieved to find that my list maps to
  1. Adobe's Acrobat Plugin
  2. the Google toolbar, and
  3. Microsoft's Money Viewer

How hard is it to write one of these? My dad, not in so many words, asked me last week about getting a plugin-version of the pinyinator. J. P. Hamilton's Visual Basic Shell Programming is an excellent resource, though I am still in the process of going through it. If any of you know of other good online resources, do let me know. The ones I found through Google were not satisfactory. Amazon has more books on writing applications for the Windows shell but I have yet to review them.

Dino Esposito has a most excellent article on BHO's from a VC++ perspective entitled Browser Helper Objects: The Browser the Way You Want It. This is the way to go.

Posted by torque at 11:59 PM | Comments (2) | TrackBack

December 31, 2004

UTF-8 and MySQL

When using MySQL's UTF-8 character set, besides setting the database character set to UTF-8, you must remember to send SET NAMES 'utf8' to MySQL prior to querying or inserting. Forgetting to do will surely cost you a substantial amount of hair, sleep, and sanity.

Posted by torque at 12:22 AM | Comments (0) | TrackBack

December 30, 2004

the pinyinator

Hallelujah, it is a dream come true. I've been wanting something like this for almost a decade. Every so often I would get inspired to learn how to read and write Chinese. Then, for about a week, I would digest any Chinese characters I could find, diligently looking up unknown or forgotten words and etching character, pinyin and definition into my journal. No more! Enter the pinyinator.

What is the pinyinator?

The pinyinator is a tool for translating both traditional and simplified Chinese, line by line, into pinyin. It is especially helpful for illiterati wishing (or having) to sing Chinese hymns. But wait, there's more! Simply moving your mouse over a character will pop-up a definition, as well as the character in traditional and simplified Chinese. Admittedly, it runs slow, but I have a couple tweaks in mind which should speed things up, i.e., grabbing the definitions and pinyin in one database call instead of character-by-character.

Here are a few things to pinyinate:

神愛世人、甚至將他的獨生子賜給他們、叫一切信他的、不至滅亡、反得永生。 -約翰福音 3:16




This project would have been impossible without open source information and software. The core of the pinyinator is Paul Denisowski's CEDICT Chinese-English Dictionary. The dictionary, in UTF-8 format, was imported into MySQL with assistance from Christopher Sexton's phpCEDICT code. The pinyinator also relies util.php from phpCEDICT. Specifically, it calls Scott Reynen's UTF-8 to Unicode conversion tools as well as Konrad Mitchell Lawson's pinyin to unicode function.

What's up ahead? It would be nice if characters could be saved in a user account to be retrieved for things like flashcard use (see my earlier posts on the Leitner cardfile system). This is a major endeavor in itself and may have to wait another decade... It would be nice if I could email the system with some Chinese and have it respond with pinyinated and defined text. It would be nice if the system could periodically email me with Chinese snippets, verses or sayings pinyinated and defined. A good source for this would have been's extensive list of Chinese material. Unfortunately, most of the text there is stored in a graphic. Chinaknowledge, a site located in Germany, uses UTF-8 encoding, which will work. It hosts a large volume of Confucian and Doaist literature, among other things.

Posted by torque at 11:19 PM | Comments (5) | TrackBack

December 11, 2004

Can't locate in @INC (@INC contains...

When installing perl modules with dependencies, e.g., PDF::Report depends on PDF::API2, in private directories, you will probably encounter an error message when running 'perl Makefile.PL' - something like "Can't locate in @INC (@INC contains... [everything but the right directory]". In my case, I had installed the dependency into my private directory, ~/cgi-bin/myapp/extlib. To fix this, set the PERL5LIB directory if it hasn't yet been set using 'setenv PERL5LIB ~/cgi-bin/myapp/extlib'. Try running 'perl Makefile.PL' again. That should do the trick.

Posted by torque at 4:36 PM | Comments (14) | TrackBack

December 4, 2004

How to write a Windows screensaver

Briefly fantasizing about writing a Hiroshige screensaver, I stumbled onto Lucian Wischik's Holistic Screensavers: Beginning to End. Nice.

Update: I swapped out the background image on Wischik's Images example for a Hiroshige print. Download the file. To install, simply right click on the .scr file. On second thought, don't install it yet. I'm not sure how to uninstall it. You can just double click on the file to look at it. Definitely more to come...

Posted by torque at 9:45 PM | Comments (0) | TrackBack

November 30, 2004

A little keywords experiment

I'm interested in how Google treats lists of links, whether these are positive or detrimental. As such, I've created a little keywords experiment. At the destination, I've placed a little counter to track referrers, ip addresses etc.

Posted by torque at 11:56 PM | Comments (0) | TrackBack

A nice recursive query

update keywords set
word3 = IF ( locate( ' ', rest) , left( rest, locate( ' ', rest)-1 ) , rest),
rest = IF ( locate( ' ', rest) , substring( rest from locate( ' ', rest)+1 ) , '' )

Posted by torque at 10:12 PM | Comments (0) | TrackBack

October 3, 2004

PDF via CGI::Application

I'm working on a little application which requires the generation of PDF files. Overseeing the whole app is CGI::Application. I was rather perplexed as to how to set header-type to something other than 'text/html'. It turns out that the answer is not $self->header_type('application/pdf'). You will get an "invalid header_type 'application/pdf'" error. The answer, courtesy of weierophinney is

Kind of unintuitive, but I can guarantee that it works.

More info from Adam Gent also shows how to name the downloaded file:

Through the header_props method is C::A, which goes via


So you can then do

$webapp->header_props(-type => "text/comma-separated-values",
-attachment => "download.csv");

Should work fine.

You can also do this for zip and pdf files, if you set the correct header type, i.e., application/zip, application/pdf

Posted by torque at 5:27 PM | Comments (4) | TrackBack

September 30, 2004

Cutting down the FAT

CNET this morning reported on the success of the Public Patent Foundation's push for re-examine one of Microsoft's key FAT patents. FAT is a old file format which, while no longer in use in OS's such as XP, still finds a great amount use on media such as floppy disks, flash memory cards, etc. Because the file format is lightweight and openly documented, and, for quite sometime, completely free, it became widely adapted. Recently, Microsoft began charging manufacturers to use to the format.

Known as ‘517, US5579517 describes a method by which short and long filenames can co-exist in an operating system.

An operating system provides a common name space for both long filenames and short filenames. In this common namespace, a long filename and a short filename are provided for each file. Each file has a short filename directory entry and may have at least one long filename directory entry associated with it. The number of long filename directory entries that are associated with a file depends on the number of characters in the long filename of the file. The long filename directory entries are configured to minimize compatibility problems with existing installed program bases.
Microsoft has 90 days to respond.

Posted by torque at 10:39 AM | Comments (0) | TrackBack

September 22, 2004

Javascript calendar

I've looked all around and Mihai Bazon's calendar script (jscalendar) really is the coolest. The other stuff on his page is quite interesting as well.

Posted by torque at 12:35 AM | Comments (0) | TrackBack

September 1, 2004

Making tones with Matlab

I needed some different beeps for my auditory stimuli. Dave Johnson has a good skeleton at the MathWorks repository. It's actually pretty simple. Remember to change the sampling frequency if you need to get higher frequency tones.
function beep2(w,t)
%plays a short tone as an audible cue
%    beep2
%    beep2(w)    specify frequency (200-1,000 Hz)
%    beep2(w,t)     "       "       and duration in seconds

fs=8192;  %sample freq in Hz

if (nargin == 0)
   w=1000;            %default
   t = [0:1/fs:.2];   %default
elseif (nargin == 1)
   t = [0:1/fs:.2];   %default
elseif (nargin == 2)
   t = [0:1/fs:t];  

%one possible wave form

%play sound
Posted by torque at 10:25 AM | Comments (0) | TrackBack

August 27, 2004 AWS 4.0 Web Services

It's out! And the new REST format makes quering the database extremely easy. Unlike the SOAP interface, REST allows you to get information from Amazon simply using a URL (with GET no less).

Amazon Web Services (AWS) is a method for programmers to access Amazon's massive database of books, software, music, etc. and their corresponding prices and reviews. You can even use it to post products (such as books). And the best part? It's free! All you need to do is sign up for an AWS account.

To the REST of the story (ok, ok, I couldn't resist). REST stands for Representational State Transfer and was developed by Dr. Roy Fielding.

REST allows you to make calls to AWS by passing parameter keys and values in a URL (Uniform Resource Locator). AWS returns its response in XML (Extensible Markup Language) format. You can experiment with AWS requests and responses using nothing more than a Web browser that is capable of displaying XML documents. Simply enter the REST URL into the browser's address bar, and the browser displays the raw XML response.

Posted by torque at 4:42 PM | Comments (0) | TrackBack

August 19, 2004

NNTP servers

Great resource I found at

Posted by torque at 12:59 AM | Comments (0) | TrackBack

August 18, 2004

Converting dates between MySQL and PHP

Thanks Simon, for the tip. "You can use MySQL's UNIX_TIMESTAMP() and FROM_UNIXTIME() functions to convert Unix timestamps to MySQL date types as part of your SQL queries." For example,
  entries.*, UNIX_TIMESTAMP(added) as unixtime
  title = 'The title', 
  added = FROM_UNIXTIME(1057941242),
Yay! No more INT(11) for me.

Posted by torque at 11:56 AM | Comments (1) | TrackBack

August 16, 2004

What is API?

API stands for Application Programming Interface. It is a generic term for the protocol by which programmers can access particular features of previously written code. This can be within your own computer, or, as is increasingly common, on the internet. The latter is most interesting, because it allows you to tap computational power outside of your own computer. It also allows the API provider to offer its tools to external developers without exposing the underlying code.

There are a number of fun API's to work with on the web. Here are a few of the more notable examples:

  • Google Web APIs - With the Google Web APIs service, software developers can query more than 4 billion web pages directly from their own computer programs. Google uses the SOAP and WSDL standards so a developer can program in his or her favorite environment - such as Java, Perl, or Visual Studio .NET.
  • Amazon Web Services - Amazon Web Services provides you with direct access to Amazon's technology platform. Using AWS, you can access catalog data, create and populate an Amazon shopping cart, and even initiate the checkout process. As an Amazon Associate, you can use our catalog data to create rich, highly effective sites featuring full product data, including accurate and timely product pricing and availability. As an Amazon Marketplace Seller, you can use AWS to get competitive pricing information, list your products on Amazon, and check the status of your listings.
  • Paypal's Instant Payment Notification - Instant Payment Notification (IPN) is PayPal's interface for handling real-time purchase confirmation and server-to-server communications. IPN delivers immediate notification and confirmation of PayPal payments you receive and provides status and additional data on pending, cancelled, or failed transactions.
  • eBay API - The Application Programming Interface (API) is the heart of the Developers Program. Normally, users buy and sell items using the eBay online interface, interacting with eBay directly. But with the eBay API, you communicate directly with the eBay database in XML format. By using the API, your application can provide a custom interface, functionality and specialized operations not otherwise afforded by the eBay interface.
  • Blogger API - For independent developers and partners who are interested in hooking into Blogger with other programs, interfaces, or environments.
Why do companies make APIs available to the public? More importantly, why would I develop software and make it available to other software developers? The answer, as they say, is in the paperwork. In some cases, the money making portion of the company, but in what the software allows you to do. For instance, the eBay API facilitates posting and bidding on eBay. When other developers make software, this only encouraging more posting and more bidding. It is really an enhancement of an affiliate program. In other cases, like the Google APIs, usage is fairly limited, i.e., you only get a certain number of queriers per day. Once you get above that threshold, you probably have a viable business model, in which case, licensing discussions commence. You see how this works. If anything, APIs allow the ambitious programmer or developer a chance to work with powerful tools, increasing public awareness of your product and enhancing the interfaces to your own software. If they develop something really good, you might just buy them. That's what happened to Picasa.

Finally, I want to emphasize again that that web-based APIs allow companies to get open source like development without revealing the underlying source code and without losing control.

Posted by torque at 10:28 AM | Comments (2) | TrackBack

June 26, 2004

Storing IP addresses in MySQL

If you ever need to store an IP address in a MySQL database, use ip2long and store it in an int(11). I think that is the best way.

int ip2long ( string ip_address)

The function ip2long() generates an IPv4 Internet network address from its Internet standard format (dotted string) representation. If ip_address is invalid then -1 is returned. Note that -1 does not evaluate as FALSE in PHP.

In PHP 5 ip2long() returns FALSE when the ip_address is in valid.

Of course, to go back, just use long2ip.

Posted by torque at 10:21 PM | Comments (6) | TrackBack

June 21, 2004

Analyzing memory in Perl

What to do about the "out of memory" error? There are two Perl-specific ways to analyze memory usage: $ENV{PERL_DEBUG_MSTATS} and -DL command-line switch. The first is available only if Perl is compiled with Perl's malloc(); the second only if Perl was built with -DDEBUGGING. Hmmm...

I couldn't do what I wanted to do with either of these methods. I ended up using 'ps', as in 'ps -lp $$', to get the amount of memory being used by the process at important points in my code. Fortunately I was able to figure out the problem, but that's another story for another day.

Posted by torque at 4:12 PM | Comments (0) | TrackBack

April 20, 2004

Replacing Java with Flash

Is it feasible? Christian Cantrell has an article entitled "Macromedia Flash Remoting Makes Macromedia Flash an Alternative to JSP and Applets" on the subject. I've played with using Flash as a web apps several years ago (for a learning tool) but haven't come back to it in several years. What are the pros and cons? Here's a nice calendar app - source here.

Posted by torque at 10:46 AM | Comments (0) | TrackBack

January 27, 2004

Large blobs

I ran into an annoying issue with one of my web hosts... max_allowed_packet on MySQL was set to 1 MB and they were insistent on it. Naturally, I tried to find a way around it. It turns out that it has been done before - see Handling huge BLOB fields with DBI and MySQL. Essentially the idea is to split up the BLOB into smaller chunks and upload each separately. It isn't actually that bad.

Posted by torque at 10:23 AM | TrackBack

January 26, 2004


Nifty, Microsoft offers a SOAP-based mapping web service called MapPoint. Like Mapquest, but even cooler. They offer a 45-day evaluation license. I haven't seen anything written in PHP yet, e.g., nusoap, but I did find a Perl-based implementation. Cool stuff. Wonder how much it costs to do for real.

Gee, this is serious stuff. On Google Groups I found a posting on pricing from 6/2003. $10,000 annual platform charge, $5000 for 500,000 transactions (1¢ each) - a render, find, and route each constituting a method. You can imagine things adding up pretty fast. Of course, if you really splurge it is 10 million transactions for $70,000 (0.7¢ each), though this is hardly a discount. Maybe times have changed?
For my application I was thinking of building probaby 200-300 route maps, each consisting of the route computation, a couple find methods, and a render method (or is it one), so it might be 1500 or so that I need. $15. I guess that isn't too bad... The 10 million number is a bit discouraging, since you won't really see too many people reselling.

Posted by torque at 1:35 AM | TrackBack

January 23, 2004

Storing files database

Leon Atkinson wrote a good article on this.

Posted by torque at 12:35 PM | TrackBack

January 17, 2004


Where do I start? I found a good article by Benson Wong entitled "Using PHP and XSL to Transform XML into Web Content".

Posted by torque at 2:46 PM | Comments (0) | TrackBack

January 15, 2004

Automate Word to Perform a Client-Side Mail Merge

A good template for automating word using VBscript can be found here. Keep in mind that to create an object means you might have to change some settings on IE.

Posted by torque at 1:44 PM | Comments (0) | TrackBack

January 14, 2004

Plesk, MySQL, and remote access

Arrghh. It appears to be tricky.

Posted by torque at 5:13 PM | Comments (0) | TrackBack

January 9, 2004


I hate how you can only print or save one page at a time on esp@cenet. This is a record of my efforts to make life a bit easier. I was interested in obtaining a copy of GB2388196: Electrodynamic sensor. Incidentally, if you are interested in getting PDFs of US patents you should take a look at Oren Tirosh's pat2pdf.

After coming off a search on one of the inventors, Prance, we get to:
How much of this is necessary? I sliced out the terms until I was left with
which seems to work. The various tabs use this number but under different directories, and they add a QPN number which doesn't seem to make a difference. The directory 'origdoc' takes you to the original document.
We can print a single page using the Print link, which points to
Now, this prints the current page... I'm not exactly sure how though. If we change the page on the viewer, the print link does not change but the page being printed does. That's peculiar! The key is F=64 - F=64 creates a PDF that prints on entry. If we cut and paste the link to another page, it displays the first page and tries to print. If we save this file and open it offline, it tries to print on entry.

Ok, I'm getting closer.
Will bring up, on a new window, the third page, attempting to print on entry. This can be saved, rather than opened. Then all the PDFs can be stitched together. The nice thing about F=64 is that the saved/printed file has only 1 page. If you try to save without F=64, you will be unable to print. Worse, the saved file with have N pages where N is the total number of pages, with exactly one viewable page.

So, the proper method would be to go through and save all the pages, then put it all together using a PDF utility.

Posted by torque at 2:10 PM | Comments (0) | TrackBack

MySQL -> XML Web Services

Helpful link here, if you ever have to do it.

Posted by torque at 9:26 AM | Comments (0) | TrackBack

January 7, 2004

Read and Write INI Files

Aisha Ikram's CIniReader is very nice, and may come in handy for reading Windows INI files using VC++.

Posted by torque at 1:42 PM | Comments (1) | TrackBack

January 3, 2004

ODBC MySQL Access (Wow!)

I can't believe it took me so many years to figure this out. Once you have the ODBC connection set up, you can do Excel-esque editing. The trick is not to use Excel, but to use Access.

Fire up MS Access and start a new database, right click on the staging area and click on Link Tables.... In the "Files of type:" drop box select ODBC Databases().

Now, select the Machine Data Source tab and you should see the database of interest.

The selected tables will available for editing. Each recorded is updated as you exit the field. This is very nice! You can do update queries using Access' nice interface. It is all very beautiful.

Posted by torque at 6:05 PM | Comments (0) | TrackBack

ODBC MySQL Mail Merge

I'm trying to figure out how I can use ODBC with MySQL so that database-driven Microsoft Office applications can work smoother (e.g., mail merge). I started by installing the latest production release of MySQL Connector/ODBC. I downloaded and executed the "Driver Installer" for Windows. I then followed along the FAQ "How do I configure Connector/ODBC DSN on Windows". I then opened up Microsoft Word, selected Tools -> Letters and Mailings -> Mail Merge Wizard. I selected Envelope. After selecting an Envelope size, use Browse to select the database. It works. Use "Connect to New Data Source" and then "ODBC DSN". Nice.

Here are more detailed instructions... starting from square one. Prerequisites are a net connection, a running MySQL server, and Microsoft Word.

  1. Download and install the MySQL Connector/ODBC driver
  2. With administrator priviledges, select Control Panel -> Adminstrative Tools -> Data Sources (ODBC)

  3. Click on Add and select "MySQL ODBC 3.51 Driver"

  4. Fill out the details on your MySQL server and then click OK

  5. Now, fire up Microsoft Word and select Tools -> Letters and Mailings -> Mail Merge Wizard
  6. Though aesthetically the correct choice is "Envelopes", the practical choice is "Labels", so choose "Labels" and click Next: Starting document
  7. Click on Label options and select the correct template (for this example I chose 5160) and go on to the next step

  8. Click Browse... to use an existing list. Use "Connect to New Data Source.odc"

  9. Select "ODBC DSN"

  10. You should see the data source created earlier, in my case, "ahcouk"

  11. Now select the desired table, e.g., the invitation labels would be stored under "guests", seating name tags under "rsvp"

  12. Finish up and you should see the contents of the selected table

  13. The Mail Merge Recipients window is very powerful, allowing you to sort and filter the records as needed by simply clicking the headers and header buttons, I suggest, however, restraining yourself and using instead the (Advanced..) option available from down arrow buttons in the header. In the example below I selected for my mail merge A-list guests in the United States with the address_1 field filled and no outstanding inquiries

  14. Fancy mail merging will be reserved for a different entry. Click on Next: Arrange your labels. The mail merge fields are available when you click More items...

  15. A label template like
    «address_2»{ IF {MERGEFIELD address_2}="" "" "¶"}«city», «state» «zip»
    should prove useful. Don't just cut and paste, the curly brackets are inserted using Ctrl-F9, and the fields using the More items... menu. Some additional logic will be needed to cope with international addresses. You can find more information on using mail merge fields here. To replicate the first label, click on Update all labels

Posted by torque at 10:09 AM | Comments (8) | TrackBack

December 8, 2003

The Spoke

What's this, a Microsoft blogging tool? How do I enter equations?

Posted by torque at 11:47 AM | Comments (0) | TrackBack

December 5, 2003

Switching back(wards)?

Most of my code for doing brain-wave recognition has been written in C++. I spent a lot of my time making beautiful objects incorportating FFTW, valarray and Lapack (via the Sun Performance Library). Though I wrote to opimize code reuse - things are just getting to be too complicated. Over the last few months, I've read a number of articles talking about how Matlab now uses FFTW and Lapack... perhaps it is time to switch back? Before I did, I wanted to check on timing... shouldn't compiled code be faster? Incidentally, time consumption in my code is basically in the linear algebra, so if Matlab uses the same libraries... After a bit of searching, I found a very useful article entitled "Timing Comparisons of Mathematica, MATLAB, R, S-Plus, C & Fortran".

Posted by torque at 2:46 PM | Comments (35) | TrackBack

December 3, 2003

Rusty perl

My Perl is pretty rusty. I found an excellent tutorial at NCSA.

Posted by torque at 4:15 PM | Comments (0) | TrackBack

November 6, 2003

MySQL and C++`

How bad could it be?

Posted by torque at 12:17 PM | Comments (0) | TrackBack

September 19, 2003

sigh - sizeof(bool)

In our old version of gcc, the size of the bool type was apparently 4 bytes, but in gcc-3.2.3, it is 1 byte. As you can imagine, if you had previously written files using the old software, you might have a hard time reading it if you didn't know this! Arg. More about this can be found here. Adding three more reads to bool seems to make everything work fine. This means I should probably convert all my old files to new files...

Posted by torque at 2:22 PM | Comments (0) | TrackBack

invalid reinterpret_cast

To read from files, I used to use,m_nChannels*sizeof(ELECTLOC));
I'm not really sure what to do now, since the (new) compiler gives 'invalid reinterpret_cast'. Ok, I fixed it with[0]),m_nChannels*sizeof(ELECTLOC));
Apparently, the new gcc doesn't treat iterators so kindly. A simlar problem showed up when I tried to do
In this case m_event is an iterator, and even though it technically is a pointer, the new gcc does not like it. I switched it to
and it worked. Which means I could have done &(*m_electlocs.begin()) though that is a lot uglier.

Posted by torque at 12:43 PM | Comments (0) | TrackBack

implicit typename is deprecated

Oh man, Stanford just updated it's gcc and gcc libraries - and now my precious code won't compile. Seems like it'll be a nightmare to sort out. I made some headway adding 'using namespace std;' right after the included files. But what is this 'implicit typename is deprecated'. I found a hint here. When getting the type of object T inside of container using value_type, e.g., valarray::value_type, the term 'typename' needs to go in front of the declaration, i.e., typename valarray::value_type. So, if before I had:

copy(&data[0],&data[0]+data.size(),ostream_iterator< valarray::value_type >(s," "));
Now I should have:
copy(&data[0],&data[0]+data.size(),ostream_iterator< typename valarray::value_type >(s," "));
Hmmm, this is also a problem with iterators. You need to preface iterators with typename. Note that use of the term 'typename' is for when one is using templates.

Posted by torque at 11:31 AM | Comments (5) | TrackBack