Ruby Hash#select{} with If condition - ruby-on-rails

I want to select all keyword until by cumulative SUM < X. This does not work because the return true stops the script.
cum_sum = 0
keywords = keywords.select{|k|
cum_sum += k[:contribution]
if cum_sum < top
return true
else
return false
end
}

Block return value is value of the last statement, you can just write:
cum_sum = 0
keywords = keywords.select{|k|
cum_sum += k[:contribution]
cum_sum < top
}
Also there's Enumerable#take_while that's more suitable for your use case

Related

Lua function constantly returning false out of SQL function

I have this code
function IsAuthorized(xPlayer, doorID, locked, usedLockpick)
local jobName, grade = {}, {}
jobName[1] = xPlayer.job.name
grade[1] = xPlayer.job.grade
if xPlayer.job2 then
jobName[2] = xPlayer.job2.name
grade[2] = xPlayer.job2.grade
end
local canOpen = false
if doorID.lockpick and usedLockpick then
count = xPlayer.getInventoryItem('lockpick').count
if count and count >= 1 then canOpen = true end
end
if not canOpen and doorID.authorizedJobs then
for job,rank in pairs(doorID.authorizedJobs) do
if (job == jobName[1] and rank <= grade[1]) or (jobName[2] and job == jobName[2] and rank <= grade[2]) then
canOpen = true
if canOpen then break end
end
end
end
if not canOpen and doorID.items then
local count
for k,v in pairs(doorID.items) do
count = xPlayer.getInventoryItem(v).count
if count and count >= 1 then
canOpen = true
local consumables = { ['ticket']=1 }
if locked and consumables[v] then
xPlayer.removeInventoryItem(v, 1)
end
break
end
end
if not count or count < 1 then canOpen = false end
end
if not canOpen then
local group = xPlayer.getGroup()
if group == 'management' or group == 'owner' then
print(group..' '..xPlayer.getName()..' was authorised to use a door')
canOpen = true
end
if doorID.authorizedgang then
print(xPlayer.identifier .. " | " .. doorID.authorizedgang)
MySQL.Async.fetchSingle('SELECT * FROM users WHERE identifier = ? AND gang = ?', {xPlayer.identifier, doorID.authorizedgang}, function(foundplayer)
if foundplayer then
print("found")
canOpen = true
print(canOpen)
end
----------------------------canopen returns true until here
end)
end
end
print(canOpen)
return canOpen
end
Essentially what is does is return a true or false value based on the if statements. I did not write this script myself, I simply added on. The code that I added to this function is
if doorID.authorizedgang then
print(xPlayer.identifier .. " | " .. doorID.authorizedgang)
MySQL.Async.fetchSingle('SELECT * FROM users WHERE identifier = ? AND gang = ?', {xPlayer.identifier, doorID.authorizedgang}, function(foundplayer)
if foundplayer then
print("found")
canOpen = true
print(canOpen)
end
----------------------------canopen returns true until here
end)
end
This code essentially makes a database call to check if it'll find a player with X identifier and Y gang, and this actually does work because it prints out "found" and canOpen returns true until the line that I marked, after this it returns false at the bottom of the function.
I've been trying other ways to get the data but ultimately I need the SQL DB call for this and im not sure why the variable isnt setting when in fact the database returns found. Any ideas what I could be doing wrong here?

how do i fix ')' (to close '(' at line 38), got '.'

