Is there an R function equivalent to wrapping assignment with `()`? - printing

I just discovered that running (y <- 1:4) prints the result in the console, but ...
(y <- 1:4)
# [1] 1 2 3 4
library(dplyr) # for the pipe operator %>%
y <- 1:4 %>% funct_parenthesis() # DOES IT EXIST ?
# [1] 1 2 3 4

print works
library(dplyr) # for the pipe operator %>%
y <- 1:4 %>% print
# [1] 1 2 3 4

Related

Formula for calculating user experience

I would like (without using a gem) to create a level and experience point system for my users.
When creating his account, he starts level 0 with 0 experience points. To reach level 1 he will need 10 additional points, for a total of 10 points. For level 3 he will need 30 additional points, for a total of 60 experience points. Each additional level requires 10 more experience points. (see example below).
Level | Total XP | XP for next level|
----------------------------------------|
0 | 0 | 10 |
1 | 10 | 20 |
2 | 30 | 30 |
3 | 60 | 40 |
4 | 100 | 50 |
5 | 150 | 60 |
etc...
I would like an xp column in my user table that would represent the total experience of a user.
In my view I would like to display its level. But what is the formula for calculating this?
Let's imagine that my user has 157 experience points in total. Which corresponds to a level 5. How to calculate a level only via the total experience points and how to calculate this regardless of its total experience point whether it is 38 like 369 or 4393.
I'm not sure if this is exactly what you wanted. It's more of an algorithm than a formula, but here is a method that will return the proper level based on the experience given. Think of the bar variable like the bar you have to get over to meet a new level, and think of the step variable like the amount of experience added between each level (as you describe in your right-most column).
def calculate_level(experience)
level = 0
bar = 10
step = 10
while experience >= bar
level += 1
step += 10
bar += step
end
level
end
Example output:
irb> calculate_level(0) # => 0
irb> calculate_level(9) # => 0
irb> calculate_level(10) # => 1
irb> calculate_level(11) # => 1
irb> calculate_level(29) # => 1
irb> calculate_level(30) # => 2
irb> calculate_level(31) # => 2
irb> calculate_level(59) # => 2
irb> calculate_level(60) # => 3
irb> calculate_level(61) # => 3
irb> calculate_level(99) # => 3
irb> calculate_level(100) # => 4
irb> calculate_level(101) # => 4
irb> calculate_level(149) # => 4
irb> calculate_level(150) # => 5
irb> calculate_level(151) # => 5
Calculate the inverse of my above comment and take the floor:
def calculate_level experience
(Math.sqrt(0.2 * experience + 0.25) - 0.5).floor
end
You can use such "formula"
def calculate_level(experience)
(1..).find { |i| (experience -= 10 * i).negative? } - 1
end
Just decrease experience on 10x steps every time and check if result is not negative
calculate_level(0)
# => 0
calculate_level(9)
# => 0
calculate_level(10)
# => 1
calculate_level(11)
# => 1
calculate_level(29)
# => 1
calculate_level(30)
# => 2
calculate_level(31)
# => 2
calculate_level(59)
# => 2
calculate_level(60)
# => 3
calculate_level(61)
# => 3
calculate_level(99)
# => 3
calculate_level(100)
# => 4
calculate_level(101)
# => 4
calculate_level(149)
# => 4
calculate_level(150)
# => 5
calculate_level(151)
# => 5
calculate_level(209)
# => 5
calculate_level(210)
# => 6

Is it possible to render/generate pdf in rails without using a gem?

There are some gems which can generate pdf. But I don't want to use a gem. I tried the following:
def show
respond_to do |format|
format.html
format.pdf
end
end
And for the link:
link_to show_path(#show, format: :pdf)
I can get the pdf output but it says the pdf document might not be displayed properly.
Rails does not generate pdf out-of-the box. PDF is a 7-bit text format with binary parts, so technically you can generate it manually using ERB-templates, show.pdf.erb:
%PDF-1.1
%¥±ë
1 0 obj << /Type /Catalog /Pages 2 0 R >>
endobj
2 0 obj << /Type /Pages /Kids [3 0 R] /Count 1 /MediaBox [0 0 300 300] >>
endobj
3 0 obj << /Type /Page /Parent 2 0 R
/Resources
<< /Font
<< /F1
<< /Type /Font /Subtype /Type1 /BaseFont /Times-Roman >>
>>
>>
/Contents 4 0 R
>>
endobj
4 0 obj << /Length 90 >>
stream
BT
/F1 18 Tf
90 150 Td
(Hello World!) Tj
ET
endstream
endobj
trailer << /Root 1 0 R /Size 4 >>
%%EOF
This minimal PDF is viewable by some apps, but has errors in it, because there's no xref section and object bytecounts will be wrong. Also once you need anything more complex than single page with couple text labels on it - it will become hard to maintain.
Better way of generation is actually using a gem like prawn or wicked_pdf

How to quickly join two strings in Ruby

It's common to need to join strings, and in Ruby we have common ways of doing it: appending, concatenating and interpolating one into the other, or using the built-in concat method in String. (We have multiple ways of doing it for flexibility and to ease the transition from other languages to Ruby.)
Starting with:
'a ' << 'z' # => "a z"
'a '.concat('z') # => "a z"
'a ' + 'z' # => "a z"
"a #{'z'}" # => "a z"
Assuming we don't want to change either string and that the strings won't be assigned to variables, what is the fastest way to join them, and does the fastest way change as the size of the "left" string grows?
For those who can't figure out why we'd post questions like this, it's to help educate and show the most efficient way to do a particular task. Newcomers to a language, Ruby in this case, often drag old ways of doing something with them, and inadvertently write code that runs more slowly than necessary. A simple change to their coding style can result in faster code.
Starting with short strings:
z = 'z'
'a ' << z # => "a z"
'a '.concat(z) # => "a z"
'a ' + z # => "a z"
"a #{z}" # => "a z"
require 'fruity'
compare do
append { 'a ' << z}
concat { 'a '.concat(z)}
plus { 'a ' + z}
interpolate { "a #{z}" }
end
# >> Running each test 65536 times. Test will take about 2 seconds.
# >> interpolate is similar to append
# >> append is similar to plus
# >> plus is faster than concat by 2x ± 0.1
Increasing the "left" string to 11 characters:
require 'fruity'
compare do
append { 'abcdefghij ' << z}
concat { 'abcdefghij '.concat(z)}
plus { 'abcdefghij ' + z}
interpolate { "abcdefghij #{z}" }
end
# >> Running each test 65536 times. Test will take about 2 seconds.
# >> interpolate is similar to append
# >> append is similar to plus
# >> plus is faster than concat by 2x ± 1.0
51 characters:
compare do
append { 'abcdefghijabcdefghijabcdefghijabcdefghijabcdefghij ' << z}
concat { 'abcdefghijabcdefghijabcdefghijabcdefghijabcdefghij '.concat(z)}
plus { 'abcdefghijabcdefghijabcdefghijabcdefghijabcdefghij ' + z}
interpolate { "abcdefghijabcdefghijabcdefghijabcdefghijabcdefghij #{z}" }
end
# >> Running each test 32768 times. Test will take about 2 seconds.
# >> plus is faster than append by 2x ± 1.0
# >> append is similar to interpolate
# >> interpolate is similar to concat
101:
compare do
append { 'abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij ' << z}
concat { 'abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij '.concat(z)}
plus { 'abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij ' + z}
interpolate { "abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij #{z}" }
end
# >> Running each test 32768 times. Test will take about 2 seconds.
# >> plus is faster than interpolate by 2x ± 0.1
# >> interpolate is similar to append
# >> append is similar to concat
501:
compare do
append { 'abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij ' << z}
concat { 'abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij '.concat(z)}
plus { 'abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij ' + z}
interpolate { "abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij #{z}" }
end
# >> Running each test 16384 times. Test will take about 1 second.
# >> plus is faster than append by 2x ± 0.1
# >> append is similar to interpolate
# >> interpolate is similar to concat
Once the strings got past 50 characters + consistently outperformed the others.
In the comments there are mention of some of these mutating the string on the left. Here's what would happen if it was a variable on the left, not a literal string:
a = 'a'
z = 'z'
a << z # => "az"
a # => "az"
a = 'a'
a.concat(z) # => "az"
a # => "az"
compared to:
a + z # => "az"
a # => "a"
"#{a} #{z}" # => "a z"
a # => "a"
Note: The initial version of answer had a bad test using:
"a #{'z'}"
The problem with that is Ruby is smart enough to recognize that 'z' is another literal and converts the string into:
"a z"
with the end result that the test would be unfairly faster than the others.
It's been a while and Ruby's smarter and faster. I added a couple additional tests:
puts "Running Ruby v%s" % RUBY_VERSION
require 'fruity'
z_ = 'z'
compare do
append { 'abcdefghij ' << 'z' }
concat { 'abcdefghij '.concat('z') }
plus { 'abcdefghij ' + 'z' }
interpolate1 { "abcdefghij #{'z'}" }
interpolate2 { "abcdefghij #{z_}" }
adjacent { 'abcdefghij' ' z' }
end
# >> Running Ruby v2.7.0
# >> Running each test 65536 times. Test will take about 3 seconds.
# >> adjacent is similar to interpolate1
# >> interpolate1 is faster than interpolate2 by 2x ± 1.0
# >> interpolate2 is similar to append
# >> append is similar to concat
# >> concat is similar to plus
interpolate1 and adjacent are basically the same as far as the interpreter is concerned and will be concatenated prior to running. interpolate2 forces Ruby to do it at run-time so it's a little slower.

How to Calculate sum of all the digits in text file

I am having text file t.txt,I want to calculate sum of all the digits in text file
Example
--- t.txt ---
The rahul jumped in 2 the well. The water was cold at 1 degree Centigrade. There were 3 grip holes on the walls. The well was 17 feet deep.
--- EOF --
sum 2+1+3+1+7
My ruby code to calculate sum is
ruby -e "File.read('t.txt').split.inject(0){|mem, obj| mem += obj.to_f}"
But i am not getting any answer??
str = "The rahul jumped in 2 the well. The water was cold at 1 degree Centigrade. There were 3 grip holes on the walls. The well was 17 feet deep."
To get sum of all integers:
str.scan(/\d+/).sum(&:to_i)
# => 23
Or to get sum of all digits as in your example:
str.scan(/\d+?/).sum(&:to_i)
# => 14
PS: I used sum seeing Rails tag. If you are only using Ruby you can use inject instead.
Example with inject
str.scan(/\d/).inject(0) { |sum, a| sum + a.to_i }
# => 14
str.scan(/\d+/).inject(0) { |sum, a| sum + a.to_i }
# => 23
Your statement is computing correctly. Just add puts before File read as:
ruby -e "puts File.read('t.txt').split.inject(0){|mem, obj| mem += obj.to_f}"
# => 23.0
For summing single digit only:
ruby -e "puts File.read('t.txt').scan(/\d/).inject(0){|mem, obj| mem += obj.to_f}"
# => 14.0
Thanks

"grep -B 1" one line per result

Hi all hopefully the below makes sense.
I have a file it contains a lot of junk as well as some data I wish to keep, the data I wish to extract is any line containing "=>" plus the previous line, my issue is however I really need to output (the line containing => and the previous line) to be contained on the same line
Example:
junk
input <= lala
thing1 => lululu
more junk
more junks
even more junks
input <= junk
extra junk
hello123 => lelele
input <= lololo
thing3 => kt
What I have currently using is using "grep -B 1 '=>' file1" is:
input <= lala
thing1 => lululu
--
extra junk
hello123 => lelele
--
input <= lololo
thing3 => kt
What I really want would be or something similar.
input <= lala thing1 => lululu
--
extra junk hello123 => lelele
--
input <= lololo thing3 => kt
Assuming you're using bash, you can do it in a one-liner:
t="";for i in $(grep -B 1 '=>' tmp.txt) ; do if [[ "$i" != "--" ]] ;then t="$t $i"; else echo "$t";echo "--";t="";fi;done;echo "$t"
OUTPUT:
alfasi$ t="";for i in $(grep -B 1 '=>' tmp.txt) ; do if [[ "$i" != "--" ]] ;then t="$t $i"; else echo "$t";echo "--";t="";fi;done;echo "$t"
input <= lala thing1 => lululu
--
extra junk hello123 => lelele
--
input <= lololo thing3 => kt
lgml-alfasi2:bin alfasi$
The process of reading the input is not too difficult using a here string and then a toggle within a while loop. There are a number of different ways to do this. This just came to mind first.
#!/bin/bash
# read input filename as first argument
ifn="$1"
# validate file is readable
[ -r "$ifn" ] || {
printf "error: file not readable '%s'.\n" "$ifn"
exit 1
}
declare -i a=0 # use 'a' as first/second line toggle
## for each line in results
while read -r line; do
[ ${line:0:1} == '-' ] && { a=0; continue; } # skip -- lines
[ $a -eq 0 ] && sav="$line" # if a=0, save line
if [ $a -eq 1 ]; then # if a=1, form output
myline="${sav} ${line}"
# printf -- "--\n" # uncomment for separator
printf "%s\n" "$myline"
fi
[ $a -eq 0 ] && a=1 || a=0 # toggle a=0/1
done <<< "$(grep -B 1 '=>' "$ifn")"
exit 0
input
$ cat dat/twotoone.dat
junk
input <= lala
thing1 => lululu
more junk
more junks
even more junks
input <= junk
extra junk
hello123 => lelele
input <= lololo
thing3 => kt
output
$ bash twointoone.sh dat/twotoone.dat
input <= lala thing1 => lululu
extra junk hello123 => lelele
input <= lololo thing3 => kt
note: if you want the separators between the lines, then add the following before you print $myline:
printf -- "--\n"
output with separator
$ bash twointoone.sh dat/twotoone.dat
--
input <= lala thing1 => lululu
--
extra junk hello123 => lelele
--
input <= lololo thing3 => kt
This is simple to do with awk
awk '/=>/ {print a,$0"\n--"} {a=$0}' file
input <= lala thing1 => lululu
--
extra junk hello123 => lelele
--
input <= lololo thing3 => kt
--
If you do not like the last -- to be printed:
awk '/=>/ {print (f++?"--\n":"")a,$0} {a=$0}' file
input <= lala thing1 => lululu
--
extra junk hello123 => lelele
--
input <= lololo thing3 => kt

Resources