Photo Gallery Member List Search Calendars FAQ Ticket List Log Out


RE: Weekly/Monthly Challenge?

 
Logged in as: Guest
arrSession:exec spGetSession 2,9,47585
 Active Users: There are 0 members and 0 guests.
 Users viewing this topic: none
 

 

 
  
  Printable Version
All Forums >> [General Forum] >> Off-Topic Lounge >> RE: Weekly/Monthly Challenge?
  Do you like VisualBasicScript.com? Link to us and help spread the word about our forum. Thanks!
Page: <<   < prev  1 [2] 3   next >   >>
Login
Message << Older Topic   Newer Topic >>
 RE: Weekly/Monthly Challenge? - 6/26/2007 6:51:28 PM   
  ginolard


Posts: 965
Score: 21
Joined: 8/10/2005
Status: offline
I deny everything.

_____________________________

Author of ManagePC - http://managepc.net
AD Query Template - http://www.visualbasicscript.com/m_40609/tm.htm
Consolidated Scripting Framework - http://www.visualbasicscript.com/m_59109/tm.htm

(in reply to DiGiTAL.SkReAM)
 
 
Post #: 21
 
 RE: Weekly/Monthly Challenge? - 6/27/2007 12:16:10 AM   
  DiGiTAL.SkReAM


Posts: 1056
Score: 6
Joined: 9/6/2005
From: Florida, USA
Status: offline
You're just in denial.

_____________________________

"There's the one man who learns by reading, the two men that learn by watching, and the rest of us have to pee on the electric fence for ourselves." - Roy Rogers

"Would you like to touch my monkey?" - Dieter (Mike Meyers)

(in reply to ginolard)
 
 
Post #: 22
 
 RE: Weekly/Monthly Challenge? - 7/12/2007 3:04:52 AM   
  mcds99


Posts: 395
Score: 4
Joined: 2/28/2006
Status: offline
LOLROF! You went so far beyond me I just have to smile or cry, haven't figured out which ;-D

quote:

ORIGINAL: ehvbs

[shameless attempt to get some attention for this topic]

This looks like becoming a yearly challenge!

[no offense meant]


_____________________________

Sam

Keep it Simple Make it Fun KiSMiF

(in reply to ehvbs)
 
 
Post #: 23
 
 RE: Weekly/Monthly Challenge? - 7/12/2007 8:27:08 PM   
  ginolard


Posts: 965
Score: 21
Joined: 8/10/2005
Status: offline
Hey, Digital Skream.  I've only noticed the irony of your sig.  Did you write it like that on purpose?

_____________________________

Author of ManagePC - http://managepc.net
AD Query Template - http://www.visualbasicscript.com/m_40609/tm.htm
Consolidated Scripting Framework - http://www.visualbasicscript.com/m_59109/tm.htm

(in reply to mcds99)
 
 
Post #: 24
 
 RE: Weekly/Monthly Challenge? - 7/13/2007 10:01:23 PM   
  TNO


Posts: 974
Score: 10
Joined: 12/18/2004
From: thenewobjective.com
Status: offline
I'm out of practice horribly (bad excuse), but here's my attempt, don't beat me too hard:


      

Using JS.Array Component: http://thenewobjective.com/website/development/VBScript/Components/vbsArrays

_____________________________

Consolidated Script Component: Now in Testing stage!

A universe of complexity...

(in reply to ginolard)
 
 
Post #: 25
 
 RE: Weekly/Monthly Challenge? - 7/15/2007 11:38:04 PM   
  DiGiTAL.SkReAM


Posts: 1056
Score: 6
Joined: 9/6/2005
From: Florida, USA
Status: offline
quote:

ORIGINAL: ginolard

Hey, Digital Skream.  I've only noticed the irony of your sig.  Did you write it like that on purpose?

Yes, I did.

_____________________________

"There's the one man who learns by reading, the two men that learn by watching, and the rest of us have to pee on the electric fence for ourselves." - Roy Rogers

"Would you like to touch my monkey?" - Dieter (Mike Meyers)

