Jump to content

I want to randomize a list


Recommended Posts

I have a file, database.txt, that looks like:

123456789;avi1.avi

987654321;avi2.avi

456789123;avi3.avi

The numbers represent a barcode and the avi is a video of the product in use. My script counts the number of lines in the database.txt file at the start of the program. The number of lines in the database.txt changes when there are new videos added to the file. I want to count the lines in the txt file and then play each video randomly but at least once per loop. I then want the list randomized again (not the same as last time) and continue playing the videos in a new order. How can I get autoit to do this?

Get Scite to add a popup when you use a 3rd party UDF -> http://www.autoitscript.com/autoit3/scite/docs/SciTE4AutoIt3/user-calltip-manager.html

Link to comment
Share on other sites

To get a randomized entry of your list I would do something like:

$iCount = n ; Number of entries in your list
$iPlay = Random(1, $iCount, 1)

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (NEW 2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to comment
Share on other sites

Search the forum for random permutation

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

>This example of jchd looks quite promising.

So read the file into an array, sort it as described in the linked to script and then process the array from start to end. Use RunWait to play each video with VLC.

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (NEW 2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to comment
Share on other sites

Use RunWait to play each video with VLC.

If VLC doesn't close after each video has finished, then RunWait probably won't be what he wants.

Better still, to send the randomly sorted array to a text file, that has the .m3u extension, and get VLC to play that, as it supports various Playlist file types.

Make sure brain is in gear before opening mouth!
Remember, what is not said, can be just as important as what is said.

Spoiler

What is the Secret Key? Life is like a Donut

If I put effort into communication, I expect you to read properly & fully, or just not comment.
Ignoring those who try to divert conversation with irrelevancies.
If I'm intent on insulting you or being rude, I will be obvious, not ambiguous about it.
I'm only big and bad, to those who have an over-active imagination.

I may have the Artistic Liesense ;) to disagree with you. TheSaint's Toolbox (be advised many downloads are not working due to ISP screwup with my storage)

userbar.png

Link to comment
Share on other sites

I'm sure VLC closes after the filename passed as command line parameter has been played.

But the playlist still seems to be the better idea :)

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (NEW 2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to comment
Share on other sites

I'm sure VLC closes after the filename passed as command line parameter has been played.

Indeed, it probably would do ... perhaps with or without a switch.

The playlist also solves any issues of delays between startups of each instance of VLC, by only having the one.

Make sure brain is in gear before opening mouth!
Remember, what is not said, can be just as important as what is said.

Spoiler

What is the Secret Key? Life is like a Donut

If I put effort into communication, I expect you to read properly & fully, or just not comment.
Ignoring those who try to divert conversation with irrelevancies.
If I'm intent on insulting you or being rude, I will be obvious, not ambiguous about it.
I'm only big and bad, to those who have an over-active imagination.

I may have the Artistic Liesense ;) to disagree with you. TheSaint's Toolbox (be advised many downloads are not working due to ISP screwup with my storage)

userbar.png

Link to comment
Share on other sites

Maybe something like this will help you.

;#include <Array.au3> ; For _ArrayDisplay() use only.

HotKeySet("!{ESC}", "Terminate") ; Press Alt and Esc keys to exit.

Local $aVideoArray, $i, $sFileContents

; Will use updated "database.txt" file at the beginning of each While-Wend loop.
While 1
    $sFileContents = "123456789;avi1.avi" & @LF & "987654321;avi2.avi" & @LF & "456789123;avi3.avi"
    ; Or
    ;$sFileContents = FileRead("database.txt") ; <---------------- Enter File Name of Video list  
    $aVideoArray = StringRegExp($sFileContents, ";([^\v]+)", 3)
    _ArrayShuffle($aVideoArray)
    ;_ArrayDisplay($aVideoArray)
    For $i = 0 To UBound($aVideoArray) - 1
        If FileExists($aVideoArray[$i]) Then ShellExecute($aVideoArray[$i]) ; Will use the application associated with the file extension.
    Next
