AND and OR function in one query, not working? sqlite - android

i run a query with a WHERE
"COMPUTERCLASSROOM_SLOT1 = 0 OR COMPUTERCLASSROOM_SLOT2 = 0 AND COMPUTERCLASSROOM_DONE = 1"
though it return all the row that met a requirement..this is the table rows data
According to column presentation, here are the values of the rows
ROW 1 = 0 0 0
ROW 2 = 1 0 0
ROW 3 = 1 2 1
ROW 4 = 1 3 0
ROW 5 = 1 4 1
ROW 6 = 0 5 1
ROW 7 = 0 0 1
they all return..why is that? if i changed the OR with an AND, it would follow the query, returning ROW 7... its just weird..i need that OR and AND in one query, because my target is to return a row with at least 0 in either SLot1 or Slot2, and DONE = 1

it should be
WHERE (COMPUTERCLASSROOM_SLOT1 = 0 OR COMPUTERCLASSROOM_SLOT2 = 0) AND
COMPUTERCLASSROOM_DONE = 1

As #Jack already pointed out, the problem is because you are not using the parentheses. And hence your query is evaluated logically different from what you are expecting.
Try #JW.'s snippet and it would work perfectly.
WHERE (COMPUTERCLASSROOM_SLOT1 = 0 OR COMPUTERCLASSROOM_SLOT2 = 0) AND (COMPUTERCLASSROOM_DONE = 1)

Underlying cause
AND is evaluated as a multiplication; OR is evaluated as an addition. So according to arithmetic precedence rule (PEMDAS), AND is evaluated before evaluating OR.
Example: 1 OR 0 is 1 + 0 = 1; 1 AND 0 is 1 * 0 = 0;
So
X or X or X and X is grouped automatically as X or X or (X and X).
Use of parenthesis avoids the confusion, as well as makes code more readable.

Related

What it is the best general way for testing overflow in Long operations?

