String manipulation overlapping - string

def Codehelp(st):
i = 0
noot = ""
while i < len(st):
if st[i] == '$':
noot += "**" + st[i] + "**"
i += 1
if '$' in noot:
return noot
else:
return "**"
return
Basically, every time user inputs a string that has '$' in it, the code will return only the '$' with 2 asterisks before and after the '$'. In most test cases the code runs fine, however once inputting a string with more than one '$', i.e. Codehelp("r$t$$"), it outputs **$****$****$** (add two * to both the beginning and end of the string), instead of ****$**$** (ignore the first two *).

Well like you say I get this output: **$****$****$**.
I can certainly say that this makes sense because it only checks on the current instance of $ and adds ** before and after.
If you want it to be more "intelligent", you might need to implement something that might peek ahead to see if there is another $ after the current one.
However, to get **$$ (not sure it that is what you expect, please correct me), you need to look at the next index to see if there is another $ (obviously taking string length boundary checks into consideration as well) and not add additional ** after the second $.

Related

Python ord() and chr()

I have:
txt = input('What is your sentence? ')
list = [0]*128
for x in txt:
list[ord(x)] += 1
for x in list:
if x >= 1:
print(chr(list.index(x)) * x)
As per my understanding this should just output every letter in a sentence like:
))
111
3333
etc.
For the string "aB)a2a2a2)" the output is correct:
))
222
B
aaaa
For the string "aB)a2a2a2" the output is wrong:
)
222
)
aaaa
I feel like all my bases are covered but I'm not sure what's wrong with this code.
When you do list.index(x), you're searching the list for the first index that value appears. That's not actually what you want though, you want the specific index of the value you just read, even if the same value occurs somewhere else earlier in the list too.
The best way to get indexes along side values from a sequence is with enuemerate:
for i, x in enumerate(list):
if x >= 1:
print(chr(i) * x)
That should get you the output you want, but there are several other things that would make your code easier to read and understand. First of all, using list as a variable name is a very bad idea, as that will shadow the builtin list type's name in your namespace. That makes it very confusing for anyone reading your code, and you even confuse yourself if you want to use the normal list for some purpose and don't remember you've already used it for a variable of your own.
The other issue is also about variable names, but it's a bit more subtle. Your two loops both use a loop variable named x, but the meaning of the value is different each time. The first loop is over the characters in the input string, while the latter loop is over the counts of each character. Using meaningful variables would make things a lot clearer.
Here's a combination of all my suggested fixes together:
text = input('What is your sentence? ')
counts = [0]*128
for character in text:
counts[ord(character)] += 1
for index, count in enumerate(counts):
if count >= 1:
print(chr(index) * count)

How to dissect and parse a string in lua?

