How to use the socket select function - sockets

I'm trying to understand the socket select function.
The first argument, I've read that nfds can be ignored, should be one more the highest descriptor value and also that it should be max count + 1.
What should that number be?
Also if I've got select fds added via FD_SET(), when select returns...
what's the way to iterate thru all the fds that are set (e.g. readable)
with doing something like
if ( FD_SET(socket1, &fds) )
...
if ( FD_SET(socket2, &fds) )
...
I suppose I could put them in an array - but i was hoping there would be an iterator function.

I've read that nfds can be ignored
Only for WinSock's select() on Windows. For select() on other platforms, nfds is required.
The first argument ... should be one more the highest descriptor value and also that it should be max count + 1.
What should that number be?
Exactly what you just said: "one more the highest descriptor value". So, for instance, if you have just socket1 in the fds, then nfds needs to be socket1 + 1. If you have both socket1 and socket2 in the fds, then nfds needs to be max(socket1, socket2) + 1. And so on, with the more descriptors you add to the fds.
Also if I've got select fds added via FD_SET(), when select returns...
what's the way to iterate thru all the fds that are set (e.g. readable)
There isn't one. At least, not a portable way. You need to test each socket individually, eg:
if ( FD_ISSET(socket1, &fds) ) {
...
}
if ( FD_ISSET(socket2, &fds) ) {
...
}
If you put socket1 and socket2 in an array/list, you can then enumerate that instead, eg:
SOCKET sockets[] = ...;
int numSockets = ...;
for(int i = 0; i < numSockets; ++i) {
if ( FD_ISSET(sockets[i], &fds) ) {
...
}
}
i was hoping there would be an iterator function.
There isn't one.

Related

unique with "with" operator in systemverilog

I am a new SystemVerilog user and I have faced a strange (from my point of view) behavior of combination of unique method called for fixed array with with operator.
module test();
int arr[12] = '{1,2,1,2,3,4,5,8,9,10,10,8};
int q[$]
initial begin
q = arr.unique() with (item > 5 ? item : 0);
$display("the result is %p",q);
end
I've expected to get queue {8,9,10} but instead I have got {1,8,9,10}.
Why there is a one at the index 0 ?
You are trying to combine the operation of the find method with unique. Unfortunately, it does not work the way you expect. unique returns the element, not the expression in the with clause, which is 0 for elements 1,2,3,4 and 5. The simulator could have chosen any of those elements to represent the unique value for 0(and different simulators do pick different values)
You need to write them separately:
module test();
int arr[$] = '{1,2,1,2,3,4,5,8,9,10,10,8};
int q[$]
initial begin
arr = arr.find() with (item > 5);
q = arr.unique();
$display("the result is %p",q);
end
Update explaining the original results
The with clause generates a list of values to check for uniqueness
'{0,0,0,0,0,0,0,8,9,10,10,8};
^. ^ ^ ^
Assuming the simulator chooses the first occurrence of a replicated value to remain, then it returns {arr[0], arr[7], arr[8], arr[9]} from the original array, which is {1,8,9,10}

Perl - least common multiple

This code should do the LCM from N numbers.
I tried to put prints wherever I can in order to see where is the mistake. and I think is in:
if($vec[0] == $vec[$n-1]){
$resultado = $vec[0];
last;
}
But I can not make it work.
Could you please help me?
I'm a rookie with Perl.
Hope you can solve this problem.
Also I tried to change the variables but it does not work. I mean
$u = 0 , $w = $n-1;
FULL CODE
To get the LCM, you can split the task into multiple subroutines:
is_prime # returns true if the value is prime
roots # returns the roots of a number (all prime numbers that make up a value. Ex: roots of 12 are: 2, 2, 3)
LCM # takes a list of values. Extract the roots while the number is not prime. Store in a hash like and increment everytime we see the root
So we'll have a hash like:
%sub_total = (
VALUE => TIMES_FOUND,
2 => 2,
3 => 1,
);
We have another hash which is the total. If the sub_total hash has a key that is used more often than in the total hash, we add it to the total.
Finally, we loop through the total hash and and find the product using the algorithm:
for (%total){
$prod *= $_ ** $total {$_};
}
Note
I'll shortly attach the code I wrote for getting the LCM. It's not with me now here.

