Performing arithmetic on string values - string

I would like to ask something about data types in Lua.
I get from serial link some message (command:value) like this:
tmp_string = "BRAKE:1"
then I parse this string to command and value in two different functions (one is for command and other one is for value). This is function for parsing value
function parser(value)
index = string.find(value, ":")
result = value.sub(value, index+1)
return result
end
I would like to now what sort of data type result is? If I use string match it works.
...if string.match(state, "1") then...
However it also works when I do something like this
x = (state*65536)/3.2808)
I thought the result is string, but I don't understand why it works also with numerical operations. Thank you in advance.

Lua 5.3 Reference Manual, §3.4.1 - Arithmetic Operators
With the exception of exponentiation and float division, the arithmetic operators work as follows: If both operands are integers, the operation is performed over integers and the result is an integer. Otherwise, if both operands are numbers or strings that can be converted to numbers (see §3.4.3), then they are converted to floats, the operation is performed following the usual rules for floating-point arithmetic (usually the IEEE 754 standard), and the result is a float.
Emphasis is mine.
When dealing with operations, Lua will attempt to convert string operands to floats, and if it works - it works. If it fails, you get an error.
>| '55' / 2
<| 27.5
>| 'foo' / 2
<| error: [string "return 'foo' / 2"]:1: attempt to perform arithmetic on a string value
If you want to be explicit about this (and safe) use tonumber, and handle the nil-case.
If you need to know the type of a value in Lua, you can pass the variable to type and check the resulting string.

Related

why is my int() conversion looking so weird?

I'm trying to take a number and divide it by 100 to get 1%, but when i tried to convert it to integer using the int(), it's giving me some weird output. i have no clue what i'm doing wrong here.
totalsupply = 1000000000000000000000000000000
onepercent = int((totalsupply/100))
print(totalsupply)
print(onepercent)
the output is coming out as such:
1000000000000000000000000000000
9999999999999999583119736832
[Finished in 68ms]
I was expecting the onepercent to be this: 10000000000000000000000000000.
According to this post, python tries to convert the number to a float on a division. However, floats are limited to 1.7976931348623157e+308. A workaround is to use the // operator which returns an int from the division, so for your example:
totalsupply = 1000000000000000000000000000000
onepercent = totalsupply//100
print(totalsupply)
print(onepercent)
Python has a built-in integer type that has infinite precision. That's what you are creating with your first line
totalsupply = 1000000000000000000000000000000
However, python has two division operators. The standard division "slash" operator ("/") is floating-point operation, whereas the double-slash gives integers.
Hence totalsupply/100 is a floating point number, which has finite precision, and so the closest it can do is 9999999999999999583119736832.
However, if instead you do
onepercent = totalsupply//100
print(onepercent)
you get the expected 100000000000000000000000000000.

How to check validity of a Boolean Expression in z3py given in string format

I have a boolean formula such as (i_0 | i_1) ^ ((~i_0) & (~i_1)). And I want to check its validity using z3 python.
The main challenge that I'm facing is How to convert this string into a formula in z3 format?
Is there any easy way to do this?
To check validity of a formula, assert its negation and see if it's unsat. If the negation is unsatisfiable, that'd mean that your formula is valid for all assignments, i.e., it's a tautology.
Here's how you do that for your formula in z3py:
from z3 import *
i_0, i_1 = Bools('i_0 i_1')
s = Solver()
s.add(Not(Xor(Or(i_0, i_1), And(Not(i_0), Not(i_1)))))
print(s.check())
Note the outermost Not as we add the formula to the solver, to negate it. Inside the Not is a straightforward encoding of your formula, using And, Or, Xor, and Not functions.
When I run this, I get:
unsat
which means that your original formula is a tautology.
Note If your question is about how to take the input as a "string" and turn it into a z3Py formula automatically, then there's really no "out-of-the-box" way of doing that; as your string can have arbitrary conventions, operators, parentheses etc. But that is the typical parsing problem, i.e., converting text input to the function calls needed to run in z3py; and should be tagged as such.

string(int), string(int32) and string([]int32) are all valid but string([]int) is invalid - what's the rationale here?

