Friday, November 28, 2008

[Shameless Plug] Resistance Is Useless (an iPhone / iPod Touch app)

A good friend of mine has recently developed an iPhone / iPod Touch app for decoding the colour bands of 4, 5 and 6 band resistors. Check it out!



© Copyright Bruce M. Axtens, 2008

Monday, November 03, 2008

[Networks] How to calculate a netmask

To say that I've been busy of late is somewhat of an understatement. Mind you, I've had time to create a presence over on StackOverflow, and to start "playing" MouseHunt on FaceBook.

I was responding to something over on StackOverflow: "
What’s the best way to convert from network bitcount to netmask?" and added my two-bob to the mix with the following bit of VBScript.
A few examples runs are as follows:
It's been ages since I did the Cisco coursework (never did sit the exam) so I'm not sure if it's totally correct.

The binary2hexadecimal and binary2decimal functions were interesting to write as I was trying to find simpler, more lateral ways of doing things.
© Copyright Bruce M. Axtens, 2008

Monday, July 28, 2008

[Delphi] Updating SysTray

I'd been lurking at ITtoolbox for a while and saw this request for help with updating the system tray.

I've had similar problems myself. For instance, if you use boost or some similar process-control tool to kill the Skype.exe and SkypePM.exe programs, the processes disappear from memory but the system tray still shows the Skype icon until you move the mouse over the icon. Then the tray refreshes, the Skype icon disappears and the remaining icons rearrange.

On
Experts Exchange I found a bit of Delphi code which moves the mouse over the systray (using system messages rather than moving the mouse pointer itself.) This convinces Windows to update the systray. Because not everyone has an Experts Exchange membership, I've turned the code into a COM DLL, which you can download. Source is included (Artistic2 license.) A copy of the original Experts Exchange code can be found here.

Once you've registered the DLL (regsvr32 UpdateSysTray.DLL) you can use it in anything that supports ActiveX/COM objects. For example, in VBScript:


© Copyright Bruce M. Axtens, 2008

Tuesday, June 10, 2008

[VBScript] StandardLibrary.zip

For those interested, who haven't been able to download it recently, here's the latest iteration of StandardLibrary.vbs. Now it's called stdlib.vbs and can be obtained from my boost account at the Perth Linux Users Group.

There have been a few changes, mostly additional functions and the odd tweak in favour of better functionality.

Significant in the additions are a few functions for sending emails: Blat, BlatAttachment, ErrorEmail, ErrorEmailApp, RedemptionSend and ThunderbirdSend. If I remember correctly, ErrorEmail has been around for a while, but is included here for completeness sake.













A while back Derek Parnell wrote a replacement for
Euphoria's print function which would show the structure of arrays. ShowStructure and a support routine AsString make this available to the VBScript programmer. By the way, in case you haven't heard, Euphoria is now open-source!



The output, then, from code such as this:
would be
which maybe leads on toward data serialisation ...

There've been some additions to the file handling space, with the addition of routines to read and write unicode files (ReadFileU, WriteFileU, ReadFirstLineU and its ANSI equivalent, ReadFirstLine.)

Logging has been worked on. It's something I'm unlikely to be totally happy with, but there's now a SetLog and a ClearLog as well as the standard Log (and, given the possibility of confusion with the logarithm system, maybe I should change it to Trace (oh man, how many scripts that would break!))

