Get all arguments after args[0] discord.js - arguments

I was trying to make a mute command, and I was adding a system where you can mute them for a reason. The bot would reply "(Username of user) was muted. Reason: (The reason)". For me args[0] is just mentioning the user that you want to mute, but I can't figure out how to get all after args[0]. I've tried doing something like this message.channel.send('I have muted' + (mutedUser) + 'Reason: ' + args[1++]. But that obviously didn't work - I was kind of guessing - I turned to listing 4 arguments like this.
message.channel.send('I have muted ' + taggedUser.user.username + ' Reason: ' + args[1] + ' ' + args[2] + ' ' + args[3] + ' ' + args[4])
But obviously, that's not very efficient - Does anyone know how to get all arguments after args[0]?

Take the array of args and slice() the number of arguments you want to delete, then join() the remaining array elements into a single string
Quick Tip
Use Template literals for easier formatting with strings and variables
const reason = args.slice(1).join(' ');
message.channel.send(`I have muted ${mutedUser}, Reason: ${reason}`);

You can use Array.prototype.join() and Array.prototype.slice()
const str = 'first second third fourth fifth sixth seventh...';
const args = str.split(' ');
console.log(args[0]); // first
console.log(args.slice(1).join(' ')); // everything after first
console.log(args[3]); // fourth
console.log(args.slice(4).join(' ')); // everything after fourth
// basically, `Array.prototype.join()` can join every element of an array (with an optional separator- in this case a space)
console.log(args.join(' ')); // join all elements with a space in between
// and `Array.prototype.slice()` can slice off elements of an array
console.log(args.slice(5)); // slice off 5 elements
// now you can combine these two :)

In a generic scenario, you can use destructuring assignment as so:
const [foo, ...bar] = args;
Here, foo is equal to args[0] and the rest of args is contained within bar as an array.
Specific to your case you could probably do this within your command:
const [mutedUser, reason] = args;
And then as Elitezen suggested, use template literals to send your message.
message.channel.send(`I have muted ${mutedUser}, Reason: ${reason}`);

Related

Changing value of existing valuelabels via Syntax

I'm currently transforming my survey results for analysis. The survey program I used (limesurvey) automatically generates value labels, but I need to change the value the labels corresponds with. SPSS sadly doesn't do that automatically with the recode command, which only changes the values but doesn't change the value labels that correspond to it (They keep pointing at the old value which doesn't have any data entries anymore).
Basically I want to change the value labels from this:
Value labels before change
to this: Value labels after (Changing the labeled Values from A1,A2,A3,A4,A5 into 1,2,3,4,5)
And I don't just want to do it for a single variable, but dozens of variables. While this can actually be accomplished by the search/replace function via the User Interface of SPSS (that's actually how I did it in the example), I would like to do this via Syntax, so I don't have to handcraft every dataset and don't risk screwing up my data with typing mistakes.
Does anyone know how it can be done with Syntax? (Or alternatively some plugin)
So I've found a solution to my problem.
I did the recodes and the relabeling with Python.
BEGIN PROGRAM PYTHON3.
import spss, spssaux, re
sDict = spssaux.VariableDict() #Get a copy of the Variable Dictionary
infotext = "Variables processed: " # begin infotext
#Iterate through all variables (in the dictionary - all variables in this case)
for var in sDict:
#Only Adress variables which are of type String and have value labels.
if spss.GetVariableType(var.index) > 0 and var.ValueLabels != {} :
infotext += spss.GetVariableName(var.index) + ', ' #Add processed variable to infotext
#Begin Value Labels and Recode commands for active variable
commandlab = 'Value Labels ' + spss.GetVariableName(var.index) + ' '
commandrecode = 'Recode ' + spss.GetVariableName(var.index) + ' '
#commandalter = 'Alter Type ' + spss.GetVariableName(var.index) + '(f2).'
#Open entry for each value of valuelabels
for key,val in var.ValueLabels.items():
newkey = re.findall(r'\d+', key)[0] #Get first number in key (value of label)
newkey = re.sub(r'0+(.+)', r'\1', newkey) #Cut leading zeros from number
#Add entry to recode and Value labels command:
commandlab = commandlab + newkey + ' ' + '"' + val + '"' + ' '
commandrecode = commandrecode + '("' + key + '"="' + newkey + '") '
#Complete commands for SPSS:
commandlab = commandlab + '.'
commandrecode = commandrecode + '.\n Execute.'
#Execute recode and relabel.
spss.Submit(commandlab)
spss.Submit(commandrecode)
#spss.Submit(commandalter)
#Print Infos
print(infotext)
print("Warning: Only Values with value labels have been recoded. Please check your dataset to make sure all entries have been affected.")
end program.
Basically this program is finding all string variables with value labels, gets the numbers from the value/key and recodes and relabels the variables. It can also automatically turn all variables numeric, but I wouldn't recommend doing that without checking all values got converted first. In my case I merged several datasets and one variable had a value without label as a result.
Does anyone know how to get the values (or frequencies) of a variable? If possible, I'd like to catch that problem by doing the recode independent of the value labels.