In Kotlin, as in Java, there is no overflow error in arithmetic operations. I know that there are special Java operations that test overflow and throw exceptions that need to be handled.
I would want a simpler way. So I thought of a model, which is not so efficient, but it is very simple and effective.
Suppose someone wants to test a 2 long numbers multiplication: a * b
I use
if ( a.doDouble()* b.toDouble() - a*b != 0.0 )
println("Overflow")
else
println("Ok")
The justification is simple. Within the universe of Long the difference between a number and its Double is always 0, even at extreme values, when the Double does not reach all precision. In this case, adding or subtracting a small number does not even change the equality test:.
var l1= -Long.MAX_VALUE
var d1 = l1.toDouble()
if (d1-l1==0.0) println("-MaxLong")
if (d1+100-l1==0.0) println("it still -MaxLong")
var l2= Long.MAX_VALUE
var d2 =l2.toDouble()
if (d2-l2==0.0) println("MaxLong")
if (d2+100-l2==0.0) println("it still MaxLong")
This generates the output:
-MaxLong
it still -MaxLong
MaxLong
it still MaxLong
Is it correct or I'm missing something?
Even if it's correct, is there any other solution better than this?
Update 1: Notice that other possibility is testing if Double calculation is greater that longValue.MAXVALUE. However, it fails!
var n1= Long.MAX_VALUE/2+1
var n2= Long.MAX_VALUE/2+1
println((n1.toDouble()+n2.toDouble()) -
Long.MAX_VALUE.toDouble()==0.0)
println((n1.toDouble()+n2.toDouble()) > Long.MAX_VALUE.toDouble())
It prints:
true
false
Update 2: Although my solution seems to work, it doesn't!
Alexey Romanov, points me in his accepted answer the following situation:
val lo1 = Long.MAX_VALUE - 600
val lo2 = 100L
var do1: Double = lo1.toDouble()
var do2:Double = lo2.toDouble()
var d= do1+do2
var l=lo1+lo2
println(d-l==0.0)
As the result is inside Long range, it should gives true, but it gives false, because Double calculation is not exact!
As he said, the best way is really using special functions like multiplyExact encapsulated in an user function.
Unfortunately, its resources only can be used in Android from API 24 onwards, so it rests the other solution from Alexey Romanov, that consists in test the inverse operation.
So, for instance, in the multiplication one should do:
var a = Long.MIN_VALUE
var b = -1L
var c = a*b
if (b!=0 && c/b != a)
println("overflow $c")
else
println("ok $c")
It prints overflow -9223372036854775808
Among traditional operations, there are usually concerns with addition, subtraction, and multiplication, which are the object of the functions addExact, subtractExact, multipyExact functions, that are easily emulated using inverse operations, as cited.
Negation (inv()) also has the negateExact function to deal with the negation of Long.MIN_VALUE, which is invalid as it has no positive counterpart. Less commented is the division, which has no specialized function in Java to lead with overflow. However it gives problem in a single case: Long.MIN_VALUE / -1 is invalid.
Within the universe of Long the difference between a number and its Double is always 0
No, not really.
println(Long.MAX_VALUE)
println(BigDecimal(Long.MAX_VALUE.toDouble()))
prints
9223372036854775807
9223372036854775808
You tried to check this:
var l2= Long.MAX_VALUE
var d2 =l2.toDouble()
if (d2-l2==0.0) println("MaxLong")
But the problem is that arithmetic operations on JVM (and in most languages, really) can only work on values of the same type, so the compiler inserts toDouble() and you really calculate d2 - l2.toDouble().
If you want a simple test, you can do
val product = a*b
if ((b != 0 && product/b != a) || (a == Long.MIN_VALUE && b == -1)) {
println("Overflow")
} else {
// can use product here
println("OK")
}
but really, using multiplyExact instead of doing it manually makes more sense. Or use Kotlin's nullable types and define
fun multiplyExact(x: Long, y: Long): Long? =
try { java.math.multiplyExact(x, y) } catch (e: ArithmeticException) { null }
EDIT: to demonstrate a fault in your test, consider addition (I am pretty sure it's wrong for multiplication as well, but it's harder to find suitable numbers):
val largeNumber = Long.MAX_VALUE - 600
val smallNumber = 100L
// prints true, even though there's no overflow
println((largeNumber.toDouble() + smallNumber.toDouble()) - (largeNumber + smallNumber) != 0.0)
The reason is that largeNumber.toDouble() + smallNumber.toDouble() == largeNumber.toDouble() while (largeNumber + smallNumber).toDouble() == Long.MAX_VALUE.toDouble().
You should know that Long DataType has a fixed number of bytes Oracle Docs
The long data type is a 64-bit signed two's complement
integer. It has a minimum value of -9,223,372,036,854,775,808 and a
maximum value of 9,223,372,036,854,775,807 (inclusive). Use this data
type when you need a range of values wider than those provided by int.
//if it is not within the range then its an overflow (infinity/undefined)
if(a*b < Long.MIN_VALUE || a*b > Long.MAX_VALUE)
println("Overflow")
else
println("Ok")
Edit
Truly and unfortunately the above method is not reliable. See below table from a run test on android studio with JDK 8
##### Overflow Test #########
Long.MAX_VALUE = 9223372036854775807
Long.MIN_VALUE = -9223372036854775808
Long.MAX_VALUE - 2 = 9223372036854775805
Long.MAX_VALUE - 1 = 9223372036854775806
Long.MAX_VALUE - 0 = 9223372036854775807
Long.MAX_VALUE + 0 = 9223372036854775807
Long.MAX_VALUE + 1 = -9223372036854775808
Long.MAX_VALUE + 2 = -9223372036854775807
Long.MAX_VALUE * 2 = -2
Long.MAX_VALUE / 2 = 4611686018427387903
Long.MIN_VALUE - 2 = 9223372036854775806
Long.MIN_VALUE - 1 = 9223372036854775807
Long.MIN_VALUE - 0 = -9223372036854775808
Long.MIN_VALUE + 0 = -9223372036854775808
Long.MIN_VALUE + 1 = -9223372036854775807
Long.MIN_VALUE + 2 = -9223372036854775806
Long.MIN_VALUE * 2 = 0
Long.MIN_VALUE / 2 = -4611686018427387904
Long.MIN_VALUE + Long.MAX_VALUE = -1
Long.MAX_VALUE - Long.MIN_VALUE = -1
Long.MAX_VALUE * Long.MIN_VALUE = -9223372036854775808
Long.MAX_VALUE / Long.MIN_VALUE = 0
Long.MIN_VALUE / Long.MAX_VALUE = -1
Long.MAX_VALUE + Long.MAX_VALUE = -2
Long.MIN_VALUE + Long.MIN_VALUE = 0
Double.MAX_VALUE = 1.7976931348623157E308
Double.MAX_VALUE * 2 = Infinity
Double.MAX_VALUE + Double.MAX_VALUE = Infinity
Long.MAX_VALUE * Double.MAX_VALUE = Infinity
Double.MAX_VALUE > Long.MAX_VALUE = true
Double.MIN_VALUE < Long.MIN_VALUE = true
Looking at the log you would notice anytime Long.MAX_VALUE reaches its peak instead of hitting Infinity like Double.MAX_VALUE, the bit is switched and its next value becomes Long.MIN_VALUE and it goes on and on like that.
So now we see why the above method isn't reliable. Hence we can assume that in java Long is a DataType with zero Infinity.
Method modified introducing floating point constants in-between
//using floating points forces larger memory allocation
//this prevents bit switch after crossing max or min value of Long
if(a * 1.0 * b < Long.MIN_VALUE || a * 1.0 * b > Long.MAX_VALUE)
println("Either a Double or Long Overflow")
else
println("Ok")

