<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-15254360</id><updated>2026-07-24T14:04:35.565+08:00</updated><category term="VBScript"/><category term="VB6"/><category term="JScript"/><category term="javascript"/><category term="rosettacode"/><category term="programming languages"/><category term="sorting"/><category term="Ada"/><category term="DLL"/><category term="Protium"/><category term="class"/><category term="Euphoria"/><category term="HTA"/><category term="Tcl"/><category term="WMI"/><category term="cygwin"/><category term="ActiveDirectory"/><category term="BOOST"/><category term="CMD.EXE"/><category term="Excel"/><category term="GNAT/GCC"/><category term="MetaCard"/><category term="StandardLibrary"/><category term="mLite"/><category term="Clipper"/><category term="Eval"/><category term="Perl"/><category term="SNOBOL4"/><category term="binary notation"/><category term="shell sort"/><category term="ADODB"/><category term="Array"/><category term="Broggle"/><category term="EOC"/><category term="Internet Explorer"/><category term="Mac OS X"/><category term="PLEAC"/><category term="PLUG"/><category term="Synthetic Include"/><category term="Unicode"/><category term="VarPtr"/><category term="Win32Ada"/><category term="batch"/><category term="bignum"/><category term="command language interpreter"/><category term="console mode"/><category term="end of contract"/><category term="php"/><category term="state tables"/><category term="tclsh"/><category term="winmgmts"/><category term="xharbour"/><category term="99 bottles of beer"/><category term="99bob"/><category term="ACT"/><category term="ADO"/><category term="ADODB.RecordSet"/><category term="ActiveX"/><category term="AdSense"/><category term="COBOL"/><category term="COM DLL"/><category term="DEF"/><category term="Delphi"/><category term="Diarmuid J Pigott"/><category term="EKM"/><category term="ESL"/><category term="Escape"/><category term="GNAT"/><category term="Google"/><category term="Google Apps Script"/><category term="HTML"/><category term="HTML Applications"/><category term="INI"/><category term="JScript.NET"/><category term="KEY"/><category term="MSScriptControl"/><category term="Map"/><category term="Matching"/><category term="Microsoft"/><category term="Modula-2"/><category term="MoonRock BASIC"/><category term="Parray"/><category term="Perth Linux Users Group"/><category term="REST"/><category term="SETSUBSYS"/><category term="Scripting.FileSystemObject"/><category term="Spitbol"/><category term="StackOverflow"/><category term="UPX"/><category term="UnEscape"/><category term="VBA"/><category term="Watcher"/><category term="XML"/><category term="algorithms"/><category term="code generation"/><category term="commandline tools"/><category term="csnobol4"/><category term="datetime"/><category term="fluent"/><category term="gawk"/><category term="globbing"/><category term="gnucobol"/><category term="grep"/><category term="heap sort"/><category term="jQuery"/><category term="newLISP"/><category term="open source"/><category term="pointers"/><category term="priority class"/><category term="recursion"/><category term="scatter"/><category term="sqlserver"/><category term="string"/><category term="structures"/><category term="tbas"/><category term="windows10"/><category term="+INFINITY"/><category term="-INFINITY"/><category term=".NET"/><category term="4GuysFromRolla"/><category term="5000d-2"/><category term="64bit"/><category term="ABAP"/><category term="AC/DC"/><category term="ADD"/><category term="ANSI"/><category term="API"/><category term="Access.Application"/><category term="ActiveScript"/><category term="ActiveState"/><category term="ActiveXObject"/><category term="Analytics"/><category term="Apple"/><category term="Artistic2"/><category term="Bliss"/><category term="Brian Eno"/><category term="Brian Tiffin"/><category term="Bruce the Goose"/><category term="CAP"/><category term="CCNA"/><category term="CLI framework"/><category term="CLIVE"/><category term="CND"/><category term="COM"/><category term="COUNTIFS"/><category term="CS-Script"/><category term="CSS"/><category term="CSV"/><category term="CUPL"/><category term="Candle"/><category term="CodePlex"/><category term="Codeaholic in print"/><category term="CollectFiles"/><category term="Collections"/><category term="Compaq Visual Fortran"/><category term="Config"/><category term="Configure"/><category term="Container"/><category term="Cornell"/><category term="Cross-referencing"/><category term="DATA"/><category term="DBD"/><category term="DBF"/><category term="DEXP"/><category term="DHD"/><category term="DIR"/><category term="DLI"/><category term="DOC"/><category term="DPR"/><category term="DTT"/><category term="DateDiff"/><category term="Department Land Information"/><category term="Dr. Dmitry A. Kazakov"/><category term="Dragon Dictate"/><category term="Drive Parameter Table"/><category term="EXP"/><category term="Edanmo"/><category term="Enumerator"/><category term="Eric Raymond"/><category term="Evaluator"/><category term="ExecuteGlobal"/><category term="ExpertsExchange"/><category term="FAST"/><category term="FBSL"/><category term="FLD"/><category term="FOR"/><category term="FOSS"/><category term="Fortran"/><category term="Fred Weigel"/><category term="FreeDOS"/><category term="GNAT/GPL"/><category term="GPL"/><category term="Get A Coder"/><category term="Get A Freelancer"/><category term="GetDomainComputers"/><category term="GetMembersWithSubStringEx"/><category term="GetObject"/><category term="Google Keep"/><category term="Gordon Peterson"/><category term="Gryphon"/><category term="HOPL"/><category term="Home Open"/><category term="IEDisplay"/><category term="IFF"/><category term="IIF"/><category term="ITE"/><category term="ITtoolbox"/><category term="Ignorance"/><category term="InetIsOffline"/><category term="Inspiration"/><category term="IronJS"/><category term="IronPython"/><category term="JACOB"/><category term="JOSS"/><category term="JVM"/><category term="Jabaco"/><category term="Java"/><category term="John Burkardt"/><category term="Join"/><category term="KOP"/><category term="Knapsack"/><category term="LET"/><category term="LIT"/><category term="Lhogho"/><category term="Lion Nathan"/><category term="Lychen"/><category term="MAC"/><category term="MINDOUBLE"/><category term="ML"/><category term="MOV"/><category term="MSJAVA.DLL"/><category term="MetaClasses.plist"/><category term="NET VIEW"/><category term="NaN"/><category term="Neko"/><category term="Neuronstorm"/><category term="Nicolas Cannasse"/><category term="Nokia"/><category term="Notebook"/><category term="Nuance"/><category term="OMT"/><category term="ONG"/><category term="OOP"/><category term="ObjectAda"/><category term="Objective Modula-2"/><category term="Oblique Strategies"/><category term="OleInitialize"/><category term="OleUninitialize"/><category term="Online Bible"/><category term="PAR"/><category term="PLOM"/><category term="PUSHD"/><category term="Pattern"/><category term="PerlCtrl"/><category term="PerlScript"/><category term="Peter Schmidt"/><category term="Pharmacy Software"/><category term="Programmers Bill of Rights"/><category term="RAN"/><category term="RANGEDCOUNT"/><category term="READ"/><category term="REALbasic"/><category term="REPL"/><category term="RES"/><category term="RST"/><category term="RXP"/><category term="Rafal M. Sulejman"/><category term="Replace"/><category term="Retrocomputing Museum"/><category term="RevInstr"/><category term="Revolution"/><category term="SAP"/><category term="SNK"/><category term="SOFA"/><category term="SORT.EXE"/><category term="Safari"/><category term="ScriptControl"/><category term="Selenium"/><category term="ShowStructure"/><category term="Sinclair Knight Merz"/><category term="Single+Float v/s Double+Float"/><category term="Stream"/><category term="String-object"/><category term="Subst"/><category term="Sudoku"/><category term="SysTray"/><category term="SysVars"/><category term="System.Environment.Exit"/><category term="System.Environment.GetCommandLineArgs"/><category term="System.IO"/><category term="TLBINF32"/><category term="TNT"/><category term="TP5"/><category term="TST"/><category term="TechTrax"/><category term="TkSLIDE"/><category term="Tony Hinkle"/><category term="UDS"/><category term="UTF-32"/><category term="VAR"/><category term="VBAdvance"/><category term="VBArray"/><category term="VM"/><category term="VOLATILE"/><category term="VT_ARRAY|VT_VARIANT"/><category term="VeryLargeInteger"/><category term="Virtual Unknowns"/><category term="Visual Studio 2005"/><category term="Vrode Editor"/><category term="WSH"/><category term="WScript.Network"/><category term="Win32::OLE"/><category term="Win32::OLE::Variant"/><category term="WinClip"/><category term="WinHttp"/><category term="Yahoo!"/><category term="Zerofill"/><category term="Zerofill2"/><category term="[VB6] MAXDOUBLE"/><category term="__Transput"/><category term="absolute reference"/><category term="ackermann"/><category term="after"/><category term="anonymous subroutines"/><category term="arguments"/><category term="automation"/><category term="backup"/><category term="bash"/><category term="basic"/><category term="before"/><category term="between"/><category term="binary"/><category term="binary clock"/><category term="binary files"/><category term="binary2decimal"/><category term="binary2hexadecimal"/><category term="bitbucket"/><category term="blogging"/><category term="browser detection"/><category term="bubble sort"/><category term="build"/><category term="bus driver"/><category term="c#"/><category term="caesar cipher"/><category term="callee"/><category term="caller"/><category term="camel case"/><category term="cell references"/><category term="cgi"/><category term="chinese"/><category term="clipboard"/><category term="clock add"/><category term="clock format"/><category term="clock seconds"/><category term="coldfusion"/><category term="collection"/><category term="command generator"/><category term="comp.lang.basic.misc"/><category term="compression"/><category term="configuration"/><category term="contracting"/><category term="data-driven code"/><category term="dave phillips"/><category term="depression"/><category term="dhall"/><category term="dialogs"/><category term="disconnected recordset"/><category term="dlltool"/><category term="docScript"/><category term="dotnet"/><category term="dotnet core"/><category term="dotnet framework"/><category term="dotnet standard"/><category term="endswith"/><category term="entities"/><category term="epoch"/><category term="find"/><category term="floppy diskette access"/><category term="fortypounthead"/><category term="foxpro"/><category term="freshmeat"/><category term="function"/><category term="function parameters"/><category term="functional"/><category term="genie"/><category term="getclip"/><category term="getrows"/><category term="github"/><category term="gnatlink"/><category term="gnatmake"/><category term="go"/><category term="gravityforms"/><category term="hashes"/><category term="help desk"/><category term="htmlfile"/><category term="iPad"/><category term="iSync"/><category term="idea mapper"/><category term="iiNet"/><category term="inf file-extension"/><category term="interpreter"/><category term="iphone"/><category term="ipod touch"/><category term="ivodne galatea"/><category term="lambda-expression"/><category term="lame"/><category term="laptimer"/><category term="late binding"/><category term="leading edge"/><category term="legacy"/><category term="libiconv"/><category term="libmp3lame.dll"/><category term="linkedin"/><category term="logarithms"/><category term="macros"/><category term="markup"/><category term="mathematics"/><category term="me"/><category term="mergesort"/><category term="method chaining"/><category term="mobile devices"/><category term="mp3"/><category term="music"/><category term="netmask"/><category term="network"/><category term="nils m holm"/><category term="non-turing-complete"/><category term="opinions"/><category term="packing manager"/><category term="pattern matching"/><category term="pearltrees"/><category term="perlmonks"/><category term="pleac_1.0"/><category term="printf"/><category term="process-priority"/><category term="profiling"/><category term="prototype"/><category term="proxy"/><category term="questionMarkIs"/><category term="quick sort"/><category term="quickedit mode"/><category term="quiz"/><category term="quora"/><category term="reading and writing files"/><category term="recordset"/><category term="reduce"/><category term="regular expressions"/><category term="relative reference"/><category term="resistance is useless"/><category term="resistors"/><category term="restart-router"/><category term="reverse-find"/><category term="rexx"/><category term="scriptProperties"/><category term="search and replace"/><category term="sed"/><category term="semaphores"/><category term="singing"/><category term="skiena"/><category term="soap"/><category term="sound"/><category term="sox"/><category term="stackexchange"/><category term="stdcall"/><category term="stopwatch"/><category term="string-reversal"/><category term="stripChars"/><category term="tcp/ip"/><category term="telnet"/><category term="template"/><category term="templates"/><category term="text transformations"/><category term="textarea"/><category term="threads"/><category term="timeline"/><category term="timemachine"/><category term="timer"/><category term="timesheets"/><category term="timing"/><category term="toArrayOfLines"/><category term="toProperCase"/><category term="toSqlString"/><category term="trailing edge"/><category term="url.dll"/><category term="usenet"/><category term="username from computername"/><category term="variant"/><category term="visual COBOL"/><category term="warbussing"/><category term="wardriving"/><category term="wav"/><category term="wildcard"/><category term="wildcards"/><category term="wireless internet"/><category term="wordpress"/><category term="xBase"/><category term="xbScript"/><category term="zodiac"/><title type='text'>Code-a-holic</title><subtitle type='html'>Past (20 years or so) and present code. A variety of languages and platforms. Some gems. More gravel. Some useful stuff and some examples of how not to do it.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://codeaholic.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://codeaholic.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>Bruce M. Axtens</name><uri>http://www.blogger.com/profile/14797830611260628579</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>191</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-15254360.post-2627706316021741561</id><published>2023-04-03T17:53:00.002+08:00</published><updated>2023-04-03T17:53:15.865+08:00</updated><title type='text'>[Exercism] Projects</title><content type='html'>&lt;p&gt;&amp;nbsp;Currently I&#39;m working on tracks for the following languages:&lt;/p&gt;&lt;p&gt;Euphoria&lt;/p&gt;&lt;p&gt;SNOBOL4&lt;/p&gt;&lt;p&gt;Seed7&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeaholic.blogspot.com/feeds/2627706316021741561/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/15254360/2627706316021741561' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default/2627706316021741561'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default/2627706316021741561'/><link rel='alternate' type='text/html' href='http://codeaholic.blogspot.com/2023/04/exercism-projects.html' title='[Exercism] Projects'/><author><name>Bruce M. Axtens</name><uri>http://www.blogger.com/profile/14797830611260628579</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15254360.post-2420002872383852599</id><published>2023-04-03T17:45:00.001+08:00</published><updated>2023-04-03T17:51:54.224+08:00</updated><title type='text'>[Regex] Regular Expression to find unescaped double-quotes in JSON</title><content type='html'>&lt;p&gt;So here we are again. Another couple of years have passed. Maybe this year I&#39;ll be more forthcoming with content. Maybe I can log what I do at the office here, though without all the WPAdmin passwords.&lt;/p&gt;&lt;p&gt;Today I had exported the entire WooCommerce inventory of a customer as JSON but found that there were embedded double-quotes that weren&#39;t properly escaped and so were messing up the tools I use for JSON traversal and extraction.&lt;/p&gt;&lt;p&gt;I used Notepad++ for most text editing (when I&#39;m not using Visual Studio Code) and I cooked up this regular expression to help me find double quotes:&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-size: large;&quot;&gt;&amp;nbsp;[^:,]\s&quot;\w+&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;That looks for a character that isn&#39;t a colon or comma, followed by a space followed by a double-quote followed by one or more word-building characters.&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: large;&quot;&gt; &lt;br /&gt;&lt;/span&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeaholic.blogspot.com/feeds/2420002872383852599/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/15254360/2420002872383852599' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default/2420002872383852599'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default/2420002872383852599'/><link rel='alternate' type='text/html' href='http://codeaholic.blogspot.com/2023/04/regular-expression-to-find-unescaped.html' title='[Regex] Regular Expression to find unescaped double-quotes in JSON'/><author><name>Bruce M. Axtens</name><uri>http://www.blogger.com/profile/14797830611260628579</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15254360.post-2007577720674321585</id><published>2021-10-08T12:39:00.014+08:00</published><updated>2023-04-03T17:50:55.729+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="linkedin"/><category scheme="http://www.blogger.com/atom/ns#" term="REST"/><title type='text'>[LinkedIn API] Accessing the LinkedIn API ... or not</title><content type='html'>&lt;p&gt;Wow, &quot;Saturday, July 20, 2019&quot; was a while ago. Nevertheless, here we are again writing about code.&lt;/p&gt;&lt;p&gt;I&#39;m trying, totally unsuccessfully at this point, to talk to the LinkedIn API. There&#39;s copious documentation but something isn&#39;t connecting up in my mind and I&#39;m having an IJDGI (I just don&#39;t get it) moment.&lt;/p&gt;&lt;p&gt;I&#39;ve followed the process listed at&amp;nbsp;https://docs.microsoft.com/en-us/linkedin/shared/authentication/client-credentials-flow?context=linkedin/compliance/context insofar as I have created an app and had it verified.&lt;/p&gt;&lt;p&gt;At the moment I&#39;m in Visual Studio Code (VSC) and using the &lt;a href=&quot;https://github.com/Huachao/vscode-restclient&quot; target=&quot;_blank&quot;&gt;RestClient&lt;/a&gt;&amp;nbsp;tool to do two-legged OAuth:&lt;/p&gt;&lt;div style=&quot;color: #d4d4d4; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; white-space: pre;&quot;&gt;&lt;div style=&quot;background-color: #1e1e1e; line-height: 19px;&quot;&gt;&lt;div&gt;&lt;span style=&quot;color: #c586c0;&quot;&gt;POST&lt;/span&gt; /oauth/v2/accessToken &lt;span style=&quot;color: #569cd6;&quot;&gt;HTTP&lt;/span&gt;/&lt;span style=&quot;color: #b5cea8;&quot;&gt;1.1&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;Host:&lt;/span&gt; &lt;span style=&quot;color: #ce9178;&quot;&gt;www.linkedin.com&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;Content-Type:&lt;/span&gt; &lt;span style=&quot;color: #ce9178;&quot;&gt;application/x-www-form-urlencoded&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;grant_type=client_credentials&amp;amp;client_id=xxxxxxxxxx&amp;amp;client_secret=zyxwvutsrqponm&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p style=&quot;text-align: left; white-space: pre;&quot;&gt;&lt;span style=&quot;font-family: inherit; font-size: x-small;&quot;&gt;(client_id and client_secret obfuscated)&lt;/span&gt;&lt;/p&gt;&lt;div style=&quot;white-space: pre;&quot;&gt;The rather long-winded response I&#39;m getting from that request ends with &lt;/div&gt;&lt;div style=&quot;white-space: pre;&quot;&gt;&lt;span style=&quot;background-color: black;&quot;&gt;&lt;span style=&quot;color: white;&quot;&gt;&lt;span class=&quot;line width-2&quot; range-end=&quot;29&quot; range-start=&quot;27&quot; start=&quot;27&quot; style=&quot;box-sizing: inherit; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; padding-left: calc(2ch + 20px); position: relative; white-space: pre-wrap;&quot;&gt;{&lt;span class=&quot;icon&quot; style=&quot;background-attachment: initial; background-clip: initial; background-image: url(&amp;quot;expand-dark.svg&amp;quot;); background-origin: initial; background-position: 0% 0%; background-repeat: no-repeat; background-size: 1.2em; box-sizing: inherit; cursor: pointer; display: inline-block; height: 1em; left: calc(2ch + 3px); position: absolute; top: 0.15em; width: 1em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; white-space: pre-wrap;&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;line width-2&quot; start=&quot;28&quot; style=&quot;box-sizing: inherit; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; padding-left: calc(2ch + 20px); position: relative; white-space: pre-wrap;&quot;&gt;  &lt;span class=&quot;hljs-attr&quot; style=&quot;box-sizing: inherit;&quot;&gt;&quot;error&quot;&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot; style=&quot;box-sizing: inherit;&quot;&gt;&quot;access_denied&quot;&lt;/span&gt;,&lt;/span&gt;&lt;span style=&quot;font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; white-space: pre-wrap;&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;line width-2&quot; start=&quot;29&quot; style=&quot;box-sizing: inherit; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; padding-left: calc(2ch + 20px); position: relative; white-space: pre-wrap;&quot;&gt;  &lt;span class=&quot;hljs-attr&quot; style=&quot;box-sizing: inherit;&quot;&gt;&quot;error_description&quot;&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot; style=&quot;box-sizing: inherit;&quot;&gt;&quot;This application is not allowed to create application tokens&quot;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; white-space: pre-wrap;&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;line width-2&quot; start=&quot;30&quot; style=&quot;box-sizing: inherit; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; padding-left: calc(2ch + 20px); position: relative; white-space: pre-wrap;&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;white-space: pre;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;white-space: pre;&quot;&gt;&lt;b&gt;LATER&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;white-space: pre;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;white-space: pre;&quot;&gt;This project may well come under what LinkedIn calls an &quot;Unapproved Use Case&quot; as their &lt;a href=&quot;https://docs.microsoft.com/en-us/linkedin/marketing/restricted-use-cases&quot; target=&quot;_blank&quot;&gt;site says&lt;/a&gt;, &lt;/div&gt;&lt;blockquote&gt;&lt;blockquote&gt;&lt;span style=&quot;white-space: pre;&quot;&gt;Unapproved Use Cases&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span style=&quot;white-space: pre;&quot;&gt;Additional use cases we do not permit:&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span style=&quot;white-space: pre;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span style=&quot;white-space: pre;&quot;&gt;No Social Feeds: Under our &lt;a href=&quot;https://business.linkedin.com/marketing-solutions/marketing-partners/become-a-partner/marketing-developer-program/terms-and-conditions&quot; target=&quot;_blank&quot;&gt;MDP Terms&lt;/a&gt;, none of the data provided via our&amp;nbsp;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span style=&quot;white-space: pre;&quot;&gt;Page Management APIs can be used in a social feed use case (e.g. to display&amp;nbsp;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span style=&quot;white-space: pre;&quot;&gt;a feed of LinkedIn company updates on the company’s website or intranet).&lt;/span&gt;&lt;/blockquote&gt;&lt;/blockquote&gt;&lt;p&gt;Hmm...&amp;nbsp;&lt;/p&gt;&lt;p&gt;I&#39;ve also asked for help on &lt;a href=&quot;https://www.reddit.com/r/linkedin/comments/q3p45t/just_starting_with_linkedin_api/&quot; target=&quot;_blank&quot;&gt;Reddit&lt;/a&gt;,&amp;nbsp;&lt;a href=&quot;https://dev.to/bugmagnet/how-to-retrieve-a-company-s-recent-posts-in-linkedin-580j&quot; target=&quot;_blank&quot;&gt;DEV&lt;/a&gt; and &lt;a href=&quot;https://stackoverflow.com/questions/69490063/how-to-retrieve-a-companys-recent-posts-in-linkedin&quot; target=&quot;_blank&quot;&gt;StackOverflow&lt;/a&gt;. I expect they&#39;ll tell me it&#39;s unapproved.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeaholic.blogspot.com/feeds/2007577720674321585/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/15254360/2007577720674321585' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default/2007577720674321585'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default/2007577720674321585'/><link rel='alternate' type='text/html' href='http://codeaholic.blogspot.com/2021/10/accessing-linkedin-api-or-not.html' title='[LinkedIn API] Accessing the LinkedIn API ... or not'/><author><name>Bruce M. Axtens</name><uri>http://www.blogger.com/profile/14797830611260628579</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15254360.post-8305110908581978605</id><published>2019-07-20T22:32:00.001+08:00</published><updated>2023-04-03T17:50:30.567+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="javascript"/><category scheme="http://www.blogger.com/atom/ns#" term="Lychen"/><category scheme="http://www.blogger.com/atom/ns#" term="string-reversal"/><category scheme="http://www.blogger.com/atom/ns#" term="timing"/><title type='text'>[JavaScript] Testing (and Timing) String Reversal Functions </title><content type='html'>So &lt;a href=&quot;https://dev.to/sarah_chima/reverse-a-string-four-javascript-solutions-2nbm&quot;&gt;Sarah Chima&lt;/a&gt; wrote an article about reversing a string, done four different ways. A few folk wrote in with other solutions. I wrote in with some too.&lt;br /&gt;
&lt;br /&gt;
Then it was suggested that we try to work out which really is the fastest. What follows is me trying.&lt;br /&gt;
&lt;br /&gt;
So I need first of all to mention my working environment. It&#39;s call &lt;a href=&quot;https://github.com/axtens/Lychen&quot;&gt;Lychen&lt;/a&gt; and it&#39;s a wrapping of the V8 JavaScript engine in a C# command line application with access to some C# objects, methods and properties. Lychen is «not supposed to be cutting-edge. Rather, it&#39;s on the spine of the blade, about as far from the cutting-edge as one can get without leaving the blade altogether.» (see the &lt;a href=&quot;https://github.com/axtens/Lychen/wiki&quot;&gt;Wiki&lt;/a&gt;).&lt;br /&gt;
&lt;br /&gt;
You might say to me, &quot;Hey, what about &lt;a href=&quot;https://nodejs.org/en/&quot;&gt;node&lt;/a&gt;?&quot; My response is usually along the lines of &quot;I just can&#39;t get my head around the promises and the asynchrony. Maybe one day.&quot;&lt;br /&gt;
&lt;br /&gt;
So here&#39;s the code.&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;&amp;nbsp;&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;const Console = CS.System.Console;
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;code&gt;CS.&lt;/code&gt; exposes a large number of C# core and third party objects into the Lychen (V8) environment. Rather than keep typing &lt;code&gt;CS.System.Console&lt;/code&gt; we create an abbreviation.&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;&amp;nbsp;&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if (CSSettings.ContainsKey(&quot;/D&quot;)) {
  debugger;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
