Simple question, is it possible to do a for loop on a range of negative values? Specifically starting at -1 and iterating down to some negative value. for i in -1..x apparently isn't kosher.
Other than the ugly solution of iterating on the absolute values and then applying the sign within the loop.
The problem isn't in the negative numbers, the problem is in the reverse range. If we assume that x < -1 then you have a range (a,b) with a > b.
The default step of a rust range in a for loop is +1, so the loop never executes. If you write it out, C++ style, you'd be saying
for (i=-1; i < x; i++) { ... }
So what you want to do is reverse the range:
for i in (x..=-1).rev()
EDIT: Because (x..-1) does not include -1, we need to change it to (x..=-1). In that case the range will include both x and 1. If we don't want that, we have to fiddle with the x bound as well, e.g. ((x+1)..=-1).rev
The standard Range type (what you get with a..b) is a half-open increasing range. If you have a range where a >= b, then the range is empty.
If you want to iterate a range in reverse (decreasing) order, then you need to use Iterator::rev to reverse the range, which is enabled by range being a DoubleEndedIterator and providing the reverse iteration next_back.
So in this case, you'd iterate over ((x + 1)..0).rev().
Just as a fun side note, you can also get basically any iterator you want out of iter::successors, by just providing a fn next(&T) -> Option<T>; in this case, |x| x - 1, if that's clearer in a specific use case than reversing an increasing range.
Related
Let's say my function (foo) takes 2 arguments: startNum, and endNum. I need to return every single a list of every multiple of 2 (or alternatively, every number evenly divisible by 2) that falls within that range by checking each number one by one. It is assumed that endNum will always be greater than startNum.
For example, if the function signature was something like this:
foo :: Int -> Int -> Int[]
Then foo(5,10) would return [6, 8, 10].
So far I have tried to mimic a "for" loop, and attempted to use map and scan/scanl in slightly unconventional ways to try and account for the fact that I am not starting off with a list, but rather a range of numbers. However, I have not been able to find a solution using these methods (my level of experience with Haskell is very low, so that is the biggest factor here in why I have not been able to accomplish so simple of a task).
I am expecting the solution, in some way, to use recursion. I am not sure exactly how to begin an implementation of this, or if my previously attempted methods are even correct ways to go about it.
Iteration in Haskell usually means either recursion, or a list comprehension.
For recursion you need a base case and an update case. In your example, we know that if startNum is greater than endNum, the list must be empty. That's easy to write:
foo startNum endNum
| startNum > endNum = []
The trick is the update. Or updates. What do you return if startNum is even? What about when it's not?
foo startNum endNum
| startNum > endNum = []
| even startNum = ...
| otherwise = ...
More natural is a list comprehension with a condition. That code is trivial.
[x | x <- [startNum..endNum], even x]
I started coding in Python 4 days ago, so I'm a complete newbie. I have a dataset that comprises an undefined number of dictionaries. Each dictionary is the x and y of a point in the coordinates.
I'm trying to compute the summatory of xy by nesting the loop that multiplies xy within the loop that sums the products.
However I haven't been able to figure out how to multiply the values for the two keys in each dictionary (so far I only got to multiply all the x*y)
So far I've got this:
If my data set were to be d= [{'x':0, 'y':0}, {'x':1, 'y':1}, {'x':2, 'y':3}]
I've got the code for the function that calculates the product of each pair of x and y:
def product_xy (product_x_per_y):
prod_xy =[]
n = 0
for i in range (len(d)):
result = d[n]['x']*d[n]['y']
prod_xy.append(result)
n+1
return prod_xy
I also have the function to add up the elements of a list (like prod_xy):
def total_xy_prod (sum_prod):
all = 0
for s in sum_prod:
all+= s
return all
I've been trying to find a way to nest this two functions so that I can iterate through the multiplication of each x*y and then add up all the products.
Make sure your code works as expected
First, your functions have a few mistakes. For example, in product_xy, you assign n=0, and later do n + 1; you probably meant to do n += 1 instead of n + 1. But n is also completely unnecessary; you can simply use the i from the range iteration to replace n like so: result = d[i]['x']*d[i]['y']
Nesting these two functions: part 1
To answer your question, it's fairly straightforward to get the sum of the products of the elements from your current code:
coord_sum = total_xy_prod(product_xy(d))
Nesting these two functions: part 2
However, there is a much shorter and more efficient way to tackle this problem. For one, Python provides the built-in function sum() to sum the elements of a list (and other iterables), so there's no need create total_xy_prod. Our code could at this point read as follows:
coord_sum = sum(product_xy(d))
But product_xy is also unnecessarily long and inefficient, and we could also replace it entirely with a shorter expression. In this case, the shortening comes from generator expressions, which are basically compact for-loops. The Python docs give some of the basic details of how the syntax works at list comprehensions, which are distinct, but closely related to generator expressions. For the purposes of answering this question, I will simply present the final, most simplified form of your desired result:
coord_sum = sum(e['x'] * e['y'] for e in d)
Here, the generator expression iterates through every element in d (using for e in d), multiplies the numbers stored in the dictionary keys 'x' and 'y' of each element (using e['x'] * e['y']), and then sums each of those products from the entire sequence.
There is also some documentation on generator expressions, but it's a bit technical, so it's probably not approachable for the Python beginner.
This question has somehow to do with an earlier post from me. See here overlap-of-nested-lists-creates-unwanted-gap
I think that I have found a solution but i can't figure out how to implement it.
First the relevant code since I think it is easier to explain my problem that way. I have prepared a fiddle to show the code:
PYFiddle here
Each iteration fills a nested list in ag depending on the axis. The next iteration is supposed to fill the next nested list in ag but depending on the length of the list filled before.
The generell idea to realise this is as follows:
First I would assign each nested list within the top for-loop to a variable like that:
x = ag[0]
y = ag[1]
z = ag[2]
In order to identify that first list I need to access data_j like that. I think the access would work that way.
data_j[i-1]['axis']
data_j[i-1]['axis'] returns either x,y or z as string
Now I need to get the length of the list which corresponds to the axis returned from data_j[i-1]['axis'].
The problem is how do I connect the "value" of data_j[i-1]['axis'] with its corresponding x = ag[0], y = ag[1] or z = ag[2]
Since eval() and globals() are bad practice I would need a push into the right direction. I couldn't find a solution
EDIT:
I think I figured out a way. Instead of taking the detour of using the actual axis name I will try to use the iterator i of the parent loop (See the fiddle) since it increases for each element from data_j it kinda creates an id which I think I can use to create a method to use it for the index of the nest to address the correct list.
I managed to solve it using the iterator i. See the fiddle from my original post in order to comprehend what I did with the following piece of code:
if i < 0:
cond = 0
else:
cond = i
pred_axis = data_j[cond]['axis']
if pred_axis == 'x':
g = 0
elif pred_axis == 'y':
g = 1
elif pred_axis == 'z':
g = 2
calc_size = len(ag[g])
n_offset = calc_size+offset
I haven't figured yet why cond must be i and not i-1 but it works. As soon as I figure out the logic behind it I will post it.
EDIT: It doesn't work for i it works for i-1. My indices for the relevant list start at 1. ag[0] is reserved for a constant which can be added if necessary for further calculations. So since the relevant indices are moved up by the value of 1 from the beginning already i don't need to decrease the iterator in each run.
An ISBETWEEN function tests whether a value falls between a lower bound and a higher bound. With no native ISBETWEEN function in Excel, the value under test must be compared twice; first with '>' and then with '<' (or '>=' and '<=' for an ISBETWEEN test that is inclusive of the bounds.)
Comparing the value twice means having to calculate it twice, and this can be extremely expensive when that value is an array. With array functions being somewhat cryptic even at the best of times, doubling up on such a calculation also sends the readability of the function plummeting.
My question is whether anyone knows of a technique that delivers ISBETWEEN-like functionality for an array of values without the double calculation of that array? My preference is to do this with native Excel functionality but, if anyone has some great VBA, that would be good too.
Many thanks for your time!
Will
Building from my comment above: This doesn't provide a 100% answer to your question, but since it was pretty generic, I think this is the closest to an answer that I can get.
Imagine a spreadsheet set up like:
We can get a count of all the values that are between 3 and 5 using CTE/Array formula:
={SUM(IF(LOOKUP(A1:A6,{3,"B";6,"C"})="B",1,0))}
Results:
5
That's a pretty round-about way of doing this, but the array of A1:A6 only needs to be referenced once. Which is pretty cool.
Note that the squirrely brackets in the above formula aren't actually entered, but are placed by excel when you enter the array formula to indicate that it's an array formula... you probably already know that though if you've read this far.
So I've been able to develop a piece of VBA, based on the idea here.
Dim vValueArg As Variant, vLowerArg As Variant, vUpperArg As Variant, vTestLower As Variant, vTestUpper As Variant
Function ISBETWEEN(vValue As Variant, vLower As Variant, vUpper As Variant, Optional bInc As Boolean = True) As Variant
vValueArg = vValue
vLowerArg = vLower
vUpperArg = vUpper
If bInc Then
vTestLower = [GetValue() >= GetLower()]
vTestUpper = [GetValue() <= GetUpper()]
Else
vTestLower = [GetValue() > GetLower()]
vTestUpper = [GetValue() < GetUpper()]
End If
ISBETWEEN = [IF((GetTestLower() * GetTestUpper()) = 1, TRUE, FALSE)]
End Function
Function GetValue() As Variant
GetValue = vValueArg
End Function
Function GetLower() As Variant
GetLower = vLowerArg
End Function
Function GetUpper() As Variant
GetUpper = vUpperArg
End Function
Function GetTestLower() As Variant
GetTestLower = vTestLower
End Function
Function GetTestUpper() As Variant
GetTestUpper = vTestUpper
End Function
The first argument can be a single value, range or array. If a single value, then the next two arguments must also be single values (but this kinda defeats the purpose of the code!)
The second and third arguments can also be a single value, range or array. If a range consisting of multiple cells or array of multiple values, then the dimensions of these arguments must match those of the first argument. (NB - I have NOT tested the code with 2 dimensional ranges or arrays!)
The final, optional, argument determines whether the ISBETWEEN test is performed including or excluding the bounds. TRUE = include bounds; i.e. arg2 <= arg1 <= arg3 (the default, and can therefore be omitted). FALSE = exclude bounds; i.e. arg2 < arg1 < arg3.
While this might not be the prettiest code in the world, it is compact, fast (no loops) and copes with ranges and arrays of any size.
Hope some of you find this useful! :)
I am using something like
int y = Verify.getIntFromList(intArray);
boolean z = Verify.getBoolean();
//do something with y and z i.e. all possible permutations of y and z etc.
I am interested in getting the live count of jpf as it go through each permutation. For example if there are 10 ints in the intArray and we know false and true for boolean so there will be total of 20 permutations. but I want live count as it is going through all of the 20 one by one. Want to use this live count in my program.
Hope I have explained clearly what I want to do?
Thanks
Before your above statements, call
Verify.setCounter(0,0);
Each time you call a Verify.getXXX() call Verify.incrementCounter(0,1);
first argument in the counter statements is the counter index, you can define more than one counter and increment each one based on your logic.
counters are something like static variables of JPF.