Finding a "best partial match" in a SQLite table without a partial index

In my Android app which uses SQLite to store user data I have a table called valency as shown below.
CREATE TABLE IF NOT EXISTS valency(urid INTEGER PRIMARY KEY AUTOINCREMENT,typ INTEGER,entity INTEGER,v0 INTEGER,v1 INTEGER,v2 INTEGER,v3 INTEGER,v4 INTEGER,v5 INTEGER,lato INTEGER,data INTEGER DEFAULT 0);
CREATE INDEX IF NOT EXISTS vTypEnt ON valency(typ,entity);
I need to find a "best" match for rows in this table for the columns v0.. v5 for a defined value for the typand entitycolumns. The greater the number of matching columns, the more weight I want to attach to the matched datacolumn.
This is how I am going about the process
Step 1 - read the relevant rows into a TEMP table
CREATE TEMP TABLE H1 AS SELECT * FROM valency WHERE (typ = T) AND (entity = E);
Set the v0..v5values to 1 or 0 depending on whether they match
UPDATE H1 SET
v0 = CASE WHEN (v0 = V0) THEN 1 ELSE 0 END,
v1 = CASE WHEN (v1 = V1) THEN 1 ELSE 0 END,
v2 = CASE WHEN (v2 = V2) THEN 1 ELSE 0 END,
v3 = CASE WHEN (v3 = V3) THEN 1 ELSE 0 END,
v4 = CASE WHEN (v4 = V4) THEN 1 ELSE 0 END,
v5 = CASE WHEN (v5 = V5) THEN 1 ELSE 0 END;
This will typically result in one or more rows in H1with zero or more v*values set to 0 with the others being set to 1. All I really care about is the "best" match - i.e. identifying the row with the biggest number of non-zero v*values.
Step 3
SELECT urid,lato,data,v0 + v1 + v2 + v3 + v4 + v5 as 'vSum' FROM H1 ORDER BY vSum DESC LIMIT 1;
which isolates the row with the "best" match. Prior to using and manipulating the best matched datain this result row I use the magnitude of vSumto assign a weighting to the data.
This works - perfectly. However, I am no SQL expert so I cannot help wondering if there might not be a better/simpler/faster way of accomplishing the same thing. The context in which this has to be used does not require speed so I am not keen on a trade off that uses up more storage with more indexing. I'd be most grateful to anyone who could comment on my approach and suggest improvements.
You can convert the select into one SELECT statement by calculating the score in one go. This eliminates the need for a temporary table and some roundtrips between your code and the database engine:
select
*
, CASE WHEN (v0 = V0) THEN 1 ELSE 0 END
+CASE WHEN (v1 = V1) THEN 1 ELSE 0 END
+CASE WHEN (v2 = V1) THEN 1 ELSE 0 END
+CASE WHEN (v3 = V3) THEN 1 ELSE 0 END
+CASE WHEN (v4 = V4) THEN 1 ELSE 0 END
+CASE WHEN (v5 = V5) THEN 1 ELSE 0 END
+ ... as vSum
FROM valency
WHERE (typ = T)
AND (entity = E)
order by vSum desc
limit 1
You may want to add more conditions to the order by clause to make sure your ordering remains consistent between runs.

Select elements with between between not work in SQLite

Following table contains my SQLite-Database on Android:
>>>>> Dumping cursor android.database.sqlite.SQLiteCursor#9f3d273
0 {
id=1543948972569
relationItemID=-1
degree=-1
}
1 {
id=-1
relationItemID=1543948972569
degree=1
}
2 {
id=1543948972569
relationItemID=1543948978808
degree=1
}
3 {
id=1543948978808
relationItemID=1543948972569
degree=-1
}
<<<<<
The SQLite-Query
SELECT id FROM itemsHierarchy
WHERE id = 1543948972569 AND degree BETWEEN 0 AND -128
Returns an empty cursor even though it should find id of first entry.
But if I use '<' instead of 'BETWEEN 0 AND -128' like below, it works.
SELECT id FROM itemsHierarchy WHERE id = 1543948972569 AND degree < 0;
Did I do something wrong or is it a problem of SQLite?
It should be -
SELECT id
FROM itemsHierarchy
WHERE id = 1543948972569
AND degree BETWEEN -128 AND 0

