In a series of IF - ELSE IF statements, only the first IF works - syntax

I am trying to create a New variable "X", from Variables "A" "B" and "C".
This is the code that I am using.
I only get the first option "VAS_USAGE=1", the other options are lost.
What I wanted was for VAS_USAGE to have 1 to 6 values.
What am I doing wrong?
```
compute VAS_USAGE=0.
DO IF ((VAS1=1) AND (VAS2=1) AND (VAS3=1)).
COMPUTE VAS_USAGE=1.
ELSE IF ((VAS1=1) AND (VAS2=1) AND (VAS3=0)).
COMPUTE VAS_USAGE=2.
ELSE IF ((VAS1=1) AND (VAS2=0) AND (VAS3=1)).
COMPUTE VAS_USAGE=3.
ELSE IF ((VAS1=1) AND (VAS2=0) AND (VAS3=0)).
COMPUTE VAS_USAGE=4.
ELSE IF ((VAS1=0) AND (VAS2=0) AND (VAS3=1)).
COMPUTE VAS_USAGE=5.
ELSE IF ((VAS1=0) AND (VAS2=0) AND (VAS3=0)).
COMPUTE VAS_USAGE=6.
END IF.
EXECUTE.```
This is how the nested table looks like. This is what I was expecting to get.
This is what I got.
1.00 = 63

As suggested by #user45392 I would check if the answers 'yes' and 'no' are indeed coded as 1 and 0.
In any case I would suggest avoiding the complex 'do if' scheme which might be prone to errors and harder to debug. For example, you could create VAS_USAGE like this:
compute VAS_USAGE = 100*VAS1 + 10*VAS2 + VAS3.
Or if you want to stick to the specific values you gave in your post, add this:
recode VAS_USAGE (111=1)(110=2)(101=3)(100=4)(1=5)(0=6).
Also if you just want a simple index from 1 to 8 you can do this:
compute VAS_USAGE = 4*VAS1 + 2*VAS2 + VAS3 + 1.

Related

Is there a way to use range with Z3ints in z3py?

I'm relatively new to Z3 and experimenting with it in python. I've coded a program which returns the order in which different actions is performed, represented with a number. Z3 returns an integer representing the second the action starts.
Now I want to look at the model and see if there is an instance of time where nothing happens. To do this I made a list with only 0's and I want to change the index at the times where each action is being executed, to 1. For instance, if an action start at the 5th second and takes 8 seconds to be executed, the index 5 to 12 would be set to 1. Doing this with all the actions and then look for 0's in the list would hopefully give me the instances where nothing happens.
The problem is: I would like to write something like this for coding the problem
list_for_check = [0]*total_time
m = s.model()
for action in actions:
for index in range(m.evaluate(action.number) , m.evaluate(action.number) + action.time_it_takes):
list_for_check[index] = 1
But I get the error:
'IntNumRef' object cannot be interpreted as an integer
I've understood that Z3 isn't returning normal ints or bools in their models, but writing
if m.evaluate(action.boolean):
works, so I'm assuming the if is overwritten in a way, but this doesn't seem to be the case with range. So my question is: Is there a way to use range with Z3 ints? Or is there another way to do this?
The problem might also be that action.time_it_takes is an integer and adding a Z3int with a "normal" int doesn't work. (Done in the second part of the range).
I've also tried using int(m.evaluate(action.number)), but it doesn't work.
Thanks in advance :)
When you call evaluate it returns an IntNumRef, which is an internal z3 representation of an integer number inside z3. You need to call as_long() method of it to convert it to a Python number. Here's an example:
from z3 import *
s = Solver()
a = Int('a')
s.add(a > 4);
s.add(a < 7);
if s.check() == sat:
m = s.model()
print("a is %s" % m.evaluate(a))
print("Iterating from a to a+5:")
av = m.evaluate(a).as_long()
for index in range(av, av + 5):
print(index)
When I run this, I get:
a is 5
Iterating from a to a+5:
5
6
7
8
9
which is exactly what you're trying to achieve.
The method as_long() is defined here. Note that there are similar conversion functions from bit-vectors and rationals as well. You can search the z3py api using the interface at: https://z3prover.github.io/api/html/namespacez3py.html

Expressing "equals" in pseudocode