I am trying to make command arguments in Roblox. For example, /kill playername. The problem is I don't know how to parse the playername from the string /kill playername. This code is in something like this:
game:GetService("Players").PlayerAdded:Connect(function(Player)
Player.Chatted:Connect(function(Message)
if string.sub(1, #Message) == "/kill " then
--this means the string starts with /kill and is expecting an argument.
--How can I parse this argument from the string
end
end)
end)
Edit: I want to add /setdata <Playername> <DataToChange eg. money> <Value>
Example command:
/setdata MyRobloxUsername Money 10000
I am trying to use something like this to do so
local Command, Playername, DataToChange, Value = string.match(???)
I just need to get the values from the string into variables. I can figure out how to change the data using the variables myself. Just how to get the values from the string. How can I do what I am describing?
I unaccepted the answer because I need further help. Once I get this help I will re accept it. My next request is similar, but with 3 arguments instead of 1. I need help as string:Match() is very counter intuitive to me
Use string.match:
Message=" /kill playername "
command, arg = Message:match("%s*/(.-)%s+(.*)%s*$")
If you want this to be more flexible to more commands in the future, I suggest you take both lhf's and BotOfWar's suggestions and combine them.
local function executeCommandInMessage(message)
-- do a quick regex of the message to see if it is formatted as a command
-- all we care about is the command, any arguments are optional.
local command, arguments = string.match(message, "^/(%w+)[%s]?([%w%s]+)$")
if command ~= nil then
-- we've found a command, parse the arguments into groups of non-space characters
-- then store each word in the parts array
local parts = {}
for w in arguments:gmatch("%S+") do
table.insert(parts, w)
end
-- handle each command individually
if command == "kill" then
local player = parts[1]
print(string.format("Killing %s", player))
elseif command == "setdata" then
local player = parts[1]
local value = parts[2]
local amount = parts[3]
print(string.format("Setting %s on %s to %s", value, player, amount))
-- add any further commands to the list..
-- elseif command == "" then
end
end
end
-- listen for any message submitted by players
game:GetService("Players").PlayerAdded:Connect(function(Player)
Player.Chatted:Connect(function(msg)
-- check for any commands
executeCommandInMessage(msg)
end)
end)
In the future, if you need a better regex to parse the message, I suggest you take a look at how to do Lua pattern matching. They're pretty easy to read once you know what to look at.
I suggest splitting the string with the string.split method to get the segments, then check if the first value is what you want.
game:GetService("Players").PlayerAdded:Connect(function(Player)
Player.Chatted:Connect(function(Message)
local segments = Message:split(" ")
if((#segments >= 1) and (segments[1] == "/kill")) then
-- The rest of the arguments can be accessed like this:
local args = {unpack(segments, 2)} -- Gets every argument after the first value,
-- which is the command.
end
end)
end)

decompressing a compressed string

My question is that I don't know where to go now with the code I have to create a decompress code. I get the error (TypeError: can't multiply sequence by non-int of type 'str') and assume its because I'm not multiplying the string correctly. Also, I can't use lists, just string manipulation for this assignment
Just as an example, the output's suppose to look like this-> cat2dog1qwerty3 -> catcatdogqwertyqwertyqwerty
Function:
def decompress(compressed_in):
new_word = True
char_holder = ""
decompressed_out = ""
for char in compressed_in:
if char.isalpha and new_word:
char_holder += char
new_word = False
elif char.isalnum:
decompressed_out += char * char_holder
new_word = True
return decompressed_out
Main:
# Import
from compress import decompress
# Inputs
compressed_in = str(input("Enter a compressed string: ")) # compressed
# Outputs
decompressed_out = decompress(compressed_in)
print(decompressed_out)
Since this is apparently a homework assignment, I won't give you the code, but here are several problems I see with what you're presented.
Indentation. This is probably an artifact of copying-and-pasting, but every line after the def should be indented.
Not calling functions. When you write char.isalpha, that probably isn't doing what you want it to. .isalpha() is a function, so you need to call it with parentheses, like char.isalpha().
isalnum() is probably not the function you want. That checks if something is a letter or a number, but you've already checked for letters, so you probably want the function that checks if something is a number. This isn't strictly necessary, since the other if condition will still trigger first, but it's something you could get marked down for.
You never clear char_holder. It looks like you meant to, since you have a boolean new_word that you keep track of, but you aren't using it properly. At some point, you should be doing char_holder = char (ie. not +=). I'll let you decide where to put that logic.
Finally, for the error you're getting. You are correct that you are not multiplying things together correctly. Think about what the types are in the multiplication statement, and what values the variables would have. For example, in the first pass, char_holder would be equal to 'cat', and char would be equal to '3'. Try typing '3' * 'cat' into a Python interpreter and see what happens. It should be evident from here what you need to do to fix this.

Error when take two numbers out of a string

I'm just playing around with Lua trying to make a calculator that uses string manipulation. Basically I take two numbers out of a string, then do something to them (+ - * /). I can successfully take a number out of x, but taking a number out of y always returns nil. Can anyone help?
local x = "5 * 75"
function calculate(s)
local x, y =
tonumber(s:sub(1, string.find(s," ")-1)),
tonumber(s:sub(string.find(s," ")+3), string.len(s))
return x * y
end
print(calculate(x))
You have a simple misplaced parenthesis, sending string.len to tonumber instead of sub.
local x, y =
tonumber(s:sub(1, string.find(s," ")-1)),
tonumber(s:sub(string.find(s," ")+3, string.len(s)))
You actually don't need the string.len, as end of string is the default value for sub if nothing is given.
EDIT:
You can actually do what you want to do way shorter by using string.match instead.
local x,y = string.match(s,"(%d+).-(%d+)")
Match looks for tries to match the string with the pattern given and returns the captured values, in this case the numbers. This pattern translates to "One or more digits, then as few as possible of any character, then one or more digits". %d is 1 digit, + means one or more. . means any character and - means as few as possible. The values within the parentheses are captured, which means that they are returned.

groovy loop does not stop

this is part of a teardown script, but it is giving me some trouble.
while ( n-- > 0 ) {
testRunner.testCase.setPropertyValue( "ExpectedNo" + n, "")
}
n starts with value 5 and does reset ExpectedNo0 through ExpectedNo4 to blank as it is supposed to do, but afterwards it sets up 46 more property entries as follows
ExpectedNo/
ExpectedNo.
ExpectedNo,
....
I am not sure what to make of this as I am not very versed in groovy.. any help would be appreaciated!
To understand the source of your problem, take a look at ASCII table (link to a one). You'll see that before characters '0'-'5' there stands (in reverse order) '/', '.', '-', etc. Groovy interprets your n as character instead of integer variable. All you need is to convert n from String to Integer. See the next SO question how to do this: Groovy String to int.

Resources