for i, v in pairs(Buttons:GetChildren()) do
local NewItem = BoughtItems:FindFirstChild(v.Item.value)
if NewItem ~= nil then
Items[NewItem.Name] = NewItem:Clone()
NewItem:Destroy()
else
v.ButtonPart.Transparency = 1
v.ButtonPart.CanCollide = false
v.ButtonPart.BillBoardGui.Frame.Visible = false
end
if v:FindFirstChild("Dependency") then
coroutine.resume(coroutine.create(function(
v.ButtonPart.Transparency = 1
v.ButtonPart.CanCollide = false
v.ButtonPart.BillBoardGui.Frame.Visible = false
if BoughtItems:WaitForChild(v.Dependency.Value, 100000)then
v.ButtonPart.Transparency = 0
v.ButtonPart.CanCollide = true
v.ButtonPart.BillBoardGui.Frame.Visible = true
end
end))
end
v.ButtonPart.Touched:Connect(function(Hit)
if Hit.Parent:FindFirstChild("Humanoid")then
local Player = game.Players:GetPlayerFromCharacter(Hit.Parent)
if Values.OwnerValue.Value == Player then
if v.ButtonPart.CanCollide == true and v.ButtonPart.Transparency == 0 then
if Player:WaitForChild("leaderstats").Cash.Value >= v.Price.Value then
Player.leaderstats.Cash.Value -= v.Price.Value
Items[v.Item.Value].Parent = BoughtItems
v:Destroy()
end
end
end
end
end)
end
how do i fix this the header is the problem i dont knw what it means so is there a fix to it for my tycoon if anyone knows pls comment (heres some random stuff since my post is mostly code) A brief Introduction to Copypasta. Copypasta means to copy a text or a part of the text from an existing manuscript and inclusion of that very text in an under-process manuscript by pasting. At present, the societies are going to be expanded with an enormous pattern.
Parenthesis always come in pairs. The error message already strongly suggests that you are missing a closing parenthesis for an opening one in line 38.
1 2 3
coroutine.resume(coroutine.create(function(
v.ButtonPart.Transparency = 1
v.ButtonPart.CanCollide = false
v.ButtonPart.BillBoardGui.Frame.Visible = false
if BoughtItems:WaitForChild(v.Dependency.Value, 100000)then
v.ButtonPart.Transparency = 0
v.ButtonPart.CanCollide = true
v.ButtonPart.BillBoardGui.Frame.Visible = true
end
end)) <--- one is missing
1 2
Use a text editor that autocompletes pairs or even better one that hightlights pairs in matching colors to avoid errors like this.

Lua: string: evaluate if characters are in ascending order

How can if evaluate whether all characters composing a string are in strictly ascending/descending order?
eg:
print(is_strictly_asc_or_desc("abcdefghijklmnopqrstuvwxyz")) --> true
print(is_strictly_asc_or_desc("abba")) --> false
print(is_strictly_asc_or_desc("dj")) --> true
print(is_strictly_asc_or_desc("ace")) --> true
print(is_strictly_asc_or_desc("cent")) --> true
print(is_strictly_asc_or_desc("foot")) --> true
print(is_strictly_asc_or_desc("old")) --> true
print(is_strictly_asc_or_desc("file")) --> false
print(is_strictly_asc_or_desc("")) --> true
print(is_strictly_asc_or_desc("b")) --> true
I tried something (but it is not working, and even if fixed, I doubt that it will be efficient...):
function is_strictly_asc_or_desc(s)
local alphabet = {a=1,b=2,c=3,d=4,e=5,f=6,g=7,h=8,i=9,j=10,k=11,l=12,m=13,n=14,o=15,p=16,q=17,r=18,s=19,t=20,u=21,v=22,w=23,x=24,y=25,z=26}
if alphabet[s[1]] < alphabet[s[2]] then
for i,letter in ipairs(s) do
if alphabet[s[i]] > alphabet[s[i+1]] then
return false
end
end
else
for i,letter in ipairs(s) do
if alphabet[s[i]] < alphabet[s[i+1]] then
return false
end
end
end
return true
end
We can assume words are solely constructed from chars in "abcdefghijklmnopqrstuvwxyz" IE only lower case letters; EG: "abc!f" --> invalid; "Hello" --> invalid; etc.
To solve this we can iterate over the string and check their byte values!
function Validate(str,asc)
local temp = asc and 0 or math.huge
local temp2
for i = 1,#str do
temp2 = str:sub(i,i):byte()
if (ask and temp2 < temp) or temp2 < temp then
return false
else
temp = temp2
end
end
return true
end
EDIT: Fixed function to accept optional ascending argument, this allows you to determine if it's ascending to descending separately. I feel this is more powerful since you can use it in different situations.
A similar variation for either ascending or descending:
function is_strictly_asc_or_desc(s)
while #s > 2 and s:sub(2,2) == s:sub(1,1) do s = s:sub(2) end
local temp = s:sub(1,1)
local up = s:sub(2,2) > temp
for c = 2, #s do
c = s:sub(c,c)
if up and c < temp or not up and c > temp then return false end
temp = c
end
return true
end

Boolean function arguments and returning

so i know you can do stuff like this in lua to kind of shorten your code so you don't have to make unnecessary if statements
function checkMath(equation)
if equation == 4 then
return true
end
return false
end
workspace.Part.BrickColor = BrickColor.Green() or BrickColor.Red()
but is there a way to do that for a return statement inside a function?
basically, what I'm asking is: is it possible to return amount and items if returnItems is true or only amount if returnItems is false without a if statement?
what I've thought of doing (haven't tested):
countDictItems = function(tab,returnItems)
local amount = 0
local items = {}
for _, ind in pairs(tab) do
amount = amount + 1
end
return amount, items or amount
end
Answered in a separate thread I posted on another website.
function blah(returnitems)
amount = 15
items = {"blah1", "blah2"}
return amount, returnitems and items or nil
end
print(blah(true))
print(blah(false))
output:
>15 table: 0x9e26e0
>15 nil

String in alphabetical order Ruby

I am new to Ruby. I have written a solution in Java
public boolean checkOrder(String input) {
boolean x = false;
for (int i = 0; i < input.length() - 1; i++) {
if (input.charAt(i) < input.charAt(i + 1) || input.charAt(i) == input.charAt(i + 1)) {
x = true;
} else {
return false;
}
}
return x;
}
I want to do the same in ruby how can I convert the same into ruby. Thanks.
def checkOrder(input)
input.chars.sort == input.chars.to_a
end
Variation of Sam's answer, in case you ever want this as a String method:
class String
def sorted?
self.chars.sort == self.chars.to_a
end
end
'abc'.sorted?
'acb'.sorted?
As requested:
def checkOrder(input)
x = false
(input.length-1).times do |i|
if input[i] < input[i+1] or input[i] == input[i+1]
x = true
else
return false
end
end
x
end

Resources