(I'm using Go 1.14.6.)
The following statements would all output the char a
Println(string(int(97) ) )
Println(string(int32(97) ) )
Println(string([]int32{97} ) )
But
Println(string([]int{97} ) )
would cause compile error
cannot convert []int literal (type []int) to type string
The behavior is confusing to me. If it handles string(int) the same as string(int32), why it handles string([]int) different from string([]int32)?
rune which represents a unicode code point is an alias for int32. So effectively string([]int32{}) is the same as string([]rune{}) which converts a slice of runes (something like the charaters of a string) to string. This is useful.
int is not int32 nor rune, so it's not logical what converting []int to string should be, it's ambiguous, so it's not allowed by the language spec.
Converting an integer number to string results in a string value with a single rune. Spec: Conversions:
Conversions to and from a string type
Converting a signed or unsigned integer value to a string type yields a string containing the UTF-8 representation of the integer. Values outside the range of valid Unicode code points are converted to "\uFFFD".
This is confusing to many, as many expects the conversion result to be the (decimal) representation as string. The Go authors have recognized this, and have taken steps to depcecate and remove it from the language in the future. In Go 1.15, go vet already warns for such conversion. Go 1.15 release notes: Vet:
New warning for string(x)
The vet tool now warns about conversions of the form string(x) where x has an integer type other than rune or byte. Experience with Go has shown that many conversions of this form erroneously assume that string(x) evaluates to the string representation of the integer x. It actually evaluates to a string containing the UTF-8 encoding of the value of x. For example, string(9786) does not evaluate to the string "9786"; it evaluates to the string "\xe2\x98\xba", or "☺".
Code that is using string(x) correctly can be rewritten to string(rune(x)). Or, in some cases, calling utf8.EncodeRune(buf, x) with a suitable byte slice buf may be the right solution. Other code should most likely use strconv.Itoa or fmt.Sprint.
This new vet check is enabled by default when using go test.
We are considering prohibiting the conversion in a future release of Go. That is, the language would change to only permit string(x) for integer x when the type of x is rune or byte. Such a language change would not be backward compatible. We are using this vet check as a first trial step toward changing the language.

Is there a built-in in Python 3 that checks whether a character is a "basic" algebraic symbol?

I know the string methods str.isdigit, str.isdecimal and str.isnumeric.
I'm looking for a built-in method that checks if a character is algebraic, meaning that it can be found in a declaration of a decimal number.
The above mentioned methods return False for '-1' and '1.0'.
I can use isdigit to retrieve a positive integer from a string:
string = 'number=123'
number = ''.join([d for d in string if d.isdigit()]) # returns '123'
But that doesn't work for negative integers or floats.
Imagine a method called isnumber that works like this:
def isnumber(s):
for c in s:
if c not in list('.+-0123456789'):
return False
return True
string1 = 'number=-1'
string2 = 'number=0.1'
number1 = ''.join([d for d in string1 if d.isnumber()]) # returns '-1'
number2 = ''.join([d for d in string2 if d.isnumber()]) # returns '0.1'
The idea is to test against a set of "basic" algebraic characters. The string does not have to contain a valid Python number. It could also be an IP address like 255.255.0.1.
.
Does a handy built-in that works approximately like that exist?
If not, why not? It would be much more efficient than a python function and very useful. I've seen alot of examples on stackoverflow that use str.isdigit() to retrieve a positive integer from a string. Is there a reason why there isn't a built-in like that, although there are three different methods that do almost the same thing?
No such function exists. There are a bunch of odd characters that can be part of number literals in Python, such as o, x and b in the prefix of integers of non-decimal bases, and e to introduce the exponential part of a float. I think those plus the hex digits (0-9 and A-F) and sign characters and the decimal point are all you need.
You can put together a string with the right character yourself and test against it:
from string import hex_digits
num_literal_chars = hex_digits + "oxOX.+-"
That will get a bunch of garbage though if you use it to test against mixed text and numbers:
string1 = "foo. bar. 0xDEADBEEF 10.0.0.1"
print("".join(c for c in string1 if c in num_literal_chars))
# prints "foo.ba.0xDEADBEEF10.0.0.1"
The fact that it gives you a bunch of junk is probably why no builtin function exists to do this. If you want to match a certain kind of number out of a string, write an appropriate regular expression to match that specific kind of number. Don't try to do it character-by-character, or try to match all the different kinds of Python numbers.

TryStrToFloat converts incorrect string

I'm using TryStrToFloat to convert string to Double variables. Everything works fine until string doesn't looks like '21e'. I get result of conversion 21.
It seems to me that compiler treats '21e' like number 21e0. String 21e1 gives result 210.
When I use Val function conversion works better. String '21e' gives error, but now '21e1' gives 210, '21e-1' gives number 2,1 etc.
How to make correct working of conversion. Should I detect letter 'e' in text, or is any simply way to convert ?
The documentation says:
Use TryStrToFloat to convert a string, S, to a floating-point value. S must consist of an optional sign (+ or -), a string of digits with an optional decimal point, and an optional mantissa. The mantissa consists of 'E' or 'e' followed by an optional sign (+ or -) and a whole number. Leading and trailing blanks are ignored.
Your input does not satisfy the conditions and so should be treated as an error.
You did not say so explicitly, but I presume that you claim that:
TryStrToFloat('21e', val)
returns True. If so, this is a bug and should be reported to Embarcadero. If you need to work around this then I suggest you code your own function that detects this case and handles it correctly.
On the other hand, if that function call returns False the function is behaving as designed and your mistake is to read the value in val.
Update
I can confirm that TryStrToFloat('21e', val) returns True. I tested on XE7 update 1. I submitted the following bug report to Embarcadero: https://quality.embarcadero.com/browse/RSP-9814

Resources