I apologize if this has been asked before (I couldn't find anything).
I'm an extreme noob in Livecode, and I want to know if there is a way of programming a button to create many new, unique variables and assign a value to them. I apologize if this is a dumb question.
Usually you use an array for that. An array is basically a list of things, where each thing is associated with an "index". An index can be any word, so you can use an array like a dictionary, where you'd e.g. have French words as the index, and English words as the value, like:
put "cow" into myDictionary["vache"]
But you can also just use numbers as the keys and make them a numbered list:
put "cow" into allMyAnimals[1]
put "duck" into allMyAnimals[2]
In end effect, you create one variable and put several things in it. For example if you had a loop that calculated something (in this example a number +100) and you wanted to have variables containing all those numbers, but named with 100 less, you'd do something like:
repeat with x = 1 to 250
put x +100 into twoHundredFiftyNumbersFrom101[x]
end repeat
And to read the first one:
answer "the first number is" && twoHundredFiftyNumbersFrom101[1]
Or all of them:
repeat with x = 1 to 250
answer twoHundredFiftyNumbersFrom101[x]
end repeat
Or whatever. You could also use 'do' to build the lines of code as a string, but then you have to make sure your variable names are generated in a fashion that makes them valid identifiers (e.g. have no spaces in them, no special characters). An array key can be any valid string, and the compiler can optimize them, and you can treat them as a whole and pass them between handlers.
Or you can do this "in the clear" with a "do" construction:
on mouseUp
repeat with y = 1 to 10
get random(100)
do "put it into onTheFlyVariable" & y
end repeat
end mouseUp
Step through this handler and watch the variables assemble themselves.
Related
I am working on a scrabble assignment. We have to assign values to each word and then put them in order of point value. We will read the words from a text file. So I'm thinking to create an ArrayList to store each word. My question is, how do I read each character and assign a value to it? I believe I will use a for loop. I'm just confused when I start working with char... I think that's what this will be.
Once I figure out how to give a score to each word, do I then use the comparator interface to sort them?
EDIT: I realized maybe I didn't make this clear. Each letter is given a value from the Scrabble game. So I have to read each letter of each word and assign a value that will add up to a total score for the word. Like the word QUIT would be 10 + 1 + 1 + 1 = 13.
What you could do is to add all words as keys in a hash table, initiating them all with a value of 0. Then you loop through the keys and use a for loop to check the value of each character of each word, adding the word’s sum value as the value for that word’s key in the hash table.
The for loop for each word would look something like this:
int sumValue = 0;
for(int i =0; i < word.length(); i++)}
sumValue += value(word.charAt(i))
}
The return value() is just my way to represent that you return the value of the specific character you are at. Of course this depends on which character it is. Maybe it would be wise to keep another hash table with each character associated with a scrabble value that you access in the loop (like A:1, X:8 etc).
This may be something really simple, but I couldn't figure it out and been trying to find an example online to no avail. I'm basically trying to remove items found in one sequence from another sequence.
Example #1
Items added to the cart is in one sequence; items removed from cart is in another sequence:
<#assign Added_Items_to_Cart = "AAAA,BBBB,CCCC,DDDD,EEEE,FFFF">
<#assign Deleted_Items_from_Cart = "BBBB,DDDD">
The result I'm looking for is: AAAA,CCCC,EEEE,FFFF
Example #2
What if the all items added to and deleted from cart are in the same sequence?
<#assign Cart_Activity = "AAAA,BBBB,BBBB,CCCC,DDDD,EEEE,DDDD,FFFF,Add,Add,Delete,Add,Add,Add,Delete,Add">
The result I'm looking for is the same: AAAA,CCCC,EEEE,FFFF
First things first: You ask about sequence but the data you are dealing with are strings.
I know you are using the string to work as a sequence (and it works), but sequences are sequences and strings are strings, and they have diferente ways of dealing with. I just felt this was important to clarify if someone who is starting to learn how to program get to this answer.
Some assumptions since you're providing strings with data separated by comma:
You want a string with data separated by comma as a result.
You know how to properly create strings with data separated by comma.
You dont have commas in your items names.
Observations:
I'll give you the logic but not the code donne, as this can be a great chance for you to learn/practice freemarker (stackoverflow spirit, you know...)
You question is not about something specific of freemaker (it just happens to be the language you want to work with). Think about adding the logic tag to you question. :-)
Now to the answer on how to do what you want on a "string that is working as a sequence":
Example #1
Change your string to a real sequence :-)
1 - Use a built-in to split your string on commas. Do it for both Added_Items_to_Cart and Deleted_Items_from_Cart. Now you have two real sequences to work with.
2 - Create a new string tha twill be your result .
3 - Iterate over the sequence of added itens.
4 - For each item of the added list, you will check if the deleted list also contains this item.
4.1 - If the deleted list contains the item you do nothing.
4.2 - If the deleted list do not contains the item, you add that item to your string result
At the end of this nested iteration (thats another hint) you should get the result you're looking for.
Example #2
There are many ways of doing it and i'll just share the one that pops out of my mind right now.
I think it's noteworthy that in this approach you will always have an even sized list, as you always insert 2 infos each time: item and action.
So always the first half will be the 'item list' and the second half will be the 'action list'.
1 - Change that string to a sequence (yes, like on the other example).
2 - Get half of its size (in your example size = 16 so half of it is 8)
3 - Iterate over a range from 0 to half-1 (in your example 0 to 7)
4 - At each iteration you'll have a number. Lets call it num (yes I'm very creative):
4.1 - If at the position num + half you have the word "Add" you add the item of position num in your result string
4.2 - If at the position num + half you have the word "Delete" you remove the item of position num from your result string
And for the grand finale, some really usefull links that will help you in your freemarker life forever!!!
All built-ins from freemarker:
https://freemarker.apache.org/docs/ref_builtins.html
All directives from freemarker:
https://freemarker.apache.org/docs/ref_directive_alphaidx.html
Freemarekr cheatsheet :
https://freemarker.apache.org/docs/dgui_template_exp.html#exp_cheatsheet
I would like to know what is preferred...
Dim sLines() As String = s.Split(NewLine)
For each:
For Each sLines_item As String In sLines
.GetUpperBound:
For i As Integer = 0 To sLines.GetUpperBound(0)
I have no idea why the "For Each" was introduced for such cases. Until now I have only used .GetUpperBound, and I don't see any PRO for the "For Each".
Thank you
ps: When I use ."GetUpperBound(0)", I do know that I am iterating over the vector.
The "For Each" in contrast sounds like "I don't care in which order the vector is given to me". But that is just personal gusto, I guess.
Short answer: Do not use GetUpperBound(). The only advantage of GetUpperBound() is that it works for multi-dimensional arrays, where Length doesn't work. However, even that usage is outdated since there is Array.GetLength() available that takes the dimension parameter. For all other uses, For i = 0 to Array.Length - 1 is better and probably the fastest option.
It's largely a personal preference.
If you need to alter the elements of the array, you should use For i ... because changing sLines_item will not affect the corresponding array element.
If you need to delete elements of the array, you can iterate For i = ubound(sLines) to 0 step -1 (or the equivalent).
Short answer
You should always use For Each on IEnumerable types unless you have no other choice.
Long answer
Contrary to the popular understanding, For Each is not a syntactic sugar on top of For Next. It will not necessarily iterate over every element of its source. It is a syntactic sugar on top of IEnumerable.GetEnumerator(). For Each will first get an enumerator to its source then loop until it cannot enumerate further. Basically, it will be replaced by the following code. Keep in mind that this is an oversimplification.
' Ask the source for a way to enumerate its content in a forward only manner.
Dim enumerator As IEnumerator = sLines.GetEnumerator()
' Loop until there is no more element in front of us.
While enumerator.Next() Then
' Invoke back the content of the for each block by passing
' the currently enumerated element.
forEachContent.Invoke(enumerator.Current)
End While
The major difference between this and a classical For Next loop is that it does not depend on any length. This fixes two limitations in modern .NET languages. The first one has to do with the Count method. IEnumerable provides a Count method, but the implementation might not be able to keep track of the actual amount of elements it stores. Because of this, calling IEnumerable.Count might cause the source to be iterated over to actually count the amount of element it contains. Moreover, doing this as the end value for traditional For Next loop will cause this process to be done for every element in the loop. This is very slow. Here is an illustration of this process:
For i As Integer = 0 To source.Count() ' This here will cause Count to be
' evaluated for every element in source.
DoSomething(source(i))
Next
The use of For Each fixes this by never requesting the length of the source.
The second limitation it fixes is the lack of a concept for arrays with infinite amount of elements. An example of such cases would be an array containing every digit of PI where each digit is only calculated when you request them. This is where LINQ makes its entrance and really shines because it enables you to write the following code:
Dim piWith10DigitPrecision = From d In InfinitePiSource
Take 10
Dim piWith250DigitPrecision = From d In InfinitePiSource
Take 250
Dim infite2PiSource = From d In InfinitePiSource
Select d * 2
Now, in an infinite source, you cannot depend on a length to iterate over all of its elements. It has an infinite length thus making a traditional For Next loop an infinite loop. This does not change anything for the first two examples I have given with pi because we explicitly provides the amount of elements we want, but it does for the third one. When would you stop iterating? For Each, when combined with Yield (used by the Take operator), makes sure that you never iterate until you actually requests a specific value.
You might have already figured it out by now but these two things means that For Each effectively have no concept of bounds because it simply does not require them. The only use for GetLowerBound and GetUpperBound are for non-zero-indexed arrays. For instance, you might have an array that indexes values from 1 instead of zero. Even then, you only need GetLowerBound and Length. Obviously, this is only if the position of the element in the source actually matters. If it does not, you can still use For Each to iterate over all elements as it is bound agnostic.
Also, as already mentioned, GetLength should be used for zero-indexed multi-dimensional arrays, again, only if the position of the element matters and not just the element itself.
When I´m using MATLAB, sometimes I feel the need to make comments on some variables. I would like to save these comments inside these variables. So when I have to work with many variables in the workspace, and I forget the context of some of these variables I could read the comments I put in every one of them. So I would like to comment variables and keep the comments inside of them.
While I'm of the opinion that the best (and easiest) approach would be to make your variables self-documenting by giving them descriptive names, there is actually a way for you to do what you want using the object-oriented aspects of MATLAB. Specifically, you can create a new class which subclasses a built-in class so that it has an additional property describing the variable.
In fact, there is an example in the documentation that does exactly what you want. It creates a new class ExtendDouble that behaves just like a double except that it has a DataString property attached to it which describes the data in the variable. Using this subclass, you can do things like the following:
N = ExtendDouble(10,'The number of data points')
N =
The number of data points
10
and N could be used in expressions just as any double value would. Using this example subclass as a template, you could create "commented" versions of other built-in numeric classes, with the exception of those you are not allowed to subclass (char, cell, struct, and function_handle).
Of course, it should be noted that instead of using the ExtendDouble class like I did in the above example, I could instead define my variable like so:
nDataPoints = 10;
which makes the variable self-documenting, albeit with a little more typing needed. ;)
How about declaring another variable for your comments?
example:
\>> num = 5;
\>> numc = 'This is a number that contains 5';
\>> whos
...
This is my first post in StackOverflow. Thanks.
A convenient way to solve this is to have a function that does the storing and displaying of comments for you, i.e. something like the function below that will pop open a dialog box if you call it with comments('myVar') to allow you to enter new (or read/update previous) comments to variable (or function, or co-worker) labeled myVar.
Note that the comments will not be available in your next Matlab session. To make this happen, you have to add save/load functionality to comments (i.e. every time you change anything, you write to a file, and any time you start the function and database is empty, you load the file if possible).
function comments(name)
%COMMENTS stores comments for a matlab session
%
% comments(name) adds or updates a comment stored with the label "name"
%
% comments prints all the current comments
%# database is a n-by-2 cell array with {label, comment}
persistent database
%# check input and decide what to do
if nargin < 1 || isempty(name)
printDatabase;
else
updateDatabase;
end
function printDatabase
%# prints the database
if isempty(database)
fprintf('no comments stored yet\n')
else
for i=1:size(database,1)
fprintf('%20s : %s\n',database{i,1},database{i,2});
end
end
end
function updateDatabase
%# updates the database
%# check whether there is already a comment
if size(database,1) > 0 && any(strcmp(name,database(:,1)))
idx = strcmp(name,database(:,1));
comment = database(idx,2);
else
idx = size(database,1)+1;
comment = {''};
end
%# ask for new/updated comment
comment = inputdlg(sprintf('please enter comment for %s',name),'add comment',...
5,comment);
if ~isempty(comment)
database{idx,1} = name;
database(idx,2) = comment;
end
end
end
Always always always keep the Matlab editor open with a script documenting what you do. That is, variable assignments and calculations.
Only exceptions are very short sessions where you want to experiment. Once you have something -- add it to the file (It's also easier to cut and paste when you can see your entire history).
This way you can always start over. Just clear all and rerun the script. You never have random temporaries floating around in your workspace.
Eventually, when you are finished, you will also have something that is close to 'deliverable'.
Have you thought of using structures (or cells, although structures would require extra memory use)?
'>> dataset1.numerical=5;
'>> dataset1.comment='This is the dataset that contains 5';
dataset1 =
numerical: 5
comment: 'This is the dataset that contains 5'
I'm on OS X, and in objective-c I'm trying to convert
for example,
"Bobateagreenapple"
into
"Bob ate a green apple"
Is there any way to do this efficiently? Would something involving a spell checker work?
EDIT: Just some extra information:
I'm attempting to build something that takes some misformatted text (for example, text copy pasted from old pdfs that end up without spaces, especially from internet archives like JSTOR). Since the misformatted text is probably going to be long... well, I'm just trying to figure out whether this is feasibly possible before I actually attempt to actually write system only to find out it takes 2 hours to fix a paragraph of text.
One possibility, which I will describe this in a non-OS specific manner, is to perform a search through all the possible words that make up the collection of letters.
Basically you chop off the first letter of your letter collection and add it to the current word you are forming. If it makes a word (eg dictionary lookup) then add it to the current sentence. If you manage to use up all the letters in your collection and form words out of all of them, then you have a full sentence. But, you don't have to stop here. Instead, you keep running, and eventually you will produce all possible sentences.
Pseudo-code would look something like this:
FindWords(vector<Sentence> sentences, Sentence s, Word w, Letters l)
{
if (l.empty() and w.empty())
add s to sentences;
return;
if (l.empty())
return;
add first letter from l to w;
if w in dictionary
{
add w to s;
FindWords(sentences, s, empty word, l)
remove w from s
}
FindWords(sentences, s, w, l)
put last letter from w back onto l
}
There are, of course, a number of optimizations you could perform to make it go fast. For instance checking if the word is the stem of any word in the dictionary. But, this is the basic approach that will give you all possible sentences.
Solving this problem is much harder than anything you'll find in a framework. Notice that even in your example, there are other "solutions": "Bob a tea green apple," for one.
A very naive (and not very functional) approach might be to use a spell-checker to try to isolate one "real word" at a time in the string; of course, in this example, that would only work because "Bob" happens to be an English word.
This is not to say that there is no way to accomplish what you want, but the way you phrase this question indicates to me that it might be a lot more complicated than what you're expecting. Maybe someone can give you an acceptable solution, but I bet they'll need to know a lot more about what exactly you're trying to do.
Edit: in response to your edit, it would probably take less effort to run some kind of OCR tool on a PDF and correct its output than it would just to correct what this system might give you, let alone program it
I implemented a solution, the code is avaible on code project:
http://www.codeproject.com/Tips/704003/How-to-add-spaces-between-spaceless-strings
My idea was to prioritize results that use up most of the characters (preferable all of them) then favor the ones with the longest words, because 2,3 or 4 character long words can often come up by chance from leftout characters. Most of the times this provides the correct solution.
To find all possible permutations I used recursion. The code is quite fast even with big dictionaries (tested with 50 000 words).