WEnd


Func _ArrayShuffle(ByRef $aArr)
    Local $iNo = UBound($aArr) - 1, $iRndNdx, $Temp, $Num
    For $Num = 0 To $iNo
        $iRndNdx = Random(0, $iNo, 1)
        ;Swap
        $Temp = $aArr[$Num]
        $aArr[$Num] = $aArr[$iRndNdx]
        $aArr[$iRndNdx] = $Temp
    Next
EndFunc   ;==>_ArrayShuffle

Func Terminate()
    Exit 0
EndFunc   ;==>Terminate
Link to comment
Share on other sites

Without having done the maths, I believe that ArrayShuffle isn't fully random. If there are ten lines, then the first line in your file will be played first only once every twenty or so times.

; Assuming $iLines is already decleared and filled with the number of lines...
local _
    $sLine, _
    $aLottery, _
    $iLottery, _
    $iPos
do
    $aLottery = Lottery(1,$iLines)
    for $iLottery = 1 to $aLottery[0]
        $sLine = FileReadLine("database.txt",$aLottery[$iLottery])
        $iPos = StringInStr($sLine,";",1)
        if $iPos then ShellExecuteWait(StringMid($sLine,$iPos+1))
        next
    until false



; Lottery([<iMin>],[<iMax>],[<iDraws>]) --> <aDraws>
; <iMin>    = lowest number that can be drawn; default 1
; <iMax>    = highest number that can be drawn; default <iMin>+9
; <iDraws>    = number of draws to take; default draw all numbers
; <aDraws>    = array with the draws, where <iDraws> is stored in [0]
func Lottery($iMin = default,$iMax = default,$iDraws = default)
    local _
        $iDraw, _
        $aDraws[1]    = [0], _
        $iNumber, _
        $aNumbers[1]    = [0], _
        $iNumbers, _
        $iRandom
    if (not IsInt($iMin)) then $iMin    = 1
    if (not IsInt($iMax)) then $iMax    = $iMin+9
    $iNumbers    = $iMax-$iMin+1
    if (not IsInt($iDraws)) or $iDraws>$iNumbers then $iDraws    = $iNumbers
    if $iMin<=$iMax and $iDraws>=1 then
        redim $aNumbers[$iNumbers+1]
        $aNumbers[0]    = $iNumbers
        for $iNumber = 1 to $iNumbers
            $aNumbers[$iNumber]    = $iMin+$iNumber-1
            next
        redim $aDraws[$iDraws+1]
        $aDraws[0]    = $iDraws
        for $iDraw = 1 to $iDraws
            if $iNumbers=1 then
                $iRandom    = 1
                ;endif
            else
                $iRandom    = Random(1,$iNumbers,1)
                endif
            $iNumber    = 0
            do
                $iNumber    += 1
                if IsInt($aNumbers[$iNumber]) then $iRandom    -= 1
                until $iRandom=0
            $aDraws[$iDraw]        = $aNumbers[$iNumber]
            $aNumbers[$iNumber]    = default
            $iNumbers        -= 1
            next
        endif
    return $aDraws
    endfunc ; Lottery

Edit: I just did a quick test and my assumption was correct. Values have less chance than the general odds to be selected as the pick where they came from using ArrayShuffle. So if randomness matters, don't use ArrayShuffle.

Edited by jacQues
Link to comment
Share on other sites

If it were me, I'd probably just keep it simple, and use _FileCountLines (etc) to get a total, then keep repeating Random on it, until all numbers are returned as a result, skipping any repeats, and adding each unique return to an array, possibly even reducing the total count, each time the total number turns up, so you get a reduced base to randomize. You could also increase the lowest number by one, each time that turns up, so that you are effectively narrowing the min/max number range over time to also help with quickening the process.

When all numbers are accounted for, then you read from the array in sequence, treating each number as a line number, the text of which you read in from your original file or list, and then FileWrite out to the text/playlist file.

That process, of course, means nothing is repeated, and everything gets a turn.

Edited by TheSaint