Seed based randomization perl

I have an array defined say #Array(1..31). Now I have a code where I randomly select a number for a certain number of times and store the results in another array. Example below :
$a1 = $Array[rand(#Array)];
push (#a2, $a1);
Now when I execute this script multiple times, I see that the new array contains very different patter everytime. But I do not want that, I want to generate a similar pattern everytime- where seed comes into picture.
Can someone please help me in how to incorporate seed to randomly select elements from array which can be predictable.?
You do not replace rand with srand: you use srand to initialize the seed for rand: so call srand(0) once and then use rand as you had been.
From your comment, you can use:
srand(0);
sub random {
my $random_select = $_[rand(#_)];
print " The random number selected is $random_select\n";
return $random_select;
}
or back to your original code just add the first line to it:
BEGIN { srand(0) }
$a1 = $Array[rand(#Array)];
push (#a2, $a1);

How to match and delete an element from a queue?

According to 1800-2012 specs,
Queue::delete( [input int index] )
deletes an element of a queue in SystemVerilog, furthermore, a Queue can perform the same operations as an unpacked Array, giving it access to:
Array::find_first_index( )
which returns the index of the first element matching a certain criteria. i.e.
find_first_index( x ) with ( x == 3)
Now I'd like to delete a unique item, guaranteed to exist, from the Queue. Combining 1 and 1 gives me:
queue.delete(queue.find_first_index( x ) with ( x == obj_to_del ));
The compiler does not appreciate that though saying that the argument passed must be either an integer or integer compatible. I could probably pull the two apart:
int index = queue.find_first_index( x ) with ( x == obj_to_del );
queue.delete( index );
or force an integer by typecasting find_first_index:
queue.delete(int'(queue.find_first_index( x ) with ( x == obj_to_del ))) //Just finished compiling, does not work.
The former does not look very elegant to me, and the latter seems somewhat forced which made me curious if there is maybe a more proper way to accomplish this. Is find_first_index possibly returning an array of size one with the index at location 0?
EDIT: I foolishly did not provide a self contained example: A stripped example of what I'm doing looks like:
class parent_task;
endclass;
class child_taskA extends parent_task;
endclass;
class child_taskB extends parent_task;
endclass;
class task_collector;
child_taskA A_queue[$];
child_taskB B_queue[$];
function delete_from_queue(parent_task task_to_del);
case (task_to_del.type):
A: A_queue.delete(A_queue.find_first_index( x ) with ( x == task_to_del));
B: B_queue.delete(B_queue.find_first_index( x ) with ( x == task_to_del));
default: $display("This shouldn't happen.");
endfunction
endclass
The error message, word for word is:
Error-[SV-IQDA] Invalid Queue delete argument
"this.A_queue.find_first_index( iterator ) with ((iterator == task))"
Queue method delete can take optional integer argument. So, argument passed
to it must be either integer or integer assignment compatible.
There are checks in place to make sure that the task in question exists before the call to delete_from_queue.
The int cast didn't work for me as well but the following worked
int index_to_del[$];
index_to_del = que.find_first_index(x) with ( x == task_to_del );
que.delete(index_to_del[0]);
queue.delete(int'(queue.find_first_index( x ) with ( x == obj_to_del )));
works for me. It would really help if you could provide complete self contained examples like the one below:
module top;
int queue[$] = {1,2,3,4,5};
let object_to_del = 3;
initial begin
queue.delete(int'(queue.find_first_index( x ) with ( x == object_to_del )));
$display("%p", queue);
end
endmodule
But what if there was no match? Would you not need to test the result from find_first_index() anyways before deleting?

Best way to create generic/method consistency for sort.data.frame?

I've finally decided to put the sort.data.frame method that's floating around the internet into an R package. It just gets requested too much to be left to an ad hoc method of distribution.
However, it's written with arguments that make it incompatible with the generic sort function:
sort(x,decreasing,...)
sort.data.frame(form,dat)
If I change sort.data.frame to take decreasing as an argument as in sort.data.frame(form,decreasing,dat) and discard decreasing, then it loses its simplicity because you'll always have to specify dat= and can't really use positional arguments. If I add it to the end as in sort.data.frame(form,dat,decreasing), then the order doesn't match with the generic function. If I hope that decreasing gets caught up in the dots `sort.data.frame(form,dat,...), then when using position-based matching I believe the generic function will assign the second position to decreasing and it will get discarded. What's the best way to harmonize these two functions?
The full function is:
# Sort a data frame
sort.data.frame <- function(form,dat){
# Author: Kevin Wright
# http://tolstoy.newcastle.edu.au/R/help/04/09/4300.html
# Some ideas from Andy Liaw
# http://tolstoy.newcastle.edu.au/R/help/04/07/1076.html
# Use + for ascending, - for decending.
# Sorting is left to right in the formula
# Useage is either of the following:
# sort.data.frame(~Block-Variety,Oats)
# sort.data.frame(Oats,~-Variety+Block)
# If dat is the formula, then switch form and dat
if(inherits(dat,"formula")){
f=dat
dat=form
form=f
}
if(form[[1]] != "~") {
stop("Formula must be one-sided.")
}
# Make the formula into character and remove spaces
formc <- as.character(form[2])
formc <- gsub(" ","",formc)
# If the first character is not + or -, add +
if(!is.element(substring(formc,1,1),c("+","-"))) {
formc <- paste("+",formc,sep="")
}
# Extract the variables from the formula
vars <- unlist(strsplit(formc, "[\\+\\-]"))
vars <- vars[vars!=""] # Remove spurious "" terms
# Build a list of arguments to pass to "order" function
calllist <- list()
pos=1 # Position of + or -
for(i in 1:length(vars)){
varsign <- substring(formc,pos,pos)
pos <- pos+1+nchar(vars[i])
if(is.factor(dat[,vars[i]])){
if(varsign=="-")
calllist[[i]] <- -rank(dat[,vars[i]])
else
calllist[[i]] <- rank(dat[,vars[i]])
}
else {
if(varsign=="-")
calllist[[i]] <- -dat[,vars[i]]
else
calllist[[i]] <- dat[,vars[i]]
}
}
dat[do.call("order",calllist),]
}
Example:
library(datasets)
sort.data.frame(~len+dose,ToothGrowth)
Use the arrange function in plyr. It allows you to individually pick which variables should be in ascending and descending order:
arrange(ToothGrowth, len, dose)
arrange(ToothGrowth, desc(len), dose)
arrange(ToothGrowth, len, desc(dose))
arrange(ToothGrowth, desc(len), desc(dose))
It also has an elegant implementation:
arrange <- function (df, ...) {
ord <- eval(substitute(order(...)), df, parent.frame())
unrowname(df[ord, ])
}
And desc is just an ordinary function:
desc <- function (x) -xtfrm(x)
Reading the help for xtfrm is highly recommended if you're writing this sort of function.
There are a few problems there. sort.data.frame needs to have the same arguments as the generic, so at a minimum it needs to be
sort.data.frame(x, decreasing = FALSE, ...) {
....
}
To have dispatch work, the first argument needs to be the object dispatched on. So I would start with:
sort.data.frame(x, decreasing = FALSE, formula = ~ ., ...) {
....
}
where x is your dat, formula is your form, and we provide a default for formula to include everything. (I haven't studied your code in detail to see exactly what form represents.)
Of course, you don't need to specify decreasing in the call, so:
sort(ToothGrowth, formula = ~ len + dose)
would be how to call the function using the above specifications.
Otherwise, if you don't want sort.data.frame to be an S3 generic, call it something else and then you are free to have whatever arguments you want.
I agree with #Gavin that x must come first. I'd put the decreasing parameter after the formula though - since it probably isn't used that much, and hardly ever as a positional argument.
The formula argument would be used much more and therefore should be the second argument. I also strongly agree with #Gavin that it should be called formula, and not form.
sort.data.frame(x, formula = ~ ., decreasing = FALSE, ...) {
...
}
You might want to extend the decreasing argument to allow a logical vector where each TRUE/FALSE value corresponds to one column in the formula:
d <- data.frame(A=1:10, B=10:1)
sort(d, ~ A+B, decreasing=c(A=TRUE, B=FALSE)) # sort by decreasing A, increasing B