Spyne: Integer Validation how can I set minimum digit limit? - spyne

I want to add validation for an Integer, that its minimum digit value is 5 and maximum digit value is 20
For Integer I have set following validations
Integer(min_occurs=1, gt=9999, max_str_len=20, nillable=False)
I just put work around for min_str_len, I do not find any attribute for min_str_len.
Instead of work around is there any default way ?

You can subclass Integer type (or another one that fits best) and implement validate_native method.
Example for prime number check from docs:
from math import sqrt, floor
class Prime(UnsignedInteger):
"""Custom integer type that only accepts primes."""
#staticmethod
def validate_native(cls, value):
return (
UnsignedInteger.validate_native(value) and \
all(a % i for i in xrange(2, floor(sqrt(a))))
)
Source: http://spyne.io/docs/2.10/manual/05-02_validation.html#a-native-validation-example

Related

How do I produce a number with absolute precision of some power of 10?

Vb.net has a decimal data type.
Unlike normal double or floating points, decimal data type can store values like 0.1
Now say I have a variable like precision.
Say precision is 8
So basically I want to do
Protected Overridable Sub setPairsPricesStep2(decimalPrecission As Long, Optional base As String = "", Optional quote As String = "")
If decimalPrecission = 8 Then
Return
End If
Dim price = 10D ^ (-decimalPrecission)
setPairsPriceStep1(price, base, quote)
End Sub
There is a problem there
the result of Dim price = 10D ^ (-decimalPrecission) is double, not decimal. I can convert it to decimal but then I will lost the precission.
So what is the right way to do it? Should I just use for next but that's hardly elegant.
It's simple
I want a function that given precisions give decimal value.
For example, if precision is 1 I got 0.1. If precision is 5, I got 0.00001
I ended up doing this
For i = 1 To decimalPrecission
price *= 0.1D
Next
But surely there is a better way
Update:
Per comment, I tried
Dim e = 10D ^ -5
Dim e1 = 10D ^ -5L
The type of e and e1 are both double.
I suppose I can do Cdec(e). But then it means I have lost accuracy because normal double cannot store .1 correctly.
I want a function that given precisions give decimal value.
For example, if precision is 1 I got 0.1. If precision is 5, I got 0.00001
Since you are working with the Decimal type, the simplest way to get this result is to use the Decimal constructor that allows you to specify the scale factor.
Public Sub New (lo As Integer, mid As Integer, hi As Integer, isNegative As Boolean, scale As Byte)
From the Remarks section of the above referenced documentation,
The binary representation of a Decimal number consists of a 1-bit sign, a 96-bit integer number, and a scaling factor used to divide the integer number and specify what portion of it is a decimal fraction. The scaling factor is implicitly the number 10 raised to an exponent ranging from 0 to 28.
So you can see that if take the value of one divided by 10 to the first power, the result is 0.1. Likewise, one divided by 10 to the fifth power, the result is 0.00001.
The lo, mid, and hi arguments in the constructor could be obtained by uisng the [Decimal.GetBits Method](Decimal.GetBits Method), but for this simple case, I chose to hard code the values for the value of one stored as a decimal.
To obtain a value of 0.1D:
New Decimal(1, 0, 0, False, 1)
To obtain a value of 0.00001D:
New Decimal(1, 0, 0, False, 5)
Dim stringrepresentation = "1E-" + decimalPrecission.ToString
Dim price = Decimal.Parse(stringrepresentation, System.Globalization.NumberStyles.AllowExponent)
This is what I basically did. Basically I created a string 1E-5, for example, and use decimal.parse to get the decimal
I wonder if there is a better way but I have no idea.
Actually Jimy ways may work too but rounded to a number

How do I get the minimum positive value over a set of integer expressions?

