In q, I am trying to call a function f on an incrementing argument id while some condition is not met.
The function f creates a table of random length (between 1 and 5) with a column identifier which is dependent on the input id:
f:{[id] len:(1?1 2 3 4 5)0; ([] identifier:id+til len; c2:len?`a`b`c)}
Starting with id=0, f should be called while (count f[id])>1, i.e. so long until a table of length 1 is produced. The id should be incremented each step.
With the "repeat" adverb I can do the while condition and the starting value:
{(count x)>1} f/0
but how can I keep incrementing the id?
Not entirely sure if this will fix your issue but I was able to get it to work by incrementing id inside the function and returning it with each iteration:
q)g:{[id] len:(1?1 2 3 4 5)0; id[0]:([] identifier:id[1]+til len; c2:len?`a`b`c);#[id;1;1+]}
In this case id is a 2 element list where the first element is the table you are returning (initially ()) and the second item is the id. By amending the exit condition I was able to make it stop whenever the output table had a count of 1:
q)g/[{not 1=count x 0};(();0)]
+`identifier`c2!(,9;,`b)
10
If you just need the table you can run first on the output of the above expression:
q)first g/[{not 1=count x 0};(();0)]
identifier c2
-------------
3 a
The issue with the function f is that when using over and scan the output if each iteration becomes the input for the next. In your case your function is working on a numeric value put on the second pass it would get passed a table.
Related
I have been trying to complete a task from automate the boring stuff.
This is the task."Write a function named collatz() that has one parameter named number. If number is even, then collatz() should print number // 2 and return this value. If number is odd, then collatz() should print and return 3 * number + 1.
Then write a program that lets the user type in an integer and that keeps calling collatz() on that number until the function returns the value 1.Add try and except statements to the previous project to detect whether the user types in a noninteger string."
def collatz(num):
ev_odd = num % 2 #detecs whether number is odd or even
if ev_odd == 1:
num = num * 3 + 1
else:
num = num//2
print(num)
global number
number = num
#the program
print('enter an integer')
number = int(input())
collatz(number)
while number != 1:
collatz(number)
i made this code it is working fine.But I am unable to use try and except statement to this..Help me out. Other recommendation to improve this code are requested.
Regards
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}
I'm trying to see the cases that have a specific sub sequence or sub string.
In the user's guide section 10.5.1-10.5.2 it specifies how to find cases with a specific sub sequence:
mysubseqstr <- character(2)
mysubseqstr[1] <- "(Parent)-(Left)-(Left+Marr)"
mysubseqstr[2] <- "(Parent)-(Left+Marr)"
mysubseq <- seqefsub(bf.seqestate, strsubseq = mysubseqstr)
print(mysubseq)
Subsequence Support Count
1 (Parent)-(Left+Marr) 0.4870 974
2 (Parent)-(Left)-(Left+Marr) 0.2275 455
Computed on 2000 event sequences
Constraint Value
countMethod One by sequence
msubcount <- seqeapplysub(mysubseq, method = "count")
msubcount[1:3, ]
Following another question answered here (Find specific patterns in sequences, I can list the sequences that contain the sub sequence:
rownames(msubcount)[msubcount[,1]==1]
but I can't figure out how to get a list of id's (defined with the id= option in the seqdef function) have this sub sequence.
The ids passed with the id= argument of seqdef are used as row names for the state sequence object. Assuming your state sequence object is seq and that you created the event sequence object bf.seqestate from it (which you do not show in your code!), you get the ids of the sequences containing your sub sequences with:
rownames(seq)[msubcount[,1] > 0]
Notice, that I use here > because with method = "count" in seqeapplysub you get the number of occurrences of the sub sequence in each sequence, which can be greater than 1.
I noticed this interesting thing about the max() and min() functions in SV LRM (1800-2012) 7.12 (Array manipulation methods). I tried out the max() and min() functions in a dummy SV file
int a[3] = {0,5,5};
int q[$];
int b;
q = a.max(); // legal
b = a.max(); // illegal
The illegal statement error was
Incompatible complex type assignment
Type of source expression is incompatible with type of target expression.
Mismatching types cannot be used in assignments, initializations and
instantiations. The type of the target is 'int', while the type of the
source is 'int$[$]'.
So I commented out the illegal statement and tested it. It compiled and ran fine but I was hoping to get some more insight as to why the function returns a queue and not a single element - I printed out the contents of q and the size, but the size is still 1 and 5 is being printed just once. Kind of redundant then to make the max() and min() functions return a queue ?
The "SystemVerilog for Verification" book by Chris Spear and Greg Tumbush has a good explanation on this topic in Chapter 2.6.2, which I am quoting below:
"The array locator methods find data in an unpacked array. At first
you may wonder why these return a queue of values. After all, there
is only one maximum value in an array. However, SystemVerilog needs a
queue for the case when you ask for a value from an empty queue or
dynamic array."
It returns a queue to deal with empty queues and when the with () conditions have no matches. The the empty queue return is a a way to differentiate a true match from no matches.
Consider the below code. to find the minimum value of a that is greater than 5. a has data but none of its entries have above 5. b is empty, so it will return an empty. c will return 7.
int a[3] = '{0,5,5};
int b[$] = '{};
int c[4] = '{0,15,5,7};
int q[$];
q = a.min() with (item > 5); // no items >5, will return an empty queue
q = b.min(); // queue is empty, will return an empty queue
q = c.min() with (item > 5); // will return a queue of size 1 with value 7
I believe the example results as per Greg's answer is not correct.
As per System Verilog Language:
min() returns the element with the minimum value or whose expression evaluates to a minimum.
max() returns the element with the maximum value or whose expression evaluates to a maximum.
So, when with expression is evaluated, the resultant value will be:
a.min() with (item > 5); {0,0,0} -> Minimum is 0 and corresponding item is 5.
c.min() with (item > 5); {0,1,0,1}-> Minimum is 0 and corresponding item is 5.
Since, example demonstrates the usage of min, the result will be:
q = a.min() with (item > 5); // A queue of size 1 with value 5.
q = c.min() with (item > 5); //A queue of size 1 with value 5.
I have this function f
f:{{z+x*y}[x]/[y]}
I am able to call f without a 3rd parameter and I get that, but how is the inner {z+x*y} able to complete without a third parameter?
kdb will assume, if given a single list to a function which takes two parameters, that you want the first one to be x and the remainder to be y (within the context of over and scan, not in general). For example:
q){x+y}/[1;2 3 4]
10
can also be achieved by:
q){x+y}/[1 2 3 4]
10
This is likely what's happening in your example.
EDIT:
In particular, you would use this function like
q){{z+x*y}[x]/[y]}[2;3 4 5 6]
56
which is equivalent to (due to the projection of x):
q){y+2*x}/[3 4 5 6]
56
which is equivalent to (due to my original point above):
q){y+2*x}/[3;4 5 6]
56
Which explains why the "third" parameter wasn't needed
You need to understand 2 things: 'over' behavior with dyadic functions and projection.
1. Understand how over/scan works on dyadic function:
http://code.kx.com/q/ref/adverbs/#over
If you have a list like (x1,x2,x3) and funtion 'f' then
f/(x1,x2,x3) ~ f[ f[x1;x2];x3]
So in every iteration it takes one element from list which will be 'y' and result from last iteration will be 'x'. Except in first iteration where first element will be 'x' and second 'y'.
Ex:
q) f:{x*y} / call with -> f/ (4 5 6)
first iteration : x=4, y=5, result=20
second iteration: x=20, y=6, result=120
2. Projection:
Lets take an example funtion f3 which takes 3 parameters:
q) f3:{[a;b;c] a+b+c}
now we can project it to f2 by fixing (passing) one parameter
q) f2:f3[4] / which means=> f2={[b;c] 4+b+c}
so f2 is dyadic now- it accepts only 2 parameters.
So now coming to your example and applying above 2 concepts, inner function will eventually become dyadic because of projection and then finally 'over' function works on this new dyadic function.
We can rewrite the function as :
f:{
f3:{z+x*y};
f2:f3[x];
f2/y
}