What else? Well, BuildTree builds a directory tree. FirstLineOf returns the first vbNewLine-delimited line from a string (useful where you've used ReadFile or ReadFileU to inhale an entire file.) LastLineOf does what FirstLineOf does but for the end of the file, and NthLineOf gets you the ... nth ... line.

I've actually forgotten what I wrote UpToAndAfter for, but it's included anyway.

IsOnLine uses the ResolveIP function with the IP address 198.182.196.48 (which points somewhere on linux.org) to see if you are still on line.

SetPriority uses the same code as used in BOOST to set process priority.

StrInArray finds a string in an array of strings, with optional case sensitivity.

StringMap scans a string for the presence of items in one array and swaps them for the equivalently indexed elements in the second array. If the second array is a string, they get swapped for that string.

Doze wraps WSCript.Sleep and HTASleep, so that it can be used in .VBS files and .HTA files.

ModalThing2 shows a modal dialog (only works in .HTA files)

And, finally, SoundMessage:


Obviously, if you see something that needs to be fixed, fix it. And tell me to fix it so that it can be fixed in the distribution and your name can be added to the list of contributors.

© Copyright Bruce M. Axtens, 2008

[Visual BASIC 6] BOOST (v3)

BOOST got another look-in recently. I had been using it exclusively to do "realtime" and "kill". This particular time I tried to do an "abovenormal" -- instead it did a "kill".

In the process of finding and fixing that bug, I replaced the Collection mechanism with the augmented Collection supplied by the "Class Builder" add-in.

The source code is essentially the same as before but with a few changes. First the SysVars and Var classes. (The comments are predominantly those supplied by the add-in.)

First, SysVars.cls:


Next, Vars.cls (it's tiny but it could hold so much more):


Now the main module. The first thing that is different here, is that nLevel is now a Long. Integer doesn't handle the ABOVENORMAL_PRIORITY value without complaint.

Next change is removing the reference to Collection, changing it to SysVars and setting up the values.

The benefit of using SysVars and that approach to the Collection object is that we now have an .Exists method, so we now have a tidier way of setting nLevel and trapping invalid settings thereof.



All the other routines are as before.

I haven't gotten around to extending this tool to do stuff to remote computers. It's not hard; killing a process on another machine means another value for sComputer in KillProcess, and, of course, the relevant privilege level.

© Copyright Bruce M. Axtens, 2008

Tuesday, March 11, 2008

[Perl] How to do it better

There are some really helpful people in the Perl community. I advertised the original posting on comp.lang.perl.misc and received some very useful responses from John W. Krahn and Michele Dondi, as below.

With respect to the rules, John wrote:



John> Why [were] you converting the '|' character and the 'e' character to 'e'?



John> The . character class matches a lot more than just letters, or did you really mean "replace any first character except newline with 'n'".



John> The . character class matches a lot more than just letters.



Then, with respect to the string eval() of each rule, John said, "Ouch! Use a dispatch table instead of string eval()."



At this point Michele Dondi chipped in with, ">my %rule = (
>  1 => sub {
>    ( my $arg = shift ) =~ tr/s//d;
>    return $arg;
>    },
>  2 => sub {
>    return join '', sort split //, shift;
>    },

Since the keys are numbers, an array may be appropriate."

So there you have it, better rules, anonymous subroutines, and hashes. Powerful stuff.

I wonder how Tcl and the other languages would have done it. Or Protium, for that matter. Any takers?

© Copyright Bruce M. Axtens, 2008

Sunday, March 02, 2008

[Perl] How not to do it?

The header for this website says, "Some useful stuff and some examples of how not to do it." This may fall into the latter category.

One of my kids had been playing a computer-based game which used a variety of word puzzles. The question he posed to me was to take a word, apply a small set of rules to it, as many times as necessary, and come up with another word. He would supply the rules and both words, and I would supply the sequence of rule applications which would effect the conversion.

(I'm no guru when it comes to Perl, so if you see something that could be expressed in a more efficient manner, please let me know.)

These are the rules:

1. Remove all 's'



2. Sort the characters of the word into alphabetic order



3. Convert all vowels to 'e'



4. Replace the first letter with 'n'



5. Drop the last letter



6. Replace letter pairs with 'ow'



My son then said that the start word was 'first' (or 'ant') and the stop word was 'now'. After some fiddling, resulting in the code below, I said, "With these rules you can't get from 'first' to 'now'. Not even from 'ant' to 'now'. But from 'gnat', yes."

So here's the code, for what it's worth. It was assumed that this would be run as a command line tool, so I load up the start word (stored in $root) and a recursion management flag (stored in $managed). Recursion management is defaulted to true. The recursion level is marked with $level and there's a hash, called %deadends, to keep track of "solutions" that shouldn't be pushed any further as they have already been proved not to get any closer to the solution.



Everything else happens in the apply function which looks at every possible combination of rules in pursuit of the target word. After getting the word to check from @_ with shift, a couple of variables are declared and a for loop initiated, stepping through the rules.



Each rule is evaluated against the passed in value in $arg, and stored in $res. $reason is cleared and each test applied to $res.



If $res is the same as $arg, $reason is "equal". If the length of $res is less than 3, $reason is set to "too short". If $managed is 1, and $res is already in the %deadends hash, $reason is set to "deadend", and if $res is equal to "now" (the goal, as it happens) then $reason is set to "found".



If $reason is not empty and not "equal" then print a newline, as many spaces as there are levels of recursion, the rule that got us here, the incoming word and the result of the rule application. If $reason is "deadend" then print an exclamation mark to show that a deadend has been reached, otherwise print a full stop.



If we've actually reached "now", indicate that with an asterisk. (We could exit the script at this point, but I left it to show all the possible paths to the stop word.)



If managing recursion, store the value of $res in the deadends hash.



Now, if $reason is, for some reason, empty, print a newline, as many spaces as there are recursion levels, the rule, and the $arg and the $res. Then increase the value of $level and recursively call apply with the contents of $res. When it returns, decrease the value of $level.



Here's the first call to apply, with a newline displayed once processing returns from the call.



Keeping track of dead-ends proved useful. Without it, the 'first' to 'now' attempt generated at 406K file (redirecting the output). With it, I got a 5K file. Similarly, 'ant' to 'now' was 1.8K without, and 457 bytes with. When it came to starting with 'gnat', a managed conversion generated an 8K file. Without management the laptop slowed to a crawl. After about five minutes I got an "Out of memory!" on stderr, so I killed the perl processing resulting in a 902 Megabyte file.

This is the result of a managed attempt with 'ant' as the start word:



Sadly, no asterisks. Next, the log of a managed run starting with 'gnat'. Success came quite quickly: start with 'gnat' and apply rules 2, 3, 4, 2, 4, 5, 6 and 2. An even shorter path appears further down: 3, 4, 2, 5, 6, and 4. The shortest appears to be 4, 2, 5, 6, 4 -- nnat, annt, ann, aow, now.



Writing this makes me wonder if I should have found some way to jump from a successful traversal back to 'gnat' rather than applying the rules to instances of 'now' in search of an extended path to 'now'. I leave that as an exercise to the reader, and if you work out how to do it, please let me know.

© Copyright Bruce M. Axtens, 2008

Thursday, February 21, 2008

[Perl/PDK/PerlCtrl] Returning an array of arrays for VB6/VBScript

For the last few weeks I've been trying to get used to working with the Perl Development Kit (PDK 7.1) from ActiveState, particularly PerlCtrl.

One of the challenges I've been facing lately is how to return an array of arrays. That is, returning something that in VB6 or VBScript might be represented as Array( Item, Array( Item, Item ), Item ).

Kudos to
Perl Monks, who have provided a function which converts a Perl array to a VB array. Interestingly, it also copes with said converted array being embedded in another array and with that array being converted as well. (Bodes well for other projects.)

So what we have below is some Perl code, a PerlCtrl wrapper around a WMI call to list System Services. The wrapper returns a two element array, the first element being an array of all the services which are running, and the second an array of all the services which have been stopped.

Note that without 'use Win32::OLE qw(in);' you can't access the elements of the $colItems collection, as it enables the use of 'in' in the foreach. Similarly, you need Win32::OLE::Variant for all the Variant() calls.

Please don't ask me to explain what's going on in the convertArrayToVBArray sub, because I have no idea. Anyone know?



The second bit of code is a VBScript testing the COM DLL. It's a assumed that you've run the above code through PerlCtrl, generated a DLL and registered it with RegSvr32.



I'm having a lot of fun with Perl. I've been able to take a lot of Perl functionality (Tree::Nary, Data::Trie, Lingua::EN::Inflect, Algorithm::LCSS, Algorithm::Knapsack, Algorithm::BinPack, Algorithm::Bucketizer, Algorithm::Permute, Algorithm::SetCovering, String::LCSS and Statistics::Benford) and turn it into something that VB6 and VBScript can use. I'm impressed. Would that every scripting language had this kind of power.

© Copyright Bruce M. Axtens, 2008

Tuesday, January 08, 2008

[Protium] Master Class #1 (Part 2)

Demonstration - Oblique Strategies

"The Oblique Strategies are a deck of cards. Up until 1996, they were quite easy to describe. They measured about 2-3/4" x 3-3/4". They came in a small black box which said "OBLIQUE STRATEGIES" on one of the top's long sides and "BRIAN ENO/PETER SCHMIDT" on the other side. The cards were solid black on one side, and had the aphorisms printed in a 10-point sans serif face on the other.

...

The deck itself had its origins in the discovery by Brian Eno that both he and his friend Peter Schmidt ... tended to keep a set of basic working principles which guided them through the kinds of moments of pressure — either working through a heavy painting session or watching the clock tick while you're running up a big buck studio bill. Both Schmidt and Eno realized that the pressures of time tended to steer them away from the ways of thinking they found most productive when the pressure was off. The Strategies were, then, a way to remind themselves of those habits of thinking — to jog the mind."         
-- Oblique Strategies
A web-based installation of Oblique Strategies is supplied in the standard Protium install. Using the "Internet Information Services" snap-in, create a virtual directory pointing to C:\protium\Code\prx\os. Specify its default as index.prx, call it 'os', and share the C:\protium\Code\prx\os directory (Microsoft Access is picky about being able to write to databases even when only reading.)

Further information on setting up IIS can be found in the Protium document "C:\protium\bin\plugins\Configuring Windows IIS 5 to use with Protium and Isis.html"

The Protium code in the index.prx file is as follows:
The above code (indented only to more clearly demonstrate document structure) outputs a different strategy each time the page is refreshed. The syllables translate as follows:
<@ DEFKEYLIT>__Transput|__HTMLTransput</@>define the Transput as HTML
<@ SAYPRO>output a document prologue. (What is output by the PRO syllable depends on the Transput defined, as is the case for all document related syllables.)
<@ SAYDOC>Enclose a document.
<@ SAYDHD>Enclose a document header, in the context of an existing document.
<@ SAYDTT>Oblique strategies</@>set the document title, in the context of an existing document body and header.
<@ SAYDBD></@>enclose a document body, in the context of an existing document.
<@ DEFDBFLIT>os</@>opens this data source, by default a JET/MSAccess database.
<@ DEFRSTCAP>select * from os where cardid = <@ SAYRANLIT>100</@></@>Open record source defined by captured output.
<@ SAYRANLIT>100</@>return a random number between 1 and 100.
<@ SAYDPR></@>enclose a document paragraph, in the context of the existing document.
<@ SAYFLD>message</@>print the contents of the field called 'message' which, in this context, is part of the 'os' recordset.
Note that the code chooses a strategy based on a random number between 1 and 100. But what if there are more than 100 strategies? Wouldn't it be better if the actual number of records could be found and that used as the basis for the RAN syllable? Two ways of handling this requirement are described below:

The changed syllables translate as follows:
<@ DEFRSTLIT>os</@>Select every record in the database.
<@ LETVARSZERST>upper|___</@>assign to the variable 'upper' the size of the default (marked by three underscores) recordset.
<@ RSTCAP>select * from os where cardid = <@ SAYRANVAR>upper</@></@>Select a new recordset, capturing the output from RAN but using the variable 'upper' to specify the limit.
Rather than get the number of records, simply ...
<@ ACTMOVRANRST></@>move the record pointer to a random place in the recordset.
This demonstrates the power of idiomatic Protium: short, sweet and to the point.

Questions and Answers

I can't see a main() anywhere. Where's the start?

Protium implements a single-pass code evaluation model. This is quite unlike most other languages which implement double-pass code evaluation: first pass to discover and make a map; second pass to evaluate.

Protium starts at the beginning of a named file, and builds its awareness of context from there. Because of this approach, we may never examine code we aren't interested in.

I keep using the same construction over and over again. Is there a way of abbreviating Protium words?

What you can do is create a compound operator (a concept borrowed from OPS-3). These are defined using the KOP syllable. If you wanted to define LVK as a shorthand for LETVARKEY, for example, then you would code


Thereafter you would be able to use the abbreviated form, replacing code like
with


There are other ways of doing this, including UDS (user-defined syllable) and BLK (code block), but this is by far the simplest.

*** End of Part 2 ***


© Copyright Bruce M. Axtens, 2008

Monday, January 07, 2008

[Protium] Master Class #1 (Part 1)

Protium is ...

Protium is essentially, and at heart, a way of finding data in a myriad of locations in a homologous manner, manipulating it in a myriad of ways, and then delivering it to a myriad of displays, in a myriad of [human] languages. A concomitant of that is that data be current, so this also involves updating old data, which means that a similar potential is there for making changes to data.

But the overriding maxim is for a direct equivalence of task to operator at the conceptual level. This means that high-level / low-level language distinctions don't enter in: branching is a single operator, but so is "work out the utility matrix for this complex set of possibilities"; the iteration syllable is at the same level as that of add and of unique-sort.

Influences

"I had as a goal the economy and power of APL (minus the cryptic nature) while having the manipulation power of SNOBOL, the one-for-one power of multimedia-instruction-set assembler (e.g. QUEXAL), the task oriented nature of NODAL, the reality representation characteristics of ATLAS, and the data ordering capabilities of the 'lost languages' (Simscript, Dectab, dBase etc.), [such that] the data is available in a way that ordinary programming languages don't permit.

"The other thing I took from NODAL was
JOSS's implicit mixing of code and data, which is much saner than LISP's, and also the way that there was an implicit hierachy of data.

"I also borrowed some control structures from
RPG, temporary constructions from Miranda, generators from Icon, multiple outcomes from COMIT and compound operators from OPS-3.

"I rejected the naive form of IO (which bedevilled Algol and Fortran). I think the ability to display is the least-used functionality of programming, only touched on in
screenwiping and SOAP.

"The idea of assignment [in most programming languages] is generally also naive - for instance the fact that it is a function has been overblown in functional languages, but ignored elsewhere. So [I implemented] scaling and multiple returns (present in
LYaPAS in 1964), multiple assigns (common in FORTRAN, APL and the original BASIC), multiple functional transforms (common in any DSP language, e.g. Faust) as well as the closer knitting of data and code (from FORTRAN and dBase).

"The final point to note is that the entirety of Protium works with a SNOBOL-/COMIT-style success/failure flag, converted to a success / failure / don't-know ternary system. Any operation will set this, but it can be qualified (success, found, quantity more than zero, test type, pattern match, etc.)

"Essentially, the idea was to revisit the nature of the programming task, and learn from where the bounds had been stretched; to try to get a thought-to-line-of-code transference capability, rather than the reductive, ALGOL-ish, 'see-how-small-I-can-get-the-core' approach."

        -- Diarmuid Pigott, personal correspondence, 9 January 2007.

How to Program in Protium

The overall Protium approach to programming is to work out what you want to do, then work out what it is that that would be in Protium terms. Sometimes this is very similar to the conventional way (most of the code examples are conventional in that way to secure familiarity). Sometimes it involves a simple task that is unfamiliar in those terms.

Unlike most other programming languages, Protium does not force the programmer to work in either a top-down / decompositional or bottom-up / compositional way. Either approach can be taken. The art of Protium is in the discovery of the idiomatic form which best describes the solution to the problem.

Workflow in Protium programming is simply this: work out what data you need to solve a problem, then extract it and present it. When there is need to extract data according to a criterion, it is specified in two stages, first the data source, then the record source, in the following hierarchy: Data Source -> Record Source -> Record -> Field ->
Subfield. Any number of Data Sources can be open at one time, and any number of Record Sources, but a Record Source will always be subordinate to its Data Source.

Protium supports a number of ways of addressing and participating in memory. Memory is untyped. It is a simple tuple of name => value (read name implies value) which can be late-bind typed using 'typifiers', but is inherently capable of any interpretation. There is one global memory space, but it is lexically divided (using namespaces) to make the equivalents of local, static etc. Memory is synthetic, in that it will create a variable (or a structure) on being first called — variables do not need to be declared nor the type of their content specified.

Protium relies heavily on the concept of aliases: when any complex computational task is invoked the operation is aliased, so that you can switch back to it at any time. Anything can be aliased: branching, looping, switching, creation and use of structures, and interaction with data. These aliases, also known as workareas, have two components: a
type and a name.

Alias names can be invoked internally, so a field called 'ChinaCollection => DateOfPurchase' will automatically invoke the aliased workspace called ChinaCollection to fulfil the data request. This means that some very powerful manipulations are possible - such as the much-used scatter/gather (borrowed from FoxPro) to swap data between aliased workspaces.

Implicit in all of this is the idea that, where possible, everything should be invokable with one operator, so DCT (dictionary) without a name is the dictionary currently in scope, and of course implicit in the entire thing is a hierarchy of context - the field is always (unless specified) invoked in the context of the current record or the current recordset (or query or view) of the current database. It is this dependence on context - Protium's context-aware, rather than context-free, grammar - which trips up the beginning Protium programmer. That and the lack of appropriate casting of numerics - all comparisons in Protium are lexical (i.e. 'a' is less than 'c'; 5 is greater than 45000), so comparison syllables must bear an explicit number-cast syllable when a numeric comparison is
required.

Conventions

Protium respects the following naming conventions with respect to the file type:
ExtensionMeaning
.pa Protium script in plain text format
.pra Protium script in rich text format (RTF)
.prea ProtiumWeb script (plain text, HTML or rich text)
.prxa Protium executable project (plain text, HTML or rich text)
.plba Protium library (plain text, HTML or rich text)
The code in a .pre or .prx file can favour HTML (the <BODY>text</BODY> approach) or favour Protium (the <@ SAYDBDLIT>text</@> approach). In the latter it is possible to write <@ DBD>text</@> as Protium will disambiguate where possible, making 'slang' forms possible .

Generally we make two files per website, a default.prx and an index.prx, but of course it could be set up to look for an index.pre, if necessary.

*** End of Part One ***


© Copyright Bruce M. Axtens, 2008