(in reply to ginolard)
 
 
Post #: 26
 
 RE: Weekly/Monthly Challenge? - 7/19/2007 11:05:09 AM   
  ehvbs

 

Posts: 1843
Score: 46
Joined: 6/22/2005
From: Germany
Status: offline
Hi all virtual and real participants,

to give TNO's contribution its due and (perhaps) to lure some other people to
this topic, I want to show you the script I currently use to tinker with the
problem.

To explain the structure of my test scripts and the reasons for it, I'd like
to point you to the very simple program I posted for the second challenge.
Comparing this to the more elaborate version may help you to make sense of
my remarks.

As I very/too often said, I start all my scripts with

   Option Explicit

to avoid problems due to misspelled variable names; furthermore Dimming
my variables forces me to think about them very carefully. Do I really need
it? Could I avoid a variable by using an expression or a function? In which
scope the variable must be known? Some people like to Dim all their variables
at once and initialize them later/as needed:

   Dim oFSO, i, iIterations, x, t1, t2, t3, e1, e2, e3, iNumItems
   Set oFSO = CreateObject("Scripting.FileSystemObject")
   ...
   iIterations = 3

I prefer to keep Dimming (=Declaring) and intializing close together, because
this may serve as a kind of documentation for the variable(s):

   Dim oFSO : Set oFSO = CreateObject("Scripting.FileSystemObject")
   ...
   Dim iIterations : iIterations = 3

As close as possible to its first use I associate the variable name with its
data type and its (first/start) value, hoping to make it easy for my feeble
memory. Do you want to comment on

   Dim i, j

, TNO?

While I'm aware of the problems caused by global variables, I will use
them, if I think it advantageous. To make them stand out, I use a "g"
prefix in their names:

   Dim goTNOArray2 ' needed for TNOJoin()

For two reasons, I restrict my main/top level code to the Dimming of global
variables and the returning of an error/success code to the operating system:

   WScript.Quit doMain()

The first reason: That way I can easily run different portions of code - tackling
various sub problems or trying out different soultions - from the same .vbs file
by writing more than one 'main' function and using reordering or commenting to
switch between them:

   WScript.Quit doThis()  | WScript.Quit doThat() | ' WScript.Quit doThis()
   WScript.Quit doThat()  | WScript.Quit doThis() |   WScript.Quit doThat()

The second reason: That way I can't introduce global variables 'by accident'.
If I had Dimmed sSep at the top level, then using it in the toDispString( vX )
function would be very tempting

   Case 8204           '      Array of Variants
     sRVal = "[" + OURJoin( vX, "," ) + "]"
==>
     sRVal = "[" + OURJoin( vX, sSep ) + "]"

As it is, I can't use this easy way out, but have to acknowledge the pending
problem: Is it ok to hard code the inner separator or must I feed it to the
function via parameter? Do I really want to implement a toDispString( vX, sSep )
or even a toDispString( vX, aSeps ) function to handle (deeply) nested arrays?

So a typical main function looks like this:

   Function doMain()
     Dim nRval  : nRVal = 0
     ...
     WScript.Echo "##### VBScript Forum Challenge 001: JoinX"
     ...
     doMain = nRVal
   End Function

The return/error code feature isn't used in most of my test scripts, but it
proved valuable for 'real world' scripts that are scheduled or used from other
programs.

Testing/trying out means testing/trying more than one thing. So most test
scripts use a simple

     ' the strings we want to test
     Dim aTStrs : aTStrs = Array( _
         "" _
       , "a b c" _
                                )

or a more complicated/structured array of data

     ' the arrays we want to test (each one named for easy reference)
     Dim aTArrs : aTArrs = Array( _
         "empty"       , Array() _
       , "one string"  , Array( "a" ) _
      ...
       , "objects"     , Array( New RegExp, CreateObject( "ADODB.Connection" ), oObj, Err ) _
                                )