cell2mat error on Matlab from accelerometer txt data and how to plot it

I am newbie on Matlab, and i am trying to plot the data from the txt file written by an android application ( https://play.google.com/store/apps/details?id=com.lul.accelerometer&hl=it)
I cleaned the file and i have only the 4 columns with values separated by the " "
X Y Z time_from_previous_sample(ms)
e.g.
-1.413 6.572 6.975 0
-1.2 6.505 7.229 5
-1.047 6.341 7.26 5
-1.024 6.305 7.295 5
-1.154 6.318 7.247 5
-1.118 6.444 7.104 5
-1.049 6.225 7.173 5
-1.098 6.063 6.939 5
-0.769 6.53 6.903 5
fileID = fopen ('provamatlav.txt');
C = textscan (fileID, '%s %s %s %s');
fclose (fileID);
>> celldisp (C)`
After importing the data i created three new variables
X = C {1};
Y = C {2};
Z= C {3}
The error occur when i try to convert the cell array X into an ordinary array
xx = cell2mat('X')
the error is the following
Cell contents reference from a non-cell array object.
Error in cell2mat (line 36)
if isnumeric(c{1}) || ischar(c{1}) || islogical(c{1}) || isstruct(c{1})
Analyzing the code:
% Copyright 1984-2010 The MathWorks, Inc.
% Error out if there is no input argument
if nargin==0
error(message('MATLAB:cell2mat:NoInputs'));
end
% short circuit for simplest case
elements = numel(c);
if elements == 0
m = [];
return
end
if elements == 1
if isnumeric(c{1}) || ischar(c{1}) || islogical(c{1}) || isstruct(c{1})
m = c{1};
return
end
end
% Error out if cell array contains mixed data types
cellclass = class(c{1});
ciscellclass = cellfun('isclass',c,cellclass);
if ~all(ciscellclass(:))
error(message('MATLAB:cell2mat:MixedDataTypes'));
end
What did i do wrong?
After solved this, what would be the next step to plot the X Y Z data in the same window, but in separate graphs?
Thank you so much!
When using cell2mat, you do not need to use quotes when giving the input argument. The quotes are the reason for the error you got. Generally speaking, you would call it like so:
xx = cell2mat(X)
But you will run into a different error with this in your code, because the cell elements in your case are strings (cell2mat expects numerical values as the output). So you need to convert them to numerical format, e.g. by using this:
xx=cellfun(#str2num,X)
Please try the code line above. It worked ok in my small test case.

android.database.CursorIndexOutOfBoundsException: Index 1 requested, with a size of 1

// This is not working. It shows first record and stops after that. I want a loop that keep running even after the last record. I got your point that cursor starts form position 0.
//Code
cur=db.getData(position);
switch(v.getId())
{
case R.id.next :
{
if (cur != null && cur.getCount()> 0 && position < cur.getCount() && position != cur.getCount()){
cur.moveToPosition(position);
textView1.setText(""+cur.getString(1));// Display Columns
position++;
cur.moveToNext();
}
}
// I want a loop to display record number
for next button
eg:
1 2 3 4 5 1 2 3 4 5 1 2 3 4 5
back button
eg:
5 4 3 2 1 5 4 3 2 1
random button
eg:
3 4 5 1
5 1 2 3
4 5 1 2
That exception appears, because you are trying to get the object in a position that do not exist. Remember index start at 0.
Direct from DOCS :
public abstract boolean moveToPosition (int position)
Added in API level 1
Move the cursor to an absolute position. The valid range of values is -1 <= position <= count.
This method will return true if the request destination was reachable, otherwise, it returns false.
Parameters
position the zero-based position to move to.
Returns
whether the requested move fully succeeded.
if (cur != null && cur.getCount()> 0 && position < cur.getCount() && position != cur.getCount()){
cur.moveToPosition(position);
textView1.setText(""+cur.getString(1));// Display Columns
}
Call get data before increments position, that because you are trying to acceed an element in a unexisting I'm your db.
cur =db. getData(position) ;
Then
position++;
Remember to first of all declare position = 0

Categories

Resources