Sort an array depending on given set of characters within each element

I have an array made of a number of elements read from a .txt file. Each element is long and has a lot of information, for instance:
20201102066000000000000000000000000020052IC04008409Z8000000000030546676591AFIP
All the lines are already part of the array lines_array, but I need to sort them out depending on the content of the 36° character until the 51°, which in the example provided above would be:
20052IC04008409Z
I was already able to catch the patterns from each of the elements in the array:
lines_array = File.readlines(complete_filename)
pattern = nil
lines_array.each do |line|
pattern = line[36] + line[37] + line[38] + line[39] + line[40] + line[41] + line[42] + line[43] +
line[44] + line[45] + line[46] + line[47] + line[48] + line[49] + line[50] + line[51]
end
What I need to do now is to be able to sort alphabetically all the elements of the array (with the long elements) based on the content of the variable variable pattern. I tried with methods sort and sort_by but I wasn't able to pass my variable pattern as a parameter. For example, a correct order of three given elements would be:
20201102066000000000000000000000000020001IC04180127X8000000000030546676591AFIP
20201104066000000000000000000000000020001IC04182757T8000000000030546676591AFIP
20201102066000000000000000000000000020001IC05020641D8000000000030546676591AFIP
Any help?
Firstly, there are easier and cleaner ways to extract the substring you're after, you could use String#[] or String#slice:
# These do the same thing, use whichever reads better to you.
pattern = line[36, 16]
pattern = line.slice(36, 16)
pattern = line[36..51]
pattern = line.slice(36..51)
Then you can Enumerable#sort_by on that slice by using a block with sort_by:
sorted = lines_array.sort_by { |str| str[36, 16] }

Ruby Truncate Words + Long Text

I have the following function which accepts text and a word count and if the number of words in the text exceeded the word-count it gets truncated with an ellipsis.
#Truncate the passed text. Used for headlines and such
def snippet(thought, wordcount)
thought.split[0..(wordcount-1)].join(" ") + (thought.split.size > wordcount ? "..." : "")
end
However what this function doesn't take into account is extremely long words, for instance...
"Helloooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
world!"
I was wondering if there's a better way to approach what I'm trying to do so it takes both word count and text size into consideration in an efficient way.
Is this a Rails project?
Why not use the following helper:
truncate("Once upon a time in a world far far away", :length => 17)
If not, just reuse the code.
This is probably a two step process:
Truncate the string to a max length (no need for regex for this)
Using regex, find a max words quantity from the truncated string.
Edit:
Another approach is to split the string into words, loop through the array adding up
the lengths. When you find the overrun, join 0 .. index just before the overrun.
Hint: regex ^(\s*.+?\b){5} will match first 5 "words"
The logic for checking both word and char limits becomes too convoluted to clearly express as one expression. I would suggest something like this:
def snippet str, max_words, max_chars, omission='...'
max_chars = 1+omision.size if max_chars <= omission.size # need at least one char plus ellipses
words = str.split
omit = words.size > max_words || str.length > max_chars ? omission : ''
snip = words[0...max_words].join ' '
snip = snip[0...(max_chars-3)] if snip.length > max_chars
snip + omit
end
As other have pointed out Rails String#truncate offers almost the functionality you want (truncate to fit in length at a natural boundary), but it doesn't let you independently state max char length and word count.
First 20 characters:
>> "hello world this is the world".gsub(/.+/) { |m| m[0..20] + (m.size > 20 ? '...' : '') }
=> "hello world this is t..."
First 5 words:
>> "hello world this is the world".gsub(/.+/) { |m| m.split[0..5].join(' ') + (m.split.size > 5 ? '...' : '') }
=> "hello world this is the world..."

