How can I separate all the characters of a word into separate fields? - livecode

I have a random word generation script that works perfectly. I also have a few single character-width fields, exactly the same amount of them as the longest possible word that can be generated. Below each field I have a line that would resemble an underscore. Each field has a unique id, numbered from one like so: "letter1", "letter2".... and so on. Likewise, each line has the id of "line1", "line2", and so on.
Now that I've set the stage, here is what I want to happen. On the opening of the card, I want all of the letter fields to hide as I will have them show individually outside this subroutine. I then want all of the lines to hide, and then only the amount of lines that are required for the random word should show again. (The same number as length(randomword) from left to right.) Now, the random word should be looped through and the first character should be put into the field "letter1", and the second into "letter2", and so on. The word will change each time the card is opened, so it is important that this is not bruteforced (which unfortunately, myself having two weeks experience with LiveCode, is the only thing I know concretely how to do).
Could someone with more experience do me a solid and provide the code I would need to do this, and the location I should put the code in? (the card? the letter fields? I really don't know at this point).
I am happy to provide further description if I have not been articulate about my problem.

Try this (my LiveCode is a bit rusty):
on openCard
//Put your word generation script here
put 0 into amtOfLines
put 0 into amtOfLetters
repeat until amtOfLines is 6 //Replace 6 with the amount of lines
add 1 to amtOfLines
put "line" & amtOfLines into x
set the visible of graphic x to false
end repeat
repeat until amtOfLetters is 6 //Replace 6 with the amount of fields
add 1 to amtOfLetters
put "letter" & amtOfLetters into x
set the visible of field x to false
end repeat
put 0 into amtOfLines
put 0 into amtOfLetters
repeat until amtOfLines is length(randomword)
add 1 to amtOfLines
put "line" & amtOfLines into x
set the visible of graphic x to true
end repeat
repeat until amtOfLetters is length(randomword)
add 1 to amtOfLetters
put "letter" & amtOfLetters into x
set the visible of field x to true
end repeat
put 0 into amtOfChars
repeat until amtOfChars is length(randomword)
add 1 to amtOfChars
put "letter" & amtOfChars into x
set the text of field x to char amtOfChars of randomword
end repeat
end openCard
This would go in the card script.
EDIT: Fixed some errors.

This would go into the card script:
on setup pRandomWord
put 6 into tNumObjs -- or however many fields there are
put length(pRandomWord) into tLen
repeat with x = 1 to tNumObjs
hide fld ("letter"&x)
if x <= tLen then
put char x of pRandomWord into fld ("letter"&x)
show grc ("line"&x)
else
hide grc ("line" & x)
end if
end repeat
end setup
When you want to use it, put the random word into a variable and call the setup handler like this:
setup randomWord
This does everything in a single repeat loop. The random word is passed to the setup handler in the parameter "pRandomWord".

Related

VB.Net For Loop Takes So Long

I have 3 textboxes. 1st and 2nd textboxes contain approximately 40.000 to 80.000 lines of data. Each line has 6-7 characters maximum. Last checkbox has 800-1000 lines of data. These lines also has 6-7 characters. To save all these data in a single text file, I first add a time tag at beginning of each line, after a tab first textbox line written, and then second tbox, and third tbox, and then a new line. It goes on like that.
I use 3 checkboxes to understand which textboxes user wants to save. After save button clicked, this loop below starts. But it takes so long. Even user selects to save only first textbox, which means, let's say 50.000 lines, it takes almost a minute!
I tried methods like writing in a string, with a StringBuilder, with do-while loops, etc. but can't get a significant effect. I searched on internet and forum about different methods but couldn't find a way.
Is there any effective way to make it work faster?
For i = 0 To linesCount - 1
textStr.Append(timeCount & vbTab)
If (cbSaveOutput.Checked And Not tbOutput.Text = "") Then textStr.Append(tbOutput.Lines(i) & vbTab)
If (cbSaveForce.Checked And Not tbForce.Text = "") Then textStr.Append(tbForce.Lines(i) & vbTab)
If (cbSaveCrop.Checked And Not tbCroppedData.Text = "" And i < tbCroppedData.Lines.Length) Then textStr.Append(tbCroppedData.Lines(i))
textStr.Append(Environment.NewLine)
timeCount = Math.Round(timeCount + (1 / tbSampleRate.Text), 6)
ProgressBar1.Increment(1)
Next
The main problem is that you are using the Lines property over and over. Lines is not "live" data. When you get the property value, the control will get the Text property value first and then split it into a new array. You are doing that for every line in every TextBox and twice for the third TextBox. That is obviously bad. As you should ALWAYS do when using the Lines property, get it once and once only and assign the value to a variable, then use that variable over and over. There are other improvements that you could make to that code but that is the major issue and will reduce the time drastically.

AppleScript: Breaking up 40 paragraphs into 10 paragraphs of 4 paragraphs

Essentially, I am taking a column of data from an excel file and breaking it up into small groups. So:
10
20
30
40
50
60
etc...
broken up into:
"10, 20, 30, 40"
"50, 60, 70, 80"
etc
Using AppleScript, I assume you would nest loops, something along the lines of:
tell application "TextEdit"
set theText to text of front document as string
set myParas to every paragraph of theText
set myNum to the number of paragraphs of theText
repeat myNum times
repeat 4 times
end repeat
end repeat
end tell
I'm going to be updating data once a month that comes through as a column of numbers and text. I can strip out all the text easy enough, just would like to know the principle of how to break up or merge the paragraphs into smaller blocks.
For many complicated reasons, I am stuck with AppleScript and textEdit, so other alternates (such as massaging with javascript or textWrangler or whatever) is not an option.
Also, maybe textEdit can do this on it's own but the script I will be using will have lots of other operations based on the above result, so AppleScript has to do all the heavy lifting.
You can specify the step size in a repeat loop, so you could do something like:
tell application "TextEdit" to set theText to text of front document
set paras to paragraphs of theText
set step to 4 -- number of items in a group
repeat with i from 1 to (count paras) by step
try
buildString(items i thru (i + step - 1) of paras)
on error errmess number errnum -- index out of bounds
log errmess
if errnum is -128 then error number -128 -- quit
buildString(items i thru -1 of paras) -- just to the end
end try
end repeat
to buildString(someList)
set tempTID to AppleScript's text item delimiters
set AppleScript's text item delimiters to ", "
set output to someList as text
set AppleScript's text item delimiters to tempTID
display dialog output -- show it
return output
end buildString

How to add data to a graph from an API

I want to make a stock app, where the stock values of the past 7 days are shown in a graph. This is the code for extracting the data from the API:
on mouseUp
put url("https://www.alphavantage.co/query?function=TIME_SERIES_DAILY&symbol=IBM&apikey=YPMBUVQ8AJXX1HQP&datatype=csv") into myData
put myData into field "Data"
set the itemdel to ","
put 1 into x
repeat until x > 8
add 1 to x
put items 1 to 5 of line 5 of myData & return after gData
end repeat
set the graphData of widget "graph" to gData
end mouseUp
The first item will be the x axis, and the rest will all be on the y axis. But when I run this code, it only puts a single line into the graphData of the graph, and nothing shows up on the graph except for the 2 axis. What am I doing wrong here?
I tried the following variation that appears to work. One issue is your data contains a volume amount at the end of each line that's super high compared to the trading values, so I delete that value from each of the lines used for the chart.
on mouseUp
put url("https://www.alphavantage.co/query?function=TIME_SERIES_DAILY&symbol=IBM&apikey=YPMBUVQ8AJXX1HQP&datatype=csv") into temp
delete line 1 of temp -- REMOVE THE COLUMN LABLES
delete line 8 to -1 of temp -- LIMIT DATA TO 7 DAYS
repeat for each line theLine in temp
delete last item of theLine -- IGNORE VOLUME (NUMBER IS TOO LARGE COMPARED TO TRADING DATA)
put theLine & return after myData
end repeat
set the graphData of widget "graph" to myData
end mouseUp

Scorlling filed is empty but it display some string why?

I have two Scrolling field and one containing some text and another containing some words. eg. (s1:s2) separated by colon my objective is to find how many words in the second Scrolling are appearing in first Scrolling field. (eg: if s1 is appearing in first scrolling field then it shows s1,1 it means s1 appearing one time). While executing my code it's work but if my first scrolling field is empty it shows some text also some times it takes some words in the first field. (eg:\documentclass)this word is not in 2'nd field.
I am using the following code.
global ar
global sam
on mouseUp
--set the caseSensitive to true
put 0 into tmp
put empty into sam
put the field SRText into myArrayT
split myArrayT by CR
put the number of lines of (the keys of myArrayT) into myArrayl
repeat for each key j in myArrayT
put myArrayT[j] into k
split k by colon
put k[1] into searchStr1
put the field "MytextField" into sss
repeat for each word ass in sss
if ass contains searchStr1 then
add 1 to tmp
put ass & CR & CR after sam
put sam into ar
end if
end repeat
end repeat
answer sam
answer tmp
--answer sa
end mouseUP
on mouseDown
answer ar
put ar into ss
get ss
repeat for each word tWord in it
add 1 to wordCount[tword]
end repeat
combine wordCount by return and comma
answer wordCount
--put empty into sam
end mouseDown
You really should use quotes around field names. I promise you'll realise some day, that you have been shooting yourself in the foot all the time.
Don't use the in front of object references,
field "Field Name"
button "Field name"
but do use the in front of property references:
the number of lines of fld "Field Name"
the text of fld "Field Name"
the name of this stack
There really use no reason for your obsession with arrays. Stop using arrays when you don't need them! It just makes things overly complicated and slow.
I have modifed your mouseUp handler. I didn't look at your mouseDown handler. I believe your mouseUp handler should look like this:
on mouseUp
--set the caseSensitive to true
put 0 into tmp
put empty into sam
repeat for each line k in fld "SRText"
set the itemDel to colon
put item 1 of k into searchStr1
repeat for each word ass in field "MytextField"
if ass contains searchStr1 then
add 1 to tmp
put ass & colon & tmp & cr after sam
end if
end repeat
put 0 into tmp
end repeat
put sam
end mouseUp
The script above is based on your approach and I really don't understand why you would do it this way and what you would do with the result. The script below is probably much more efficient and it seems more useful to me.
on mouseUp
// I assume fld SRText contains a list similar to
// "abc:1" & cr & "bcd:2" & cr & "cde:1" & cr & "def:4"
put fld "SRText" into myData
split myData by cr and colon
put the keys of myData into myData
// myData is not an array!
repeat for each word myWord in fld "MytextField"
if myWord is among the lines of myData then
// use an array to store data, not to loop through
if myCounts[myWord] is empty then
put 1 into myCounts[myWord]
else
add 1 to myCounts[myWord]
end if
end if
end repeat
combine myCounts by cr and colon
put myCounts
end mouseUp

Keyboard shortcuts in an AppleScript list dialog

I am looking for a way to assign keyboard shortcuts to the items in a list dialog in AppleScript.
I am using the following to display a long list of folder names and am looking for an easy way to select an item from the list.
set selectedFolderName to {choose from list folderList}
Currently the list displays like :
Office
Personal
Projects
...
Vendors
and I have to navigate down the list with the cursor keys or mouse to select an item. I would like to be able to show either :
a) Office
b) Personal
c) Projects
...
m) Vendors
or :
Office
Personal
pRojects
...
Vendors
Then I could press the C key (first example) or R key (second example) to select 'Projects'.
I studied the AppleScript documentation, such as it is, and searched far and wide, but have not been able to spot a way to accomplish this.
I'm not totally sure if this is what you want, but I use the construct below, so that I can press "a", to select the first item, "b" to select the second item, and so on.
set litems to {"apples", "pears", "banana", "oranges", "plums", "grapes"}
set deli to "." & space & space
repeat with i from 1 to (count litems)
set item i of litems to character id (i + 96) & deli & item i of litems
end repeat
log litems
set theRes to choose from list litems
(*a. apples, b. pears, c. banana, d. oranges, e. plums, f. grapes*)
set origItem to text 5 thru -1 of item 1 of theRes
log origItem
—> plums
The second version of what you're asking is not possible. But, the first is. There is nothing built in for this kind of functionality, but you can build your own sub-routine for it. You can prepend your list items with letters or numbers (I'll use numbers since it's simpler).
on choose_from_list_with_shortcut(ls)
-- prepend the choices with "1) "
repeat with i from 1 to (count ls)
set item i of ls to (i as string) & ") " & item i of ls
end repeat
set chosenItems to choose from list ls
-- strip the prefixes from the chosen items
repeat with i from 1 to (count chosenItems)
set item i of chosenItems to text 4 thru -1 of item i of chosenItems
end repeat
return chosenItems
end choose_from_list_with_shortcut
Another option is to just start typing. Just like in the Finder, if you type the letters "pro," the list will highlight "Projects."

Resources