Random Text from a list of 10 or so choices

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:

KM has a couple of actions that helps with regard to processing tokens, variables and calculations:

image
image
image
image

There's also another (older?) way to dereference a variable: using AppleScript. The method is different depending upon whether your variable is local or global. You didn't indicate whether your variable was local or global. The following example shows how to assign a value (the parameter passed to the macro) to a local variable called LocalValue.

image

Those are your options. But your scenario involves finding the variable(s) in the line and replacing them with their values. That may require some extra coding. But I want to get some breakfast soon so for now I'll just leave you with this lead.

Thanks for your answer :slight_smile:

My objective is not to filter these sentences which contain variables put I just want KM to replace the variables inside those sentences by a specific text which I indicate at the beginning of the macro.

The variables are local ones, I set them as follow:

That is very easy to do:

image

Did you see the solution I offered above to select a random sentence?

Yes I know, that's what my examples were meant to show. I wasn't "filtering" anything, that's just the name of the KM action (and it's a bit of a misnomer for the example I provided.) In particular the first example shows how to replace a variable name with its contents. That's what you are asking for.

Then you said your variables are "local ones" but your example showed a "global variable". Are you familiar with the difference between local and global variables?

JM gave another answer. His advice is almost always great. In this case, I don't think it is because you want the variable evaluated not when the sentence is assigned to a variable, but at a future time. That's what my advice was attempting to solve for you. My advice was about letting you store variable names as part of sentences and evaluating them later. JM's advice was about evaluating a variable name at the time it is assigned to a variable, which I think is not what you want. But if I'm wrong, that's fine.

@Sleepy thanks for your answer.

I checked the difference between local / global variables and yes my variables are global ones.

If I have followed correctly, by integrating the AppleScript, I'll be able to assign the variable which is set at the beginning of the macro and then use it within the shell script ?

@JMichaelTX thanks for your solution !

If I have understand well what your macro is doing:

  • I set a list of sentences
  • The macro create a temporary txt file
  • The macro processes the actions I have defined until every one of the sentence has been used (and they are used once they have been removed from the list

Is that it ?

  • I set a list of sentences -- :white_check_mark:
  • The macro create a temporary txt file -- NO
  • The macro processes the actions I have defined until every one of the sentence has been used (and they are used once they have been removed from the list -- :white_check_mark:

Have you tried running the macro? I think that will answer all your questions.
It does NOT require a file, but you can optionally get your question list from a file using this Action:
image

Does that work for you?

Thanks ! Looks like it runs and does what i'm looking for :slight_smile:

Now I have to find a way to integrate it to my whole macro. I will keep you update about that.

@JMichaelTX Your macro is working but there is one thing which does not fit exactly my needs.

Indeed, the macro is set to loop until the list is empty while I only need the macro to select a random line within the list, remove it so when it's processed again, the previously chose line is not available.

In that sense, I would need the macro not to loop the actions until the list is empty.

Thanks !

That's easy enough. Just take the Actions out of the Repeat Action, and change the "Local__Master" list to a global variable like "DND_RT__MasterList". Of course you need some way to initialize that variable.

1 Like

So, I just took out the actions from the Repeat Action as you suggested, it worked perfectly. However, I did not change the "Local__Master" list to a global variable. Is it really necessary ?

1 Like

Depends on your use case. Local variables cease to exist when the Macro terminates, so each time you trigger the Macro it will start with the same data. If you want the line removed to NOT be in the data for the next trigger, then you would need to use a global variable.

Understood !

Then, I need to tweak it because I have interlocked many macros within macros to save time when editing the general one.

To give you a better idea of what it looks like, here's the structure:

  • Connect to Profile 1
  • Execute the macro named RUN 1
    • within RUN 1 macro, there is your macro list which allows me to pick one sentence randomly
  • Quit Profile 1
  • Connect to Profile 2
  • Execute the macro named RUN 1 (exact same macro, not a duplicate, every profile is linked to this macro)
  • Quit Profile 3
  • Connect to Profile 3
  • Execute the macro named RUN 1
    ...

With your explanations, It seems that I really need a global variable.

1 Like

@JMichaelTX So, I have transformed the Local variables into Instance ones. But it does not work as it's not writting anything when it should be.

I've done the following modification to your script:

I've placed the 2 first actions (Replace with your... + Set Variable "Instance__CurrentList") before connecting to the first profile (i'm referring to the scheme I previously posted)

Then, in each "RUN 1" macro, at some point the following actions are taking action to insert a random sentence

Are my modifications correct ? Would you script work the way I arranged it (or should all the actions of the script be at the same place to work properly) ?