Trimming a String

I'm using windows 7 and Visual C++. I have a console program and I am trying to trim a string at the begining and the end. TrimLeft() and TrimRight() don't seem to work without MFC. Here is what I have so far.
pBrowser->get_LocationURL(&bstr);
wprintf(L" URL: %s\n\n", bstr);
SysFreeString(bstr);
std::wstring s;
s = bstr;
s.TrimStart("http://");
s.TrimEnd("/*");
wprintf(L" URL: %s\n\n", s);
I'm trying to go from this:
"http://www.stackoverflow.com/questions/ask"
to this:
"www.stackoverflow.com"
TrimStart/End usually return a value, so you would have to set 's' to equal the value of s.TrimStart() and s.TrimEnd() respectively.
try,
s = s.TrimStart("http://");
s = s.TrimEnd("/*");
You should use find/rfind(right find - find from right) and substr(sub string) in sequence to do what you need to do.
1) Find the index of the first pattern (such as http://) with find - you already know its length, add this to the start index as the origo of your trimmed string
2) Find the last index of the ending pattern with find
3) Create a substring from the origo to the end using substr
These methods are all in std::string

Ruby replace text within single quotes or backticks for html tag

Hello I am trying to build a simple action in Ruby that takes one string like
result = "This is my javascript variable 'var first = 1 + 1;' and here is another 'var second = 2 + 2;' and that's it!"
So basically I would like to take the text within single quotes ' or backticks ` and and replace it by:
<code>original text</code> note I'm replacing it by an opening and closing code tag
Just like in markdown
so I would have a result like
result = "This is my javascript variable <code>var first = 1 + 1;<code> and here is another <code>var second = 2 + 2;</code> and that's it"
If it's possible to run this natively without the need of any extra gem it would be great :)
Thanks a lot
I guess you'll need to iterate the string and parse it. While you can do non-greedy regex matches, e.g. result.gsub!(/'([^']*)'/, '<code>\1</code>') you might find the result might not behave correctly in corner-cases.
Without any other advanced requirement
>> result.gsub(/\s+'/,"<code>").gsub(/'\s+/,"</code>")
=> "This is my javascript variable<code>var first = 1 + 1;</code>and here is another<code>var second = 2 + 2;</code>and that's it!"
You will need to come-up with a character as a delimiter for your code, which you don't use otherwise..
Why? because of all the corner cases. E.g. the following string
result = "This's my javascript variable 'var first = 1 + 1;' and here is another 'var second = 2 + 2;' and that's it!"
which would otherwise produce:
"This<code>s my javascript variable </code>var first = 1 + 1;<code> and here is another </code>var second = 2 + 2;<code> and that</code>s it!"
Total garbage out..
However if you use a unique character as a delimiter that's otherwise not used, you can create a non-greedy RegExp which will do the search/replace
e.g. using a # character to delimit the code:
"This's my javascript variable #var first = 1 + 1;# and here is another #var second = 2 + 2;# and that's it!"

Resources