On launch, &lt;code&gt;CSSettings&lt;/code&gt; (a &lt;code&gt;Dictionary&lt;string object=&quot;&quot;&gt;&lt;/string&gt;&lt;/code&gt;) receives all the command line parameters. In this case, if it&#39;s &lt;code&gt;/D&lt;/code&gt; we debug.&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;const times = CSSettings.ContainsKey(&quot;/TIMES&quot;) ? parseInt(CSSettings(&quot;/TIMES&quot;), 10) : 1000;
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
Similarly, here we check for the presence of &lt;code&gt;/TIMES&lt;/code&gt; and if it&#39;s, say, &lt;code&gt;/TIMES:123&lt;/code&gt; then &lt;code&gt;times&lt;/code&gt; is set to &lt;code&gt;123&lt;/code&gt;. Otherwise &lt;code&gt;times&lt;/code&gt; defaults to &lt;code&gt;1000&lt;/code&gt;. &lt;code&gt;/TIMES&lt;/code&gt; exists because we want to be able to run each test many times. &lt;br /&gt;
&lt;br /&gt;
The first test of any routine usually takes a bit longer than subsequent runs due to operating system caching. We&#39;ll take many measurements and then average them in the hope of getting a better idea of how long things &lt;i&gt;really&lt;/i&gt; take. &lt;br /&gt;
&lt;pre&gt;&lt;code&gt;&amp;nbsp;&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;var original;
if (CSSettings.ContainsKey(&quot;/RANDOM&quot;)) {
  original = Array(12500)
    .fill(0)
    .map(function () {
      return String.fromCharCode(Math.floor(Math.random() * 256));
    }).join(&quot;&quot;);
} else {
  original = Array(500).join(&quot;lewd did i live - evil i did dwel&quot;).substr(0, 12500);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
If the command-line contains &lt;code&gt;/RANDOM&lt;/code&gt; we generate a test string of 12500 random ASCII characters. Otherwise we fill an array with some text and then truncate it to 12500 characters. 12500 was chosen because larger numbers caused the recursive functions to fail impolitely.&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;&amp;nbsp;&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;var reversed = Sarah_ForOf(original);
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
We use one of the following reversal functions to reverse the &lt;code&gt;original&lt;/code&gt; test string so that we can double check that the reversal actually WAA (Works As Advertised).&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;&amp;nbsp;&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;function TimeTest(name, fn, original) {
  var Stopwatch = new CS.System.Diagnostics.Stopwatch();
  Stopwatch.Start();
  var answer = fn(original);
  Stopwatch.Stop();
  var ts = Stopwatch.Elapsed;
  return {
    name: name,
    ticks: ts.Ticks,
    reversed: answer
  };
}
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
We use C#&#39;s &lt;code&gt;System.Diagnostics.Stopwatch&lt;/code&gt; to track the run time of the function being tested. The parameters are: the name of the function, the function&#39;s reference, and the string to be tested. The &lt;code&gt;Ticks&lt;/code&gt; of the &lt;code&gt;Elapsed&lt;/code&gt; result of the run are returned along with the name and the results of the reversal. More about &lt;code&gt;Ticks&lt;/code&gt; at the end.&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;&amp;nbsp;&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;function EmptyFunction(string) {
  return string;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
We want to account for the cost of actually making the call, so we will time how long it takes just to load run an empty function that returns a string.&lt;br /&gt;
&lt;br /&gt;
Next come the contributed routines.&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;&amp;nbsp;&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;const Sarah_SplitReverseJoin = (string) =&amp;gt; string.split(&quot;&quot;).reverse().join(&#39;&#39;);

const Nathanael_SplitReverseJoin = (string) =&amp;gt; [...string].reverse().join(&#39;&#39;);

function Sarah_ForOf(string) {
  let reverseString = &quot;&quot;;
  for (let character of string) {
    reverseString = character + reverseString;
  }
  return reverseString;
}

const Sarah_Reduce = (string) =&amp;gt; string.split(&#39;&#39;).reduce((rev, char) =&amp;gt; char + rev, &#39;&#39;)

function Sarah_Recursive(string) {
  return string ? Sarah_Recursive(string.substring(1)) + string[0] : string;
}

function Theophanis_SplitFor(string) {
  let result = string.split(&#39;&#39;);
  for (let i = 0, j = string.length - 1; i &amp;lt; j; i++, j--) {
    result[i] = string[j];
    result[j] = string[i];
  }
  return result.join(&#39;&#39;);
}

function Theophanis_SplitFor_Bruced(string) {
  let result = string.split(&#39;&#39;);
  for (let i = 0, j = string.length - 1; i &amp;lt; j; i++, j--) {
    const string_i = string[i];
    const string_j = string[j];
    if (result[i] !== string_j) {
      result[i] = string_j;
    }
    if (result[j] !== string_i) {
      result[j] = string_i;
    }
  }

  return result.join(&#39;&#39;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
I thought that checking for the need to swap before actually swapping would be a good optimisation. I was wrong, especially with respect to random data&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;&amp;nbsp;&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;function Bruce_ArrayApplyMap(string) {
  return Array.apply(null, new Array(string.length).fill(0).map(function (_, i) {
      return string.charAt(string.length - 1 - i);
    })).join(&quot;&quot;);
}

function Bruce_MapSortMap(string) {
  return Array(string.length)
  .fill({})
  .map(function (item, index) {
    return {
      index: index,
      character: string.charAt(index)
    };
  }).sort(function (a, b) {
    return a.index &amp;gt; b.index ? -1 : (a.index === b.index ? 0 : 1);
  }).map(function (item) {
    return item.character;
  }).join(&quot;&quot;);
}

function Bruce_Recursive1(string) {
  return (string.length === 1)
   ? string
   : Bruce_Recursive1(string.substr(1)) + string.substr(0, 1);
}

function Bruce_Recursive2(string) {
  if (1 &amp;gt;= string.length)
    return string;
  return (
    string.substr(-1) +
    Bruce_Recursive2(string.substr(1, string.length - 2)) +
    string.substr(0, 1));
}

function Bruce_CharAt(string) {
  const result = Array(string.length);
  for (let i = string.length - 1, j = 0; i &amp;gt;= 0; i--, j++) {
    result[j] = string.charAt(i);
  }
  return result.join(&quot;&quot;);
}

function Bruce_CharAt2(string) {
    const result = Array(string.length).fill(1);
    result.map(function (item,index) {
        let rhs = string.length - 1 - index;
        result[index] = string.charAt(index);
    });
    return result.join(&quot;&quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
That&#39;s all the contributed functions.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;const namesAndCodes = [{
    name: &quot;Sarah_SplitReverseJoin&quot;,
    code: Sarah_SplitReverseJoin
  }, {
    name: &quot;Sarah_ForOf&quot;,
    code: Sarah_ForOf
  }, {
    name: &quot;Sarah_Reduce&quot;,
    code: Sarah_Reduce
  }, {
    name: &quot;Sarah_Recursive&quot;,
    code: Sarah_Recursive
  }, {
    name: &quot;Theophanis_SplitFor&quot;,
    code: Theophanis_SplitFor
  }, {
    name: &quot;Theophanis_SplitFor_Bruced&quot;,
    code: Theophanis_SplitFor_Bruced
  }, {
    name: &quot;Nathanael_SplitReverseJoin&quot;,
    code: Nathanael_SplitReverseJoin
  }, {
    name: &quot;Bruce_ArrayApplyMap&quot;,
    code: Bruce_ArrayApplyMap
  }, {
    name: &quot;Bruce_MapSortMap&quot;,
    code: Bruce_MapSortMap
  }, {
    name: &quot;Bruce_Recursive1&quot;,
    code: Bruce_Recursive1
  }, {
    name: &quot;Bruce_Recursive2&quot;,
    code: Bruce_Recursive2
  }, {
    name: &quot;Bruce_CharAt&quot;,
    code: Bruce_CharAt
  }, {
    name: &quot;Bruce_CharAt2&quot;,
    code: Bruce_CharAt2
  }
];
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
The names and functions to be tested.&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;&amp;nbsp;&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;var gathering = {};

for (let i = 0; i &amp;lt; times; i++) {
  namesAndCodes.forEach(function (item) {
    const eps = TimeTest(&quot;EmptyFunction&quot;, EmptyFunction, original).ticks;
    const result = TimeTest(item.name, item.code, original);
    if (!gathering[result.name]) {
      gathering[result.name] = [];
    }
    gathering[result.name].push(result.ticks - eps);
  });
}
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
Here we do the testing, looping from zero to whatever value &lt;code&gt;times&lt;/code&gt; holds. We &lt;code&gt;forEach&lt;/code&gt; through the &lt;code&gt;namesAndCodes&lt;/code&gt; structure. We calculate the time it takes to run an empty function and then we subtract that from the ticks of the result of the test. &lt;code&gt;gathering&lt;/code&gt; holds the result of each test in an array keyed to the name of the function.&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;&amp;nbsp;&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;const average = arr =&amp;gt; arr.reduce((p, c) =&amp;gt; p + c, 0) / arr.length;

Object.keys(gathering).map(function (item) {
  return [item, average(gathering[item])];
}).sort(function (a, b) {
  return a[1] &amp;gt; b[1] ? 1 : a[1] === b[1] ? 0 : -1;
}).forEach(function (item) {
  Console.WriteLine(&quot;{0,-28}{1} ticks&quot;, item[0], item[1]);
});
&quot;&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
Report on the results: Convert the gathering object into array[,] of name and averge, sort on the second item so that fastest comes first, write the results to the console with the name left-justified in a 28 character field, followed by the ticks.&lt;br /&gt;
And the results?&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;&amp;nbsp;&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt;timer.ly  /TIMES:1000
Sarah_ForOf                 2141.86 ticks
Sarah_SplitReverseJoin      2444.758 ticks
Sarah_Reduce                2805.243 ticks
Bruce_CharAt                2842.139 ticks
Nathanael_SplitReverseJoin  3035.17 ticks
Theophanis_SplitFor         3142.142 ticks
Bruce_Recursive1            3319.84 ticks
Bruce_Recursive2            3451.674 ticks
Theophanis_SplitFor_Bruced  3616.858 ticks
Sarah_Recursive             4645.366 ticks
Bruce_ArrayApplyMap         5637.1 ticks
Bruce_MapSortMap            9754.566 ticks
Bruce_CharAt2               13721.967 ticks


&amp;gt;timer.ly  /TIMES:1000 /RANDOM
Sarah_ForOf                 1850.582 ticks
Sarah_SplitReverseJoin      2655.574 ticks
Theophanis_SplitFor         2815.478 ticks
Nathanael_SplitReverseJoin  2832.566 ticks
Bruce_CharAt                2842.439 ticks
Sarah_Reduce                2845.746 ticks
Bruce_Recursive2            3224.578 ticks
Bruce_Recursive1            3306.136 ticks
Theophanis_SplitFor_Bruced  3428.827 ticks
Sarah_Recursive             4258.6 ticks
Bruce_ArrayApplyMap         5421.202 ticks
Bruce_MapSortMap            9748.012 ticks
Bruce_CharAt2               13477.231 ticks
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
On my computer there are 10,000,000 ticks per second (using CS.System.Diagnostics.Stopwatch.Frequency). According do the &lt;a href=&quot;https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.stopwatch.elapsedticks?view=netframework-4.8&quot;&gt;documentation&lt;/a&gt; &quot;Each tick in the ElapsedTicks value represents the time interval equal to 1 second divided by the Frequency.&quot;&lt;br /&gt;
&lt;br /&gt;
The bottom line? Sarah&#39;s ForOf and SplitReverseJoin are by far the fastest. Theophanis&#39;s SplitFor is also really good. That said, the differences are in microseconds or less.&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;NOTE&lt;/i&gt;: All suggestions on how to improve this testing regime gratefully received. Thanks in advance.&lt;br /&gt;
&lt;br /&gt;
Please note: this blog post was originally &lt;a href=&quot;https://dev.to/bugmagnet/testing-string-reversal-functions-8m6&quot;&gt;published at Dev.to&lt;/a&gt; on 2019-07-20.</content><link rel='replies' type='application/atom+xml' href='http://codeaholic.blogspot.com/feeds/8305110908581978605/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/15254360/8305110908581978605' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default/8305110908581978605'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default/8305110908581978605'/><link rel='alternate' type='text/html' href='http://codeaholic.blogspot.com/2019/07/testing-and-timing-string-reversal.html' title='[JavaScript] Testing (and Timing) String Reversal Functions '/><author><name>Bruce M. Axtens</name><uri>http://www.blogger.com/profile/14797830611260628579</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15254360.post-5046289460580473173</id><published>2019-07-17T22:20:00.001+08:00</published><updated>2023-04-03T17:51:39.184+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Google Keep"/><category scheme="http://www.blogger.com/atom/ns#" term="javascript"/><category scheme="http://www.blogger.com/atom/ns#" term="Selenium"/><title type='text'>[Scraping] Do I really want to write a Google Keep tool?</title><content type='html'>After writing so many wrappers and so many scraping tools over the last few years, I&#39;m now asking myself: &quot;Do I really want to write tools for &lt;a href=&quot;https://keep.google.com/&quot;&gt;Google Keep&lt;/a&gt;?&quot; There&#39;s been a few folk calling for a Google Keep API but nothing has materialized as yet (AFAICT.)&lt;br /&gt;
&lt;br /&gt;
I do use Keep a lot as a general catchall for interesting web content. Mind you, I use &lt;a href=&quot;https://app.getpocket.com/&quot;&gt;Pocket&lt;/a&gt; as well. And &lt;a href=&quot;https://www.pearltrees.com/&quot;&gt;PearlTrees&lt;/a&gt;. And &lt;a href=&quot;https://zim-wiki.org/&quot;&gt;Zim&lt;/a&gt;. &lt;br /&gt;
&lt;br /&gt;
Fiddling with my Keep collection in &lt;a href=&quot;https://www.mozilla.org/en-US/firefox/developer/&quot;&gt;Firefox Developer&lt;/a&gt; sees me trying to spot some structures that could be targeted in &lt;a href=&quot;https://www.seleniumhq.org/&quot;&gt;Selenium&lt;/a&gt;. One item of interest is via &lt;code&gt;document.querySelectorAll(&quot;.RNfche&quot;)&lt;/code&gt;. At this point I don&#39;t know if the RNfche class is specific to my collection or to everyone&#39;s, but it&#39;s on every containing DIV. The number of results of the querySelectAll() increases as one scrolls down the page. Thus, to find every one of them one would have to script Selenium to scroll right down to the bottom of the collection before pulling up the list of &lt;code&gt;RNfche&lt;/code&gt;-class elements.&lt;br /&gt;
&lt;br /&gt;
Can I really be bothered?&lt;br /&gt;
&lt;br /&gt;
Please note: this blog post was originally &lt;a href=&quot;https://dev.to/bugmagnet/do-i-really-want-to-write-a-google-keep-tool-2a82&quot;&gt;published at Dev.to&lt;/a&gt; on 2019-07-17.</content><link rel='replies' type='application/atom+xml' href='http://codeaholic.blogspot.com/feeds/5046289460580473173/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/15254360/5046289460580473173' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default/5046289460580473173'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default/5046289460580473173'/><link rel='alternate' type='text/html' href='http://codeaholic.blogspot.com/2019/07/do-i-really-want-to-write-google-keep.html' title='[Scraping] Do I really want to write a Google Keep tool?'/><author><name>Bruce M. Axtens</name><uri>http://www.blogger.com/profile/14797830611260628579</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15254360.post-8958504531562761548</id><published>2019-07-16T22:13:00.001+08:00</published><updated>2023-04-03T17:50:11.383+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Google Apps Script"/><category scheme="http://www.blogger.com/atom/ns#" term="javascript"/><category scheme="http://www.blogger.com/atom/ns#" term="scriptProperties"/><title type='text'>[Google Apps Script] ScriptProperties Gotcha in Google Apps Script</title><content type='html'>For reasons of insanity I have wrapped the &lt;code&gt;ScriptProperties&lt;/code&gt; of the &lt;code&gt;PropertiesService&lt;/code&gt; in a object with &lt;code&gt;get&lt;/code&gt;, &lt;code&gt;set&lt;/code&gt;, &lt;code&gt;forget&lt;/code&gt; and &lt;code&gt;getKeys&lt;/code&gt; methods, viz:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;function ScptProps() {
  this.scriptProperties = PropertiesService.getScriptProperties();
}

ScptProps.prototype.get = function (name) {
  return this.scriptProperties.getProperty(name);
};

ScptProps.prototype.set = function (name, value) {
  return this.scriptProperties.setProperty(name, value);
};

ScptProps.prototype.forget = function (name) {
  return this.scriptProperties.deleteProperty(name);
};

ScptProps.prototype.getKeys = function () {
  return this.scriptProperties.getKeys();
};
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
Using the REPL from my previous posting, I issued the following commands:&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;&amp;nbsp;&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;(new ScptProps).set(&#39;goose&#39;,58);
typeof (new ScptProps).get(&#39;goose&#39;);
(new ScptProps).forget(&#39;goose&#39;);
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
Goose is me and 58 my age for those interested. &lt;br /&gt;
&lt;br /&gt;
And the gotcha? Well, I was a little taken aback recently, while debugging a number to number comparison issue, to discover that when I store a number I don&#39;t get one back. I get a string back and have to do a &lt;code&gt;parseInt()&lt;/code&gt; on it to get its original value. The result of &lt;code&gt;typeof (new ScptProps).get(&#39;goose&#39;);&lt;/code&gt; is, you guessed it, &lt;code&gt;string&lt;/code&gt;!&lt;br /&gt;
&lt;br /&gt;
Please note: this blog posting was originally &lt;a href=&quot;https://dev.to/bugmagnet/scriptproperties-gotcha-in-google-apps-script-4blk&quot;&gt;published in Dev.to&lt;/a&gt; on 2019-07-16&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeaholic.blogspot.com/feeds/8958504531562761548/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/15254360/8958504531562761548' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default/8958504531562761548'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default/8958504531562761548'/><link rel='alternate' type='text/html' href='http://codeaholic.blogspot.com/2019/07/scriptproperties-gotcha-in-google-apps.html' title='[Google Apps Script] ScriptProperties Gotcha in Google Apps Script'/><author><name>Bruce M. Axtens</name><uri>http://www.blogger.com/profile/14797830611260628579</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15254360.post-6833606969146945601</id><published>2019-07-11T22:00:00.001+08:00</published><updated>2023-04-03T17:49:54.261+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Google Apps Script"/><category scheme="http://www.blogger.com/atom/ns#" term="javascript"/><category scheme="http://www.blogger.com/atom/ns#" term="REPL"/><title type='text'>[Google Apps Script] REP and almost L in Google Apps Script</title><content type='html'>It&#39;s been quite a while since I blogged about computing (I usually blog about &lt;a href=&quot;https://therapeutic-baking.blogspot.com/&quot;&gt;baking&lt;/a&gt;) but here goes.&lt;br /&gt;
&lt;br /&gt;
Lately I&#39;ve been climbing a steep learning curve, trying to get my head around Google Apps Script (GAS). Now a few spreadsheets later, I&#39;m on a trajectory that should see me crash-land on Planet Add-On in a month or two.&lt;br /&gt;
&lt;br /&gt;
REPL (read-evaluate-print-loop) has been a big thing for a long time with all manner of programming languages. So why not GAS? (Okay, it&#39;s more REP than REPL as the looping doesn&#39;t happen, but it&#39;s close.) &lt;br /&gt;
&lt;br /&gt;
In my Code.gs I have the following (among other things)&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;function onOpen() { 
  var ui = SpreadsheetApp.getUi();
  ui.createMenu(&#39;Debugging&#39;)
  .addItem(&#39;REPL&#39;, &#39;REPL&#39;)
  .addToUi();  
}
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
This adds a custom menu to the menubar and populates it with one entry, namely &#39;REPL&#39; which, when selected, runs a function called &#39;REPL&#39;.&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;&amp;nbsp;&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;function REPL() {
  var code = Browser.inputBox(&#39;code&#39;);
  if (code !== &#39;cancel&#39;) {
    Browser.msgBox(eval(code));
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
Also in there, for demonstration purposes, is a function that totals the ASCII values of the characters in the parameter string. &lt;br /&gt;
&lt;pre&gt;&lt;code&gt;&amp;nbsp;&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;function TotalAscii(str) {
  return str.split(&quot;&quot;).reduce(function (result, item, index) {
    return result + item.charCodeAt(0)
  }, 0)
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;nbsp;&lt;/code&gt;&lt;/pre&gt;
Visually there we are selecting the REPL option from the Debugging menu&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&lt;img alt=&quot;&quot; height=&quot;80&quot; referrerpolicy=&quot;no-referrer&quot; src=&quot;https://thepracticaldev.s3.amazonaws.com/i/e6gsqisdagqo8y8es4oi.png&quot; width=&quot;400&quot; /&gt;&lt;br /&gt;
&lt;br /&gt;
entering something to be evaluated and getting a response.&lt;br /&gt;
&lt;br /&gt;
&lt;img alt=&quot;&quot; referrerpolicy=&quot;no-referrer&quot; src=&quot;https://thepracticaldev.s3.amazonaws.com/i/1zyllftfpcld8z465czv.png&quot; /&gt; &lt;img alt=&quot;&quot; referrerpolicy=&quot;no-referrer&quot; src=&quot;https://thepracticaldev.s3.amazonaws.com/i/skl0g3azc3mec6acye0o.png&quot; /&gt;&lt;br /&gt;
&lt;br /&gt;
I&#39;d like at some stage to put together an HTML form with a TEXTAREA. Maybe after I crawl out of the crater.&lt;br /&gt;
&lt;br /&gt;
Please note: This blog posting was first &lt;a href=&quot;https://dev.to/bugmagnet/rep-and-almost-l-in-google-apps-script-5448&quot;&gt;published at Dev.to&lt;/a&gt; on 2019-07-11</content><link rel='replies' type='application/atom+xml' href='http://codeaholic.blogspot.com/feeds/6833606969146945601/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/15254360/6833606969146945601' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default/6833606969146945601'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default/6833606969146945601'/><link rel='alternate' type='text/html' href='http://codeaholic.blogspot.com/2019/07/rep-and-almost-l-in-google-apps-script.html' title='[Google Apps Script] REP and almost L in Google Apps Script'/><author><name>Bruce M. Axtens</name><uri>http://www.blogger.com/profile/14797830611260628579</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15254360.post-6687863802611335763</id><published>2018-12-24T13:50:00.000+08:00</published><updated>2019-07-22T22:17:40.880+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="chinese"/><category scheme="http://www.blogger.com/atom/ns#" term="DATA"/><category scheme="http://www.blogger.com/atom/ns#" term="READ"/><category scheme="http://www.blogger.com/atom/ns#" term="rosettacode"/><category scheme="http://www.blogger.com/atom/ns#" term="tbas"/><category scheme="http://www.blogger.com/atom/ns#" term="zodiac"/><title type='text'>[tbas] Chinese Year of the ...</title><content type='html'>&lt;!-- [tbas] Chinese Year of the ...  ---&gt;&lt;span style=&quot;font-family: &amp;quot;georgia&amp;quot;; font-size: normal;&quot;&gt;The author of tbas, Antonio Maschio, loves DATA and READ statements, and after putting together a &lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;georgia&amp;quot;; font-size: normal;&quot;&gt;&lt;a href=&quot;http://rosettacode.org/wiki/Chinese_zodiac&quot; target=&quot;_blank&quot;&gt;Chinese Zodiac&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;georgia&amp;quot;; font-size: normal;&quot;&gt; submission for RosettaCode, I can see why. And then there&#39;s TAB() which is also very helpful.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;source-code&quot;&gt;DATA &quot;甲&quot;,&quot;乙&quot;,&quot;丙&quot;,&quot;丁&quot;,&quot;戊&quot;,&quot;己&quot;,&quot;庚&quot;,&quot;辛&quot;,&quot;壬&quot;,&quot;癸&quot;
 DECLARE celestial$(10)
 MAT READ celestial$
 
 DATA &quot;子&quot;,&quot;丑&quot;,&quot;寅&quot;,&quot;卯&quot;,&quot;辰&quot;,&quot;巳&quot;,&quot;午&quot;,&quot;未&quot;,&quot;申&quot;,&quot;酉&quot;,&quot;戌&quot;,&quot;亥&quot;
 DECLARE terrestrial$(12)
 MAT READ terrestrial$
 
 DATA &quot;Rat&quot;,&quot;Ox&quot;,&quot;Tiger&quot;,&quot;Rabbit&quot;,&quot;Dragon&quot;,&quot;Snake&quot;,&quot;Horse&quot;,&quot;Goat&quot;,&quot;Monkey&quot;,&quot;Rooster&quot;,&quot;Dog&quot;,&quot;Pig&quot;
 DECLARE animals$(12)
 MAT READ animals$
 
        DATA &quot;Wood&quot;,&quot;Fire&quot;,&quot;Earth&quot;,&quot;Metal&quot;,&quot;Water&quot;
 DECLARE elements$(5)
 MAT READ elements$
 
 DATA &quot;yang&quot;,&quot;yin&quot;
 DECLARE aspects$(2)
 MAT READ aspects$
 
 DATA &quot;jiă&quot;,&quot;yĭ&quot;,&quot;bĭng&quot;,&quot;dīng&quot;,&quot;wù&quot;,&quot;jĭ&quot;,&quot;gēng&quot;,&quot;xīn&quot;,&quot;rén&quot;,&quot;gŭi&quot;
 DATA &quot;zĭ&quot;,&quot;chŏu&quot;,&quot;yín&quot;,&quot;măo&quot;,&quot;chén&quot;,&quot;sì&quot;,&quot;wŭ&quot;,&quot;wèi&quot;,&quot;shēn&quot;,&quot;yŏu&quot;,&quot;xū&quot;,&quot;hài&quot;
 DECLARE celestialpinyin$(UBOUND(celestial$(),1))
 DECLARE terrestrialpinyin$(UBOUND(terrestrial$(),1))
 MAT READ celestialpinyin$
 MAT READ terrestrialpinyin$
 
 DATA 1935,1938,1931,1961,1963,1991,1993,1996,2001
 DECLARE years(9)
 MAT READ years
 
 DECLARE _base = 4  
 DECLARE _year 
 DECLARE cycleyear 
 DECLARE stemnumber 
 DECLARE stemhan$    
 DECLARE stempinyin$ 
 DECLARE elementnumber 
 DECLARE element$       
 DECLARE branchnumber 
 DECLARE branchhan$    
 DECLARE branchpinyin$ 
 DECLARE animal$       
 DECLARE aspectnumber 
 DECLARE aspect$       
 DECLARE index 
 
 DECLARE i 
 DECLARE top = UBOUND(years(),1)
 FOR i = 1 TO top
  _year = years(i)
  cycleyear = _year - _base
  stemnumber = MOD(cycleyear, 10) 
  stemhan$    = celestial$(stemnumber + 1)
  stempinyin$ = celestialpinyin$(stemnumber + 1)
  elementnumber = div(stemnumber, 2) + 1
  element$       = elements$(elementnumber)
  branchnumber = MOD(cycleyear, 12)  
  branchhan$    = terrestrial$(branchnumber + 1)
  branchpinyin$ = terrestrialpinyin$(branchnumber + 1)
  animal$       = animals$(branchnumber + 1)
  aspectnumber = MOD(cycleyear, 2)
  aspect$       = aspects$(aspectnumber + 1)
  index = MOD(cycleyear, 60) + 1  
  PRINT _year; 
  PRINT TAB(5);stemhan$+branchhan$;
  PRINT TAB(12);stempinyin$;&quot;-&quot;;branchpinyin$;
  PRINT TAB(25);element$;&quot; &quot;;animal$;&quot; (&quot;+aspect$+&quot;)&quot;;
  PRINT TAB(50);&quot;year&quot;;index;&quot;of the cycle&quot;  
 NEXT
&lt;/pre&gt;&lt;span style=&quot;font-family: &amp;quot;georgia&amp;quot;; font-size: normal;&quot;&gt;Running the program gives&lt;/span&gt;&lt;br /&gt;
&lt;pre class=&quot;source-code&quot;&gt;$ tbas chinZod.bas
 1935 乙亥 yĭ-hài     Wood Pig (yin)           year 12 of the cycle
 1938 戊寅 wù-yín     Earth Tiger (yang)       year 15 of the cycle
 1931 辛未 xīn-wèi    Metal Goat (yin)         year 8 of the cycle
 1961 辛丑 xīn-chŏu   Metal Ox (yin)           year 38 of the cycle
 1963 癸卯 gŭi-măo    Water Rabbit (yin)       year 40 of the cycle
 1991 辛未 xīn-wèi    Metal Goat (yin)         year 8 of the cycle
 1993 癸酉 gŭi-yŏu    Water Rooster (yin)      year 10 of the cycle
 1996 丙子 bĭng-zĭ    Fire Rat (yang)          year 13 of the cycle
 2001 辛巳 xīn-sì     Metal Snake (yin)        year 18 of the cycle
&lt;/pre&gt;&lt;span style=&quot;font-family: &amp;quot;georgia&amp;quot;; font-size: normal;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;georgia&amp;quot;; font-size: xx-small;&quot;&gt;&lt;i&gt;© Copyright Bruce M. Axtens, 2018&lt;/i&gt;&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeaholic.blogspot.com/feeds/6687863802611335763/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/15254360/6687863802611335763' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default/6687863802611335763'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default/6687863802611335763'/><link rel='alternate' type='text/html' href='http://codeaholic.blogspot.com/2018/12/the-author-of-tbas-antonio-maschio.html' title='[tbas] Chinese Year of the ...'/><author><name>Bruce M. Axtens</name><uri>http://www.blogger.com/profile/14797830611260628579</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15254360.post-1574359792181305555</id><published>2018-03-15T21:53:00.000+08:00</published><updated>2018-03-15T21:57:30.819+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="AC/DC"/><category scheme="http://www.blogger.com/atom/ns#" term="gravityforms"/><category scheme="http://www.blogger.com/atom/ns#" term="php"/><category scheme="http://www.blogger.com/atom/ns#" term="TNT"/><title type='text'>[PHP] Include a data structure once</title><content type='html'>&lt;!-- [PHP] Include a data structure once ---&gt;&lt;span style=&#39;font-family: georgia;font-size: normal;&#39;&gt;Today&#39;s job at work was to get some data into &lt;/span&gt;&lt;span style=&#39;font-family: georgia;font-size: normal;&#39;&gt;&lt;a href=&#39;https://www.gravityforms.com/&#39; target=_blank&gt;GravityForms&lt;/a&gt;&lt;/span&gt;&lt;span style=&#39;font-family: georgia;font-size: normal;&#39;&gt;, a forms tool for &lt;/span&gt;&lt;span style=&#39;font-family: georgia;font-size: normal;&#39;&gt;&lt;a href=&#39;https://wordpress.com/&#39; target=_blank&gt;WordPress&lt;/a&gt;&lt;/span&gt;&lt;span style=&#39;font-family: georgia;font-size: normal;&#39;&gt;.&lt;br /&gt;
&lt;br /&gt;
So one page has a postcode entry, and the next page has some hidden postcode-specific fields that are used to calculate values later in the form-set, in this case freight costs on goods delivered by &lt;/span&gt;&lt;span style=&#39;font-family: georgia;font-size: normal;&#39;&gt;&lt;a href=&#39;https://www.tnt.com/express/en_au/site/home.html&#39; target=_blank&gt;TNT&lt;/a&gt;&lt;/span&gt;&lt;span style=&#39;font-family: georgia;font-size: normal;&#39;&gt; (no relation to &lt;/span&gt;&lt;span style=&#39;font-family: georgia;font-size: normal;&#39;&gt;&lt;a href=&#39;https://www.youtube.com/watch?v=kR6pxe8jaMs&#39; target=_blank&gt;the song by AC/DC&lt;/a&gt;&lt;/span&gt;&lt;span style=&#39;font-family: georgia;font-size: normal;&#39;&gt;).  &lt;br /&gt;
&lt;br /&gt;
The documentation for GravityForms suggests putting code into &lt;tt&gt;functions.php&lt;/tt&gt; in the active theme. I&#39;m a little wary of doing that given that changes there can work or not work in a rather catastrophic way.&lt;br /&gt;
&lt;br /&gt;
Nevertheless, I ended up coding against the &lt;tt&gt;gform_field_input&lt;/tt&gt; hook&lt;/span&gt;&lt;pre class=&#39;source-code&#39;&gt;add_filter(&#39;gform_field_input&#39;, &#39;update_hidden&#39;, 10, 5);
function update_hidden($input, $field, $value, $lead_id, $form_id)
{
}
&lt;/pre&gt;&lt;span style=&#39;font-family: georgia;font-size: normal;&#39;&gt;So then the was the issue of how to &lt;tt&gt;include&lt;/tt&gt; the postcode-to-charges array (PCA) (stored in an external php file) &lt;i&gt;once&lt;/i&gt; rather than each time &lt;tt&gt;gform_field_input&lt;/tt&gt; fired, which is once per control. With the PCA being just shy of a megabyte in length, I wasn&#39;t particularly interested in having it load repeatedly.&lt;br /&gt;
&lt;br /&gt;
The PCA looks like this&lt;/span&gt;&lt;pre class=&#39;source-code&#39;&gt;&amp;lt;?php
return array(
 &#39;0221&#39; =&gt; array(
  &#39;BasicChrg&#39; =&gt; 9.982, 
  &#39;KgChrg&#39; =&gt; 0.5405, 
  &#39;MinChrg&#39; =&gt; 15.3755, 
  &#39;RemotAreaChrg&#39; =&gt; 0, 
  &#39;ResidChrg&#39; =&gt; 5, 
  &#39;0to15Chrg&#39; =&gt; 0, 
  &#39;15to199Chrg&#39; =&gt; 10, 
  &#39;200to299Chrg&#39; =&gt; 30, 
  &#39;300to399Chrg&#39; =&gt; 40, 
  &#39;400to499Chrg&#39; =&gt; 150, 
  &#39;500to599Chrg&#39; =&gt; 250, 
  &#39;600plusChrg&#39; =&gt; 300, 
  &#39;FuelSurchrg&#39; =&gt; 0.07)
  ...
);
&lt;/pre&gt;&lt;span style=&#39;font-family: georgia;font-size: normal;&#39;&gt;&lt;/span&gt;&lt;span style=&#39;font-family: georgia;font-size: normal;&#39;&gt;&lt;a href=&#39;https://stackoverflow.com/questions/6709449/run-php-function-once&#39; target=_blank&gt;StackOverflow&lt;/a&gt;&lt;/span&gt;&lt;span style=&#39;font-family: georgia;font-size: normal;&#39;&gt; did offer a suggestion on how to deal with this but I had no joy with it. So I went with using &lt;tt&gt;include_once&lt;/tt&gt;. That, however, also had problems. According to the documentation, &lt;tt&gt;include_once&lt;/tt&gt; &lt;/span&gt;&lt;span style=&#39;font-family: georgia;font-size: normal;&#39;&gt;&lt;a href=&#39;https://secure.php.net/manual/en/function.include-once.php&#39; target=_blank&gt;returns a boolean true&lt;/a&gt;&lt;/span&gt;&lt;span style=&#39;font-family: georgia;font-size: normal;&#39;&gt; when it gets called the second time for the same file. So one must use a temporary variable to hold the result rather than committing it immediately to your PCA variable.&lt;br /&gt;
&lt;br /&gt;
So the code I have ended up with is (some omitted for brevity&#39;s sake):&lt;/span&gt;&lt;pre class=&#39;source-code&#39;&gt;function update_hidden($input, $field, $value, $lead_id, $form_id)
{
 global $TNTFreightPrices, $PostCode;

 $path = $_SERVER[&#39;DOCUMENT_ROOT&#39;] . &#39;/wp-content/uploads/tntfreightprices/TNTFreightPrices.php&#39;;
 $tmp = include_once $path;
 if (gettype($tmp) == &quot;array&quot;) {
  $TNTFreightPrices = $tmp;
  $PostCode = rgpost(&#39;input_52&#39;);
 }

 if ($form_id == 8) {
  $BasicChrg = $TNTFreightPrices[$PostCode][&#39;BasicChrg&#39;];
  
  ...

  $fid = $field[&#39;id&#39;];
  
  if ($fid == 53) {
   $input = &quot;&amp;lt;input id=&#39;input_8_53&#39; class=&#39;gform_hidden&#39; name=&#39;input_53&#39; aria-invalid=&#39;false&#39; value=&#39;$BasicChrg&#39; type=&#39;hidden&#39;&gt;&quot;;
  }
  ...
 }
}
&lt;/pre&gt;&lt;span style=&#39;font-family: georgia;font-size: normal;&#39;&gt;It remains to be seen whether I stay with &lt;tt&gt;$TNTFreightPrices&lt;/tt&gt; and &lt;tt&gt;$PostCode&lt;/tt&gt; in global space as that&#39;s a carryover from other experiments. &lt;br /&gt;
&lt;br /&gt;
It was part fun and part hairloss but at least we&#39;re closer to a solution. Probably there are better ways. WooCommerce?&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&#39;font-family: georgia;font-size: xx-small;&#39;&gt;&lt;i&gt;&amp;copy; Copyright Bruce M. Axtens., 2018&lt;/i&gt;&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeaholic.blogspot.com/feeds/1574359792181305555/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/15254360/1574359792181305555' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default/1574359792181305555'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default/1574359792181305555'/><link rel='alternate' type='text/html' href='http://codeaholic.blogspot.com/2018/03/php-include-data-structure-once.html' title='[PHP] Include a data structure once'/><author><name>Bruce M. Axtens</name><uri>http://www.blogger.com/profile/14797830611260628579</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15254360.post-5614545418705432686</id><published>2018-02-12T14:08:00.000+08:00</published><updated>2018-02-12T14:08:39.513+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="dotnet"/><category scheme="http://www.blogger.com/atom/ns#" term="dotnet core"/><category scheme="http://www.blogger.com/atom/ns#" term="dotnet framework"/><category scheme="http://www.blogger.com/atom/ns#" term="dotnet standard"/><category scheme="http://www.blogger.com/atom/ns#" term="StackOverflow"/><title type='text'>[dotnet] core, standard and framework</title><content type='html'>Riiiiiight, now I get it ... maybe.&lt;a href=&quot;https://i.stack.imgur.com/445Pv.jpg&quot; imageanchor=&quot;1&quot; style=&quot;clear: right; display: inline !important; margin-bottom: 1em; margin-left: 1em; text-align: center;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;302&quot; data-original-width=&quot;800&quot; height=&quot;240&quot; src=&quot;https://i.stack.imgur.com/445Pv.jpg&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
Check the &lt;a href=&quot;https://stackoverflow.com/questions/42493785/dotnet-core-vs-dotnetstandard#42499285&quot; target=&quot;_blank&quot;&gt;original posting on StackOverflow&lt;/a&gt; for the full description.&lt;/div&gt;
&lt;br /&gt;
&lt;i style=&quot;background-color: white; font-family: georgia; font-size: xx-small;&quot;&gt;© Copyright Bruce M. Axtens, 2018&lt;/i&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeaholic.blogspot.com/feeds/5614545418705432686/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/15254360/5614545418705432686' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default/5614545418705432686'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default/5614545418705432686'/><link rel='alternate' type='text/html' href='http://codeaholic.blogspot.com/2018/02/dotnet-core-standard-and-framework.html' title='[dotnet] core, standard and framework'/><author><name>Bruce M. Axtens</name><uri>http://www.blogger.com/profile/14797830611260628579</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15254360.post-789670640857848522</id><published>2018-02-09T13:01:00.001+08:00</published><updated>2018-09-18T13:42:10.687+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="after"/><category scheme="http://www.blogger.com/atom/ns#" term="before"/><category scheme="http://www.blogger.com/atom/ns#" term="between"/><category scheme="http://www.blogger.com/atom/ns#" term="endswith"/><category scheme="http://www.blogger.com/atom/ns#" term="javascript"/><category scheme="http://www.blogger.com/atom/ns#" term="questionMarkIs"/><category scheme="http://www.blogger.com/atom/ns#" term="stripChars"/><category scheme="http://www.blogger.com/atom/ns#" term="toArrayOfLines"/><category scheme="http://www.blogger.com/atom/ns#" term="toProperCase"/><category scheme="http://www.blogger.com/atom/ns#" term="toSqlString"/><title type='text'>[JavaScript] String.prototype </title><content type='html'>&lt;!-- [JavaScript] String prototypes ---&gt;&lt;span style=&quot;font-family: &amp;quot;georgia&amp;quot;; font-size: normal;&quot;&gt;Back in 2011, I started learning JavaScript. I&#39;m still learning but haven&#39;t moved beyond ES3, largely because that&#39;s the dialect I&#39;m using for most of my server-side scripting. In other words, Microsoft JScript (gasp, shock, horrors, gevalt etc.)&lt;br /&gt;&lt;br /&gt;Most of the rest of what I do at the moment is using C#. A while back I went looking for a way to extend my C# programs with scripting and found &lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;georgia&amp;quot;; font-size: normal;&quot;&gt;&lt;a href=&quot;https://github.com/Microsoft/ClearScript&quot; target=&quot;_blank&quot;&gt;ClearScript&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;georgia&amp;quot;; font-size: normal;&quot;&gt;. I&#39;ve been using it to great effect for the last 3 years in the vast majority of my work projects. I&#39;ve even written a JScript-on-steroids which exposes large chunks of C# to JScript and permits the writing of some very powerful scripts.&lt;br /&gt;&lt;br /&gt;In the next few postings I&#39;ll be discussing some of the interesting things I&#39;ve discovered. For a lot of folk, it&#39;ll be old hat ... so old that mice are living in it. But, who knows, maybe someone will find a use for some of it, or be able to adapt it to newer dialects.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;toProperCase()&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class=&quot;source-code&quot;&gt;String.prototype.toProperCase = function () {
  return this.replace(/\w\S*/g, function (txt) {
    return String(txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase());
  });
};
&lt;/pre&gt;
&lt;span style=&quot;font-family: &amp;quot;georgia&amp;quot;; font-size: normal;&quot;&gt;I found this on StackOverflow. It attempts to proper-case (title-case) every word in a string. I don&#39;t use it often but it was an interesting find.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;after&lt;/b&gt;&lt;/span&gt;&lt;b style=&quot;font-family: georgia;&quot;&gt;()&lt;/b&gt;&lt;br /&gt;
&lt;pre class=&quot;source-code&quot;&gt;String.prototype.after = function (a, including) {
  including = including || false;
  a = this.indexOf(a);
  return -1 === a ? String(this) : String(this.substr(a + (including ? 0 : 1)));
};
&lt;/pre&gt;
&lt;span style=&quot;font-family: &amp;quot;georgia&amp;quot;; font-size: normal;&quot;&gt;A staple, this gives whatever is after a substring in a string. The substring can be included or excluded for the result.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;before&lt;/b&gt;&lt;/span&gt;&lt;b style=&quot;font-family: georgia;&quot;&gt;()&lt;/b&gt;&lt;br /&gt;
&lt;pre class=&quot;source-code&quot;&gt;String.prototype.before = function (a, including) {
  including = including || false;
  a = this.indexOf(a);
  return -1 === a ? String(this) : String(this.substr(0, a + (including ? 1 : 0)));
};
&lt;/pre&gt;
&lt;span style=&quot;font-family: &amp;quot;georgia&amp;quot;; font-size: normal;&quot;&gt;Another staple, this gives whatever is before a substring in a string. Again, the substring can be included or excluded for the result.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;stripChars&lt;/b&gt;&lt;/span&gt;&lt;b style=&quot;font-family: georgia;&quot;&gt;()&lt;/b&gt;&lt;br /&gt;
&lt;pre class=&quot;source-code&quot;&gt;String.prototype.stripChars = function (chars, cnt) {
  var i,
  j;
  cnt = cnt || 0;
  var answer = this;
  for (i = 0; i &amp;lt; chars.length; i++) {
    var chr = chars.charAt(i);
    if (cnt === 0) {
      var pat = new RegExp(chr, &quot;g&quot;);
      answer = answer.replace(pat, &quot;&quot;);
    } else {
      for (j = 0; j &amp;lt; cnt; j++) {
        answer = answer.replace(chr, &quot;&quot;);
      }
    }
  }
  return String(answer);
};
&lt;/pre&gt;
&lt;span style=&quot;font-family: &amp;quot;georgia&amp;quot;; font-size: normal;&quot;&gt;I don&#39;t use this often, but it has been useful. It removes each element of &lt;i&gt;chars &lt;/i&gt;from the string. If &lt;i&gt;cnt &lt;/i&gt;is undefined or zero, all are removed. If &lt;i&gt;cnt &lt;/i&gt;is 1 or more, then that many are removed.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;between&lt;/b&gt;&lt;/span&gt;&lt;b style=&quot;font-family: georgia;&quot;&gt;()&lt;/b&gt;&lt;br /&gt;
&lt;pre class=&quot;source-code&quot;&gt;String.prototype.between = function (begin, end, including) {
  including = including || false;
  var left = this.indexOf(begin);
  if (left &amp;lt; 0) {
    return String(&#39;&#39;);
  }
  left += begin.length;
  var right = typeof end === &#39;undefined&#39; ? this.length : this.indexOf(end, left);
  if (right &amp;lt; 0) {
    return String(&#39;&#39;);
  }
  return including ? String(begin + this.substring(left, right) + end) : String(this.substring(left, right));
};
&lt;/pre&gt;
&lt;span style=&quot;font-family: &amp;quot;georgia&amp;quot;; font-size: normal;&quot;&gt;There are various ways of pulling SGML and other markups apart. This one, in various languages, has been in the toolkit for years. This variant permits excluding or including the delimiters. Apart from that, it isn&#39;t smart -- &lt;span style=&quot;font-size: x-small;&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace; font-size: normal;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;drooling singing&quot;.between(&quot;droo&quot;,&quot;ing&quot;)&lt;/span&gt; &lt;/span&gt;&lt;span style=&quot;font-family: inherit; font-size: normal;&quot;&gt;gives &lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace; font-size: x-small;&quot;&gt;l&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;georgia&amp;quot;; font-size: normal;&quot;&gt;&lt;br /&gt;&lt;b&gt;endswith&lt;/b&gt;&lt;/span&gt;&lt;b style=&quot;font-family: georgia;&quot;&gt;()&lt;/b&gt;&lt;br /&gt;
&lt;pre class=&quot;source-code&quot;&gt;String.prototype.endswith = function (str) {
  return this.indexOf(str) !== -1 &amp;amp;&amp;amp; this.indexOf(str) === this.length - str.length;
};
&lt;/pre&gt;
&lt;span style=&quot;font-family: &amp;quot;georgia&amp;quot;; font-size: normal;&quot;&gt;Returns true if the strings ends with contents of str otherwise false. Has helped with detecting filetypes in filenames. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;toSqlString&lt;/b&gt;&lt;/span&gt;&lt;b style=&quot;font-family: georgia;&quot;&gt;()&lt;/b&gt;&lt;br /&gt;
&lt;pre class=&quot;source-code&quot;&gt;String.prototype.toSqlString = function () {
  return String(&quot;&#39;&quot; + String(this).replace(/&#39;/g, &quot;&#39;&#39;&quot;) + &quot;&#39;&quot;);
};
&lt;/pre&gt;
&lt;span style=&quot;font-family: &amp;quot;georgia&amp;quot;; font-size: normal;&quot;&gt;This puts a single quote at the start and end of the string and doubles any embedded single quotes. I use this in combination with .questionMarkIs() to format SQL statements.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;georgia&amp;quot;; font-size: normal;&quot;&gt;&lt;br /&gt;&lt;/span&gt;

&lt;span style=&quot;font-family: &amp;quot;georgia&amp;quot;; font-size: normal;&quot;&gt;&lt;b&gt;toArrayOfLines&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class=&quot;source-code&quot;&gt;String.prototype.toArrayOfLines = function () {
  return this.split(/\r\n|\r|\n/g);
};
&lt;/pre&gt;
&lt;span style=&quot;font-family: &amp;quot;georgia&amp;quot;; font-size: normal;&quot;&gt;Splitting a text file to lines is something I do a lot of. This is the functional variant of code I have in almost every script written over the last 7 years.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;questionMarkIs&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class=&quot;source-code&quot;&gt;String.prototype.questionMarkIs = function (val) {
  return String(this.replace(&quot;?&quot;, val));
};
&lt;/pre&gt;
&lt;span style=&quot;font-family: &amp;quot;georgia&amp;quot;; font-size: normal;&quot;&gt;For a while I was doing all kinds of weird things to build SQL queries. Lately I&#39;ve taken to simply putting question marks in and then replacing them with the value (with or without .toSqlString()).&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;georgia&amp;quot;; font-size: normal;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: &amp;quot;georgia&amp;quot;; font-size: normal;&quot;&gt;That should do for now. Enjoy!&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;georgia&amp;quot;; font-size: normal;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;georgia&amp;quot;; font-size: xx-small;&quot;&gt;&lt;i&gt;© Copyright Bruce M. Axtens, 2018&lt;/i&gt;&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeaholic.blogspot.com/feeds/789670640857848522/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/15254360/789670640857848522' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default/789670640857848522'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default/789670640857848522'/><link rel='alternate' type='text/html' href='http://codeaholic.blogspot.com/2018/02/javascript-stringprototype.html' title='[JavaScript] String.prototype '/><author><name>Bruce M. Axtens</name><uri>http://www.blogger.com/profile/14797830611260628579</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15254360.post-8091625656213025915</id><published>2018-02-08T13:08:00.000+08:00</published><updated>2018-02-08T13:09:27.822+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="configuration"/><category scheme="http://www.blogger.com/atom/ns#" term="dhall"/><category scheme="http://www.blogger.com/atom/ns#" term="non-turing-complete"/><category scheme="http://www.blogger.com/atom/ns#" term="programming languages"/><title type='text'>[configuration files] dhall</title><content type='html'>Okay, I know next to nothing about this at the moment but it does look interesting.&lt;br /&gt;
&lt;blockquote class=&quot;tr_bq&quot;&gt;
&lt;a href=&quot;https://github.com/dhall-lang/dhall-lang&quot; target=&quot;_blank&quot;&gt;dhall&lt;/a&gt;&amp;nbsp;is a programmable configuration language that is not Turing-complete. You can think of Dhall as: JSON + functions + types + imports&lt;/blockquote&gt;
I can think of some places where this approach to config would be helpful and less dangerous that what I am currently doing.&lt;br /&gt;
&lt;br /&gt;
&lt;i style=&quot;background-color: white; font-family: georgia; font-size: xx-small;&quot;&gt;© Copyright Bruce M. Axtens, 2018&lt;/i&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeaholic.blogspot.com/feeds/8091625656213025915/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/15254360/8091625656213025915' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default/8091625656213025915'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default/8091625656213025915'/><link rel='alternate' type='text/html' href='http://codeaholic.blogspot.com/2018/02/configuration-files-dhall.html' title='[configuration files] dhall'/><author><name>Bruce M. Axtens</name><uri>http://www.blogger.com/profile/14797830611260628579</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15254360.post-413058119276303217</id><published>2018-02-07T15:13:00.000+08:00</published><updated>2018-12-21T16:44:15.988+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="basic"/><category scheme="http://www.blogger.com/atom/ns#" term="caesar cipher"/><category scheme="http://www.blogger.com/atom/ns#" term="comp.lang.basic.misc"/><category scheme="http://www.blogger.com/atom/ns#" term="cygwin"/><category scheme="http://www.blogger.com/atom/ns#" term="GPL"/><category scheme="http://www.blogger.com/atom/ns#" term="interpreter"/><category scheme="http://www.blogger.com/atom/ns#" term="rosettacode"/><category scheme="http://www.blogger.com/atom/ns#" term="tbas"/><category scheme="http://www.blogger.com/atom/ns#" term="usenet"/><category scheme="http://www.blogger.com/atom/ns#" term="windows10"/><title type='text'>[tbas] tbas basic interpreter</title><content type='html'>In my ample (NOT!) spare time, I&#39;m helping out with a programming language project called &lt;i&gt;tbas&lt;/i&gt;. I saw it advertised on comp.lang.basic.misc in September 2017 (yep, usenet is still going strong.)&lt;br /&gt;
&lt;br /&gt;
The author is one Antonio Maschio from Italy.&lt;br /&gt;
&lt;br /&gt;
You can get source, documentation and a CygWin binary from the &lt;a href=&quot;http://digilander.libero.it/tonibinhome/tbas/index.html&quot; target=&quot;_blank&quot;&gt;main site&lt;/a&gt;.&amp;nbsp;There are some examples on &lt;a href=&quot;http://rosettacode.org/wiki/Category:Tbas&quot; target=&quot;_blank&quot;&gt;RosettaCode&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
To give you an idea of the flavour of the language, the following is a simple CAESAR cipher implementation.&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; LET MSG$ = &quot;&quot;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;LET OFFS = 0&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;LINE INPUT &quot;Message&quot;; MSG$&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;INPUT &quot;Offset&quot;; OFFS&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;DIM TARG(LEN(MSG$))&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;CHANGE MSG$ TO TARG&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;FOR I = 1 TO UDIM(TARG)&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;TARG(I) = TARG(I) + OFFS&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;NEXT&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;CHANGE TARG TO MSG$&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;PRINT MSG$&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
An example of running the above&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;gt;tbas CAESAR.BAS&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; Message ? My dog&#39;s got fleas&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; Offset ? 1&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; Nz!eph(t!hpu!gmfbt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;i style=&quot;background-color: white; font-family: georgia; font-size: xx-small;&quot;&gt;© Copyright Bruce M. Axtens, 2018&lt;/i&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://codeaholic.blogspot.com/feeds/413058119276303217/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/15254360/413058119276303217' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default/413058119276303217'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default/413058119276303217'/><link rel='alternate' type='text/html' href='http://codeaholic.blogspot.com/2018/02/tbas-tbas-basic-interpreter.html' title='[tbas] tbas basic interpreter'/><author><name>Bruce M. Axtens</name><uri>http://www.blogger.com/profile/14797830611260628579</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15254360.post-8882333146544166950</id><published>2017-07-20T22:25:00.000+08:00</published><updated>2017-08-10T22:06:45.578+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="FAST"/><category scheme="http://www.blogger.com/atom/ns#" term="FreeDOS"/><category scheme="http://www.blogger.com/atom/ns#" term="HOPL"/><category scheme="http://www.blogger.com/atom/ns#" term="SOFA"/><category scheme="http://www.blogger.com/atom/ns#" term="Tcl"/><title type='text'>[FreeDOS] The FAST and SOFA compilers</title><content type='html'>&lt;!-- [FreeDOS] The FAST and SOFA compilers ---&gt;&lt;span style=&#39;font-family: georgia;font-size: normal;&#39;&gt;Two recent additions to the FreeDOS stable of development languages are FAST (Fast PC Compiler) and SOFA (Super Optimised Fast Assembler), inventions of one Peter Campbell of New Zealand. Peter developed FAST and SOFA in the mid 1980s and they were used as the main development languages for the Fastbase accounting system. In 2000, Peter rewrote the entire system in Tcl. All use and development of FAST and SOFA stopped at that point. &lt;br /&gt;
&lt;br /&gt;
SOFA is an 8088 (and semi-80386) assembler. The syntax has some similarities to two other shareware assemblers, &lt;/span&gt;&lt;span style=&#39;font-family: georgia;font-size: normal;&#39;&gt;&lt;a href=&#39;http://www.eji.com/a86/&#39; target=_blank&gt;A86&lt;/a&gt;&lt;/span&gt;&lt;span style=&#39;font-family: georgia;font-size: normal;&#39;&gt; and &lt;/span&gt;&lt;span style=&#39;font-family: georgia;font-size: normal;&#39;&gt;&lt;a href=&#39;http://www.intel-assembler.it/portale/5/chasm-cheap-assembler-for-pc/x86-assembler-with-8087-fpu-support.asp&#39; target=_blank&gt;CHASM&lt;/a&gt;&lt;/span&gt;&lt;span style=&#39;font-family: georgia;font-size: normal;&#39;&gt;. SOFA can assemble its own source-code. Its features include quick assembly time (thousands of lines per second), conditional compilation and include files.&lt;br /&gt;
&lt;br /&gt;
FAST was written in SOFA. The language syntax was influenced by Basic, Pascal, C and Assembler. The binaries produced are small and fast&lt;/span&gt;&lt;sup&gt;&lt;a href=&#39;#foot1&#39;&gt;[1]&lt;/a&gt;&lt;/sup&gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;span style=&#39;font-family: georgia;font-size: normal;&#39;&gt;Peter Campbell died in &lt;a href=&#39;http://www.stuff.co.nz/national/174682/Handymen-warned-of-dangers-of-electrocution&#39; target=_blank&gt;tragic circumstances&lt;/a&gt; at Easter 2007, leaving the &lt;/span&gt;&lt;span style=&#39;font-family: georgia;font-size: normal;&#39;&gt;&lt;a href=&#39;http://fastbase.co.nz&#39; target=_blank&gt;Fastbase&lt;/a&gt;&lt;/span&gt;&lt;span style=&#39;font-family: georgia;font-size: normal;&#39;&gt; business to his brother, Russell Bell.&lt;br /&gt;
&lt;br /&gt;
The adding of FAST and SOFA to FreeDOS took a little too long: I had heard of the language during the 1990s and had rediscovered it in the &lt;/span&gt;&lt;span style=&#39;font-family: georgia;font-size: normal;&#39;&gt;&lt;a href=&#39;http://vetusware.com&#39; target=_blank&gt;Vetusware&lt;/a&gt;&lt;/span&gt;&lt;span style=&#39;font-family: georgia;font-size: normal;&#39;&gt; abandonware collection. From there I found out about FastBase and made contact with Russell. This was 2009 and it was at that time that I suggested to Russell that SOFA/FAST could be re-released as Open Source software, thus preserving in some way Peter&#39;s legacy. Russell promptly gave permission and provided me with the sources. Embarassingly, it has taken me eight years to finalise the process. &lt;br /&gt;
&lt;br /&gt;
SOFA and FAST will appear eventually on &lt;/span&gt;&lt;span style=&#39;font-family: georgia;font-size: normal;&#39;&gt;&lt;a href=&#39;http://hopl.info&#39; target=_blank&gt;HOPL&lt;/a&gt;&lt;/span&gt;&lt;span style=&#39;font-family: georgia;font-size: normal;&#39;&gt; (The Online Historical Encyclopaedia of Programming Languages). In the meantime, postings regarding the languages can be found on &lt;/span&gt;&lt;span style=&#39;font-family: georgia;font-size: normal;&#39;&gt;&lt;a href=&#39;https://www.facebook.com/HistoryOfProgrammingLanguages&#39; target=_blank&gt;HOPL&#39;s Facebook front-end&lt;/a&gt;&lt;/span&gt;&lt;span style=&#39;font-family: georgia;font-size: normal;&#39;&gt; at &lt;/span&gt;&lt;span style=&#39;font-family: georgia;font-size: normal;&#39;&gt;&lt;a href=&#39;https://www.facebook.com/notes/hopl/sofa-super-optimised-fast-assembler/1797011657227403/&#39; target=_blank&gt;SOFA&lt;/a&gt;&lt;/span&gt;&lt;span style=&#39;font-family: georgia;font-size: normal;&#39;&gt; and &lt;/span&gt;&lt;span style=&#39;font-family: georgia;font-size: normal;&#39;&gt;&lt;a href=&#39;https://www.facebook.com/notes/hopl/fast-fast-pc-compiler/1796705143924721/&#39; target=_blank&gt;FAST&lt;/a&gt;&lt;/span&gt;&lt;span style=&#39;font-family: georgia;font-size: normal;&#39;&gt; respectively. &lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a name=&#39;foot1&#39; style=&#39;font-family: georgia; font-size: smaller;&#39;&gt;[1] Already some FreeDOS utilities have been rewritten in FAST.&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&#39;font-family: georgia;font-size: xx-small;&#39;&gt;&lt;i&gt;&amp;copy; Copyright Bruce M. Axtens, 2017&lt;/i&gt;&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeaholic.blogspot.com/feeds/8882333146544166950/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/15254360/8882333146544166950' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default/8882333146544166950'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default/8882333146544166950'/><link rel='alternate' type='text/html' href='http://codeaholic.blogspot.com/2017/07/freedos-fast-and-sofa-compilers.html' title='[FreeDOS] The FAST and SOFA compilers'/><author><name>Bruce M. Axtens</name><uri>http://www.blogger.com/profile/14797830611260628579</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15254360.post-3323294521555426697</id><published>2015-12-02T22:46:00.000+08:00</published><updated>2015-12-02T22:46:17.519+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="entities"/><category scheme="http://www.blogger.com/atom/ns#" term="HTML"/><title type='text'>[Browsers] Inconsistent HTML Entities</title><content type='html'>&lt;!-- [Browsers] Inconsistent HTML Entities  ---&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;I fancy that this is old hat to most of you, but I had thought HTML entities cut and dried: An ampersand, a word and a semicolon (reminds me a little of dBase III, actually.) It seems, however, that certain browsers are still unsure as to what constitutes an HTML entity, and where it should end. &lt;br /&gt;&lt;br /&gt;One of the languages I use for server-side management uses the ampersand + word + semicolon format to mark where variables may be interpolated into the output stream. So it was with some surprise when it was pointed out to me by a colleague that &lt;code&gt;&amp;amp;currentValue;&lt;/code&gt; was being rendered as &lt;code&gt;&amp;curren;tValue;&lt;/code&gt;. &lt;br /&gt;&lt;br /&gt;Being the inquisitive sort, I went to &lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;&lt;a href=&quot;http://dev.w3.org/html5/html-author/charref&quot; target=&quot;blank&quot;&gt;dev.w3.org&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt; and downloaded all the HTML entity names. After a bit of fiddling about in jQuery, I had the list. After a bit more fiddling, this time in JScript, I ended up with an HTML file showing the entity name, the entity as rendered, and then what happens when you leave off the trailing semicolon and append some other text (in this case &#39;es&#39;). This is where things get ... well ... unusual. Some HTML entites follow the standard. Others like &lt;code&gt;&amp;amp;curren;&lt;/code&gt; and &lt;code&gt;&amp;amp;pound;&lt;/code&gt; don&#39;t. You enter &lt;code&gt;&amp;amp;poundage&lt;/code&gt;, expecting the browser to give &lt;code&gt;&amp;amp;poundage&lt;/code&gt; only to have it give you &lt;code&gt;&amp;pound;age&lt;/code&gt;. Weirdness abounds. Take &lt;code&gt;&amp;amp;centerdot;&lt;/code&gt; which actually renders as &lt;code&gt;&amp;cent;erdotes&lt;/code&gt;!&lt;br /&gt;&lt;br /&gt;So as to give you an idea of how it looks in your browser, I&#39;ve put the file up in a &lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;&lt;a href=&quot;http://jsfiddle.net/bugmagnet/6pvtw34w/2/&quot; target=&quot;blank&quot;&gt;jsfiddle&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt; . Let me know how you get on and whether your browser is as compliant is it makes out.&lt;br /&gt;&lt;br /&gt;Enjoy!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: georgia;font-size: xx-small;&quot;&gt;&lt;i&gt;&amp;copy; Copyright Bruce M. Axtens, 2015&lt;/i&gt;&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeaholic.blogspot.com/feeds/3323294521555426697/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/15254360/3323294521555426697' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default/3323294521555426697'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default/3323294521555426697'/><link rel='alternate' type='text/html' href='http://codeaholic.blogspot.com/2015/12/browsers-inconsistent-html-entities.html' title='[Browsers] Inconsistent HTML Entities'/><author><name>Bruce M. Axtens</name><uri>http://www.blogger.com/profile/14797830611260628579</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15254360.post-8776010354906737082</id><published>2015-11-07T13:01:00.000+08:00</published><updated>2015-12-03T21:41:39.087+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ADD"/><category scheme="http://www.blogger.com/atom/ns#" term="COBOL"/><category scheme="http://www.blogger.com/atom/ns#" term="gnucobol"/><category scheme="http://www.blogger.com/atom/ns#" term="rosettacode"/><category scheme="http://www.blogger.com/atom/ns#" term="visual COBOL"/><title type='text'>[COBOL] Sum multiples of 3 and 5</title><content type='html'>&lt;!-- [COBOL] Sum multiples of 3 and 5 ---&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;Last night I posted the following code on &lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;&lt;a href=&quot;http://rosettacode.org/wiki/Rosetta_Code&quot; target=&quot;blank&quot;&gt;RosettaCode&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt; as another solution to the &lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;&lt;a href=&quot;http://rosettacode.org/wiki/Sum_multiples_of_3_and_5#COBOL&quot; target=&quot;blank&quot;&gt;Sum multiples of 3 and 5&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt; challenge. (Mine is the third one down after all the more-mathematical solutions.)&lt;br /&gt;
&lt;br /&gt;
My solution is as brute-force as it gets, using only adds and comparisons.&lt;/span&gt;&lt;pre class=&#39;source-code&#39;&gt;       IDENTIFICATION DIVISION.
       PROGRAM-ID. SUM35.

       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  THREE-COUNTER   USAGE BINARY-CHAR value 1.
           88 IS-THREE VALUE 3.
       01  FIVE-COUNTER    USAGE BINARY-CHAR value 1.
           88 IS-FIVE VALUE 5.
       01  SUMMER          USAGE BINARY-DOUBLE value zero. 
       01  I               USAGE BINARY-LONG.
       01  N               USAGE BINARY-LONG.

       PROCEDURE DIVISION.
       10-MAIN-PROCEDURE.
           MOVE 1000000000 TO N.
           MOVE 1 TO I.
           PERFORM 20-INNER-LOOP WITH TEST AFTER UNTIL I &gt;= N.
           DISPLAY SUMMER.
           STOP RUN.
       20-INNER-LOOP.
           IF IS-THREE OR IS-FIVE 
               ADD I TO SUMMER END-ADD
               IF IS-THREE
                   MOVE 1 TO THREE-COUNTER
               ELSE
                   ADD 1 TO THREE-COUNTER
               END-IF
               IF IS-FIVE
                   MOVE 1 TO FIVE-COUNTER
               ELSE    
                   ADD 1 TO FIVE-COUNTER
               END-IF
           ELSE
               ADD 1 TO FIVE-COUNTER END-ADD
               ADD 1 TO THREE-COUNTER END-ADD
           END-IF.
           ADD 1 TO I.
           EXIT.
       END PROGRAM SUM35.
&lt;/pre&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;The above code compiles on &lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;&lt;a href=&quot;http://sourceforge.net/projects/open-cobol/&quot; target=&quot;blank&quot;&gt;GnuCOBOL 2.0&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt; and &lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;&lt;a href=&quot;https://microfocus.com/products/micro-focus-developer/visual_cobol/index.aspx&quot; target=&quot;blank&quot;&gt;MicroFocus Visual COBOL 2.3&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;. In the latter environment, I was able to get a run time of 7.3 seconds for the 1,000,000,000 iterations (AMD A6-5200 APU running at 2.00 GHz.)&lt;br /&gt;
&lt;br /&gt;
I ended up in COBOL via the usual circuitous route through other programming languages after figuring out a solution using &lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;&lt;a href=&quot;http://www.t3x.org/mlite/index.html&quot; target=&quot;blank&quot;&gt;mLite&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;. The next postings will demonstrate the mLite and perhaps others.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: georgia;font-size: xx-small;&quot;&gt;&lt;i&gt;&amp;copy; Copyright Bruce M. Axtens., 2015&lt;/i&gt;&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeaholic.blogspot.com/feeds/8776010354906737082/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/15254360/8776010354906737082' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default/8776010354906737082'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default/8776010354906737082'/><link rel='alternate' type='text/html' href='http://codeaholic.blogspot.com/2015/11/cobol-sum-multiples-of-3-and-5.html' title='[COBOL] Sum multiples of 3 and 5'/><author><name>Bruce M. Axtens</name><uri>http://www.blogger.com/profile/14797830611260628579</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15254360.post-1850496273263859235</id><published>2015-10-11T22:23:00.000+08:00</published><updated>2015-12-03T21:41:57.387+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Brian Tiffin"/><category scheme="http://www.blogger.com/atom/ns#" term="COBOL"/><category scheme="http://www.blogger.com/atom/ns#" term="COM"/><category scheme="http://www.blogger.com/atom/ns#" term="gnucobol"/><category scheme="http://www.blogger.com/atom/ns#" term="OleInitialize"/><category scheme="http://www.blogger.com/atom/ns#" term="OleUninitialize"/><title type='text'>[GnuCOBOL 2.0] Beginning COM</title><content type='html'>&lt;!-- [GnuCOBOL 2.0] Beginning COM ---&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;In my ample (NOT!) spare time, I&#39;m exploring making COM available to the Windows implementation of &lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;&lt;a href=&quot;http://savannah.gnu.org/projects/gnucobol&quot; target=&quot;blank&quot;&gt;GnuCOBOL&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;. You can do GnuCOBOL on Linux and Mac as well.&lt;br /&gt;
&lt;br /&gt;
Many thanks to &lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;&lt;a href=&quot;http://stackoverflow.com/users/1848585/brian-tiffin&quot; target=&quot;blank&quot;&gt;Brian Tiffin&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt; over on GnuCOBOL&#39;s &lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;&lt;a href=&quot;https://sourceforge.net/p/open-cobol/discussion/help/&quot; target=&quot;blank&quot;&gt;Sourceforge Forum&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt; for cheering me on.&lt;/span&gt;&lt;pre class=&#39;source-code&#39;&gt;       IDENTIFICATION DIVISION.
       PROGRAM-ID. OLE.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  HRESULT     USAGE BINARY-LONG.
           88 S_OK     VALUE 0.
           88 S_FALSE  VALUE 1.
       01  NUL         USAGE BINARY-LONG VALUE 0.
       
       PROCEDURE DIVISION.
       MAIN-PROCEDURE.
        CALL STDCALL &quot;OleInitialize&quot;
            USING BY VALUE NUL
            RETURNING HRESULT.
            DISPLAY HRESULT.

        CALL STDCALL &quot;OleUninitialize&quot; USING
            BY REFERENCE OMITTED
            GIVING NULL.

            STOP RUN.
       END PROGRAM OLE.
&lt;/pre&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;The are some runtime settings (Windows 10 Home, 64bit) required to get that working, namely&lt;/span&gt;&lt;pre class=&#39;source-code&#39;&gt;set COB_PRE_LOAD=ole32
set COB_LIBRARY_PATH=C:\windows\syswow64
&lt;/pre&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;I should sometime create a Github project for this, in case others want to run with it.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: georgia;font-size: xx-small;&quot;&gt;&lt;i&gt;&amp;copy; Copyright Bruce M. Axtens, 2015&lt;/i&gt;&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeaholic.blogspot.com/feeds/1850496273263859235/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/15254360/1850496273263859235' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default/1850496273263859235'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default/1850496273263859235'/><link rel='alternate' type='text/html' href='http://codeaholic.blogspot.com/2015/10/gnucobol-20-beginning-com.html' title='[GnuCOBOL 2.0] Beginning COM'/><author><name>Bruce M. Axtens</name><uri>http://www.blogger.com/profile/14797830611260628579</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15254360.post-6828172635191897422</id><published>2015-10-11T22:02:00.000+08:00</published><updated>2015-10-11T22:29:49.122+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="binary notation"/><category scheme="http://www.blogger.com/atom/ns#" term="csnobol4"/><category scheme="http://www.blogger.com/atom/ns#" term="DEXP"/><category scheme="http://www.blogger.com/atom/ns#" term="Fred Weigel"/><category scheme="http://www.blogger.com/atom/ns#" term="Gordon Peterson"/><category scheme="http://www.blogger.com/atom/ns#" term="Rafal M. Sulejman"/><category scheme="http://www.blogger.com/atom/ns#" term="TkSLIDE"/><category scheme="http://www.blogger.com/atom/ns#" term="Yahoo!"/><title type='text'>[CSNOBOL4] Decimal to Binary #2</title><content type='html'>&lt;!-- [CSNOBOL4] Decimal to Binary #2 ---&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;Many thanks to &lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;&lt;a href=&quot;https://www.linkedin.com/in/gordonpeterson&quot; target=&quot;blank&quot;&gt;Gordon Peterson&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt; who took my non-idiomatic code and improved it both in size and speed, viz&lt;/span&gt;&lt;pre class=&#39;source-code&#39;&gt;         DEFINE(&quot;BIN(N)&quot;)                            :(BIN_END)
BIN      BIN = (GT(N,1) BIN(N / 2), ) REMDR(N,2)     :(RETURN)
BIN_END
&lt;/pre&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;This is guru level stuff. &lt;br /&gt;
&lt;br /&gt;
I&#39;m also grateful to &lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;&lt;a href=&quot;https://github.com/ratboy666&quot; target=&quot;blank&quot;&gt;Fred Weigel&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt; who first responded to my posting in the &lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;&lt;a href=&quot;https://groups.yahoo.com/neo/groups/snobol/info&quot; target=&quot;blank&quot;&gt;Snobol Yahoo! Group&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt; and made some very useful suggestions. He points out that Gordon&#39;s solution is a prime candidate for &lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;&lt;a href=&quot;http://www.j-paine.org/dobbs/snobol_foot.html&quot; target=&quot;blank&quot;&gt;DEXP&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;, viz:&lt;/span&gt;&lt;pre class=&#39;source-code&#39;&gt;dexp(&#39;bin(n) = (gt(n, 1) bin(n / 2), ) remdr(n, 2)&#39;)
&lt;/pre&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;That&#39;s enough CSNOBOL4 for now, though if you do want to spend some time with it (Windows or Linux), I&#39;d suggest using Rafal M. Sulejman&#39;s  &lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;&lt;a href=&quot;http://rms.republika.pl/slide.shtml&quot; target=&quot;blank&quot;&gt;TkSLIDE&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: georgia;font-size: xx-small;&quot;&gt;&lt;i&gt;&amp;copy; Copyright Bruce M. Axtens, 2015&lt;/i&gt;&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeaholic.blogspot.com/feeds/6828172635191897422/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/15254360/6828172635191897422' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default/6828172635191897422'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default/6828172635191897422'/><link rel='alternate' type='text/html' href='http://codeaholic.blogspot.com/2015/10/csnobol4-decimal-to-binary-2.html' title='[CSNOBOL4] Decimal to Binary #2'/><author><name>Bruce M. Axtens</name><uri>http://www.blogger.com/profile/14797830611260628579</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15254360.post-1254990803778835739</id><published>2015-10-07T23:51:00.002+08:00</published><updated>2015-10-07T23:57:45.746+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="binary notation"/><category scheme="http://www.blogger.com/atom/ns#" term="csnobol4"/><category scheme="http://www.blogger.com/atom/ns#" term="SNOBOL4"/><title type='text'>[CSNOBOL4] Decimal to Binary</title><content type='html'>&lt;!-- [CSNOBOL4] Decimal to Binary ---&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;Okay, I think this is the last of the solutions to  &lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;&lt;a href=&quot;http://rosettacode.org/wiki/Binary_digits&quot; target=&quot;blank&quot;&gt;Binary Digits&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;. Thie one&#39;s in  &lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;&lt;a href=&quot;http://www.snobol4.org/csnobol4/2.0/&quot; target=&quot;blank&quot;&gt;CSNOBOL4&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;. Kudos to   &lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;&lt;a href=&quot;http://www.ultimate.com/phil/ &quot; target=&quot;blank&quot;&gt;Phil Budne&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt; for maintaining and expanding this amazing programming language.&lt;br /&gt;
&lt;br /&gt;
The code below, like all the ones before it, is recursive.&lt;/span&gt;&lt;pre class=&#39;source-code&#39;&gt;        DEFINE(&#39;BIN(N,STR)&#39;)              :(BIN_END)
BIN     EQ(N,0)                           :S(NZERO)
        BIN = BIN(N / 2, REMDR(N,2) STR)  :S(RETURN)
NZERO   BIN = EQ(SIZE(STR),0) &#39;0&#39;         :S(RETURN)
        BIN = STR                         :(RETURN)
BIN_END

        OUTPUT = BIN(0)
        OUTPUT = BIN(5)
        OUTPUT = BIN(50)
        OUTPUT = BIN(9000)
END
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: georgia;font-size: xx-small;&quot;&gt;&lt;i&gt;&amp;copy; Copyright Bruce M. Axtens, 2015&lt;/i&gt;&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeaholic.blogspot.com/feeds/1254990803778835739/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/15254360/1254990803778835739' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default/1254990803778835739'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default/1254990803778835739'/><link rel='alternate' type='text/html' href='http://codeaholic.blogspot.com/2015/10/csnobol4-decimal-to-binary.html' title='[CSNOBOL4] Decimal to Binary'/><author><name>Bruce M. Axtens</name><uri>http://www.blogger.com/profile/14797830611260628579</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15254360.post-5917363854113107135</id><published>2015-10-07T22:26:00.000+08:00</published><updated>2015-10-07T22:26:29.660+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="binary"/><category scheme="http://www.blogger.com/atom/ns#" term="Euphoria"/><category scheme="http://www.blogger.com/atom/ns#" term="rosettacode"/><title type='text'>[Euphoria] Decimal to Binary</title><content type='html'>&lt;!-- [Euphoria] Decimal to Binary ---&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;Having solved the &lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;&lt;a href=&quot;http://rosettacode.org/wiki/Binary_digits&quot; target=&quot;blank&quot;&gt;Binary Digits&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt; task in mLite and FBSL, I thought I&#39;d have a go in &lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;&lt;a href=&quot;http://www.rapideuphoria.com/index.html&quot; target=&quot;blank&quot;&gt;OpenEuphoria&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;. Kudos to David Craig of  &lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;&lt;a href=&quot;http://www.rapideuphoria.com/contract.htm &quot; target=&quot;blank&quot;&gt;Rapid Deployment Software&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt; for the original implementation and to the subsequent &lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;&lt;a href=&quot;http://openeuphoria.org/forum/index.wc&quot; target=&quot;blank&quot;&gt;team of heroes&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt; for a very powerful Windows/Linux/Mac programming (interpreted and/or compiled) language. &lt;br /&gt;&lt;br /&gt;The code below, expressed in v4.1.0 form, follows the FBSL fairly closely.&lt;/span&gt;&lt;pre class=&#39;source-code&#39;&gt;include std/math.e 
include std/convert.e

function Bin(integer n, sequence s = &quot;&quot;)
  if n &gt; 0 then
   return Bin(floor(n/2),(mod(n,2) + #30) &amp; s)
  end if
  if length(s) = 0 then
   return to_integer(&quot;0&quot;)
  end if
  return to_integer(s)
end function

printf(1, &quot;%d\n&quot;, Bin(0))
printf(1, &quot;%d\n&quot;, Bin(5))
printf(1, &quot;%d\n&quot;, Bin(50))
printf(1, &quot;%d\n&quot;, Bin(9000))
&lt;/pre&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;There&#39;s already an Euphoria solution to the task. Some enterprising soul might want to check which of the two solutions is the faster.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: georgia;font-size: xx-small;&quot;&gt;&lt;i&gt;&amp;copy; Copyright Bruce M. Axtens, 2015&lt;/i&gt;&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeaholic.blogspot.com/feeds/5917363854113107135/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/15254360/5917363854113107135' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default/5917363854113107135'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default/5917363854113107135'/><link rel='alternate' type='text/html' href='http://codeaholic.blogspot.com/2015/10/euphoria-decimal-to-binary.html' title='[Euphoria] Decimal to Binary'/><author><name>Bruce M. Axtens</name><uri>http://www.blogger.com/profile/14797830611260628579</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15254360.post-2907593564353940860</id><published>2015-10-07T17:48:00.000+08:00</published><updated>2015-10-07T17:48:07.830+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ABAP"/><category scheme="http://www.blogger.com/atom/ns#" term="binary notation"/><category scheme="http://www.blogger.com/atom/ns#" term="FBSL"/><category scheme="http://www.blogger.com/atom/ns#" term="mLite"/><category scheme="http://www.blogger.com/atom/ns#" term="rosettacode"/><category scheme="http://www.blogger.com/atom/ns#" term="SAP"/><title type='text'>[FBSL] Decimal to Binary</title><content type='html'>&lt;!-- [FBSL] Decimal to Binary ---&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;Having solved the &lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;&lt;a href=&quot;http://rosettacode.org/wiki/Binary_digits&quot; target=&quot;blank&quot;&gt;Binary Digits&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt; task in mLite, I thought I&#39;d have a go in &lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;&lt;a href=&quot;http://www.fbsl.net&quot; target=&quot;blank&quot;&gt;FBSL&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;. Kudos to &lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;&lt;a href=&quot;http://www.fbsl.net/pmwiki/index.php?n=Main.TheTeam&quot; target=&quot;blank&quot;&gt;the FBSL team&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt; for a very useful and powerful Windows scripting language. Even &lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;&lt;a href=&quot;http://scn.sap.com/docs/DOC-45869&quot; target=&quot;blank&quot;&gt;ABAP&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt; users can leverage it!&lt;br /&gt;&lt;br /&gt;The code below, expressed in v3.5 RC form, follows the mLite fairly closely.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;pre class=&#39;source-code&#39;&gt;#AppType Console
function Bin(byval n as integer, byval s as string = &quot;&quot;) as string
 if n &gt; 0 then return Bin(n \ 2, (n mod 2) &amp; s)
 if s = &quot;&quot; then return &quot;0&quot;
 return s
end function

print Bin(5)
print Bin(50)
print Bin(9000)

pause
&lt;/pre&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;It was during the testing of this code that it dawned on me that the mLite wasn&#39;t handling the &lt;code&gt;binary 0;&lt;/code&gt; appropriately. Thus those who notice such things will discover a subtle change in the mLite posting.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: georgia;font-size: xx-small;&quot;&gt;&lt;i&gt;&amp;copy; Copyright Bruce M. Axtens, 2015&lt;/i&gt;&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeaholic.blogspot.com/feeds/2907593564353940860/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/15254360/2907593564353940860' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default/2907593564353940860'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default/2907593564353940860'/><link rel='alternate' type='text/html' href='http://codeaholic.blogspot.com/2015/10/fbsl-decimal-to-binary.html' title='[FBSL] Decimal to Binary'/><author><name>Bruce M. Axtens</name><uri>http://www.blogger.com/profile/14797830611260628579</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15254360.post-6726278568849487438</id><published>2015-10-06T14:51:00.000+08:00</published><updated>2015-10-07T17:34:05.060+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="binary notation"/><category scheme="http://www.blogger.com/atom/ns#" term="mLite"/><category scheme="http://www.blogger.com/atom/ns#" term="nils m holm"/><category scheme="http://www.blogger.com/atom/ns#" term="recursion"/><category scheme="http://www.blogger.com/atom/ns#" term="rosettacode"/><title type='text'>[mLite] Convert to Binary Notation</title><content type='html'>&lt;!-- [mLite] Convert to Binary Notation ---&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;A short diversion: the Standard ML dialect called &lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;&lt;a href=&quot;http://www.t3x.org/mlite/index.html&quot; target=&quot;blank&quot;&gt;mLite&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt; is where I go for the intellectual challenge of thinking in a functional programming way. Kudos to &lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;&lt;a href=&quot;http://www.t3x.org/index.html&quot; target=&quot;blank&quot;&gt;Nils M. Holm&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt; for developing it. mLite is one of the languages I use to solve &lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;&lt;a href=&quot;http://rosettacode.org/wiki/Rosetta_Code&quot; target=&quot;blank&quot;&gt;RosettaCode&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt; tasks, in this case, &lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;&lt;a href=&quot;http://rosettacode.org/wiki/Binary_digits&quot; target=&quot;blank&quot;&gt;Binary Digits&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;. &lt;br /&gt;
&lt;br /&gt;
This turned out to be a fairly simple task and only took me a few minutes to solve. Granted, I reused some code from the logarithm calculator of a few postings ago, but that was just for the conversion of a list of numbers to their printable form.&lt;/span&gt;&lt;pre class=&#39;source-code&#39;&gt;fun binary
   (0, []) = &quot;0&quot;
 | (0, x) = implode ` map (fn x = if int x then chr (x + 48) else x) x
 | (n, b) = binary (n div 2, n mod 2 :: b)
 | n = binary (n, [])
; 
&lt;/pre&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;The gist of that is&lt;ul&gt;&lt;li&gt;pass in a number and recurse with the number and an empty list.&lt;br /&gt;
&lt;li&gt;With a number that isn&#39;t zero recurse with the number divved by 2 and the list prepended with the number modded by 2.&lt;br /&gt;
&lt;li&gt;Keep going until the number is zero. At that point, convert the answer&#39;s digits to string representation and implode them into a single string.&lt;br /&gt;
&lt;li&gt;If the number is zero and there are no digits, return &quot;0&quot;&lt;/ul&gt;Might get back to some VB6 next. Or javascript.&lt;/span&gt;  &lt;span style=&quot;font-family: georgia;font-size: xx-small;&quot;&gt;&lt;i&gt;&amp;copy; Copyright Bruce M. Axtens, 2015&lt;/i&gt;&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeaholic.blogspot.com/feeds/6726278568849487438/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/15254360/6726278568849487438' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default/6726278568849487438'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default/6726278568849487438'/><link rel='alternate' type='text/html' href='http://codeaholic.blogspot.com/2015/10/mlite-convert-to-binary-notation.html' title='[mLite] Convert to Binary Notation'/><author><name>Bruce M. Axtens</name><uri>http://www.blogger.com/profile/14797830611260628579</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15254360.post-753997608853477535</id><published>2015-10-04T12:00:00.000+08:00</published><updated>2015-10-04T12:01:22.295+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="collection"/><category scheme="http://www.blogger.com/atom/ns#" term="fluent"/><category scheme="http://www.blogger.com/atom/ns#" term="Map"/><category scheme="http://www.blogger.com/atom/ns#" term="PerlScript"/><category scheme="http://www.blogger.com/atom/ns#" term="reduce"/><category scheme="http://www.blogger.com/atom/ns#" term="variant"/><category scheme="http://www.blogger.com/atom/ns#" term="VB6"/><category scheme="http://www.blogger.com/atom/ns#" term="VBScript"/><category scheme="http://www.blogger.com/atom/ns#" term="WSH"/><title type='text'>[VB6] Map and Reduce</title><content type='html'>&lt;!-- [VB6] Map and Reduce ---&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;Following on from a previous posting about &lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;&lt;a href=&quot;http://codeaholic.blogspot.com.au/2015/10/vb6-what-about-me-aka-method-chaining.html&quot; target=&quot;blank&quot;&gt;Fluent VB6&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt; we look now at two routines which pop up a lot these days: Map and Reduce. On offer here is one way of implementing these two functional programming stalwarts. They are presented here as part of a FluentVB6 object, but could just as easily be declared and used separately.&lt;br /&gt;
&lt;br /&gt;
I&#39;m implementing these using the &lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;&lt;a href=&quot;https://msdn.microsoft.com/en-us/library/aa227400(v=vs.60).aspx&quot; target=&quot;blank&quot;&gt;MSScript object&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt; which also appeared in the aforementioned posting. This makes available to the programmer, out of the box, the functionality of two scripting languages, VBScript and JScript. Other languages are available within the &lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;&lt;a href=&quot;http://docs.activestate.com/activeperl/5.14/Windows/WindowsScriptHost.html&quot; target=&quot;blank&quot;&gt;Windows Scripting Host&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt; environment and these could also be used (e.g. PerlScript as per the link.)&lt;br /&gt;
&lt;br /&gt;
The code below tests the Map and Reduce functions. After this the implementation will be discussed.&lt;/span&gt;&lt;pre class=&#39;source-code&#39;&gt;Dim words As New Collection
    words.Add &quot;cat&quot;
    words.Add &quot;dog&quot;
    words.Add &quot;cow&quot;
    words.Add &quot;wolf&quot;
    words.Add &quot;rat&quot;
    
    Dim F As New FunctionalObject
    
    Dim upperwords As New Collection
    Set upperwords = F.WorkingWith(words).Map(&quot;UCase(Value)&quot;).AsCollection()
    
    Dim concatenated As Variant
    F.Reset
    concatenated = F.WorkingWith(upperwords).Reduce(vbNullString, &quot;InitValue = InitValue &amp; Value&quot;).asValue()
    
    Dim counted As Variant
    counted = F.Reset().WorkingWith(upperwords).Reduce(0, &quot;initValue = initValue + Len(Value)&quot;).asValue()
&lt;/pre&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;For the sake of simplicity, I&#39;m limiting things to Collections in, Collections and Variants out. The code could be readily changed to handle Arrays, Dictionaries and other data structures. &lt;br /&gt;
&lt;br /&gt;
The class is called &lt;code&gt;FunctionalObject&lt;/code&gt; and it begins with &lt;/span&gt;&lt;pre class=&#39;source-code&#39;&gt;Option Explicit

Private workingCollection As Collection
Private incomingCollection As Collection
Private workingValue As Variant
Private SC As ScriptControl

Private Sub Class_Initialize()
    Set workingCollection = New Collection
    Set incomingCollection = New Collection
    workingValue = vbEmpty
    Set SC = New ScriptControl
End Sub
&lt;/pre&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;No surprises there. Again, the ScriptControl object is the OCX added via the Project menu as a Reference rather than as a Component. One could late-bind with &lt;code&gt;CreateObject&lt;/code&gt; but there&#39;s not much point in this case.&lt;br /&gt;
&lt;br /&gt;
Next the public function to receive the incoming collection&lt;/span&gt;&lt;pre class=&#39;source-code&#39;&gt;Public Function WorkingWith(inCol As Collection) As FunctionalObject
    Set incomingCollection = inCol
    Set WorkingWith = Me
End Function
&lt;/pre&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;&lt;code&gt;Reset&lt;/code&gt; clears the workingCollection (in the event that you reuse the currently instantiation of the &lt;code&gt;FunctionalObject&lt;/code&gt; rather than instantiate another one.)&lt;/span&gt;&lt;pre class=&#39;source-code&#39;&gt;Public Function Reset() As FunctionalObject
    Dim i As Integer
    For i = 1 To workingCollection.Count
        workingCollection.Remove 1
    Next
    workingValue = vbEmpty
    Set Reset = Me
End Function
&lt;/pre&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;&lt;code&gt;wrapText&lt;/code&gt; you&#39;ll seen before from the previous posting. It just makes the incoming collection&#39;s value palatable to VBScript.&lt;/span&gt;&lt;pre class=&#39;source-code&#39;&gt;Private Function wrapItem(v As Variant) As String
    If VarType(v) = vbString Then
        wrapItem = Chr$(34) &amp; v &amp; Chr$(34)
    Else
        wrapItem = CStr(v)
    End If
End Function
&lt;/pre&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;Next the &lt;code&gt;Map&lt;/code&gt; function. The ScriptControl language is set to VBScript and the &lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;&lt;a href=&quot;http://stackoverflow.com/questions/31064164/what-cant-i-use-when-usesafesubset-is-true&quot; target=&quot;blank&quot;&gt;&quot;safe subset&quot;&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt; of script language functions is selected. Then the code iterates through each element of the incoming collection, and sets a VBScript place-holder variable called &lt;code&gt;Value&lt;/code&gt; to that element. Next the map script is evaluated in the context of &lt;code&gt;Value&lt;/code&gt;, the result being added to the working collection. &lt;br /&gt;
&lt;br /&gt;
The example at the top of page has the map script as &lt;code&gt;&quot;UCase(Value)&quot;&lt;/code&gt;, so the value stored in the working collection is the uppercase of the value in the incoming collection.  &lt;/span&gt;&lt;pre class=&#39;source-code&#39;&gt;Public Function Map(Optional script As String = &quot;Value&quot;) As FunctionalObject
    SC.Language = &quot;VBScript&quot;
    SC.UseSafeSubset = True
    Dim i As Integer
    For i = 1 To incomingCollection.Count
        SC.ExecuteStatement &quot;Value = &quot; &amp; wrapItem(incomingCollection.Item(i))
        workingCollection.Add SC.Eval(script)
    Next
    Set Map = Me
End Function
&lt;/pre&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;Reduce works in a similar manner except the result is a variant. There is the expectation that the reduce script will somehow work toward deriving a single value from the incoming collection, thus the use of an second place-holder called &lt;code&gt;InitValue&lt;/code&gt;. The first parameter of the &lt;code&gt;Reduce&lt;/code&gt; call is stored in &lt;code&gt;InitValue&lt;/code&gt; with the expectation that the reduce script will refer to it and to the &lt;code&gt;Value&lt;/code&gt; place-holder.&lt;br /&gt;
&lt;br /&gt;
For example, one of the examples from the first code block reads, in part,&lt;/span&gt;&lt;pre class=&#39;source-code&#39;&gt;Reduce(0, &quot;initValue = initValue + Len(Value)&quot;).
&lt;/pre&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;This reduces the collection to a value accruing the lengths of the strings assumed to be in the incoming collection.&lt;br /&gt;
&lt;br /&gt;
Both parameters to Reduce are marked as optional. If neither is specified, the Reduce does nothing except set Value to InitValue, effectively filling the working collection with as many zeroes as there are items in the incoming collection. &lt;/span&gt;&lt;pre class=&#39;source-code&#39;&gt;Public Function Reduce(Optional initval As Variant = 0, Optional script As String = &quot;Value = InitValue&quot;) As Variant
    SC.Language = &quot;VBScript&quot;
    SC.UseSafeSubset = True
    Dim vAnswer As Variant
    Dim vItem As Variant
    Dim vResult As Variant
    Dim i As Integer
    SC.ExecuteStatement &quot;InitValue = &quot; &amp; wrapItem(initval)
    For i = 1 To incomingCollection.Count
        vItem = incomingCollection.Item(i)
        SC.ExecuteStatement &quot;Value = &quot; &amp; wrapItem(vItem)
        SC.ExecuteStatement script
    Next
    workingValue = SC.Eval(&quot;InitValue&quot;)
    Set Reduce = Me
End Function
&lt;/pre&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;Finally the two output functions, &lt;code&gt;asCollection&lt;/code&gt; and &lt;code&gt;asValue&lt;/code&gt;. The former copies the working collection to an answer collection and returns that to the caller. &lt;code&gt;asValue&lt;/code&gt; returns the working value from the &lt;code&gt;Reduce&lt;/code&gt;.&lt;/span&gt;&lt;pre class=&#39;source-code&#39;&gt;Public Function AsCollection() As Collection
    Dim answerCollection As New Collection
    Dim i As Integer
    For i = 1 To workingCollection.Count
        answerCollection.Add workingCollection.Item(i)
    Next
    Set AsCollection = answerCollection
End Function

Public Function asValue() As Variant
    asValue = workingValue
End Function
&lt;/pre&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;I will make the sources available on Github in the near future. &lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: georgia;font-size: xx-small;&quot;&gt;&lt;i&gt;&amp;copy; Copyright Bruce M. Axtens, 2015&lt;/i&gt;&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeaholic.blogspot.com/feeds/753997608853477535/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/15254360/753997608853477535' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default/753997608853477535'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default/753997608853477535'/><link rel='alternate' type='text/html' href='http://codeaholic.blogspot.com/2015/10/following-on-from-previous-posting.html' title='[VB6] Map and Reduce'/><author><name>Bruce M. Axtens</name><uri>http://www.blogger.com/profile/14797830611260628579</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15254360.post-4849449196206572717</id><published>2015-10-02T17:22:00.000+08:00</published><updated>2015-10-02T17:22:12.075+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="fluent"/><category scheme="http://www.blogger.com/atom/ns#" term="me"/><category scheme="http://www.blogger.com/atom/ns#" term="method chaining"/><category scheme="http://www.blogger.com/atom/ns#" term="MSScriptControl"/><category scheme="http://www.blogger.com/atom/ns#" term="soap"/><category scheme="http://www.blogger.com/atom/ns#" term="VB6"/><category scheme="http://www.blogger.com/atom/ns#" term="XML"/><title type='text'>[VB6] What about Me a.k.a. Method Chaining a.k.a. Fluent VB6</title><content type='html'>&lt;!-- [VB6] What about Me a.k.a. Method Chaining a.k.a. Fluent VB6 ---&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;This is nothing to do with Shannon Noll&#39;s song, &lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=OzQKECQgjW8&quot; target=&quot;blank&quot;&gt;What about Me&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;. No, it&#39;s about Method Chaining, the mechanism described in &lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;&lt;a href=&quot;http://www.sitepoint.com/javascript-like-boss-understanding-fluent-apis/&quot; target=&quot;blank&quot;&gt;Fluent Javascript&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt; and making that same mechanism available to the VB6 programmer.&lt;br /&gt;&lt;br /&gt;But first, kudos. I am grateful to Vidar Løvbrekke Sømme. On his zbz5.net blog, he posted an article called &lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;&lt;a href=&quot;http://zbz5.net/bending-vb6-functional-direction&quot; target=&quot;blank&quot;&gt;Bending Vb6 in the functional direction&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;. In that article, he gives his take on method chaining. What follows is my take on the subject.&lt;br /&gt;&lt;br /&gt;Having found a way to get &lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;&lt;a href=&quot;http://codeaholic.blogspot.com.au/2015/09/vb6-installation-in-windows-10.html&quot; target=&quot;blank&quot;&gt;VB6 running without emulation in 64bit Windows 10&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;, I&#39;ve been encouraged to get back into it and revisit some of my older projects.&lt;br /&gt;&lt;br /&gt;So what&#39;s this got to do &quot;What about Me&quot;? Well, the thing that makes method chaining possible in JavaScript is the &lt;code&gt;this&lt;/code&gt; keyword. The VB6 equivalent keyword is &lt;code&gt;Me&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;The challenge is to create a mechanism which allows something like Vidar&#39;s&lt;/span&gt;&lt;span style=&quot;font-family: georgia; font-size: normal;&quot;&gt;&lt;blockquote&gt;concatenated = List.From(originalCollection).SelectProperty(&quot;Property&quot;).Concat(&quot;,&quot;)&lt;p align=&#39;right&#39;&gt;&amp;mdash;&amp;nbsp;&lt;a href=&#39;http://zbz5.net/bending-vb6-functional-direction&#39; target=_blank&gt;But this isn&#39;t too bad, is it?&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;What I&#39;ve done doesn&#39;t use Map or Reduce (I have implemented those but differently and I&#39;ll deal with both in a subsequent post.)&lt;br /&gt;&lt;br /&gt;First, launch the VB6 IDE, create a new project and remove the default form. Next create a class and call it SelectorObject. In the code editor for the class enter class variables, viz&lt;/span&gt;&lt;pre class=&#39;source-code&#39;&gt;Dim cWorking As Collection
Dim dWorking As Dictionary
Dim aWorking() As Variant
Dim iWorking As Integer
Dim cOriginal As Collection
Dim dOriginal As Dictionary
Dim aOriginal() As Variant
Dim sPattern As String
Dim bPatternDefined As Boolean
Dim oScript As ScriptControl

Private Enum FROMS
    FromCollection = 1
    FromDictionary = 2
    FromArray = 3
    Fromstring = 4
End Enum

Dim source As FROMS
&lt;/pre&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;The above is out of my own project so there&#39;s extra stuff in there that goes beyond Vidar&#39;s original. Ultimately I&#39;d like to be able to hand a Collection, Dictionary, Array or String to the class and be able to pull out of it a Collection, Dictionary, Array or String. The code you&#39;ll see is part way to realising that.&lt;br /&gt;&lt;br /&gt;Notice also the &lt;code&gt;Dim oScript As ScriptControl&lt;/code&gt;. To make an element selection mechanism, I&#39;m calling in the &lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;&lt;a href=&quot;https://msdn.microsoft.com/en-us/library/aa227413(v=vs.60).aspx&quot; target=&quot;blank&quot;&gt;MSScript&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt; OCX object (as a Project Reference).&lt;br /&gt;&lt;br /&gt;Next comes the class initialisation&lt;/span&gt;&lt;pre class=&#39;source-code&#39;&gt;Private Sub Class_Initialize()
    Set cWorking = New Collection
    Set dWorking = New Dictionary
    sPattern = vbNullString
    bPatternDefined = False
    iWorking = -1
    Set oScript = New ScriptControl
    oScript.Language = &quot;VBScript&quot;
    oScript.UseSafeSubset = True
End Sub
&lt;/pre&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;Next the first public function &lt;code&gt;Selecting&lt;/code&gt; which will introduce the selection statement. I&#39;d love to be able to use &lt;code&gt;Select&lt;/code&gt;, but that&#39;s a VB6 reserved word. Notice the use of the &lt;code&gt;Me&lt;/code&gt; keyword. Because it&#39;s an object, it has to be assigned to the function name (as a return value) using &lt;code&gt;Set&lt;/code&gt;.&lt;/span&gt;&lt;pre class=&#39;source-code&#39;&gt;Public Function Selecting() As SelectorObject
    Set Selecting = Me
End Function
&lt;/pre&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;Next the &lt;code&gt;From&lt;/code&gt; public function. This ascertains the type of the incoming variable and assigns it to a relevant worker object. An enum takes care of letting the class know what was passed in.&lt;/span&gt;&lt;pre class=&#39;source-code&#39;&gt;Public Function From(c As Variant) As SelectorObject
    If TypeName(c) = &quot;Collection&quot; Then
        Set cOriginal = c
        source = FromCollection
    ElseIf TypeName(c) = &quot;Dictionary&quot; Then
        Set dOriginal = c
        source = FromDictionary
    Else
        If VarType(c) = vbArray Then
            aOriginal = c
            source = FromArray
        Else
            aOriginal = Split(c, &quot;&quot;)
            source = Fromstring
        End If
    End If
    Set From = Me
End Function
&lt;/pre&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;Next comes the &lt;code&gt;Where&lt;/code&gt; function. Rather that doing any further processing, the &lt;code&gt;Where&lt;/code&gt; simply accepts the &#39;where&#39; text (a script fragment for MSScript to use later) and a flag to say we have it is set.&lt;/span&gt;&lt;pre class=&#39;source-code&#39;&gt;Public Function Where(pattern As String) As SelectorObject
    sPattern = pattern
    bPatternDefined = True
    Set Where = Me
End Function
&lt;/pre&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;Next a helper function which puts double quotes around strings and leaves other data types undecorated. This exists because the current element in the Collection/Dictionary/Array/String is assigned to a VBScript variable before the &lt;code&gt;Where&lt;/code&gt; script is evaluated. Being a VBScript assignment statement, double quotes need to be around strings. At this point there is no special handling for booleans and dates etc.&lt;/span&gt;&lt;pre class=&#39;source-code&#39;&gt;Private Function WrapData(data As Variant) As String
    If VarType(data) = vbString Then
        WrapData = Chr$(34) &amp; data &amp; Chr$(34)
    Else
        WrapData = CStr(data)
    End If
End Function
&lt;/pre&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;Finally, one of the three output routines. This is where all the hard work is done. Notice that these functions don&#39;t specify &lt;code&gt;SelectorObject&lt;/code&gt; as the return type. In this first case, a Collection is returned. The Dictionary output routine has not been written. &lt;br /&gt;&lt;br /&gt;Notice also that, if a &lt;code&gt;Where&lt;/code&gt; clause has been specified, the current item is set as a variable to the MSScript engine, and then the &#39;where&#39; text is evaluated by MSScript, using the VBScript language. The result is interpreted as a boolean to decide whether or not to include the current item in the output collection. Otherwise, everything that went in comes out.&lt;/span&gt;&lt;pre class=&#39;source-code&#39;&gt;Public Function asCollection() As Collection
    Dim i As Integer
    Dim b As Boolean
    For i = 1 To cOriginal.Count
        If bPatternDefined Then
            oScript.ExecuteStatement &quot;Value = &quot; &amp; WrapData(cOriginal.Item(i))
            b = CBool(oScript.Eval(sPattern))
            If b Then
                cWorking.Add cOriginal.Item(i)
            End If
        Else
            cWorking.Add cOriginal.Item(i)
        End If
    Next
    Set asCollection = cWorking
End Function
&lt;/pre&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;Next, a string output routine, with an optional argument to supply an inter-item separator.&lt;/span&gt;&lt;pre class=&#39;source-code&#39;&gt;Public Function asStringSeparatedBy(Optional separator As String = vbNullString) As String
    Dim i As Integer
    Dim b As Boolean
    Dim answer As String
    For i = 1 To cOriginal.Count
        If bPatternDefined Then
            oScript.ExecuteStatement &quot;Value = &quot; &amp; WrapData(cOriginal.Item(i))
            b = CBool(oScript.Eval(sPattern))
            If b Then
                answer = answer &amp; cOriginal.Item(i)
                If i &lt; cOriginal.Count Then
                    answer = answer &amp; separator
                End If
            End If
        Else
            cWorking.Add cOriginal.Item(i)
            If i &lt; cOriginal.Count Then
                answer = answer &amp; separator
            End If
        End If
    Next
    
    If bPatternDefined And Right$(answer, 1) = separator Then
        answer = Mid$(answer, 1, Len(answer) - 1)
    End If
    
    asStringSeparatedBy = answer
End Function
&lt;/pre&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;And finally, an output routine returning an array. The array element variable, iWorking, was initialised as -1, thus the pre-increment. Perhaps something else could be done about array initialisation to make things more efficient than a &lt;code&gt;ReDim Preserve&lt;/code&gt; for each element.&lt;/span&gt;&lt;pre class=&#39;source-code&#39;&gt;Public Function asArray() As Variant
    Dim i As Integer
    Dim b As Boolean
    For i = 1 To cOriginal.Count
        If bPatternDefined Then
            oScript.ExecuteStatement &quot;Value = &quot; &amp; WrapData(cOriginal.Item(i))
            b = CBool(oScript.Eval(sPattern))
            If b Then
                iWorking = iWorking + 1
                ReDim Preserve aWorking(iWorking)
                aWorking(iWorking) = cOriginal.Item(i)
            End If
        Else
            iWorking = iWorking + 1
            ReDim Preserve aWorking(iWorking)
            aWorking(iWorking) = cOriginal.Item(i)
        End If
    Next
    asArray = aWorking
End Function
&lt;/pre&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;That&#39;s all that&#39;s currently in the &lt;code&gt;SelectorObject&lt;/code&gt;. &lt;br /&gt;&lt;br /&gt;Now, out in the main module, in the Main subroutine, a couple of tests.&lt;/span&gt;&lt;pre class=&#39;source-code&#39;&gt;Dim words As New Collection
    words.Add &quot;cat&quot;
    words.Add &quot;dog&quot;
    words.Add &quot;cow&quot;
    words.Add &quot;wolf&quot;
    words.Add &quot;rat&quot;

    Dim S As New SelectorObject

    Debug.Print S.Selecting().From(words).Where(&quot;instr(Value,&quot;&quot;o&quot;&quot;) &gt; 0&quot;).asStringSeparatedBy(&quot;,&quot;)
    Debug.Print Join(S.Selecting().From(words).Where(&quot;instr(Value,&quot;&quot;a&quot;&quot;) &gt; 0&quot;).asArray(), &quot;|&quot;)
&lt;/pre&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;The output being&lt;/span&gt;&lt;pre class=&#39;source-code&#39;&gt;dog,cow,wolf
cat|rat
&lt;/pre&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;So that&#39;s my take on Fluent VB6. &lt;br /&gt;&lt;br /&gt;In my experimentations I have used this technique to re-implement Google Adwords SOAP request code that I originally wrote in JScript, viz&lt;/span&gt;&lt;pre class=&#39;source-code&#39;&gt;Dim pred As String
    Dim sele As String
    Dim campaignID As Long
    campaignID = 1000222

    Dim OPE As New OperationObject
    Dim PRE As New PredicateObject
    Dim SEL As New SelectObject
 
    pred = PRE.Field(&quot;CampaignId&quot;).Operator(&quot;=&quot;).Value(campaignID).toXML()
    sele = SEL.Fields(&quot;BudgetId&quot;).Fields(&quot;Amount&quot;).Predicates(pred).toXML()
    &#39;sele = SEL.Fields(&quot;BudgetId&quot;).Fields(&quot;Amount&quot;).Predicates(PRE.Field(&quot;CampaignId&quot;).Operator(&quot;=&quot;).Value(campaignID).toXML()).toXML()

    Dim bid As Long
    bid = 2199199
    Dim amt As Long
    amt = 1000000
    Dim oper As String
    oper = OPE.Operator(&quot;SET&quot;).Field(&quot;budgetId&quot;).Value(bid).Amount(amt).toXML()

    Debug.Print pred
    Debug.Print sele
    Debug.Print oper
&lt;/pre&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;outputting&lt;/span&gt;&lt;pre class=&#39;source-code&#39;&gt;&amp;lt;field&amp;gt;CampaignId&amp;lt;/field&amp;gt;&amp;lt;operator&amp;gt;EQUALS&amp;lt;/operator&amp;gt;&amp;lt;values&amp;gt;1000222&amp;lt;/values&amp;gt;
 &amp;lt;fields&amp;gt;BudgetId&amp;lt;/fields&amp;gt;&amp;lt;fields&amp;gt;Amount&amp;lt;/fields&amp;gt;&amp;lt;predicates&amp;gt;&amp;lt;field&amp;gt;CampaignId&amp;lt;/field&amp;gt;&amp;lt;operator&amp;gt;EQUALS&amp;lt;/operator&amp;gt;&amp;lt;values&amp;gt;1000222&amp;lt;/values&amp;gt;&amp;lt;/predicates&amp;gt;
 &amp;lt;operations&amp;gt;&amp;lt;operator&amp;gt;SET&amp;lt;/operator&amp;gt;&amp;lt;operand&amp;gt;&amp;lt;budgetId&amp;gt;2199199&amp;lt;/budgetId&amp;gt;&amp;lt;amount&amp;gt;&amp;lt;microAmount&amp;gt;1000000&amp;lt;/microAmount&amp;gt;&amp;lt;/amount&amp;gt;&amp;lt;/operand&amp;gt;&amp;lt;/operations&amp;gt;
&lt;/pre&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;Okay, that&#39;s it. A long-winded posting, this one. If you have any questions, use the comments.&lt;br /&gt;&lt;br /&gt;Enjoy!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: georgia;font-size: xx-small;&quot;&gt;&lt;i&gt;&amp;copy; Copyright Bruce M. Axtens, 2015&lt;/i&gt;&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeaholic.blogspot.com/feeds/4849449196206572717/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/15254360/4849449196206572717' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default/4849449196206572717'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default/4849449196206572717'/><link rel='alternate' type='text/html' href='http://codeaholic.blogspot.com/2015/10/vb6-what-about-me-aka-method-chaining.html' title='[VB6] What about Me a.k.a. Method Chaining a.k.a. Fluent VB6'/><author><name>Bruce M. Axtens</name><uri>http://www.blogger.com/profile/14797830611260628579</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15254360.post-5936167826884483785</id><published>2015-09-28T23:25:00.000+08:00</published><updated>2015-09-29T10:30:14.028+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="htmlfile"/><category scheme="http://www.blogger.com/atom/ns#" term="Internet Explorer"/><category scheme="http://www.blogger.com/atom/ns#" term="jQuery"/><category scheme="http://www.blogger.com/atom/ns#" term="JScript"/><category scheme="http://www.blogger.com/atom/ns#" term="WinHttp"/><title type='text'>[JScript] jQuery without IE</title><content type='html'>&lt;!-- [JScript] jQuery without IE ---&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;For those who looked, this is mod of plasticgrammer&#39;s post. Most of the comments are Google Translates attempts at the original programmer&#39;s Japanese. &lt;br /&gt;
&lt;br /&gt;
The single biggest difference from the previous posting is that Internet Explorer is not called into to manage jQuery. Instead the &lt;code&gt;htmlfile&lt;/code&gt; object is used.&lt;br /&gt;
&lt;br /&gt;
jQuery expects a few global symbols (it is after all a browser library), so the beginning of the code declares them: &lt;code&gt;document&lt;/code&gt;, &lt;code&gt;window&lt;/code&gt; etc. Then the jQuery file is dragged across the internet and eval&#39;d in the context of the script.&lt;br /&gt;
&lt;br /&gt;
You&#39;ll notice that the jQuery version is quite ancient. This is another problem with this approach. I imagine that it&#39;s just a case of declaring some more public symbols. If anyone tries this, please let me know how recent you can go before things break. And if you succeed in using more recent jQuery libraries, please do let me know what modifications were required.&lt;/span&gt;&lt;pre class=&#39;source-code&#39;&gt;// To prepare, such as window or document to the global name space
(function (url) {
  if (&quot;undefined&quot; === typeof document)
    document = new ActiveXObject(&quot;htmlfile&quot;);
  document.write(&quot;&lt;&quot; + &quot;html&quot; + &quot;&gt;&quot; + &quot;&lt;&quot; + &quot;/html&gt;&quot;); // this important
  if (&quot;undefined&quot; === typeof window)
    window = document.parentWindow;
  if (&quot;undefined&quot; === typeof alert)
    alert = function (s) {
      return window.alert(s);
    };
  if (&quot;undefined&quot; === typeof confirm)
    confirm = function (s) {
      return window.confirm(s)
    };
  if (&quot;undefined&quot; === typeof location)
    location = window.location;
  if (&quot;undefined&quot; === typeof navigator)
    navigator = window.navigator;
  if (&quot;undefined&quot; === typeof window.ActiveXObject)
    window.ActiveXObject = ActiveXObject;

  var XMLHttpRequest = new ActiveXObject(&quot;WinHttp.WinHttpRequest.5.1&quot;);
  var o = XMLHttpRequest.open(&quot;GET&quot;, url, false);
  var s = XMLHttpRequest.send();
  eval(XMLHttpRequest.ResponseText);
  return true;
})(&quot;http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.js&quot;);
&lt;/pre&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;Now a bit of demo code. Notice how we tell JScript what &lt;code&gt;$&lt;/code&gt; means. Possibly that could go in the earlier block of code as yet another global.&lt;/span&gt;&lt;pre class=&#39;source-code&#39;&gt;var $ = window.$;

// Operation example of a simple jQuery object
WScript.Echo($(&quot;&lt;&quot; + &quot;div&quot; + &quot;&gt;&quot;).attr(&quot;a&quot;, &quot;fo&quot;).get(0).outerHTML);

// Course alert even I can use.
alert($(&quot;&lt;&quot; + &quot;div&quot; + &quot;&gt;&quot;).attr(&quot;a&quot;, &quot;fo&quot;).get(0).outerHTML);
&lt;/pre&gt;&lt;span style=&quot;font-family: georgia;font-size: normal;&quot;&gt;(Blogspot didn&#39;t like seeing &lt;code&gt;div&lt;/code&gt; etc as markup, thus the odd syntax).&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: georgia;font-size: xx-small;&quot;&gt;&lt;i&gt;&amp;copy; Copyright Bruce M. Axtens, 2015&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
</content><link rel='replies' type='application/atom+xml' href='http://codeaholic.blogspot.com/feeds/5936167826884483785/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/15254360/5936167826884483785' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default/5936167826884483785'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15254360/posts/default/5936167826884483785'/><link rel='alternate' type='text/html' href='http://codeaholic.blogspot.com/2015/09/jscript-jquery-without-ie.html' title='[JScript] jQuery without IE'/><author><name>Bruce M. Axtens</name><uri>http://www.blogger.com/profile/14797830611260628579</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>