Make sure brain is in gear before opening mouth!
Remember, what is not said, can be just as important as what is said.

Spoiler

What is the Secret Key? Life is like a Donut

If I put effort into communication, I expect you to read properly & fully, or just not comment.
Ignoring those who try to divert conversation with irrelevancies.
If I'm intent on insulting you or being rude, I will be obvious, not ambiguous about it.
I'm only big and bad, to those who have an over-active imagination.

I may have the Artistic Liesense ;) to disagree with you. TheSaint's Toolbox (be advised many downloads are not working due to ISP screwup with my storage)

userbar.png

Link to comment
Share on other sites

If it were me, I'd probably just keep it simple, and use _FileCountLines (etc) to get a total, then keep repeating Random on it, until all numbers are returned as a result, skipping any repeats, and adding each unique return to an array, possibly even reducing the total count, each time the total number turns up, so you get a reduced base to randomize. You could also increase the lowest number by one, each time that turns up, so that you are effectively narrowing the min/max number range over time to also help with quickening the process.

When all numbers are accounted for, then you read from the array in sequence, treating each number as a line number, the text of which you read in from your original file or list, and then FileWrite out to the text/playlist file.

That process, of course, means nothing is repeated, and everything gets a turn.

Nice alternative! This is possible, but has some implications. For example, when all numbers but 1 and 100 have been picked, a Random(1,100,1) could easily be repeated 500 times before a 'match' is found. Not very efficient. Also, be aware that Random(1,1,1) is not syntaxically (is that a word?) correct and will return 0, so work the min/max in a quicksort manner. The code would be very small, much smaller then any of the alternatives mentioned in this thread and still produce a truly random result.

Link to comment
Share on other sites

Maybe this _ArrayShuffle function could replace the _ArrayShuffle function in my example of post #9.
 

#include <Array.au3>
; jchd's example slightly modified from:-
; http://www.autoitscript.com/forum/topic/110309-randomly-sort-an-array/#entry796412

Local Const $limit = 10000
Local $Data[$limit]

For $i = 0 To $limit - 1
    $Data[$i] = $i
Next
Local $Data2 = $Data
_ArrayDisplay($Data, "Original Array")

Local $begin = TimerInit()
_ArrayShuffle($Data2)
ConsoleWrite("Time taken: " & TimerDiff($begin) & @LF)
_ArrayDisplay($Data2, "_ArrayShuffle")

Local $begin = TimerInit()
_ArrayShuffle2($Data, 5, UBound($Data) - 3) ; 9997) ; First 5 and last 3 elements are not shuffled.
ConsoleWrite("Time taken: " & TimerDiff($begin) & @LF)
_ArrayDisplay($Data, "_ArrayShuffle2")


Func _ArrayShuffle(ByRef $aArray)
    SRandom(@AutoItPID)
    For $i = UBound($aArray) - 1 To 0 Step -1 ; 0-based array
        $j = Random(0, $i, 1)
        $Temp = $aArray[$j]
        $aArray[$j] = $aArray[$i]
        $aArray[$i] = $Temp
    Next
EndFunc   ;==>_ArrayShuffle

; Shuffle only those the elements of an array between the array's indices
; that are stored in the parameters $iLowerBound and $iUpperBound.
Func _ArrayShuffle2(ByRef $aArray, $iLowerBound = 0, $iUpperBound = Default)
    SRandom(@AutoItPID)
    Local $iUpper, $i, $j, $Temp
    $iUpper = UBound($aArray)
    If $iLowerBound < 0 Or $iLowerBound = "" Or $iLowerBound = Default Then $iLowerBound = 0
    If $iUpperBound > $iUpper Or $iUpperBound <= 0 Or $iUpperBound = "" Or $iUpperBound = Default Then $iUpperBound = $iUpper
    For $i = $iUpperBound - 1 To $iLowerBound + 1 Step -1
        $j = Random($iLowerBound, $i, 1)
        $Temp = $aArray[$j]
        $aArray[$j] = $aArray[$i]
        $aArray[$i] = $Temp
    Next
