I am using texreg for regression output. I would like to align on decimals in the table. However, all numbers are in math mode, between '$' characters. Is there an option to only enclose the significance stars in '$', leaving the numbers as regular text?
Used stringr to modify the output of texreg. For anyone interested:
tex <- texreg(list(model1,model2,model3,model4),
digits = 3,
stars=c(0.1,0.05,0.01,0.001),
symbol='+')
#
# convert numbers to text, grabbing stars and keeping between math symbols.
library(stringr)
newTex <- str_replace_all(tex,"\\$\\(?-?\\d+(,\\d+)*(\\.\\d+(e\\d+)?)?\\)?\\^?\\{?(\\*+)?\\+?\\}?\\$",
function(x) {
if(str_detect(x,"\\^")) {
ret <- sub("^","$^",sub("$","",x,fixed=T),fixed=T)
} else {
ret <- gsub("$","",x,fixed=T)
}
return(ret)
})
Related
This question already has answers here:
Calculate string value in javascript, not using eval
(12 answers)
Closed 4 months ago.
When the text was '2+3+5+1', the logic was easy
Split('+') so the string is converted to an array.
loop over the array and calculate the sum.
check the code below
void main() {
const text = '2+3+5+1';
final array = text.split('+');
int res =0;
for (var i=0; i<= array.length -1; i++){
res+=int.parse(array[i]);;
}
print(array);
print(res);
}
Now this String "2+3-5+1" contains minus.
how to get the right response using split method?
I am using dart.
note: I don't want to use any library (math expression) to solve this exercice.
Use the .replace() method.
text = text.replace("-", "+-");
When you run through the loop, it will calculate (-).
You can split your string using regex text.split(/\+|\-/).
This of course will fail if any space is added to the string (not to mention *, / or even decimal values).
const text = '20+3-5+10';
const arr = text.split(/\+|\-/)
let tot = 0
for (const num of arr) {
const pos = text.indexOf(num)
if (pos === 0) {
tot = parseInt(num)
} else {
switch (text.substr(text.indexOf(num) - 1, 1)) {
case '+':
tot += parseInt(num)
break
case '-':
tot -= parseInt(num)
break
}
}
}
console.log(tot)
I see 2 maybe 3 options, definitely there are hundreds
You don't use split and you just iterate through the string and just add or subtract on the way. As an example
You have '2+3-5+1'. You iterate until the second operator (+ or -) on your case. When you find it you just do the operation that you have iterated through and then you just keep going. You can do it recursive or not, doesn't matter
"2+3-5+1" -> "5-5+1" -> "0+1" -> 1
You use split on + for instance and you get [ '2', '3-5', '1' ] then you go through them with a loop with 2 conditions like
if(isNaN(x)) res+= x since you know it's been divided with a +
if(!isNaN(x)) res+= x.split('-')[0] - x.split('-')[1]
isNaN -> is not a number
Ofc you can make it look nicer. If you have parenthesis though, none of this will work
You can also use regex like split(/[-+]/) or more complex, but you'll have to find a way to know what operation follows each digit. One easy approach would be to iterate through both arrays. One of numbers and one of operators
"2+3-5+1".split(/[-+]/) -> [ '2', '3', '5', '1' ]
"2+3-5+1".split(/[0-9]*/).filter(x => x) -> [ '+', '-', '+' ]
You could probably find better regex, but you get the idea
You can ofc use a map or a switch for multiple operators
My task is to generate a random string with following parameters:
At least one Uppercase
At least one lower
At least one digit
No repeated chars/digits allowed ( e.g. aa not allowed, aba is allowed, Aa is allowed)
I'm able to generate a random string with 1,2,3 parameters but parameter 4 logic is missing.
inputChars = [('a'..'z'), ('A'..'Z'),(0..9)].map(&:to_a).flatten
string = (0...16).map { inputChars[rand(inputChars.length)] }.join
require 'set'
inputChars = [('a'..'z'), ('A'..'Z'),(0..9)].map(&:to_a).flatten
set_string = Set.new
loop do
break if set_string.size == 16
cr = inputChars[rand(inputChars.length)]
set_string << cr
end
output = set_string.to_a.join
i just change your map operation to loop operation and add Set data structure to store the character from random inputChars operation. Using Set will not allow same character
Let's begin by defining two constants.
CHARS_BY_TYPE = {
lower: ('a'..'z').to_a.freeze,
upper: ('A'..'Z').to_a.freeze,
digit: ('0'..'9').to_a.freeze
}.freeze
ALL = (CHARS_BY_TYPE[:lower] + CHARS_BY_TYPE[:upper] + CHARS_BY_TYPE[:digit]).freeze
#=> [["a", "b",..., "z", "A", "B",..., "Z", "0", "1",..., "9"]
I will initially build a string of a specified length by randomly selecting one character at a time from the array ALL, ensuring that no two consecutive characters are the same. There is no assurance, however, that the resulting string will contain at least one uppercase letter, one lowercase letter and one digit.
def append_random_char(last_char)
loop do
ch = ALL.sample
break ch unless ch == last_char
end
end
Our main method will begin as follows:
def random_string(str_len)
raise ArgumentError if str_len < 3
(str_len - 2).times.with_object('') { |_,s| s << append_random_char(s[-1]) }
# ...
end
For example:
s = random_string(40)
#=> "arN64kDw6ClzcNMj8WAkj1NJC2B5oFoRlcXl5S"
str_len is the required string length, 40 in the example. Observe that s contains 38 characters of which no two successive characters are equal. We will need to add 2 characters later. If the string contained no digits, for example, at least one of those two characters added (at a random location) will be a (randomly-selected) digit. If the string were shorter and contained, for example, digits only, the two characters added will be an uppercase letter and a lowercase letter.
Next we need to see if the string is lacking an uppercase letter, a lowercase letter and/or a digit. (It cannot be missing all three, as the string must contain at least three characters.)
require 'set'
def types_to_add(str)
[:lower, :upper, :digit].select do |type|
st = CHARS_BY_TYPE[type].to_set
str.each_char.none? { |ch| st.include?(ch) }
end
end
For the random string generated above we obtain:
types_to_add(s)
#=> []
meaning that the string contains at least one uppercase letter, one lowercase letter and one digit. Try this:
types_to_add(s.gsub(/\d|[A-Z]/, '')
#=> [:upper, :digit]
See Enumerable#none?. CHARS_BY_TYPE[type] is converted to a set merely to speed look-ups.
Suppose now we need to insert an uppercase letter, lowercase letter or digit to satisfy the requirement that there is at least one of each in the string. Specifically, we wish to insert a randomly-drawn character (from CHARS_BY_TYPE[:lower], CHARS_BY_TYPE[:upper] or CHARS_BY_TYPE[:digit]) at a random location in the string we are constructing, with the restriction that neither the preceding nor following character is the same character.
def insert_in_string(str, ch)
i = loop do
i = rand(str.size + 1)
next if ch == str[i]
break i if i.zero? || ch != str[i-1]
end
str.insert(i, ch)
end
For example, if we were to insert the character '0' into (a copy of) our string s (which is not needed):
insert_in_string(s.dup, '0')
#=> "arN64kDw6ClzcN0Mj8WAkj1NJC2B5oFoRlcXl5S"
s #=> "arN64kDw6ClzcNMj8WAkj1NJC2B5oFoRlcXl5S"
^
This inserts the character ch before the character in str at index i. If rand(str.size + 1) returns str.size ch is inserted after the last character of str.
Following this operation the final step is to use the method append_random_char to build the string out to the desired length.
The completed main method is as follows.
def random_string(str_len)
raise ArgumentError if str_len < 3
s = (str_len - 2).times.with_object('') { |_,s| s << append_random_char(s[-1]) }
types_to_add(s).each { |type| insert_in_string(s, CHARS_BY_TYPE[type].sample) }
(str_len - s.size).times { s << append_random_char(s[-1]) }
s
end
s = random_string(40)
#=> "PtQrVFZWUYFwiwRy3ySfAy42G1NT98J6cMVMaWeT"
s.match?(/[a-z]/)
#=> true
s.match?(/[A-Z]/)
#=> true
s.match?(/\d/)
#=> true
s.size
#=> 40
This is how I would do it (warning: Not tested. Just want to present the idea
for my algorithm). I first take a random number for the length of the resulting random string (the length will be between 4 and 16 characters). Then I determine
randomly, how many of them are upper case / lower case / digits, and based on
these decision, I generate the string, ensuring that I don't get any duplicates
in succession.
uchars=('A'..'Z').to_a
lchars=('a'..'z').to_a
dchars=('0'..'9').to_a
charmap = { u: uchars, l: lchars, d: dchars }
total_length=rand(13)+4 # Total length of string to be generated
total_u=rand(total_length-3)+1 # Total number of uchars to be generated
total_l=rand(total_length-total_u-2)+1 # Total number of lchars
total_d=total_length-total_u-total_l # Total number of digits
# Array of types to generate
chartypes=([:u]*total_u + [:l]*total_l + [:d]*total_d).shuffle
# chartypes is an array similar to [:u,:d,:d,:l,:u], where the
# symbols designate the kind of character to be generated.
# outstr : random string to be generated
outstr = charmap[chartypes.first].sample
last_char = outstr.dup
total_length.times do |index|
loop do
nextchar = charmap[chartypes[index]].sample
if nextchar != last_char
outstr << nextchar
last_char = nextchar
break
end
end
end
Given this string:
one#two*three#four#five*
What is a fast solution to extract the list of Pairs?
Each pair contains the word with its separator character like this:
[
['one', '#'],
['two', '*'],
['three', '#'],
['four', '#'],
['five', '*']
]
Specifically in my case I want to use both white space and new line characters as separators.
You'd need a regular expression:
(\w+)([#|*])
See example Dart code here that should get you going: https://dartpad.dartlang.org/ae3897b2221a94b5a4c9e6929bebcfce
Full disclosure: dart is a relatively new language to me.
That said, regex might be your best bet. Assuming you are only working with lowercase a-z letters followed by a single character, this should do the trick.
RegExp r = RegExp("([a-z]+)(.)");
var matches = r.allMatches("one#two*three#four#five*");
List<dynamic> l = [];
matches.toList().asMap().forEach((i, m) => l.add([m.group(1), m.group(2)]));
print(l);
Based on other responses here's my solution for white spaces and new lines as separators:
void main() {
RegExp r = RegExp(r"(\S+)([\s]+|$)");
var text = 'one two three \n\n four ';
var matches = r.allMatches(text);
List<dynamic> l = [];
matches.toList().asMap().forEach((i, m) => l.add([m.group(1), m.group(2)]));
print(l);
}
Output
[[one, ], [two, ], [three,
], [four, ]]
Explanation: https://regex101.com/r/cRpMVq/2
I finally got around to learning the basics of lex and bison. The problem I had was that I was calculating how much money I was going to give to my co-worker for picking up a burrito, and didn't like doing it manually.
For example, a $7.75 burrito + 20% tip can be figured out using 7.75*(1 + 20/100.0). However, I'd rather have the computer just take $7.75 + 20% and do it for me.
So I made this: https://github.com/tlehman/tipcalc
The lexing rules are
%%
\$ return TOKDOLLAR;
\% return TOKPERCENT;
[0-9]+(\.[0-9]+)* yylval=atof(yytext); return NUMBER;
[ \t]+ /* eat whitespace */
[\+\-] return TOKOP;
%%
And the parsing rules are
%%
start:
dollars TOKOP percentage
{
double dollars = $1;
double percentage = ($3)/(100.0);
double total = dollars + dollars*percentage;
printf("debug: dollars = %f\n", dollars);
printf("debug: percent = %f\n", percentage);
printf("%.2f", total);
}
dollars:
TOKDOLLAR NUMBER
{
$$ = (double)$2;
}
percentage:
NUMBER TOKPERCENT
{
$$ = (double)$1;
}
%%
The only problem is that dollars is getting handled incorrectly, when I run
$ echo '$7.75 + 20%' | ./tipcalc
I get this output:
debug: dollars = 7.000000
debug: percent = 0.200000
8.40
The dollars value is getting rounded somewhere. I think the rounding is happening after lexing since percentage seems to work with all the values I threw at it. I can't figure out where it is happening, have any ideas?
By default, the values passed around by the Bison-generated parser (yylval and the dollar things) are integers. So unless you explicitly tell Bison they are doubles, they will be integers. This includes yylval, so the truncation happens already here: yylval=atof(yytext);
How can I convert a string like s = "6.1101,17.592,3.3245\n" to numbers in Lua.
In python, I usually do
a = s.strip().split(',')
a = [float(i) for i in a]
What is the proper way to do this with Lua?
This is fairly trivial; just do a repeated match:
for match in s:gmatch("([%d%.%+%-]+),?") do
output[#output + 1] = tonumber(match)
end
This of course assumes that there are no spaces in the numbers.