Random Text from a list of 10 or so choices

Hello there. I'm looking for a macro that, when executed, will paste some random text from a list I'll create inside the macro of about 10 different sentences. In other words, when I trigger the macro it will insert one of the following phrases into my document.

Today was a great day.
Today was a wonderful day.
Today was a routine day.

etc...

Anyone have suggestions? Ideally, it will have 10 different sentences to choose from.

There is a neat trick for when you want to select a random entry from a list: scan through the list, and for each entry select it as the result with a chance of 1/Line Number. So here is a working macro:

Paste Random.kmmacros (3.5 KB)

3 Likes

Peter beat me to the punch by a few minutes, but since I already finished making it, here's an alternative (and admittedly more complex) macro that uses a KM dictionary and chooses a sentence at random via a calculation designed to only return a number from 1 to 10, using the result for the dictionary key containing the sentence:

Example - Paste Random Sentence.kmmacros (6.9 KB)
image

1 Like

Thank you, guys. I'll start with the easy one first. Do either of you guys see an advantage to one over the other?

All things being equal, I'd lean towards Peter's macro over mine, since the simpler solution that produces the desired result is usually the way to go, but both should do what you want at about the same imperceptible speed. Whichever one you stick with, I would recommend that you disable the part of the macro that creates the sentence list after running it successfully though, since you shouldn't need to do that every time you want to paste a random sentence.

1 Like

And, of course, in an Execute a Script action you can use a function which returns a random integer value chosen between a lowest and a highest integer.

Perhaps, for example:

Applescript

-- randomRInt :: Int -> Int -> Int
on randomRInt(low, high)
    (low + ((random number) * (1 + (high - low)))) div 1
end randomRInt

Javascript

// randomRInt :: Int -> Int -> Int
const randomRInt = (low, high) =>
    low + Math.floor(
        (Math.random() * ((high - low) + 1))
    );

e.g.

Randomly chosen line of text.kmmacros (19.0 KB)
yadekha

1 Like

Or in an Applescript version:

on run
    
    tell application "Keyboard Maestro Engine" to ¬
        set xs to paragraphs of (getvariable "randomLines")
    
    item randomRInt(1, length of xs) of xs
end run


-- GENERIC FUNCTION ------------------------------

-- https://github.com/RobTrew/prelude-applescript

-- randomRInt :: Int -> Int -> Int
on randomRInt(low, high)
    (low + ((random number) * (1 + (high - low)))) div 1
end randomRInt

Thank you everyone. I went with @gglick's version, and it works perfectly!!

1 Like

I kept it simple and just used PHP:

2018-09-04_07-56-54%20(1)

2 Likes

Chris, sorry to bump it up, but could you please attach the actual script? Simply so there's no need to retype it (then fix manual errors and whatnot).

1 Like
#! /usr/bin/php
<?
$description = <<<end_here
Today was a great day.
Today was a wonderful day.
Today was a routine day.
end_here;
$desc = explode("\n", $description);
shuffle($desc);
echo $desc[1];
?>
3 Likes

Chris, thanks so very much!

On a related note, do you happen to know if there's a way to save the output of this script into a variable that Keyboard Maestro can use?

I did google around a bit for this, but I couldn't yet find a way to do this.

Hey @adamas,

Look at the options of the Execute a Shell Script action.

Note “Save Results to Variable”.

-Chris

Hey, Christopher!

Thank you so very much!! I mean, OMG, it was actually right there in the options indeed. My apologies for such silly questions, I literally started using Keyboard Maestro yesterday evening, so there's a bit of a learning curve for me :]

1 Like

Hi Chris,

Thanks for this piece of code which works well.

I was wondering if it was possible to do the following thing:
At the beginning of the macro, I will have to enter several lines of text, then your piece of code will take one line randomly from the list I have entered at the beginning.

Thanks !

My solutions often differ from other people's. Here's how I would pick (and, in this case, display) a random line from a KM variable:

image

The sort -R sorts the lines of the file in random order and the head -n statement selects the first line.

It sounds like your question is more about how to pick a random line rather than how to input a string, so that's the part I chose to answer.

3 Likes

Thanks for your insight, i'll try that too.

I was wondering if there was a "scripting" way to do the following:

Multiple profiles use the same macro in which they randomly choose one sentence among a list (this is already done thanks to all the answers on this thread). However, even if my list contains 60 uniques sentences, it happens that some profiles pick the same sentence.

To reduce that risk, I first though of creating a large number of unique sentences which would statistically reduce the risk of having the same sentence used twice.

I was wondering if there was a way to do it with a script, something like "if this sentence has already been used, it is "removed" as a choice for the next profile. This has do be done only while running the macro, I don't want the script to really delete the sentence as I would need it for a new run where it would be available again.

I hope I was clear enough !

Thanks

Is each sentence on a unique line containing no newline characters? Or can a sentence span multiple lines? I've never heard the word "profile" used in a KM discussion before so can you clarify what you mean by that? Do you mean calling macro? Is there just one set of sentences, or does each calling macro have its own set? Are you worried about duplicates from two different macros which call this routine - can they end up using the same sentence, or is each sentence usable only once no matter who calls it? And what happens when you run out of sentences, do you want to start over? The devil is in the details.

There are just so many questions, I don't know where to begin coding, but I assure you, if you answer all my questions, I can give you an answer. I enjoy text processing problems.

One of the tricks I use is to invisibly mark which sentences were chosen by adding a space to the end. But this trick is dependent upon one of the answers to my questions above. Another trick I have is to do all the random selection at the initialization rather than each time a call is made for a random sentence. But I sure wouldn't add a bunch of random sentences to reduce the chance of a failure. I don't like dealing with chance. Apparently whoever designed quantum physics enjoys chance, but I don't.

I'm not exactly sure what you want, but here is an example to get you started.
You will have to add whatever "profile" processing you need, and adjust the macro as needed.

Let us know if this will meet your needs:

MACRO: Get & Remove Random Sentence from List [Example]

Hi guys, sorry for the delay, I had a computer issue, could not get my mac working for 2 weeks, but now it's working well again :slight_smile:

@Sleepy
Is each sentence on a unique line containing no newline characters? Or can a sentence span multiple lines?
Yes each sentence is on a unique line. I'm using this script to randomize the choice of a sentence within a list:

I've never heard the word "profile" used in a KM discussion before so can you clarify what you mean by that? Do you mean calling macro?
For an experiment, I'm trying to automatize interactions between several profiles / accounts of a social media. In that sense, my macro is set like this : connection to profile 1 > post a random sentence > quit internet browser > connection to profile 2 > post a random sentence. To do so, my macros are structured as follow:

Macro named Time 1
1 - Run macro "Connection to profile 1"
2 - Run macro "Post a sentence"
3 - Run macro "Connection to profile 2"
4 - Run macro "Post a sentence"
5 - Run macro "Connection to profile 3"
6 - Run macro "Post a sentence"
...

Is there just one set of sentences, or does each calling macro have its own set?
Yes there is only one set of sentences as some sentences may contain variables.

Are you worried about duplicates from two different macros which call this routine - can they end up using the same sentence, or is each sentence usable only once no matter who calls it?
Indeed, each sentence should be usable only once, no matter which profiles use it.

And what happens when you run out of sentences, do you want to start over?
I already have 60 variations of sentences, so I cannot run out of sentences as the macro is only run once.

Moreover, I've tried to set a variable and use it in the shell script I've added above but it does not work. How can I use a variable within a sentence which is part of the list in the shell script ?

Thanks a lot for your help :slight_smile: