Re: Idle Help
Re: Idle Help
- Subject: Re: Idle Help
- From: John W Baxter <email@hidden>
- Date: Thu, 7 Dec 2000 18:24:39 -0800
Bryon,
One alternate possibility would be to let AppleScript worry about the
random number stuff.
In one trial, this script:
set x to {1, 2, 3, 4, 5, 6}
set y to {}
repeat 6 times
set end of y to some item of x
end repeat
set z to {}
repeat 6 times
set end of z to some item of x
end repeat
{y, z}
Produced
{{3, 1, 5, 3, 4, 2}, {5, 4, 3, 5, 2, 3}}
In another it produced
{{6, 5, 6, 1, 4, 4}, {6, 1, 3, 4, 1, 1}}
You would still want to remove the used item from the list, which would
become a matter of searching through the list for the item retrieved from
it...one way might be like
set x to {1, 2, 3, 4, 5, 6}
set y to {}
repeat 6 times
set a to some item of x
set end of y to a
set newx to {}
repeat with i in x
if contents of i is not a then
set end of newx to contents of i
end if
copy newx to x
end repeat
end repeat
y
Which in one run produced
{6, 5, 3, 2, 1, 4}
and in another produced
{6, 3, 5, 1, 2, 4}
and another (because I didn't like that repeated leading 6 and trailing 4)
{3, 6, 4, 5, 1, 2}
The inner repeat would execute each time you select an image; the outer is
like the part of your code which does everything but check for the list
becoming 0, but in your case it is distributed over several executions of
the idle handler.
I don't know whether the is not operator behaves sensibly with aliases (it
should). And "English-like" isn't "English" (contents ... is not). And I
don't know whether either or both "contents of" are really necessary...I've
just become gunshy.
--John
At 11:50 -0500 12/7/00, email@hidden wrote:
>
On Wed, 6 Dec 2000 19:38:27 -0700, Byron Peterson <email@hidden> asked,
>
>
> OK, let me break down the problem I am having and maybe you can help.
>
> I have written a script to change the desktop picture at a set
>
> interval. The script has support for two monitors and the ability to
>
> alternate back and fourth between them. I read the picture files
>
> from a folder (as well as from sub folders) into a list (this happens
>
> during the run stage). I then get a random number (1 to total number
>
> of items in the list) and display that image on either monitor 1 or 2
>
> (whichever is next) using the appearance manager during the idle
>
> stage. After I select an image, I remove it from the list (so that
>
> the same picture won't be displayed again until all pictures have
>
> been displayed). After the list reaches 0, I then re-read the
>
> picture files back into the list and start the process over. The
>
> problem I am having is it isn't random at all. After a computer
>
> restart, it starts with the same picture every time,then goes to the
>
> same second picture and so fourth. I have looked and looked for the
>
> problem but it doesn't appear to be how I get the random number.
>
> Below is the code that gets the random number.
>
>
>
> set listTotal to the count of desktopPictures
>
> set randomNumber to random number listTotal from 1 to listTotal
>
>
One immediate thing to note, although its not the source of your problem. If
>
you have both a direct parameter and a "from... to" parameter, the
>
"from... to"
>
is ignored. "random number 6 from 10 to 20" returns a random number between 0
>
and 6. In your case, you'll occasionally get a random number of 0.
>
>
And oddly, "item 0" of a list doesn't do anything sensible. (At least, in OS
>
8.6 and AppleScript 1.3.7. IIRC, this is a known bug.) Sometimes it seems
>
like
>
"item 0 of desktopPictures" returns no result, and in other ways, it seems
>
like
>
a reference to the current application. You'll probably get "no result was
>
returned from some part of this expression" or "can't make some data into the
>
expected type" if you try to get item 0. (The command,
>
>
tell application "Appearance"
>
set picture file of monitor 1 to item 0 of pictureList
>
end tell
>
>
shows in the event log as "set picture of monitor 1 to current
>
application" and
>
produces the error "Can't make some data into the expected type.")
>
>
But to the root of the problem...
>
>
First thing to check: make sure you are not using the "with seed" parameter to
>
the random number command. Not *anywhere* in the script.
>
>
The way the AppleScript random number is set up, you can use it in two ways: a
>
"random but predictable" way, and a "random, different each time" way.
>
"Random
>
but predictable" is nice for troubleshooting, regression testing, and speed
>
comparisons, but for most applications (like yours) you want "random,
>
different
>
every time."
>
>
The way AppleScript random numbers do this is with a "seed" variable. If you
>
tell call the random number command "with seed x", it will start
>
generating the
>
numbers from a fixed point determined by x, and every time you say "random
>
number" after that, you'll get the next number in the sequence determined by
>
that seed. If you don't provide a seed, or if you tell it "with seed 0", it
>
uses something that changes, like the time of day in milliseconds, for the
>
seed,
>
and you get apparently random behavior.
>
>
(Actually, it looks like "with seed 0" uses something that changes no faster
>
than once per second--a bunch of sequences generated from seed 0 are identical
>
if they are generated quickly. Its probably using the "seconds since
>
1904" date
>
as an integer. So don't say, "I'll just use seed 0 all the time, for extra
>
randomness. Just say "with seed 0" once, at the beginning of the script, or
>
don't say "with seed" anywhere, and you'll be fine.)
>
>
If this doesn't fix the problem, we need to make sure you have the program
>
flow
>
correct. You are generating the random number anew each time you are
>
trying to
>
pick a picture from the list, right? That is, the code, slightly enlarged,
>
looks something like this:
>
>
property pictureInterval : 15 -- seconds. How often to change pictures
>
on run
>
global desktopPictures
>
set desktopPictures to findDesktopPictures()
>
-- I'm assuming somehow you get a list of aliases for the pictures
>
-- You might as well write a handlers to do it, since you will update
>
-- the list of pictures in idle handler as well.
>
end run
>
>
on idle
>
global desktopPictures
>
if count of desktopPictures is 0 then
>
-- either we're done with list, or no pictures available
>
set desktopPictures to findDesktopPictures()
>
if count of desktopPictures is 0 then return pictureInterval
>
-- no pictures. Do nothing and hope the user provides pictures later
>
end if
>
set listTotal to the count of desktopPictures
>
set randomNumber to random number from 1 to listTotal
>
switchPicture to item randomNumber of desktopPictures
>
>
-- the following two lines delete the used picture from the list
>
set item randomNumber of desktopPictures to missing value
>
set desktopPictures to aliases of desktopPictures
>
>
return pictureInterval
>
end idle
>
>
If you are always getting the same pictures, in the same order, I'd
>
suspect you
>
are not updating the random number each time. The random value is
>
generated and
>
fixed when "random number" is called, and stays the same until you call random
>
number again. (This sounds obvious, but I've seen people who
>
misunderstand what
>
random number generators return. They return ordinary numbers, not a thing
>
that
>
constantly changes its value.)
>
>
If the first picture is always the same but the rest are random, make sure you
>
generate the random number early enough in the process. (Here, a global is
>
better than a property; if you compile the script fresh, and try to access a
>
global before setting it, you'll get a "variable not defined" error.) Try
>
using
>
"display dialog" statements to show what the random number actually is.
>
>
--
>
Scott Norton Phone: +1-703-299-1656
>
DTI Associates, Inc. Fax: +1-703-706-0476
>
2920 South Glebe Road Internet: email@hidden
>
Arlington, VA 22206-2768 or email@hidden
>
_______________________________________________
>
applescript-users mailing list
>
email@hidden
>
http://www.lists.apple.com/mailman/listinfo/applescript-users
--
John Baxter email@hidden Port Ludlow, WA, USA