Lua char spacing perfectly - lua

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!

Related

How do I make it look like the picture in Lua

This is my code
local level = 5
for i = 1, level do
local text = ""
for j = 1, i do
text = text..""
end
for j = 1, level-i, 1 do
text = text.." "
end
for j = 1+level, level+(level-i) do
text = text.." "
end
for j = 1, level + i-level do
text = text..""
end
print(text)
end
I want the result to be similar to the one in the picture.
Here is what your code looks like with proper formatting.
local level = 5
for i = 1, level do
local text = ""
for j = 1, i do
text = text..""
end
for j = 1, level-i, 1 do
text = text.." "
end
for j = 1+level, level+(level-i) do
text = text.." "
end
for j = 1, level + i-level do
text = text..""
end
print(text)
end
Your current code prints... well... an empty string. You haven't yet added the characters it's to display to be on par with the image.
The amount of characters per row is 9. So you ideally need 9 characters per row. You will also be incrementing the number once per row. The amount of characters per row also increases by 2; one on each side.
We can use the string.rep(string, number) function to duplicate a 'string' 'number' times. You can feed in your current level into that so it generates 1 2 or 3 depending on the line the number of times. Then you have whitespace to worry about. You can use string.rep again along with a bit of distance math to calculate the amount of whitespace you need from what you take up. Then finally throw everything together concatenated trailing with the first string and print.
local levels = 5
local columns = 9
for i=1, levels do
local str = string.rep(i, i)
local padding = columns - (#str * 2) + 1
print(str .. string.rep(" ", padding) .. str)
end

A better way on improving my roman numeral decoder

Quick explanation, I have recently started using codewars to further improve my programming skills and my first challenge was to make a roman numeral decoder, I went through many versions because I wasnt satisfied with what I had, So I am asking if there is an easier way of handling all the patterns that roman numerals have, for example I is 1 but if I is next to another number it takes it away for example V = 5 but IV = 4.
here is my CODE:
function Roman_Numerals_Decoder (roman)
local Dict = {I = 1, V = 5, X = 10, L = 50, C = 100, D = 500, M = 1000}
local number = 0
local i = 1
while i < #roman + 1 do
local letter = roman:sub(i,i) -- Gets the current character in the string roman
if roman:sub(i,i) == "I" and roman:sub(i + 1,i + 1) ~= "I" and roman:sub(i + 1,i + 1) ~= "" then -- Checks for the I pattern when I exists and next isnt I
number = number + (Dict[roman:sub(i +1,i + 1)] - Dict[roman:sub(i,i)]) -- Taking one away from the next number
i = i + 2 -- Increase the counter
else
number = number + Dict[letter] -- Adds the numbers together if no pattern is found, currently checking only I
i = i + 1
end
end
return number
end
print(Roman_Numerals_Decoder("MXLIX")) -- 1049 = MXLIX , 2008 = MMVIII
at the moment I am trying to get 1049 (MXLIX) to work but I am getting 1069, obviously I am not following a rule and I feel like its more wrong then it should be because usually if its not correct its 1 or 2 numbers wrong.
The algorithm is slightly different: you need to consider subtraction when the previous character has less weight than the next one.
function Roman_Numerals_Decoder (roman)
local Dict = {I = 1, V = 5, X = 10, L = 50, C = 100, D = 500, M = 1000}
local num = 0
local i = 1
for i=1, #roman-1 do
local letter = roman:sub(i,i) -- Gets the current character in the string roman
local letter_p = roman:sub(i+1,i+1)
if (Dict[letter] < Dict[letter_p]) then
num = num - Dict[letter] -- Taking one away from the next number
print("-",Dict[letter],num)
else
num = num + Dict[letter] -- Adds the numbers together if no pattern is found, currently checking only I
print("+",Dict[letter],num)
end
end
num = num + Dict[roman:sub(-1)];
print("+",Dict[roman:sub(-1)], num)
return num
end
print(Roman_Numerals_Decoder("MXLIX")) -- 1049 = MXLIX , 2008 = MMVIII

Displaying the bits values of a number in Wireshark Postdissector

I am writing a wireshark dissector of a custom protocol using LUA.For this custom protocol,there are no underlying TCP port or UDP port hence i have written a postdissector.
I am able to capture the payload from the below layers and convert it into a string.
local io_b = tostring(customprotocol)
After this, io_b has the following data
io_b = 10:10:10:10:01:0f:00:0d:00:00:00:00:01:00:00:00:00:20:0a:00:00
At first I split this string with : as the seperator and copy the elements into an array/table.
datafields = {}
index = 1
for value in string.gmatch(io_b, "[^:]+") do
datafields[index] = value
index = index + 1
end
Then I read each element of the datafield array as a uint8 value and check if a bit is set in that datafield element.How to make sure that each element of the table is uint8?
function lshift(x, by)
return x * 2 ^ by
end
--checks if a bit is set at a position
function IsBitSet( b, pos)
if b ~= nil then
return tostring(bit32.band(tonumber(b),lshift(1,pos)) ~= 0)
else
return "nil"
end
end
Then I want to display the value of each bit in the wireshark.I dont care about the first four bytes. The script displays each bit of the 5th byte(which is the 1st considered byte) correctly but displays all the bits value of the 6th byte and other remaining bytes as "nil".
local data_in_2 = subtree:add(customprotocol,"secondbyte")
data_in_2:add(firstbit,(IsBitSet((datafields[6]),7)))
data_in_2:add(secondbit,(IsBitSet((datafields[6]),6)))
data_in_2:add(thirdbit,(IsBitSet((datafields[6]),5)))
data_in_2:add(fourbit,(IsBitSet((datafields[6]),4)))
data_in_2:add(fivebit,(IsBitSet((datafields[6]),3)))
data_in_2:add(sixbit,(IsBitSet((datafields[6]),2)))
data_in_2:add(sevenbit,(IsBitSet((datafields[6]),1)))
data_in_2:add(eightbit,(IsBitSet((datafields[6]),0)))
What am i doing wrong?
Maybe i am wrong but it seems you can do it simpler with...
io_b = '10:10:10:10:01:0f:00:0d:00:00:00:00:01:00:00:00:00:20:0a:00:00'
-- Now replace all : on the fly with nothing and convert it with #Egor' comment tip
-- Simply by using string method gsub() from within io_b
b_num = tonumber(io_b:gsub('%:', ''), 16)
print(b_num)
-- Output: 537526272
#shakingwindow - I cant comment so i ask here...
Do you mean...
io_b = '10:10:10:10:01:0f:00:0d:00:00:00:00:01:00:00:00:00:20:0a:00:00'
-- Converting HEX to string - Replacing : with ,
io_hex = io_b:gsub('[%x]+', '"%1"'):gsub(':', ',')
-- Converting string to table
io_hex_tab = load('return {' .. io_hex .. '}')()
-- Put out key/value pairs by converting HEX value string to a number on the fly
for key, value in pairs(io_hex_tab) do
print(key, '=', tonumber(value, 16))
end
...that puts out...
1 = 16
2 = 16
3 = 16
4 = 16
5 = 1
6 = 15
7 = 0
8 = 13
9 = 0
10 = 0
11 = 0
12 = 0
13 = 1
14 = 0
15 = 0
16 = 0
17 = 0
18 = 32
19 = 10
20 = 0
21 = 0
...?

How to arrange picture in lua like a grid?

I'm learning lua and I want to arrange my bubble picture with some specific x and y coordinates, here's my code so far, the value of my j and i is only incrementing by 1 instead of the +29, I know I'm lacking some knowledge so any help will be appreciated
local background = display.newImageRect("blueBackground.png",642, 1040)
background.x = display.contentCenterX
background.y = display.contentCenterY
local x = 15
local y=15
for i=15,25 do
for j=15, 25 do
local bubble = display.newImageRect("bubble.png", 23,23)
bubble.x = i
bubble.y = j
j = j + 29
print("j",j)
end
i = i + 29
print("i",i)
end
This should helps you.
From Lua documentation
The for statement has two variants: the numeric for and the
generic for.
A numeric for has the following syntax:
for var=exp1,exp2,exp3 do
something
end
That loop will execute something for each value of var from exp1
to exp2, using exp3 as the step to increment var. This third
expression is optional; when absent, Lua assumes one as the step
value. As typical examples of such loops, we have
for i=1,f(x) do print(i) end
for i=10,1,-1 do print(i) end
Use
for i=15, 29*10+15, 29 do
for j=15, 29*10+15, 29 do
local bubble = display.newImageRect("bubble.png", 23,23)
bubble.x = i
bubble.y = j
print("j",j)
end
print("i",i)
end
or
for i=0, 10 do
for j=0, 10 do
local bubble = display.newImageRect("bubble.png", 23,23)
bubble.x = 15 + i * 29
bubble.y = 15 + j * 29
...

Parsing Lua strings, more specifically newlines

I'm trying to parse Lua 5.3 strings. However, I encountered an issue. For example,
$ lua
Lua 5.3.4 Copyright (C) 1994-2017 Lua.org, PUC-Rio
> print(load('return "\\z \n\r \n\r \r\n \n \n \\x"', "#test"))
nil test:6: hexadecimal digit expected near '"\x"'
>
> print(load('return "\\z\n\r\n\r\r\n\n\n\\x"', "#test"))
nil test:6: hexadecimal digit expected near '"\x"'
Both of these error on line 6, and the logic behind that is pretty simple: eat newline characters (\r or \n) if they're different from the current one (I believe this to be an accurate description of how the lua lexer works, but I may be wrong).
I have this code, which should do it:
local ln = 1
local skip = false
local mode = 0
local prev
for at, crlf in eaten:gmatch('()[\r\n]') do
local last = eaten:sub(at-1, at-1)
if skip and prev == last and last ~= crlf then
skip = false
else
skip = true
ln = ln + 1
end
prev = crlf
end
It decides whether to eat newlines based on the previous char. Now, from what I can tell, this should work, but no matter what I do it doesn't seem to work. Other attempts have made it report 5 lines, while this one makes it report 9(!). What am I missing here? I'm running this on Lua 5.2.4.
This is part of a routine for parsing \z:
local function parse52(s)
local startChar = string.sub(s,1,1)
if startChar~="'" and startChar~='"' then
error("not a string", 0)
end
local c = 0
local ln = 1
local t = {}
local nj = 1
local eos = #s
local pat = "^(.-)([\\" .. startChar .. "\r\n])"
local mkerr = function(emsg, ...)
error(string.format('[%s]:%d: ' .. emsg, s, ln, ...), 0)
end
local lnj
repeat
lnj = nj
local i, j, part, k = string.find(s, pat, nj + 1, false)
if i then
c = c + 1
t[c] = part
if simpleEscapes[v] then
--[[ some code, some elseifs, some more code ]]
elseif v == "z" then
local eaten, np = s:match("^([\t\n\v\f\r ]*)%f[^\t\n\v\f\r ]()", nj+1)
local p=np
nj = p-1
--[[ the newline counting routine above ]]
--[[ some other elseifs ]]
end
else
nj = nil
end
until not nj
if s:sub(-1, -1) ~= startChar then
mkerr("unfinished string near <eof>")
end
return table.concat(t)
end
Compact code for iterating lines of Lua script:
local text = "First\n\r\n\r\r\n\n\nSixth"
local ln = 1
for line, newline in text:gmatch"([^\r\n]*)([\r\n]*)" do
print(ln, line)
ln = ln + #newline:gsub("\n+", "\0%0\0"):gsub(".%z.", "."):gsub("%z", "")
end
Efficient code for iterating lines of Lua script:
local text = "First\n\r\n\r\r\n\n\nSixth"
local sub = string.sub
local ln = 1
for line, newline in text:gmatch'([^\r\n]*)([\r\n]*)' do
print(ln, line)
local pos, max_pos = 1, #newline
while pos <= max_pos do
local crlf = sub(newline, pos, pos + 1)
if crlf == "\r\n" or crlf == "\n\r" then
pos = pos + 2
else
pos = pos + 1
end
ln = ln + 1
end
end

Resources