Undefined offset ??? PHP my code attached [duplicate] - for-loop

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
PHP: “Notice: Undefined variable” and “Notice: Undefined index”
i am getting "ranksection" array at run time and after implementing ksort on "ranksection" i wanna move its data upward on null index as i am printing ranksection before moving its data upward if there were any free array i am successfully getting what i want but it also giving error "Undefined Index" i dont know why my code is,
$sortvar = count($ranksection);
$seqnum = 0;
for ($var = 0; $var <= $sortvar; $var++) {
if ($ranksection[$var] != null) {
$sequence[$seqnum] = $ranksection[$var];
$seqnum++;
}
}
print_r($sortvar);
print_r($ranksection);
print_r($sequence);
the result is,
3
Array ( [1] => Self Introduction [2] => Experience in Econometrics and multivariate S [3] => Experience )
Array ( [0] => Self Introduction [1] => Experience in Econometrics and multivariate S [2] => Experience )
Hopes for your suggestions

See your print_r section of second array it starts with index 1 and your $var assigned to 0.
Now here you are trying to access the 0th index. that is why you're getting this error.
Try to use foreach
foreach($ranksection as $key => $value ) {
if ($ranksection[$key] != null) {
$sequence[$seqnum] = $ranksection[$key];
$seqnum++;
}
}