to be fed to the code/functions. This setup and the effort put into the formatting
makes it easy to add interesting/critical test cases. Of course the structure of
the data is reflected in the code to loop over them. For simple arrays simple loops:

     ' loop over all strings to test
     For Each sTest In aTStrs
         ...
     Next

for implicitly structured arrays, the Step feature of the For loop comes handy:

     ' loop over all arrays to test
     For nTArr = 0 To UBound( aTArrs ) Step 2
         ...
         WScript.Echo "=====", nTArr / 2, "Array:", aTArrs( nTArr ) ' <-- the name
         ...
             sRes     = fncJ( aTArrs( nTArr + 1 ), sSep ) ' <-- the array to feed to the function
         ...
     Next

Explicitly structured arrays

     ' the different versions of JoinX( aX, sSep )
     Dim aFuncs : aFuncs = Array( _
         Array( "VBS Join", GetRef( "VBSJoin" ), "|" ) _
       , Array( "TNO Join", GetRef( "TNOJoin" ), "|" ) _
       , Array( "Our Join", GetRef( "OurJoin" ), "|" ) _
                                )

can be looped over by For (+ index):

     ' loop over all functions to use
     For nFunc = 0 To UBound( aFuncs )
         WScript.Echo "-----", nFunc, "Function:", aFuncs( nFunc )( 0 )
         Set fncJ = aFuncs( nFunc )( 1 ) ' the function used
         sSep     = aFuncs( nFunc )( 2 ) ' the separator used for display
         sRes     = fncJ( aTArrs( nTArr + 1 ), sSep ) ' call the function
         WScript.Echo ">|" + sRes + "|<"
     Next

or by For Each:

     Dim aFunc
     For Each aFunc In aFuncs
         WScript.Echo "----- Function:", aFunc( 0 )
         Set fncJ = aFunc( 1 ) ' the function used
         sSep     = aFunc( 2 ) ' the separator used for display
         sRes     = fncJ( aTArrs( nTArr + 1 ), sSep ) ' call the function
         WScript.Echo ">|" + sRes + "|<"
     Next

If you don't need a numeric index variable, For Each is more convenient; but
changing elements needs For, because the For Each variable is a copy. Run

       Function ForForEach()
         Dim aTest : aTest = Array( "zero", "one", "two" )
         Dim nIdx  : nIdx  = 0
         Dim sTest
         For Each sTest In aTest
             sTest = CStr( nIdx )
             nIdx  = nIdx + 1
         Next
         WScript.Echo "For Each", Join( aTest )
         For nIdx = 0 To UBound( aTest )
             aTest( nIdx ) = CStr( nIdx )
         Next
         WScript.Echo "For     ", Join( aTest )
         ForForEach = 0
       End Function

to see the difference.

       For Each zero one two
       For      0 1 2

The script demonstrates 3 Join functions: The VBScript Join() that fails
even for simple cases:

       ===== 2 Array: the empties
       ----- Function: VBS Join
       >|Typen unverträglich|<    i.e. Type mismatched caused by Null
       ----- Function: TNO Join
       >|[vbEmpty]|[vbNull]|[vbObject]|<
       ----- Function: Our Join
       >|<Empty>|<Null>|<Nothing>|<

I don't want to spend further words on this miserable thing. The second
functions is (my revision of) TNO's Join() function, that really is an
significant improvement. The nits I feel the need to pick don't lower
its value - that goes without saying.

No surprise, that I don't like the use of the global variable (though - as
I said before - I use them myself if they are proved necessary). How could
goTNOArray2 be avoided? By passing the second array as an parameter:

