So in my app I am trying to do a simple math in one of my methods without using a ton of if/else statements.
So I have an integer named 'StartInt' which is at max 13. Now what I need to get is FinishInt an integer that will be the result of this pattern:
StartInt: 13 FinishInt: 1
StartInt: 12 FinishInt: 2
StartInt: 11 FinishInt: 3
etc... all the way down until StartInt is 1 and FinishInt is 13. Anyway how would I accomplish this? I know this must be simple but I am just not that great in Math! :)
All the way down until StartInt is 0 and FinishInt is 13. Anyway how
would I accomplish this?
That won't quite work if startInt = 13 gives finishInt = 1 and you want a finishInt to increment 1 for each decrement of startInt. Check out the following table:
13 1
12 2
11 3
10 4
9 5
8 6
7 7
6 8
5 9
4 10
3 11
2 12
1 13
So you're off by 1 at either the beginning or end of your sequence. Nevertheless, it looks like you want something like this:
(int) calculateFinish(int startInt)
{
int finishInt = -1;
if (startInt >= 0 && startInt <= 13) {
finishInt = 14 - startInt;
}
return finishInt;
}
That'd give a value of 14 for finishInt when startInt = 0.
Related
How can I code this 'if' conditions in GAMS?
Set j/1*10/
S/1*6/;
Parameter
b(s,j) export this from excel
U(s,j) export from excel
M(s)/1 100,2 250,3 140,4 120,5 132/ export from excel
;
table b(s,j)
1 2 3 4 5 6 7 8 9 10
1 3 40 23 12 9 52 9 14 89 33
2 0 0 42 0 11 32 11 15 3 7
3 10 20 12 9 5 30 14 5 14 5
4 0 0 0 9 0 3 8 0 13 5
5 0 10 11 32 11 0 3 1 12 1
6 12 20 2 9 15 3 14 5 14 5
;
u(s,j)=0;
u(s,j)$(b(s,j))=1;
Variable delta(j); "binary"
After solving a model I got the value of delta ( suppose delta(1)=1, delta(5)=1). Then Set A is
A(j)$(delta.l(j)=1)=Yes; (A={1,5})
I want to calculate parameter R(s) according to the following :
If there is no j in A(j) s.t. j in u(s,j) then R(s)=M(s)
Else if there is a j in A(j) s.t. j in u(s,j) then R(s)=min{b(s,j): j in A(j) , j in u(s,j) }
Then R(1)=3, R(2)=11,R(3)=5, R(4)=120, R(5)=11,R(6)=12.
Is it possible to code this ' if then ' statement only by $ utility?
Thanks
Following on from the comments, I think this should work for you.
(Create a parameter that mimics your variable delta just for demonstration:)
parameter delta(j);
delta('1') = 1;
delta('5') = 1;
With loop and if/else:
Create parameter R(s). Then, looping over s , pick the minimum of b(s,A) across set A where b(s,A) is defined if the sum of b(s,A) is not zero (i.e. if one of the set is non-zero. Else, set R(s) equal to M(s).
Note, the loop is one solution to the issue you were having with mixed dimensions. And the $(b(s,A)) needs to be on the first argument of smin(.), not on the second argument.
parameter R(s);
loop(s,
if (sum(A, b(s,A)) ne 0,
R(s) = smin(A$b(s,A), b(s,A));
else
R(s) = M(s);
);
);
With $ command only (#Lutz in comments):
R(s)$(sum(A, b(s,A)) <> 0) = smin(A$b(s,A), b(s,A));
R(s)$(sum(A, b(s,A)) = 0) = M(s);
Gives:
---- 56 PARAMETER R
1 3.000, 2 11.000, 3 5.000, 4 120.000, 5 11.000, 6 12.000
I am trying to make an auctions system but can not figure out the logical conditions for doing so..
Lets say that I have 10 credit
$credit
I have already bet 5 credits on another auction... so I owe 5 from 10 $owe
I thus have 5 available... $available = $credit - $owe (=5)
I bet 3 from available (on a different item)...
I wish to bet again 4 (cancel 3, update to 4), but credit available is now $available - 3 (=2)
Can't find a logical solution.... written in code.
What is the condition for setting a bet???
Made up a matrix with the dependence between variables:
bet available owe lastbet
1 10 10 0
2 9 11 1
3 7 13 2
4 4 16 3
5 0 20 4
6 -5 25 5
7 -11 31 6
8 -18 38 7
9 -26 46 8
10 -35 55 9
11 -45 65 10
Need to translate it into a condition statement.... (the next row would not meet the conditions)
The condition should fail on the 11th row....
Based on the Matrix... I found out that the condition is:
if ($bet <= (($owe + $available) / 2)) {}
Not very intuitive......
I tried parsing a common string depiction of ranges (e.g. 1-9) into actual ranges (e.g. 1 .. 9), but often got weird results when including two digit numbers. For example, 1-10 results in the single value 1 instead of a list of ten values and 11-20 gave me four values (11 10 21 20), half of which aren't even in the expected numerical range:
put get_range_for('1-9');
put get_range_for('1-10');
put get_range_for('11-20');
sub get_range_for ( $string ) {
my ($start, $stop) = $string.split('-');
my #values = ($start .. $stop).flat;
return #values;
}
This prints:
1 2 3 4 5 6 7 8 9
1
11 10 21 20
Instead of the expected:
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18 19 20
(I figured this out before posting this question, so I have answered below. Feel free to add your own answer if you'd like to elaborate).
The problem is indeed that .split returns Str rather than Int, which the original answer solves. However, I would rather implement my "get_range_for" like this:
sub get_range_for($string) {
Range.new( |$string.split("-")>>.Int )
}
This would return a Range object rather than an Array. But for iteration (which is what you most likely would use this for), this wouldn't make any difference. Also, for larger ranges the other implementation of "get_range_for" could potentially eat a lot of memory because it vivifies the Range into an Array. This doesn't matter much for "3-10", but it would for "1-10000000".
Note that this implementation uses >>.Int to call the Int method on all values returned from the .split, and then slips them as separate parameters with | to Range.new. This will then also bomb should the .split return 1 value (if it couldn't split) or more than 2 values (if multiple hyphens occurred in the string).
The result of split is a Str, so you are accidentally creating a range of strings instead of a range of integers. Try converting $start and $stop to Int before creating the range:
put get_range_for('1-9');
put get_range_for('1-10');
put get_range_for('11-20');
sub get_range_for ( $string ) {
my ($start, $stop) = $string.split('-');
my #values = ($start.Int .. $stop.Int).flat; # Simply added .Int here
return #values;
}
Giving you what you expect:
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18 19 20
The raw data in my table consists of an ID column and a column 'IsFolder' which can be 1 or 0, like this:
ID IsFolder
1 1
2 0
3 0
4 1
5 0
6 0
7 0
8 0
9 0
10 0
11 1
12 0
13 0
14 0
15 1
16 0
17 0
The way the code interprets this is that if a line has a 1 for 'IsFolder' then it is a Folder, and all of the tasks below it (until you hit the next Folder) are children of that folder.
What I'd like to have is a Select statement that will just return the ID of the parent folder for all non-folder tasks. So something like:
ID ParentFolder
2 1
3 1
5 4
6 4
7 4
8 4
9 4
10 4
12 11
13 11
14 11
16 15
17 15
I'm using MS SQL Server Management Studio 2005. I feel like this is an easy answer to those familiar with using cursors (which I am not). I can't think of any other way to do it but maybe someone else can. Anyway thanks in advance for any answers and sorry if I did something wrong, this is my first post.
You don't need a cursor for that - just a subquery:
SELECT ID,
(SELECT MAX(ID)
FROM Folders
WHERE ID < f.ID
AND IsFolder = 1) AS Parent
FROM Folders f
WHERE IsFolder = 0
I'd just like to point out that this task would be much easier, and the overall design much more extensible, if the structure of the data was changed a little. How are you going to add a task to folder 4, for example? If the parent and child relationship was extracted to two different tables, it might help.
I have to manipulate range of cells in excel using VB. Can I do it in the following manner ?
Range("a1:b5")=[1 2 3 4 5 6 7 8 9 0]
I don't think so, I've never seen that syntax. One thing you can do is something like:
For Row = 1 To 5
Range("a" + CStr(Row)).Value = Row
Range("b" + CStr(Row)).Value = (Row + 5) Mod 10
Next Row
assuming that you want it set up thus:
A B
+------
1 | 1 6
2 | 2 7
3 | 3 8
4 | 4 9
5 | 5 0
You may need to use Mid(CStr(Row),2) - I can't remember off the top of my head if Cstr gives you a leading space for non-negative numbers.