Using a variable when specifying formatting options in string.format - lua

I am trying to write a function that produces a string of a fixed length. There are two cases I think I need to consider:
The string is too long and must be cropped
The string is too short and must be padded with whitespace
To do this, I have written the following:
foo = "testtesttesttest"
bar = "test"
function fixed_width_a(s)
return string.format("%-6s", string.sub(s, 1, 6))
end
print(fixed_width_a(foo))
print(fixed_width_a(bar))
-- testte
-- test__ (Using underscores to denote spaces)
While I don't know if this is the best way, it works. Great!
Now, I'd like to be able to specify the width of the string as a parameter. For example,
function fixed_width_b(s, w)
w = w or 6
return string.format("%-ws", string.sub(s, 1, w))
end
Of course, this naive attempt doesn't work because "%-ws" isn't parsed correctly. Another attempt might be to specify,
string.format("%-{%d}s", w, string.sub(s, 1, w))
but obviously this makes no sense either.
Question: how do I specify formatting options using a variable in string.format?

print(("%-_._s"):gsub("_", 6):format("teststring"))
print(("%-"+6+"."+"s"):format("teststring"))
print(("%%-%d.%ds"):format(6,6):format("teststring"))

Okay, so this seems to work okay, although I don't know if it's the best option.
function fixed_width_b(s, w)
w = w or 6
tmp = string.format("%%-%ds", w)
return string.format(tmp, string.sub(s, 1, w))
end
Here, I construct the first argument to the crop/pad part of the code as a string called tmp. If w = 5, for example, then tmp = "%-5s".
Edit
For brevity, I suppose I could just write,
function fixed_width_b(s, w)
w = w or 6
return string.format(string.format("%%-%ds", w), string.sub(s, 1, w))
end
and avoid an intermediate variable.

Related

Obtaining numerical values from the mnewton function of the Maxima program