EndFunc   ;==>_ArrayShuffle2

Edit: Changed the comment "; Randomizes only those the elements of an array between ..." to
"; Shuffle only those the elements of an array between ...".

Edited by Malkey
Link to comment
Share on other sites

@jacQues - I did say "I'd probably ...".

So they were my quick thoughts on it only, subject to testing and deep serious thinking.

One thing though, is that I was presuming the number of videos wouldn't be anywhere near 100, but I may be wrong in that.

And I'm not sure that you fully understand what I was suggesting, as I would certainly never use Random(1, 1, 1).

Here's a quick example without much thought, for say 20 videos.

You start with Random(1, 20, 1)

At some point (when 1 or 20 have returned as result) it would become either Random(1, 19, 1) or Random(2, 20, 1)

That's using the full min/max idea I suggested as quickest.

Next it would be Random(1, 18, 1) or Random(2, 19, 1) or Random(3, 20, 1), when either 19, 1 or 2 resulted.

And so on.

Obviously, the Min and Max are variables, and you skip any resulting numbers that have previously been returned.

And obviously, speed tests would need to be done, to see just how viable this idea is, especially if large numbers of lines/videos are going to be used. Too large, and it would indeed, not be viable.

Another way to possibly speed things up for large numbers of videos, would be to divide the job up.

i.e. Random(1, 10, 1) until complete, and then Random(11, 20, 1) and so on.

My logic says that would probably be quicker, due to less repeats over a smaller range of numbers.

Be an interesting test/exercise anyway.

EDIT

However, it may be, that you don't need to go to the extravagance of adjusting the Min/Max numbers. Been a while since I used Random in a project, and I seem to recall reading somewhere, that it is guaranteed to return every number at least once before doing repeats, but I may have that wrong.

Edited by TheSaint

Make sure brain is in gear before opening mouth!
Remember, what is not said, can be just as important as what is said.

Spoiler

What is the Secret Key? Life is like a Donut

If I put effort into communication, I expect you to read properly & fully, or just not comment.
Ignoring those who try to divert conversation with irrelevancies.
If I'm intent on insulting you or being rude, I will be obvious, not ambiguous about it.
I'm only big and bad, to those who have an over-active imagination.

I may have the Artistic Liesense ;) to disagree with you. TheSaint's Toolbox (be advised many downloads are not working due to ISP screwup with my storage)

userbar.png

Link to comment
Share on other sites

 Been a while since I used Random in a project, and I seem to recall reading somewhere, that it is guaranteed to return every number at least once before doing repeats, but I may have that wrong.

 

If it did that it would be an extremely poor PRNG unusable for any serious use. Random(1, $N, 1) returning the same value 173 times in a row must have the same probability as any sequence of 173 numbers taken from 1..$N. Every other behavior would be badly flawed.

Hopefully, AutoIt PRNG behaves.

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

That makes sense, so I did wonder where I got the notion from, as it is not mentioned in the Help file.

I seem to recall AutoIt changing what it used for the Random function some time back (may be a faulty memory of that too?), so perhaps it comes from there? Though probably not or you would recall that ... unless your Mind Closet is too full like mine?

I also recall looking into Random some time back, even third party apps I seem to recall ... perhaps one of those had a switch ... or I'm just remembering something my iPod does or one of the Apps for my phone or PC?

Edited by TheSaint

Make sure brain is in gear before opening mouth!
Remember, what is not said, can be just as important as what is said.

Spoiler

What is the Secret Key? Life is like a Donut

If I put effort into communication, I expect you to read properly & fully, or just not comment.
Ignoring those who try to divert conversation with irrelevancies.
If I'm intent on insulting you or being rude, I will be obvious, not ambiguous about it.
I'm only big and bad, to those who have an over-active imagination.

I may have the Artistic Liesense ;) to disagree with you. TheSaint's Toolbox (be advised many downloads are not working due to ISP screwup with my storage)

userbar.png

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...