I was just wondering if there is a special way of saying when something equals something. For example in python, if you declare something equals 2, you say something = 2, whereas when you check if something equals something else, you would say:
if something == somethingelse:
So my question is in pseudocode for algorithms if I'm checking to see if a entered password equals a stored password in an IF THEN ELSE ENDIF loop, would I use one or two equal signs:
WHILE attempts < 3
Get EnteredPassword
**IF EnteredPassword = StoredPassword THEN**
Validated = TRUE
ELSE
attempts = attempts + 1
ENDIF
ENDWHILE
Usually, pseudocode is very broad and every author has their own way of expressing it. As
Aziz has noted, usually x <- 1 is used for an assignment and x := x + 1 for an update. Read ':=' as 'becomes' instead of 'equals', however, they are interchangeably used. As for your question, both = and == are accepted answers, as long as it is clear to your reader what your intention is.
To express equals you use the equal mark symbol once, unlike in python where you use the symbol twice to compare two values (eg if variable == 'one'). An example syntax is:
variable = 'one'
WHILE variable = 'one' DO
SEND "hi" TO DISPLAY

Lua 'attempt to call a number value near for..in' error due to unrelated table index assignment -- why?

I'm writing some Lua scripts in Tabletop Simulator and seeing the error attempt to call a number value near for..in that has me completely perplexed. Here's the code snippet with the for loop that is causing the error:
function resetTurnOrder()
local map = getObjectFromGUID(GUIDs.Map)
local shift, center, points = map.getPosition(), map.getTable('MapData').center, map.getSnapPoints()
local i, p = 0
for nation, guids in pairs(GUIDs.Nations) do
print('Resetting turn order for ' .. nation)
if checkScenario(nation) then
i = i + 1
p = map.positionToLocal(shift - points[i].position)
p[1] = p[1] * 0.75 + center[1] * 0.25
p[3] = p[3] * 0.75 + center[3] * 0.25
getObjectFromGUID(guids.turn_token).setPositionSmooth(map.positionToWorld(p), false, false)
getObjectFromGUID(guids.turn_token).setRotationSmooth({0, points[i].rotation[2], 0}, false, false)
print('Done resetting turn order for ' .. nation)
else
print(nation .. ' not in this scenario')
end
end
end
Okay, so first of all I will say that the error went away by commenting out the two lines that assign directly to p[1] and p[3], and when I replaced those lines with the equivalent statement
p = {p[1] * 0.75 + center[1] * 0.25, p[2], p[3] * 0.75 + center[3] * 0.25}
then everything worked perfectly. However, I am completely dumbfounded as to why this would fix the error. I use this exact for loop definition in like half a dozen places to iterate over the players and their components (which are stored in the global GUIDs) and it has worked flawlessly everywhere else.
To add a little more detail, even with the old code the first iteration of the loop works perfectly. The first turn token is moved to its proper position, both messages are printed, but the error prevents further iterations. The error is clearly occurring when incrementing the loop iterator, but I can't understand how assigning directly to p[1] and p[3] could possibly interfere with this but assigning to p is fine. One more detail: declaring p inside the for loop instead of outside beforehand didn't help.
(EDITED TO ADD MORE DETAILS)
After more testing it looks like #luther is probably correct that something weird is going on with the metatable for the value returned by positionToLocal. The value returned by this function is a Vector defined by Tabletop Simulator which I believe is an extension of Unity's Vector3 type. An important detail is that this type allows you to refer to the indices x,y,z and 1,2,3 interchangeably.
So, I replaced the p[1] and p[3] assignments with p.x and p.z which fixed the error. This seems to imply that the Vector returned by positionToLocal did not define indices 1,2,3 explicitly but instead uses a metamethod to link those indices to x,y,z. And, somehow, that metamethod is messing with the loop iterator... but honestly that still boggles my mind.
GUIDs.Nations is the table passed to the pairs() function which is used to generate the iterator and it is basically a constant--I never add to or update it in any function because it contains static GUIDs. It certainly has no connection to p.
FURTHER DETAILS
This definitely seems likely to be connected to Tabletop Simulator's Vector implementation: https://forums.tabletopsimulator.com/showthread.php?8344-For-loop
The above example just uses a simple numeric for loop to update indices 1,2,3 of a Vector value, and an assignment statement which uses i to index the Vector ends up changing the value of i to the same value that is assigned.
I'm still unable to understand how this is even possible in the language though...
Okay, I'm certain that this is a bug in Moonsharp, which is the Lua interpreter used by Tabletop Simulator: https://github.com/moonsharp-devs/moonsharp/issues/133
The bug was fixed in March 2016 (https://github.com/moonsharp-devs/moonsharp/commit/3ebc0e1fc706c452df9b309d51daec88a15eb0d1) but it seems like TTS probably hasn't updated Moonsharp.

Optimizing Array Memory Usage

I currently have a very large array of permutations, which is currently using a significant amount of RAM. This is the current code I have which SHOULD:
Count all but the occurrences where more than one '1' exists or three '2's exist in a row.
arr = [*1..3].repeated_permutation(30).to_a;
count = 0
arr.each do |x|
if not x.join('').include? '222' and x.count(1) < 2
count += 1
end
end
print count
So basically this results in a 24,360 element array, each of which have 30 elements.
I've tried to run it through Terminal but it literally ate through 14GB of RAM, and didn't move for 15 minutes, so I'm not sure whether the process froze while attempting to access more RAM or if it was still computing.
My question being: is there a faster way of doing this?
Thanks!
I am not sure what problem you try to solve. If your code is just an example for a more complex problem and you really need to check programatically every single permumation, then you might want to experiment with lazy:
[*1..3].repeated_permutation(30).lazy.each do ||
# your condition
end
Or you might want to make the nested iteratior very explicit:
[1,2,3].each do |x1|
[1,2,3].each do |x2|
[1,2,3].each do |x3|
# ...
[1,2,3].each do |x30|
permutation = [x1,x2,x3, ... , x30]
# your condition
end
end
end
end
end
But it feels wrong to me to solve this kind of problem with Ruby enumerables at all. Let's have a look at your strings:
111111111111111111111111111111
111111111111111111111111111112
111111111111111111111111111113
111111111111111111111111111121
111111111111111111111111111122
111111111111111111111111111123
111111111111111111111111111131
...
333333333333333333333333333323
333333333333333333333333333331
333333333333333333333333333332
333333333333333333333333333333
I suggest to just use enumerative combinatorics. Just look at the patterns and analyse (or count) how often your condition can be true. For example there are 28 indexes in your string at which a 222 substring could be place, only 27 for the 2222 substring... If you place a substring how likely is it that there is no 1 in the other parts of the string?
I think your problem is a mathematics problem, not a programming problem.
NB This is an incomplete answer, but I think the idea might give a push to the proper solution.
I can think of a following approach: let’s represent each permutation as a value in ternary number base, padded by zeroes:
1 = 000..00001
2 = 000..00002
3 = 000..00010
4 = 000..00011
5 = 000..00012
...
Now consider we restated the original task, treating zeroes as ones, ones as twos and twos as threes. So far so good.
The whole list of permutations would be represented by:
(1..3**30-1).map { |e| x = e.to_s(3).rjust(30, '0') }
Now we are to apply your conditions:
def do_calc permutation_count
(1..3**permutation_count-1).inject do |memo, e|
x = e.to_s(3).rjust(permutation_count, '0')
!x.include?('111') && x.count('0') < 2 ? memo + 1 : memo
end
Unfortunately, even for permutation_count == 20 it takes more than 5 minutes to calculate, so probably some additional steps are required. I will be thinking of further optimization. Currently I hope this will give you a hint to find the good approach yourself.

Oracle Discoverer BI: how to use DECODE into a calculation with a SUM

Is it possible to use DECODE on a SUM field ?
For example, something like this :
DECODE( SUM("QTA' CONV SUM 1 2 2"),'>0',1,'=0',0)
In your specific case, where you want the result to be 1 if the SUM is greater than zero or 0 if the SUM is zero, you can use the Oracle SIGN function. I'm not sure if there's any special Discoverer syntax, but outside of Discoverer I'd do it something like this:
SIGN(SUM(whatever you're summing))
The "techonthenet" site documents the function here.
An alternative to #EdGibbs, if the values that you're summing are integers:
Greatest(Sum(...),1)
If you had negatives to contend with then maybe:
Least(Greatest(Sum(...),1),0)
The syntax gets a bit gnarly so if you did want to stick with Decode or Case then:
Case Sum(...)
When 0 Then 0
Else 1
End
... or ...
Decode(Sum(...),0,0,Sum(...))
I wouldn't go for a solution that repeats the Sum() though. Keep it DRY

Resources