Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!

random option for for loops? /m?

Jul
516
10
Could we please have an option that processes the items in a for loop in random order?

There’s an infinite # of use cases for this, but to put it the most abstract terms possible:

  • Say you have a list of 10,000 tasks to do. [Files to process. People to call. Games to play. Items to purchase. Whatever.]
  • Say you can only process 100 at a time. [Maybe it takes an hour.]
  • Say the items are alphabetized [Maybe a lists of names, or files, YYYYMMDD dates, etc)
  • Some people deliberately want their queues handled via LIFO or FIFO.
  • But if you don’t, doing things in alphabetical order creates a huge bias towards things at the beginning of the alphabet
My specific example?

1) Gathering lyrics for songs without lyrics. I’m dealing with an audit script that generates 3000+ get-lyrics commands. If I spend a week doing this, do I want all my effort concentrated on the A, B, Cs?

2) Another example: Copying a playlist of music to a USB drive for listening to music in your car. If the playlist’s size exceeds the size of the USB drive, guess what? You’re never going to hear your X-Ray Spex or your Wrathchild America or your White Stripes or your Ween, because your usb drive ran out of space before you got to the end of the alphabet. [My playlist-sync script copies in random order to avoid this!]

3) FTP uploads. Ever notice the glut of folders on FTP servers that are alphabetically biased? You find that one person who has all the cool 1918 songs and you download them from that person, only to see there’s 900 songs ranging from A-S, and 0 songs ranging from T-Z. Their upload aborted and they didn’t notice. T-Z is now dead. If only they had used random order, the bias wouldn’t exist.

4) Folder searching / searching in general. Sometimes I need to find a folder that meets a certain criteria, one that must be calculated. It is rare that this criteria magically aligns with the alphabet. This basically delves into search algorithm comparisons, but it basically makes a search that is closer to O(n/2) become closer to O(n) than it otherwise would be. If it’s something that tends to affect later folders (like if folders are YYYYMMDD dates, and a process changed at a certain date, so only later folders apply) ..... In that situation, starting first alphabetically is the slowest way to find it. (Indeed, going backwards might be the fastest! But we have DO for that.)

5) Playlists. Of course most players have a shuffle button, but if we are playing a list of files via script, a 1-character-per-for-loop option would make life soooooo much easier.

6) Custom randomizations. We may want to select a random value from a list of values that has many gaps in it. %@RANDOM can’t handle something like that, but we could get a random value back like this. Would sort of be a mis-use, but a fun one.




[ As for the letter to represent the option..... /R, /A, /N, /D, /O are all taken, but not /M ]


This may apply to other loops too, but i’m mostly personally looking at for.

I keep having to randomize files as an intermediate step and just keep thinking how the for command itself could be the one handling the randomosity. Would smooth things over for people in situations, I think.
 
I can help if I knew exactly what you want to do ... process the lines of a file (excluding blank ones) in random order?

There are so many possibilities that I doubt you're going to see it built-in ...

process the lines of a file randomly (do x in @file)

process 1 to N randomly (do i=1 to N)

process a list randomly (do x in /L a b c d e )

process the characters in a string randomly (do x in /C abcde)

I'll be back in a little while showing how to do the non-empty lines of a file.
 
Here's an example of processing (echoing) the non-empty lines of a file in random order. It relies on a random permutation of 0 through %@lines[<file>]. The BTM is after the example.

Code:
v:\> type 1to10.txt
1

2

3

4

5

6

7

8

9

10


v:\> randomlines.btm 1to10.txt
10
5
7
3
9
6
4
2
8
1

Code:
v:\> type randomlines.btm
setlocal
set file=%1
set nLast=%@lines[%file]
set nLines=%@inc[%nLast]
setarray /f a[%nLines]

:: initialize array to 1 2 3 4 ...
do i=0 to %nLast ( set a[%i]=%i )

gosub RandomizeArray

:: echo the non-empty lines in random order
do i=0 to %nLast
    if "%@line[%file,%a[%i]]" != "" echo %@line[%file,%a[%i]]
enddo

quit

:: swap each line with a random one after it
:RandomizeArray
do i=0 to %@dec[%nLast]
    set j=%@random[%@inc[%i],%nLast]
    set tmp=%a[%i]
    set a[%i]=%a[%j]
    set a[%j]=%tmp
enddo
 
Here's a new randomlines.btm. It uses SETDOS which helps.

Code:
v:\> type randomlines.btm
setlocal
setdos /x-145678

set file=%1
set nLast=%@lines[%file]
set nLines=%@inc[%nLast]
setarray /f a[%nLines]
do i=0 to %nLast ( set a[%i]=%i )

gosub RandomizeArray

:: echo the non-empty lines in random order
do i=0 to %nLast
    if "%@line[%file,%a[%i]]" != "" echo %@line[%file,%a[%i]]
enddo
setdos /x+145678

quit

:: swap each with a random one below
:RandomizeArray
do i=0 to %@dec[%nLast]
    set j=%@random[%@inc[%i],%nLast]
    set tmp=%a[%i]
    set a[%i]=%a[%j]
    set a[%j]=%tmp
enddo
 
Oh, I have random line selectors and file scramblers already... It’s just so trivial to have to stop and do that every time when we could just have a /M option to go through the items in random order. Of course we could randomize the order ourselves.

But easier is better than hard. I think it’s a good improvement.
 
Back
Top