I have a string containing several elements, some identical and some unique. I want my code to check every 2 following elements in my string and if they're equal, it should call a function ShuffleString, where the input variable (randomize) is the string itself, that will re-shuffle the string in a new position. Then, the script should re-check every 2 following elements in the string again until no two identical elements appear next to each other.
I have done the following:
My function file ShuffleString works fine. The input variable randomize, as stated earlier, contains the same elements as MyString but in a different order, as this was needed on an unrelated matter earlier in the script.
function [MyString] = ShuffleString(randomize)
MyString = [];
while length(randomize) > 0
S = randi(length(randomize), 1);
MyString = [MyString, randomize(S)];
randomize(S) = [];
end
The script doesn't work as intended. Right now it looks like this:
MyString = ["Cat" "Dog" "Mouse" "Mouse" "Dog" "Hamster" "Zebra" "Obama"...
"Dog" "Fish" "Salmon" "Turkey"];
randomize = MyString;
while(1)
for Z = 1:length(MyString)
if Z < length(MyString)
Q = Z+1;
end
if isequal(MyString{Z},MyString{Q})
[MyString]=ShuffleString(randomize)
continue;
end
end
end
It just seems to reshuffle the string an infinite amount of times. What's wrong with this and how can I make it work?
You are using an infinite while loop that has no way to break and hence it keeps iterating.
Here is a simpler way:
Use the third output argument of the unique function to get the elements in numeric form for easier processing. Apply diff on it to check if consecutive elements are same. If there is any occurrence of same consecutive elements, the output of diff will give at least one zero which when applied with negated all will return true to continue the loop and vice versa. At the end, use the shuffled indices/numeric representation of the strings obtained after the loop to index the first output argument of unique (which was calculated earlier). So the script will be:
MyString = ["Cat" "Dog" "Mouse" "Mouse" "Dog" "Hamster" "Zebra" "Obama"...
"Dog" "Fish" "Salmon" "Turkey"]; %Given string array
[a,~,c] = unique(MyString);%finding unique elements and their indices
while ~all(diff(c)) %looping until there are no same strings together
c = ShuffleString(c); %shuffling the unique indices
end
MyString = a(c); %using the shuffled indices to get the required string array
For the function ShuffleString, a better way would be to use randperm. Your version of function works but it keeps changing the size of the arrays MyString and randomize and hence adversely affects the performance and memory usage. Here is a simpler way:
function MyString = ShuffleString(MyString)
MyString = MyString(randperm(numel(MyString)));
end
I have a test case with the following line:
XCTAssert(testVal == value)
value and testVal are both Decimals. In most cases the equivalence test gives the expected result, but not always. For instance
let value = Decimal(0xFFFF)
... do stuff that generates testVal
XCTAssert(testVal == value) // evaluates false
BUT, when I look at value and testVal, they appear to be the same.
(lldb) print testVal == value
(Bool) $R0 = false // the condition causing the test to fail
(lldb) print value.description
(String) $R1 = "65535" // what you would expect, given the init
(lldb) print testVal.description
(String) $R2 = "65535" // the same as value. Hmmm...
(lldb) print (testVal - value).isZero
(Bool) $R3 = true // the difference is zero, but they are not equal?
I checked all the attributes of the two Decimals and even the hash values are the same, yet they evaluate to not being equal. The only difference I see is that one is compact and the other is not. I don't see a way to force compaction, so I don't know if this is a factor.
When initializing with other values, like 0xFF, 65535.1, and a host of others, the tests compare successfully.
While this sort of behavior is typical of floats, it should not happen for Decimals, should it?
OK, found the answer not long after posting this: It does have to do with the Decimal being compacted. From the docs:
All the NSDecimal... arithmetic functions expect compact NSDecimal arguments.
Once I added the line
NSDecimalCompact(&testVal)
The comparisons worked as expected.
I'm new here. After reading through how to ask and format, I hope this will be an OK question. I'm not very skilled in perl, but it is the programming language what I known most.
I trying apply Perl to real life but I didn't get an great understanding - especially not from my wife. I tell her that:
if she didn't bring to me 3 beers in the evening, that means I got zero (or nothing) beers.
As you probably guessed, without much success. :(
Now factually. From perlop:
Unary "!" performs logical negation, that is, "not".
Languages, what have boolean types (what can have only two "values") is OK:
if it is not the one value -> must be the another one.
so naturally:
!true -> false
!false -> true
But perl doesn't have boolean variables - have only a truth system, whrere everything is not 0, '0' undef, '' is TRUE. Problem comes, when applying logical negation to an not logical value e.g. numbers.
E.g. If some number IS NOT 3, thats mean it IS ZERO or empty, instead of the real life meaning, where if something is NOT 3, mean it can be anything but 3 (e.g. zero too).
So the next code:
use 5.014;
use Strictures;
my $not_3beers = !3;
say defined($not_3beers) ? "defined, value>$not_3beers<" : "undefined";
say $not_3beers ? "TRUE" : "FALSE";
my $not_4beers = !4;
printf qq{What is not 3 nor 4 mean: They're same value: %d!\n}, $not_3beers if( $not_3beers == $not_4beers );
say qq(What is not 3 nor 4 mean: #{[ $not_3beers ? "some bears" : "no bears" ]}!) if( $not_3beers eq $not_4beers );
say ' $not_3beers>', $not_3beers, "<";
say '-$not_3beers>', -$not_3beers, "<";
say '+$not_3beers>', -$not_3beers, "<";
prints:
defined, value><
FALSE
What is not 3 nor 4 mean: They're same value: 0!
What is not 3 nor 4 mean: no bears!
$not_3beers><
-$not_3beers>0<
+$not_3beers>0<
Moreover:
perl -E 'say !!4'
what is not not 4 IS 1, instead of 4!
The above statements with wife are "false" (mean 0) :), but really trying teach my son Perl and he, after a while, asked my wife: why, if something is not 3 mean it is 0 ? .
So the questions are:
how to explain this to my son
why perl has this design, so why !0 is everytime 1
Is here something "behind" what requires than !0 is not any random number, but 0.
as I already said, I don't know well other languages - in every language is !3 == 0?
I think you are focussing to much on negation and too little on what Perl booleans mean.
Historical/Implementation Perspective
What is truth? The detection of a higher voltage that x Volts.
On a higher abstraction level: If this bit here is set.
The abstraction of a sequence of bits can be considered an integer. Is this integer false? Yes, if no bit is set, i.e. the integer is zero.
A hardware-oriented language will likely use this definition of truth, e.g. C, and all C descendants incl Perl.
The negation of 0 could be bitwise negation—all bits are flipped to 1—, or we just set the last bit to 1. The results would usually be decoded as integers -1 and 1 respectively, but the latter is more energy efficient.
Pragmatic Perspective
It is convenient to think of all numbers but zero as true when we deal with counts:
my $wordcount = ...;
if ($wordcount) {
say "We found $wordcount words";
} else {
say "There were no words";
}
or
say "The array is empty" unless #array; # notice scalar context
A pragmatic language like Perl will likely consider zero to be false.
Mathematical Perspective
There is no reason for any number to be false, every number is a well-defined entity. Truth or falseness emerges solely through predicates, expressions which can be true or false. Only this truth value can be negated. E.g.
¬(x ≤ y) where x = 2, y = 3
is false. Many languages which have a strong foundation in maths won't consider anything false but a special false value. In Lisps, '() or nil is usually false, but 0 will usually be true. That is, a value is only true if it is not nil!
In such mathematical languages, !3 == 0 is likely a type error.
Re: Beers
Beers are good. Any number of beers are good, as long as you have one:
my $beers = ...;
if (not $beers) {
say "Another one!";
} else {
say "Aaah, this is good.";
}
Boolification of a beer-counting variable just tells us if you have any beers. Consider !! to be a boolification operator:
my $enough_beer = !! $beers;
The boolification doesn't concern itself with the exact amount. But maybe any number ≥ 3 is good. Then:
my $enough_beer = ($beers >= 3);
The negation is not enough beer:
my $not_enough_beer = not($beers >= 3);
or
my $not_enough_beer = not $beers;
fetch_beer() if $not_enough_beer;
Sets
A Perl scalar does not symbolize a whole universe of things. Especially, not 3 is not the set of all entities that are not three. Is the expression 3 a truthy value? Yes. Therefore, not 3 is a falsey value.
The suggested behaviour of 4 == not 3 to be true is likely undesirable: 4 and “all things that are not three” are not equal, the four is just one of many things that are not three. We should write it correctly:
4 != 3 # four is not equal to three
or
not( 4 == 3 ) # the same
It might help to think of ! and not as logical-negation-of, but not as except.
How to teach
It might be worth introducing mathematical predicates: expressions which can be true or false. If we only ever “create” truthness by explicit tests, e.g. length($str) > 0, then your issues don't arise. We can name the results: my $predicate = (1 < 2), but we can decide to never print them out, instead: print $predicate ? "True" : "False". This sidesteps the problem of considering special representations of true or false.
Considering values to be true/false directly would then only be a shortcut, e.g. foo if $x can considered to be a shortcut for
foo if defined $x and length($x) > 0 and $x != 0;
Perl is all about shortcuts.
Teaching these shortcuts, and the various contexts of perl and where they turn up (numeric/string/boolean operators) could be helpful.
List Context
Even-sized List Context
Scalar Context
Numeric Context
String Context
Boolean Context
Void Context
as I already said, I don't know well other languages - in every language is !3 == 0?
Yes. In C (and thus C++), it's the same.
void main() {
int i = 3;
int n = !i;
int nn = !n;
printf("!3=%i ; !!3=%i\n", n, nn);
}
Prints (see http://codepad.org/vOkOWcbU )
!3=0 ; !!3=1
how to explain this to my son
Very simple. !3 means "opposite of some non-false value, which is of course false". This is called "context" - in a Boolean context imposed by negation operator, "3" is NOT a number, it's a statement of true/false.
The result is also not a "zero" but merely something that's convenient Perl representation of false - which turns into a zero if used in a numeric context (but an empty string if used in a string context - see the difference between 0 + !3 and !3 . "a")
The Boolean context is just a special kind of scalar context where no conversion to a string or a number is ever performed. (perldoc perldata)
why perl has this design, so why !0 is everytime 1
See above. Among other likely reasons (though I don't know if that was Larry's main reason), C has the same logic and Perl took a lot of its syntax and ideas from C.
For a VERY good underlying technical detail, see the answers here: " What do Perl functions that return Boolean actually return " and here: " Why does Perl use the empty string to represent the boolean false value? "
Is here something "behind" what requires than !0 is not any random number, but 0.
Nothing aside from simplicity of implementation. It's easier to produce a "1" than a random number.
if you're asking a different question of "why is it 1 instead of the original # that was negated to get 0", the answer to that is simple - by the time Perl interpreter gets to negate that zero, it no longer knows/remembers that zero was a result of "!3" as opposed to some other expression that resulted in a value of zero/false.
If you want to test that a number is not 3, then use this:
my_variable != 3;
Using the syntax !3, since ! is a boolean operator, first converts 3 into a boolean (even though perl may not have an official boolean type, it still works this way), which, since it is non-zero, means it gets converted to the equivalent of true. Then, !true yields false, which, when converted back to an integer context, gives 0. Continuing with that logic shows how !!3 converts 3 to true, which then is inverted to false, inverted again back to true, and if this value is used in an integer context, gets converted to 1. This is true of most modern programming languages (although maybe not some of the more logic-centered ones), although the exact syntax may vary some depending on the language...
Logically negating a false value requires some value be chosen to represent the resulting true value. "1" is as good a choice as any. I would say it is not important which value is returned (or conversely, it is important that you not rely on any particular true value being returned).
I have a cell array of matlab.unittest.constraints and a cell array of values. I'd like to see if the values match the constraints (respectively). Of course, I can just use a for cycle, something like the following code:
satisfied = zeros(1,argLength);
for i=1:argLength
satisfied(i) = satisfiedBy(cons{i}, val{i});
end;
answer = all(satisfied);
but knowing MATLAB, there must be a way to condense all that into a single line, I just don't know it. I compare the lengths of the arrays beforehand and return false if they're not equal.
Here is a possible CELLFUN statement:
satisfied = cellfun(#satisfiedBy, cons, val);
Make sure satisfiedBy returns only single numeric/logical value.
I have a cell array of length 3 and I want to make a for loop with another cell array with length of 6 , so how can I add extra 3 cells for the first array in order to make the 2 cell arrays equal and to use my for loop in MATLAB?
For example, with 2 inputs:
type = { '12' '62' '5' };
colour = {'re' 'green' 'yellow' 'brown' 'blue' 'black'};
for i = 1:length(colour)
if isequal(colour(i), type(:))
result(i) = type(i);
else
end
end
I need to make the type cell array with the same size with colour cell array (I think I have to add extra 3 empty cells in side the type cell array).
I have to address several issues in your code first:
If you use a cell array, you must use curly braces ({}) to extract elements from it. Instead of writing colour(i) you should be writing colour{i}.
This is not a problem, but it's a matter of good practice. If you don't need to handle the else part of the if statement, don't write it at all.
Preallocate memory so that arrays don't grow inside the loop (it slows down the program). Specifically, add the line result = cell(size(colour)); before the for loop.
Your isequal logic is flawed. Practically, it would always return false because colour{1} is one element and type{:} is many.
According to your example, types contain numbers and colours letters, although they are both strings. Does it make sense to compare the two?
Now, regarding your question, it's up to you to decide how the for loop runs. Since you don't mention what you want to achieve (you rather ask how you want to achieve something without saying what exactly), I cannot say what your for loop should look like, if necessary at all. Maybe you meant to use ismember instead of isequal? If so, the fixed code can look like this:
result = cell(size(colour));
for i = 1:length(colour)
if ismember(colour{i}, type)
result{i} = type{i};
end
end
or shorter, like this:
result = cell(size(colour));
[found, idx] = ismember(colour, type);
result(found) = type{idx(found)}
If you provide more details, maybe I can refine my answer so that it helps you more.