I use Maxima for calculations. I solve a system of nonlinear equations using Newton's method (mnewton()). I get the solution in the form of a list:
[[φ2=5.921818183272879,s=5.155870949147037]]
How to get the numerical value of the first (φ2) and second (s) unknown. If I substitute:
x: roz1[1][2]$
I get that x is equal to: s=5.155870949147037
What to do to make x equal to a numerical value only: 5.155870949147037
(without s=).
My code:
Maxima code
I have two ideas. (1) You can call rhs to return the right-hand side of an equation (likewise lhs for the left-hand side). E.g. rhs(s = 123) returns 123.
(2) You can call assoc to find the value associated with s (or any variable) in the mnewton results. E.g. assoc('s, [a = 1, b = 2, s = 3, u = 5]) returns 3.
I like (2) better since it is not necessary to know where in the list is the one that you're interested in.

How to Round to the Nearest Tenth?

Given any number of the sort 78.689 or 1.12 for instance, what I'm looking for is to programmatically round the number to the nearest tenth place after the decimal.
I'm trying to do this in an environment where there is a math.floor() function that rounds to the lowest whole number, and as far as I can tell from documentation there's nothing like PHP's round() function.
There's simple snippet at: http://lua-users.org/wiki/SimpleRound
function round(num, numDecimalPlaces)
local mult = 10^(numDecimalPlaces or 0)
return math.floor(num * mult + 0.5) / mult
end
It will misbehave when numDecimalPlaces is negative, but there's more examples on that page.
You can use coercion to do this...
It work just like printf... You can try to do something like in this snippet.
value = 8.9756354
print(string.format("%2.1f", value))
-- output: 9.0
Considering that this is roblox, it would just be easier to make this a global variable instead of making a single module or creating your own gloo.
_G.round = function(x, factor)
local factor = (factor) and (10 ^ factor) or 0
return math.floor((x + 0.5) * factor) / factor
end
In my case, I was simply trying to make a string representation of this number... however, I imagine this solution could prove useful to others as well.
string.sub(tostring(percent * 100), 1, 4)
so to bring it back to a numerical representation, you could simply call tonumber() on the resulting number.

Unexpected result after calling Exists on substituted formula

When calling Z3py's Exists function subsequently on different variables and formulas, I get the exact same result. Is that some sort of Python problem or is Z3 broken here? How to fix? The following minimal example illustrates the problem:
from z3 import *
a, a0, a1, b, b0, b1 = Ints('a a0 a1 b b0 b1')
x, y = Bools('x y')
s = Solver()
formula = Implies(x, And(a>0,b1<0))
substitution1 = substitute(formula,(a1,a0),(b1,b0))
substitution2 = substitute(formula,(a1,a0),(b1,b0),(a,a1),(b,b1))
print substitution1
print substitution2
exist1 = Exists([a,b],substitution1)
exist2 = Exists([a1,b1],substitution2)
print exist1
print exist2
Output:
Implies(x, And(a > 0, b0 < 0))
Implies(x, And(a1 > 0, b0 < 0))
Exists([a, b], Implies(x, And(a > 0, b0 < 0)))
Exists([a, b], Implies(x, And(a > 0, b0 < 0)))
Thanks for reporting that. Z3 is in fact correct about this, but the output is confusing. Internally, Z3 uses deBrujin indices and the names of bound variables are immaterial. When a quantifier is created that has the same body (and patterns, no_patterns, etc) then the exactly same expression that was seen before is used, to avoid having to solve the same quantified constraint as before. This creates the confusing situation as suddenly the names of bound variables seem to have changed.
In the example given here, the bodies of both quantifiers are indeed identical and the names of variables do not matter. Z3 could use any names for those variables, but it chooses to use the ones that were used when the quantifier was created the first time. We could disable that, e.g., by adding
compare_arrays(to_quantifier(n1)->get_decl_names(),
to_quantifier(n2)->get_decl_names(),
to_quantifier(n1)->get_num_decls()) &&
at src/ast/ast.cpp:470. This however would likely have a negative impact on Z3's performance on some benchmarks, so I will not make this change. If you would like to use it, you can add it to your local copy of Z3 of course.

Can Z3 call python function during decision making of variables?

I am trying to solve a problem, for example I have a 4 point and each two point has a cost between them. Now I want to find a sequence of nodes which total cost would be less than a bound. I have written a code but it seems not working. The main problem is I have define a python function and trying to call it with in a constraint.
Here is my code: I have a function def getVal(n1,n2): where n1, n2 are Int Sort. The line Nodes = [ Int("n_%s" % (i)) for i in range(totalNodeNumber) ] defines 4 points as Int sort and when I am adding a constraint s.add(getVal(Nodes[0], Nodes[1]) + getVal(Nodes[1], Nodes[2]) < 100) then it calls getVal function immediately. But I want that, when Z3 will decide a value for Nodes[0], Nodes[1], Nodes[2], Nodes[3] then the function should be called for getting the cost between to points.
from z3 import *
import random
totalNodeNumber = 4
Nodes = [ Int("n_%s" % (i)) for i in range(totalNodeNumber) ]
def getVal(n1,n2):
# I need n1 and n2 values those assigned by Z3
cost = random.randint(1,20)
print cost
return IntVal(cost)
s = Solver()
#constraint: Each Nodes value should be distinct
nodes_index_distinct_constraint = Distinct(Nodes)
s.add(nodes_index_distinct_constraint)
#constraint: Each Nodes value should be between 0 and totalNodeNumber
def get_node_index_value_constraint(i):
return And(Nodes[i] >= 0, Nodes[i] < totalNodeNumber)
nodes_index_constraint = [ get_node_index_value_constraint(i) for i in range(totalNodeNumber)]
s.add(nodes_index_constraint)
#constraint: Problem with this constraint
# Here is the problem it's just called python getVal function twice without assiging Nodes[0],Nodes[1],Nodes[2] values
# But I want to implement that - Z3 will call python function during his decission making of variables
s.add(getVal(Nodes[0], Nodes[1]) + getVal(Nodes[1], Nodes[2]) + getVal(Nodes[2], Nodes[3]) < 100)
if s.check() == sat:
print "SAT"
print "Model: "
m = s.model()
nodeIndex = [ m.evaluate(Nodes[i]) for i in range(totalNodeNumber) ]
print nodeIndex
else:
print "UNSAT"
print "No solution found !!"
If this is not a right way to solve the problem then could you please tell me what would be other alternative way to solve it. Can I encode this kind of problem to find optimal sequence of way points using Z3 solver?
I don't understand what problem you need to solve. Definitely, the way getVal is formulated does not make sense. It does not use the arguments n1, n2. If you want to examine values produced by a model, then you do this after Z3 returns from a call to check().
I don't think you can use a python function in your SMT logic. What you could alternatively is define getVal as a Function like this
getVal = Function('getVal',IntSort(),IntSort(),IntSort())
And constraint the edge weights as
s.add(And(getVal(0,1)==1,getVal(1,2)==2,getVal(0,2)==3))
The first two input parameters of getVal represent the node ids and the last integer represents the weight.

Lua base converter

I need a base converter function for Lua. I need to convert from base 10 to base 2,3,4,5,6,7,8,9,10,11...36 how can i to this?
In the string to number direction, the function tonumber() takes an optional second argument that specifies the base to use, which may range from 2 to 36 with the obvious meaning for digits in bases greater than 10.
In the number to string direction, this can be done slightly more efficiently than Nikolaus's answer by something like this:
local floor,insert = math.floor, table.insert
function basen(n,b)
n = floor(n)
if not b or b == 10 then return tostring(n) end
local digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
local t = {}
local sign = ""
if n < 0 then
sign = "-"
n = -n
end
repeat
local d = (n % b) + 1
n = floor(n / b)
insert(t, 1, digits:sub(d,d))
until n == 0
return sign .. table.concat(t,"")
end
This creates fewer garbage strings to collect by using table.concat() instead of repeated calls to the string concatenation operator ... Although it makes little practical difference for strings this small, this idiom should be learned because otherwise building a buffer in a loop with the concatenation operator will actually tend to O(n2) performance while table.concat() has been designed to do substantially better.
There is an unanswered question as to whether it is more efficient to push the digits on a stack in the table t with calls to table.insert(t,1,digit), or to append them to the end with t[#t+1]=digit, followed by a call to string.reverse() to put the digits in the right order. I'll leave the benchmarking to the student. Note that although the code I pasted here does run and appears to get correct answers, there may other opportunities to tune it further.
For example, the common case of base 10 is culled off and handled with the built in tostring() function. But similar culls can be done for bases 8 and 16 which have conversion specifiers for string.format() ("%o" and "%x", respectively).
Also, neither Nikolaus's solution nor mine handle non-integers particularly well. I emphasize that here by forcing the value n to an integer with math.floor() at the beginning.
Correctly converting a general floating point value to any base (even base 10) is fraught with subtleties, which I leave as an exercise to the reader.
you can use a loop to convert an integer into a string containting the required base. for bases below 10 use the following code, if you need a base larger than that you need to add a line that mapps the result of x % base to a character (usign an array for example)
x = 1234
r = ""
base = 8
while x > 0 do
r = "" .. (x % base ) .. r
x = math.floor(x / base)
end
print( r );

Resources