How do i make a string in Lua contain random characters? - lua

I'm curious on how to make a random string get printed out to the output in Lua I was wondering if this was possible for strings. because I know that you can generate random numbers using the function in Lua called. math.Random() but I'm not sure how to make a string random. how could I make characters in a string random that print to the output?
-- I want to print out random characters in a string to the consoles output
local Number = math.random(1,80) -- prints out a number 1-80
print(Number)

The capital letters are in string.char(math.random(65, 90)) and can be lazy lowered with another string method...
local randuppercase = string.char(math.random(65, 65 + 25))
local randlowercase = string.char(math.random(65, 65 + 25)):lower()
print(randlowercase, randuppercase)
-- Example output: g W
Without string method lower() lowercases start at...
local randlowercase = string.char(math.random(97, 97 + 25))
print(randlowercase, randlowercase:upper())
-- Sample output: c C
Another possible solve is doing it more oldschool like...
local chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" -- The Char Library
local rint = math.random(1, #chars) -- 1 out of length of chars
local rchar = chars:sub(rint, rint) -- Pick it
print(rint, rchar)
-- Sample Output: 12 L

Related

Reliable way of getting the exact decimals from any number

I'm having problem returning spesific amount of decimal numbers from this function, i would like it to get that info from "dec" argument, but i'm stuck with this right now.
Edit: Made it work with the edited version bellow but isn't there a better way?
local function remove_decimal(t, dec)
if type(dec) == "number" then
for key, num in pairs(type(t) == "table" and t or {}) do
if type(num) == "number" then
local num_to_string = tostring(num)
local mod, d = math.modf(num)
-- find only decimal numbers
local num_dec = num_to_string:sub(#tostring(mod) + (mod == 0 and num < 0 and 3 or 2))
if dec <= #num_dec then
-- return amount of deciamls in the num by dec
local r = d < 0 and "-0." or "0."
local r2 = r .. num_dec:sub(1, dec)
t[key] = mod + tonumber(r2)
end
end
end
end
return t
end
By passing the function bellow i want a result like this:
result[1] > 0.12
result[2] > -0.12
result[3] > 123.45
result[4] > -1.23
local result = remove_decimal({0.123, -0.123, 123.456, -1.234}, 2)
print(result[1])
print(result[2])
print(result[3])
print(result[4])
I tried this but it seems to only work with one integer numbers and if number is 12.34 instead of 1.34 e.g, the decimal place will be removed and become 12.3. Using other methods
local d = dec + (num < 0 and 2 or 1)
local r = tonumber(num_to_string:sub(1, -#num_to_string - d)) or 0
A good approach is to find the position of the decimal point (the dot, .) and then extract a substring starting from the first character to the dot's position plus how many digits you want:
local function truncate(number, dec)
local strnum = tostring(number)
local i, j = string.find(strnum, '%.')
if not i then
return number
end
local strtrn = string.sub(strnum, 1, i+dec)
return tonumber(strtrn)
end
Call it like this:
print(truncate(123.456, 2))
print(truncate(1234567, 2))
123.45
1234567
To bulk-truncate a set of numbers:
local function truncate_all(t, dec)
for key, value in pairs(t) do
t[key] = truncate(t[key], dec)
end
return t
end
Usage:
local result = truncate_all({0.123, -0.123, 123.456, -1.234}, 2)
for key, value in pairs(result) do
print(key, value)
end
1 0.12
2 -0.12
3 123.45
4 -1.23
One could use the function string.format which is similar to the printf functions from C language. If one use the format "%.2f" the resulting string will contain 2 decimals, if one use "%.3f" the resulting string will be contain 3 decimals, etc. The idea is to dynamically create the format "%.XXXf" corresponding to the number of decimal needed by the function. Then call the function string.format with the newly created format string to generate the string "123.XXX". The last step would be to convert back the string to a number with the function tonumber.
Note that if one want the special character % to be preserved when string.format is called, you need to write %%.
function KeepDecimals (Number, DecimalCount)
local FloatFormat = string.format("%%.%df", DecimalCount)
local String = string.format(FloatFormat, Number)
return tonumber(String)
end
The behavior seems close to what the OP is looking for:
for Count = 1, 5 do
print(KeepDecimals(1.123456789, Count))
end
This code should print the following:
1.1
1.12
1.123
1.1235
1.12346
Regarding the initial code, it's quite straight-forward to integrate the provided solution. Note that I renamed the function to keep_decimal because in my understanding, the function will keep the requested number of decimals, and discard the rest.
function keep_decimal (Table, Count)
local NewTable = {}
local NewIndex = 1
for Index = 1, #Table do
NewTable[NewIndex] = KeepDecimal(Table[Index], Count)
NewIndex = NewIndex + 1
end
return NewTable
end
Obviously, the code could be tested easily, simply by copy and pasting into a Lua interpreter.
Result = keep_decimal({0.123, -0.123, 123.456, -1.234}, 2)
for Index = 1, #Result do
print(Result[Index])
end
This should print the following:
0.12
-0.12
123.46
-1.23
Edit due to the clarification of the need of truncate:
function Truncate (Number, Digits)
local Divider = Digits * 10
local TruncatedValue = math.floor(Number * Divider) / Divider
return TruncatedValue
end
On my computer, the code is working as expected:
> Truncate(123.456, 2)
123.45

Lua char spacing perfectly

Failed Spacing
I'm trying to get all of these names with a max char of 31 to line up all together in the same row by adding the number of spaces per player name that it needs. I've been trying to accomplish this for some time now and I just can't figure this out completely.
This is my current code which is a disaster I know..
local c = client.GetPlayerNameByIndex(i)
if c ~= nil and client.GetPlayerNameByIndex(i) ~= "nil" then
playerlist[i] = all_trim(client.GetPlayerNameByIndex(i))
local leve = 67
local namelength = #client.GetPlayerNameByIndex(i) --max 31 chars
local output = "" .. client.GetPlayerNameByIndex(i)
local newspace = ""
local neededspaces = 31 - #client.GetPlayerNameByIndex(i)
print(neededspaces)
for i=1, 31-#string.sub(client.GetPlayerNameByIndex(i), 1, 31) do
newspace = newspace .. " "
end
playerinfolist[i] = output .. newspace .. "a"
end
In simple terms I want all of the "a"s to line up with each string. Thanks for helping me!

regex for matching a string into words but leaving multiple spaces

Here's what I expect. I have a string with numbers that need to be changed into letters (a kind of cipher) and spaces to move into different letter, and there is a tripple spaces that represent a space in output. For example, a string "394 29 44 44 141 6" will be decrypted into "Hell No".
function string.decrypt(self)
local output = ""
for i in self:gmatch("%S+") do
for j, k in pairs(CODE) do
output = output .. (i == j and k or "")
end
end
return output
end
Even though it decrypts the numbers correctly I doesn't work with spacebars. So the string I used above decrypts into "HellNo", instead of expected "Hell No". How can I fix this?
You can use
CODE = {["394"] = "H", ["29"] = "e", ["44"] = "l", ["141"] = "N", ["6"] = "o"}
function replace(match)
local ret = nil
for i, v in pairs(CODE) do
if i == match then
ret = v
end
end
return ret
end
function decrypt(s)
return s:gsub("(%d+)%s?", replace):gsub(" ", " ")
end
print (decrypt("394 29 44 44 141 6"))
Output will contain Hell No. See the Lua demo online.
Here, (%d+)%s? in s:gsub("(%d+)%s?", replace) matches and captures one or more digits and just matches an optional whitespace (with %s?) and the captured value is passed to the replace function, where it is mapped to the char value in CODE. Then, all double spaces are replaced with a single space with gsub(" ", " ").

Lua find operand in a string

I have a Lua string like "382+323" or "32x291" or "94-23", how can I check and return the position of the operands?
I found String.find(s, "[+x-]") did not work. Any ideas?
th> str = '5+3'
th> string.find(str, '[+-x]')
1 1
th> string.find(str, '[+x-]')
2 2
[+-x] is a pattern match for 1 character in the range between "+" and "x".
When you want to use dash as character and not as the meta character you should start or end the character group with it.
print("Type an arithmetic expression, such as 382 x 3 / 15")
expr = io.read()
i = -1
while i do
-- Find the next operator, starting from the position of the previous one.
-- The signals + and - are special characters,
-- so you have to use the % char to escape each one.
-- [The find function returns the indices of s where this occurrence starts and ends][1].
-- Here we are obtaining just the start index.
i = expr:find("[%+x%-/]", i+1)
if i then
print("Operator", expr:sub(i, i), "at position", i)
end
end

How to convert a Lua string to float

I am writing a simple Lua script to calculate a median from a Sorted Set (http://redis.io/commands/#sorted_set) within Redis 2.8. The script is below
local cnt = redis.call("ZCARD", KEYS[1])
if cnt > 0 then
if cnt%2 > 0 then
local mid = math.floor(cnt/2)
return redis.call("ZRANGE", KEYS[1], mid, mid)
else
local mid = math.floor(cnt/2)
local vals = redis.call("ZRANGE", KEYS[1], mid-1, mid)
return (tonumber(vals[1]) + tonumber(vals[2]))/2.0
end
else
return nil
end
The problem is the script always returns an integer, when the result should be a float. The result is wrong.
$ redis-cli zrange floats 0 100
1) "1.1"
2) "2.1"
3) "3.1"
4) "3.4975"
5) "42.63"
6) "4.1"
$ redis-cli EVAL "$(cat median.lua)" 1 floats
(integer) 3
The correct result should be (3.1 + 3.4975)/2.0 == 3.298
From the documentation for EVAL:
Lua has a single numerical type, Lua numbers. There is no distinction between integers and floats. So we always convert Lua numbers into integer replies, removing the decimal part of the number if any. If you want to return a float from Lua you should return it as a string, exactly like Redis itself does (see for instance the ZSCORE command).
Therefore, you should update your script so you are returning the float as a string:
return tostring((tonumber(vals[1]) + tonumber(vals[2]))/2.0)
sorry i have no explanation of this i encounter this by accidental when making script
function int2float(integer)
return integer + 0.0
end

Resources