I have a model with the following condition:
z[i] = min{t*x[i][t] | x[i][t] = 1},
x[i][t] - boolean,
z[i] - integer
Which means I am trying to find a minimum positive value over a set of integer expressions. The "min" condition can be easily converted into a set of linear conditions if only we weren't looking for a positive value but a boolean (0 or 1) one.
Here the situation is a bit more complicated. Let's say that
t*x[i][t]
can have the following values:
0,3,4,5
I am looking for a way to get the value 3 (minimum positive one) and assign it to another variable (z[i])
Is there a way to convert the condition into a set of linear ones so that my model is not a non-linear programming model?

Get maximum from absolute values returning signed value

Supposing I have a class
Public Class Foo
Property fooProp1 as Single
Property fooProp2 as Single
Property fooProp3 as Single
End Class
to find the absolut maximum of a property (which contains positive or negative values) in a Collection(Of Foo) I can do:
Collection.Max(Function(x As foo) Math.Abs(x.fooProp1))
and it returns the greater absolute value WITHOUT sign.
The question is how can I do to get the number WITH sign?
Thanks in advance.
RG
Math.Abs will always return an unsigned value (the actual meaning of Absolute).
The get the value of a property you need only to READ it.
To get a MAX or MIN, you MUST compare values, like this:
dim x as integer = foo.property
dim y as integer = last_foo_property (or anything else)
Minimum = Math.Min(x,y)
Maximum = Math.Max(x,y)
But, if are trying to get the lower and upper values of a collection, you may utilize:
MaxValue = Collection.Find(Collection, Function(Z) (Z > BiggerValue))
MinValue = Collection.Find(Collection, Function(Z) (Z < LowerValue))
where these values are gotten before the call.
Another way is to make a SORT and get the first and the last values...
Collection.Select(Function(x) a.fooProp1).Aggregate(Function(a, b)
If(Math.Abs(a) > Math.Abs(b), a, b))

Truncate integer to specific number of digits?

We want an SQL (not PL/pgSQL) function that given a random positive integer of any size, returns an integer between 0 & 999999 inclusive. The return value should retain as much as possible the randomness of the argument.
In PostgresSQL:
set seed sets the random for the next time you call the random function:
setseed (arg)
This statement will generate a number in the range [0:999999] inclusive
SELECT floor(random()*(999999-0+1))+10;
In Python:
import random
def get_rand_int(arg)
random.seed(arg)
return random.randrange(0,100000)
Something to keep in mind when using random
" The Mersenne Twister is one of the most extensively tested random number generators in existence. However, being completely deterministic, it is not suitable for all purposes, and is completely unsuitable for cryptographic purposes." https://docs.python.org/3/library/random.html?highlight=random#random.random
In SQL:
This will return a floored integer between 999999 and 0 using [seed] as a seed value.
SELECT FLOOR(RAND([seed])*(999999-0));

ceil() not working as I expected

I'm trying to divide one number by another and then immediately ceil() the result. These would normally be variables, but for simplicity let's stick with constants.
If I try any of the following, I get 3 when I want to get 4.
double num = ceil(25/8); // 3
float num = ceil(25/8); // 3
int num = ceil(25/8); // 3
I've read through a few threads on here (tried the nextafter() suggestion from this thread) as well as other sites and I don't understand what's going on. I've checked and my variables are the numbers I expect them to be and I've in fact tried the above, using constants, and am still getting unexpected results.
Thanks in advance for the help. I'm sure it's something simple that I'm missing but I'm at a loss at this point.
This is because you are doing integer arithmetic. The value is 3 before you are calling ceil, because 25 and 8 are both integers. 25/8 is calculated first using integer arithmetic, evaluating to 3.
Try:
double value = ceil(25.0/8);
This will ensure the compiler treats the constant 25.0 as a floating point number.
You can also use an explicit cast to achieve the same result:
double value = ceil(((double)25)/8);
This is because the expressions are evaluated before being passed as an argument to the ceil function. You need to cast one of them to a double first so the result will be a decimal that will be passed to ceil.
double num = ceil((double)25/8);