Do this as the condition for your for loop:
for ($var = 0; $var <= $sortvar - 1; $var++) {
The -1 is important since arrays start from 0 and go the length of the array, minus one.

You ought to be using count()-1 in your for loop:
$sortvar = count($ranksection) -1;
$seqnum = 0;
for ($var = 0; $var <= $sortvar; $var++) {
Or, use less than (without less than equal to) as the operator:
for ($var = 0; $var < $sortvar; $var++) {

You're going past the end of your array because:
$sortvar = count($ranksection); // This is 4
Array indexs start at 0, but count returns the number where 1 is the first item, not 0. Do this to fix it:
$sortvar = count($ranksection) - 1;
Or change <= to <
for ($var = 0; $var < $sortvar; $var++) {
if ($ranksection[$var] != null) {
$sequence[$seqnum] = $ranksection[$var];
$seqnum++;
}
}

Related

How to chech if the string characters have equal duplicates

I want to Check if the characters of a string have equal duplicate
if I enter :"abaababb"
returns true because I have 4 'a' and 4 'b' in that string
if I enter : "addda"
returns false because I have 2 'a' and 3 'd'
I tryed to check the duplicates but I found out I have to do it for some characters
just need to create an empty object and loop through each character and increment the value associated with the key. Keep track of the highest value so we can easily use every on the array from Object.values and check if all character counts match this value
let check = "abaababb";
let check2 = "addda";
function hasEqualCharacters( input ) {
let characters = {};
let highestCount = 0;
for( let i =0; i < input.length; i++) {
if( characters[input[i]]) {
characters[input[i]]++;
if( highestCount < characters[input[i]]) {
highestCount = characters[input[i]];
}
} else {
characters[input[i]] = 1;
}
}
return Object.values(characters).every( (charCount) => {
return charCount === highestCount;
});
}
console.log(hasEqualCharacters(check));
console.log(hasEqualCharacters(check2));
Can see it working here
https://playcode.io/1024243

In the following code variable 'checkNumber' is not incrementing to 1 even after 'if' block get executed and so that Break is not working

In the following code variable 'checkNumber' is not incrementing to 1 even after 'if' block get executed and so that Break is not working where i need to break the loop
var checkNumber =0
for (let i = 0; i < totalRowCountAllocPrj; i++){
allocationObjects.getAllocationStatusfromGrid(i).then(text => {
appAllocStatus = Cypress.$(text).text()
cy.log("Allocation Status :" + appAllocStatus)
if(appAllocStatus == userData.approvalReservedAllocStatus){
allocationObjects.getAppAllCheckBoxesfromGrid(i).click()
checkNumber=checkNumber+1
cy.log("index="+i)
}
else{
cy.log("Project is not Reserved")
}
})
cy.log("number="+checkNumber)
if(checkNumber==1)
{
break
}
The variable checkNumber gets incremented inside an asynchronous command, but the loop is running synchronously.
You can't use break but you should be able to stop executing the commands with the inverse check.
Since checkNumber never should go above 0, it's more sensible to use a boolean
let found = 0
for (let i = 0; i < totalRowCountAllocPrj; i++) {
cy.then(() => {
if (!found) {
allocationObjects.getAllocationStatusfromGrid(i).then(text => {
appAllocStatus = Cypress.$(text).text()
if (appAllocStatus === userData.approvalReservedAllocStatus) {
allocationObjects.getAppAllCheckBoxesfromGrid(i).click()
found = true
}
})
}
})
}
BTW you should be able to rewrite allocationObjects.getAllocationStatusfromGrid() to directly search for userData.approvalReservedAllocStatus and get rid of the loop altogether.

Create a sorted list from n sorted sublists (efficiently)

I was playing around with parallel sorting tonight.
creating sort file
naive-sort ...
1000000
23.61265496
partial-hyper-sort ...
4
7.4924575
simple-hyper-sort ...
1000000
141.7945921
naive-hyper-sort ...
1000000
23.5756172
Two things stand out.
a) naive-hyper-sort is just as fast as ordinary sort
b) The sorting in partial-hyper-sort is 66% faster than ordinary sort.
My problem: partial-hyper-sort is exactly that: "partial". It returns (on my system) 4 sublists, but you want of course one. My attempt to merge them into one (simple-hyper-sort) is an order of magnitude slower than the whole sorting!
So how do I get this faster? And if someone can explain why naive-hyper-sort is not faster than naive-sort, bonus points and a cookie (seriously, a literal cookie).
create-sortfile
unless "tosort.txt".IO.e;
my $start = DateTime.now;
say "naive-sort ...";
say naive-sort.elems;
say DateTime.now - $start;
$start = DateTime.now;
say "partial-hyper-sort ...";
say partial-hyper-sort.elems;
say DateTime.now - $start;
$start = DateTime.now;
say "simple-hyper-sort ...";
say simple-hyper-sort.elems;
say DateTime.now - $start;
$start = DateTime.now;
say "naive-hyper-sort ...";
say naive-hyper-sort.elems;
say DateTime.now - $start;
sub create-sortfile
{
say "creating sort file";
my $to-sort = "tosort.txt".IO.open(:w);
$to-sort.say( ( 10_000 .. 99_999 ).pick )
for ( 1 .. 1_000_000 );
$to-sort.close;
}
sub simple-hyper-sort
{
my $to-sort = "tosort.txt".IO.open( :r );
my $lines = $to-sort.lines;
my $degrees = $*KERNEL.cpu-cores;
my $batch = $lines.elems div $degrees;
my #parts = $lines.batch( $batch ).hyper( :batch(1) ).map({ .sort });
my #index = 0 xx $degrees;
return gather loop
{
my $smallest = Inf;
my $smallest-index = -1;
my $smallest-degree = -1;
for ^$degrees -> $degree
{
my $index = #index[$degree];
if ( $index < $batch )
{
my $value = #parts[$degree;$index];
if $value < $smallest
{
$smallest = $value;
$smallest-index = $index;
$smallest-degree = $degree;
}
}
}
last if $smallest-index < 0;
#index[$smallest-degree]++;
take $smallest;
}
}
sub partial-hyper-sort
{
my $to-sort = "tosort.txt".IO.open( :r );
my $lines = $to-sort.lines;
my $degrees = $*KERNEL.cpu-cores;
my $batch = $lines.elems div $degrees;
my #parts = $lines.batch( $batch ).hyper( :batch(1) ).map({ .sort });
}
multi sub naive-hyper-sort
{
my $to-sort = "tosort.txt".IO.open( :r );
my $lines = $to-sort.lines;
my $degrees = $*KERNEL.cpu-cores;
my $batch = $lines.elems div $degrees;
$lines.hyper( :$batch, :$degrees ).sort;
}
sub naive-sort {
my $to-sort = "tosort.txt".IO.open( :r );
$to-sort.lines.sort;
}
Using .hyper and .race only results in a speedup if there is a parallel implementation of the operation that follows. At the time of writing, there is not a parallel sort implementation in Rakudo, which means that it will fall back to using the regular sort implementation. So, this answers why native-hyper-sort doesn't come out faster right now (however it almost certainly will in the future).
The idea in simple-hyper-sort is along the right lines: break the data up into sublists, sort the sublists, and then merge them. We can therefore parallelize the sorting of the sublists. As you've observed, this achieving a win is dependent on the merge operation itself being fast enough, and so we'd need to carefully optimize that.
It's much easier to write a tight (not to mention correct!) merge operation if it only needs to merge two sublists. Thus, we need to structure the problem in a way that gives us that. This points to a different approach:
Break the list in half
start a task to sort each half
await the two tasks
Merge the results of the two tasks
Note that step 2 involves recursion. We stop recursing when the size of a partition is too small, and use the built-in sort on such partitions. (We can choose to define "too small" by dividing the input list size by the number of CPU cores, along the lines of your example.)
Thus we get a solution like this:
sub parallel-merge-sort {
my $to-sort = "tosort.txt".IO.open( :r );
my $lines = $to-sort.lines;
return do-sort $lines, ceiling($lines.elems / $*KERNEL.cpu-cores);
sub do-sort(#in, $limit) {
if #in.elems < $limit {
#in.sort
}
else {
my $pivot = #in.elems div 2;
merge |await
(start do-sort #in[0..$pivot], $limit),
(start do-sort #in[$pivot^..#in.end], $limit)
}
}
sub merge(#a, #b) {
my #result;
my int $a-idx = 0;
my int $a-elems = +#a;
my int $b-idx = 0;
my int $b-elems = +#b;
my int $r-idx = 0;
while $a-idx < $a-elems && $b-idx < $b-elems {
my $a := #a[$a-idx];
my $b := #b[$b-idx];
if $a before $b {
$a-idx++;
#result[$r-idx++] := $a;
}
else {
$b-idx++;
#result[$r-idx++] := $b;
}
}
if $a-idx < $a-elems {
#result[$r-idx++] := $_ for #a[$a-idx..*];
}
elsif $b-idx < $b-elems {
#result[$r-idx++] := $_ for #b[$b-idx..*];
}
return #result;
}
}
I didn't spend terribly long optimizing this (haven't profiled, etc.), but did take care to use natives and binding in order to reduce allocations. On My Machine, this does give a speedup over the serial sorting, however.
One other easy speedup we can get on this - at the cost of a tad more complexity in the code - comes from realizing that we don't need to slice the input in do-sort until the point that we actually need to send it to the built-in sort:
sub do-sort(#in, $limit, $from = 0, $to = #in.end) {
my $elems = $to - $from;
if $elems < $limit {
#in[$from..$to].sort
}
else {
my $pivot = $from + $elems div 2;
merge |await
(start do-sort #in, $limit, $from, $pivot),
(start do-sort #in, $limit, $pivot + 1, $to)
}
}
Which saves some work; by this point, I measure a factor of two speedup on the machine I'm testing it on, which isn't amazing, but given we've an enforced serial O(n) step, and a bunch more parallelized O(n) steps, over the serial sort algorithm, it's perhaps not so disappointing after all.

For loop won't end. Don't know why

I'm writing a for loop for a project that prompts the user to input a number and keeps prompting, continually adding the numbers up. When a string is introduced, the loop should stop. I've done it with a while loop, but the project states that we must do it with a for loop also. The problem is that the prompt keeps running even when 'a = false'. Could someone explain javascript's thinking process? I want to understand why it keeps running back through the loop even though the condition isn't met. Thank you
var addSequence2 = function() {
var total = 0;
var a;
for (; a = true; ) {
var input = prompt("Your current score is " +total+ "\n" + "Next number...");
if (!isNaN(input)) {
a = true;
total = +total + +input;
}
else if (isNaN(input)) {
a = false;
document.write("Your total is " + total);
}
}
};
There is a difference between a = true and a == true.
Your for-loop is basically asking "can I set 'a' to true?", to which the answer is yes, and the loop continues.
Change the condition to a == true (thus asking "Is the value of 'a' true?")
To elaborate, in most programming languages, we distinguish between assignment ("Make 'x' be 4") and testing for equality ("Is 'x' 4?"). By convention (at least in languages that derive their syntax from C), we use '=' to assign/set a value, and '==' to test.
If I'm understanding the specification correctly (no guarantee), what happens here is that the condition condenses as follows:
Is (a = true) true?
Complete the bracket: set a to true
Is (a) true? (we just set it to true, so it must be!)
Try using the equal to operator, i.e. change
for (; a = true; ) {
to
for (; a == true; ) {
You should use a == true instead of a = true......= is an assignment operator
for (; a = true; ), you are assigning the value to the variable "a" and it will always remain true and will end up in infinite loop. In JavaScript it should a===true.
I suspect you want your for to look like this :
for(;a==true;)
as a=true is an assignment, not a comparison.
a == true. The double equal sign compares the two. Single equal assigns the value true to a so this always returns true.
for (; a = true; ) <-- this is an assignation
for (; a == true; ) <-- this should be better
Here's your fixed code :
var addSequence2 = function() {
var total = 0;
var a = true;
for(;Boolean(a);) {
var input = prompt("Your current score is " +total+ "\n" + "Next number...");
if (!isNaN(input)) {
total = total + input;
}
else{
a = false;
document.write("Your total is " + total);
}
}
};

String: replacing spaces by a number

I would like to replace every blank spaces in a string by a fixnum (which is the number of blank spaces).
Let me give an example:
s = "hello, how are you ?"
omg(s) # => "hello,3how10are2you1?"
Do you see a way (sexy if possible) to update a string like this?
Thank you Rubists :)
gsub can be fed a block for the "replace with" param, the result of the block is inserted into place where the match was found. The argument to the block is the matched string. So to implement this we capture as much whitespace as we can ( /\s+/ ) and feed that into the block each time a section is found, returning that string's length, which gets put back where the whitespace was originally found.
Code:
s = "hello, how are you ?"
res = s.gsub(/\s+/) { |m| m.length }
puts res
# => hello,3how10are2you1?
it is possible to do this via an array split : Javascript example
var s = "hello, how are you ?";
function omg( str ) {
var strArr = str.split('');
var count = 0;
var finalStr = '';
for( var i = 0; i < strArr.length; i++ ) {
if( strArr[i] == ' ' ) {
count++;
}
else
{
if( count > 0 ) {
finalStr += '' + count;
count = 0;
}
finalStr += strArr[i];
}
}
return finalStr
}
alert( omg( s ) ); //"hello,3how10are2you1?"
Lol, this seems the best it can be for javascript

Resources