(1) add an element to aFuncs

     Dim aFuncs : aFuncs = Array( _
         Array( "VBS Join", GetRef( "VBSJoin" )    , "|" ) _
       , Array( "TNO Join", GetRef( "TNOJoin" )    , "|" ) _
       , Array( "TNO NOGV", GetRef( "TNOJoinNOGV" ), "|" ) _
       , Array( "Our Join", GetRef( "OurJoin" )    , "|" ) _

(2) add a nonrecursive 'entry' function:

       ''# TNOJoinNOGV - calls TNO's Join (no global variable)
       ' ############################################################################
       Function TNOJoinNOGV( ByRef Array1, Sep )
         TNOJoinNOGV = TNOJoinNOGV_( Array1, Array(), Sep )
       End Function

(3) that passes the second array to the recursive work function:

       Function TNOJoinNOGV_( Array1, Array2, Sep )
         Dim JS : Set JS = CreateObject( "JS.Array" )
         Dim i, j

         For Each i In Array1
             If IsArray(i) Then
                TNOJoinNOGV_ i, Array2, Sep
             Else
                Select Case VarType(i)
                  Case  0 JS.Push Array2, "[vbEmpty]"
                  Case  1 JS.Push Array2, "[vbNull]"
                  ...
                  Case 13 JS.Push Array2, "[vbDataObject]"
                  Case 17 JS.Push Array2, CStr(i)
                End Select
             End If
         Next

         TNOJoinNOGV_ = Join( Array2, Sep )
       End Function

Compare this to OURJoin

   ''# OURJoin - crossbred of contributions
   ' ############################################################################
   Function OURJoin( aX, sSep )
     ReDim aClone( UBound( aX ) )
     Dim   nIdx : nIdx = 0
     Dim   vElm
     For Each vElm In aX
         aClone( nIdx ) = toDispString( vElm )
         nIdx           = nIdx + 1
     Next
     OURJoin = Join( aClone, sSep )
   End Function

that uses a second array too - but one that is dimensioned suitably right from
the start (no need for growing/push) and keeps it local (no parameter passing
to the recursive work function toDispString()).

My verdict on the reliance on the JS.Array component is the same as what I said
about ginolard's use of the .NET System.Collections.ArrayList. Non native VBScript
means are ok if unavoidable, but I'd prefer a 'pure' solution. In TNO's case
the foreign component is used only to make the dynamic growing of the second array
more efficient. But that isn't necessary: We know the UBound of the second array
beforehand - we nead exactly as many elements as the first one contains:

   ''# TNOJoinNOJS - calls TNO's Join (no JS.Array)
   ' ############################################################################
   Function TNOJoinNOJS( ByRef Array1, Sep )
     ReDim Array2( UBound( Array1 ) )
     TNOJoinNOJS = TNOJoinNOJS_( Array1, Array2, Sep )
   End Function

   Function TNOJoinNOJS_( Array1, Array2, Sep )
     Dim JS   : Set JS = CreateObject( "JS.Array" )
     Dim nIdx : nIdx   = 0
     Dim vElm

     For Each vElm In Array1
         If IsArray( vElm ) Then
            Array2( nIdx ) = TNOJoinNOJS( vElm, Sep )
         Else
            Select Case VarType( vElm )
              Case  0 Array2( nIdx ) = "[vbEmpty]"
              Case  1 Array2( nIdx ) = "[vbNull]"
              Case  2 Array2( nIdx ) = CStr( vElm )
              Case  3 Array2( nIdx ) = CStr( vElm )
              Case  4 Array2( nIdx ) = CStr( vElm )
              Case  5 Array2( nIdx ) = CStr( vElm )
              Case  6 Array2( nIdx ) = CStr( vElm )
              Case  7 Array2( nIdx ) = CStr( vElm )
              Case  8 Array2( nIdx ) = vElm
              Case  9 Array2( nIdx ) = "[vbObject]"
              Case 10 Array2( nIdx ) = "["&CStr( vElm )&"]"
              Case 11 Array2( nIdx ) = CStr( vElm )
              Case 12 Array2( nIdx ) = "[vbVariant]"
              Case 13 Array2( nIdx ) = "[vbDataObject]"
              Case 17 Array2( nIdx ) = CStr( vElm )
            End Select
         End If
         nIdx = nIdx + 1
     Next

     TNOJoinNOJS_ = Join( Array2, Sep )
   End Function

I'm not happy with the use of magic numbers instead of the predefined VBScript
constants:

   Case vbEmpty        '    0 Uninitialized (default)
     sRVal = "<Empty>"

may be more characters to enter than

   Case  0 Array2( nIdx ) = "[vbEmpty]"

but you write a script once (or - if you are like me - about 12 times),
but you resp. your clients read it 4711 times. Think of all the time wasted
to remember/check that VarType 0 means Empty (and not Null).

As most of the solutions presented here, TNO's function flattens arrays of
arrays:

   "nested arrs" , Array( Array( 1, 2, 3 ), Array( "one", "two", "three" ) ) _

   ===== 3 Array: nested arrs
   ----- Function: VBS Join
   >|Typen unverträglich|<
   ----- Function: TNO Join
   >|1|2|3|one|two|three|<
   ----- Function: TNO NOGV
   >|1|2|3|one|two|three|<
   ----- Function: TNO NOJS
   >|1|2|3|one|two|three|<
   ----- Function: Our Join
   >|[1,2,3]|["one","two","three"]|<

So perhaps this should be considered a feature.

All my usual carping must not hide the fact that the third function -
OURJoin() - wouldn't exist without all your contributions to this topic.
It's much easier to program on the base of concrete working code than
doing it from scratch. All fame and glory is due to the participants;
extra thanks to TNO for his code (and the JS.Array which downloaded,
installed and worked flawlessly for me). I just crossbred all the
suggestions with some of my own thoughts. For example my very first
version of the JoinX() function used string concatenation, DiGiTAL.SkReAM's
dictionary approach and dm_4ever's use of Split and ReDim made me realize
the (irony of the) possibility to let VBScript's Join() do the concatenation.
Likewise there would be no dictionary joining without ebgreen. And I'm still
waiting for ginolard to come up with some String.Join( ArrayList, "," ) magic
to make OURJoined effort obsolete.

I think that splitting the joining into a 'put together' loop (see above)
and a 'handle each element according to its data type' part (see below)
makes the code easy to understand. mcds99, don't cry! You would make me
happy/smile, if you could post some questions as to the what, how, and why
of the code that forces me to make the code better (to comprehend). There
are some points worth discussing in the monster Select Case. Should the
(german) "," really replaced with "." in real numbers? Would it be
necessary to check the locale? Should dates be delimited? Should strings be
not delimited? How to discriminate between a plain date and the datetime
midnight?

Ok, it's after midnight in Germany - here is all the code:


      

And the output


      

What still needs to be done:

(1) All Join functions strive to display the elements of the array; I would
   like to have a second version (JoinY (?)) that returns a string that
   could be fed to Eval() - as a kind of (simple) persistency feature.
   [I was not amused when ebgreen hijacked the persistency problem in
       http://www.visualbasicscript.com/fb.aspx?m=49431
    and even mentioned XML - I had to revise my second challenge (see
    below)]

(2) Some objects - with default properties - are difficult/impossible
   to display:

       "objects"     , Array( New RegExp, CreateObject( "ADODB.Connection" ), oObj, Err )

       ===== 7 Array: objects
       ----- 0 Function: VBS Join
       >|Das Objekt unterstützt diese Eigenschaft oder Methode nicht.|<
       ----- 1 Function: TNO Join
       >|[vbObject]||[vbObject]|0|<
       ----- 2 Function: Our Join
       >|RegExp-Obj|""|FileSystemObject-Obj|0|<

   Just now I can't even think of a way to identify these nasty cases.

(3) How about arrays of more than one dimension?

But perhaps you feel bored by this challenge or think the problem isn't worth
further discussion. In that case look at my next posting!

Thanks again for all the input - and my apologies for the number of lines!

ehvbs

(in reply to DiGiTAL.SkReAM)
 
 
Post #: 27
 
 RE: Weekly/Monthly Challenge? - 7/19/2007 11:06:17 AM   
  ehvbs

 

Posts: 1843
Score: 46
Joined: 6/22/2005
From: Germany
Status: offline
Hi all who would like another challenge!

The VBScript Split() function is nice. Lots of sample of its creative
use in this forum. But other languages - notably Perl - provide an even
nicer split(): one that allows a regular expression to be used instead of
a mere string.

The easy version of the challenge: Write a

Split( expression, regexp|regexp.pattern )

function that uses a regexp(.pattern) - e.g. "[,;:]" - to split a
string - e.g "a,b;c:d" - into an array ["a","b","c","d"]. To motivate
you: Think of something like:

  aParts = SplitRE( "19.07.2007 22:01:03", "[. :]" )

The more complex task: Write a

Split(expression[, regexp|regexp.pattern[, count[, compare]]])

function that mimics the VBScript Split() regarding the fancy options.

For even more ambitious persons: try to implement some of the Perl
features like splitting a string into an array of its characters or
the option to return the separators as well.

Not to predetermine your approach, but simply to give you an idea
of how to start: this is my test script that eagerly waits for your
ideas/code/input:


      

As you can see, I included (commented out) a call to OURJoin() as an advertisement
for the first challenge.

ehvbs

(in reply to ehvbs)
 
 
Post #: 28
 
 RE: Weekly/Monthly Challenge? - 7/19/2007 12:39:20 PM   
  dm_4ever


Posts: 1944
Score: 30
Joined: 6/29/2006
From: Orange County, California
Status: offline
I'll take a shot when I get the chance...man...your thought process...it is something else.

_____________________________

dm_4ever

My philosophy: K.I.S.S - Keep It Simple Stupid
Read Me: http://www.visualbasicscript.com/m_24727/tm.htm
Frequently Asked Stuff: http://www.visualbasicscript.com/m_47117/tm.htm

(in reply to ehvbs)
 
 
Post #: 29
 
 RE: Weekly/Monthly Challenge? - 7/19/2007 7:13:04 PM   
  ginolard


Posts: 965
Score: 21
Joined: 8/10/2005
Status: offline
Ooh, this one is more interesting.  Primarily because it helps me learn more about RegEx

Anyway, here's a first crack at the simple one.  


      

< Message edited by ginolard -- 7/19/2007 7:50:24 PM >


_____________________________

Author of ManagePC - http://managepc.net
AD Query Template - http://www.visualbasicscript.com/m_40609/tm.htm
Consolidated Scripting Framework - http://www.visualbasicscript.com/m_59109/tm.htm

(in reply to dm_4ever)
 
 
Post #: 30
 
 RE: Weekly/Monthly Challenge? - 7/19/2007 9:11:32 PM   
  ehvbs

 

Posts: 1843
Score: 46
Joined: 6/22/2005
From: Germany
Status: offline
Hi ginolard,

thanks a lot! Very promising approach and nice implementation! I incorporated your
function into my test script (I removed the joining part to keep the function compatible
to VBScript's Split()). Doing this, I had to realize that my simple plain array setup
for the test cases doesn't scale: the split pattern has to be specified too. My quick
and dirty revison


      

isn't really satisfactory, but its output


      

shows that

    objDict.Add Mid(StringToSearch,PreviousExpressionIndex + 2,(expressionmatched.FirstIndex - PreviousExpressionIndex)-1),"foo"
    ...
    objDict.Add Mid(StringToSearch,PreviousExpressionIndex + 2),"foo"

needs reconsidering. As you want to learn about RegExps - have a look at the properties of the Match object:
isn't there a .Length?

Thanks again for your quick and definitely not dirty solution!

ehvbs

  

(in reply to ginolard)
 
 
Post #: 31
 
 RE: Weekly/Monthly Challenge? - 7/19/2007 9:18:36 PM   
  ginolard


Posts: 965
Score: 21
Joined: 8/10/2005
Status: offline
I'll have to check it out.  I'm sure there is a better way of doing it.  That code was more a "proof of concept" ;)

_____________________________

Author of ManagePC - http://managepc.net
AD Query Template - http://www.visualbasicscript.com/m_40609/tm.htm
Consolidated Scripting Framework - http://www.visualbasicscript.com/m_59109/tm.htm

(in reply to ehvbs)
 
 
Post #: 32