Is there any way to simplify this method that takes the first letter from first, middle, and last names and joins them together? - python-3.7

def to_initials(name):
initials = [x[0] for x in name.split()]
return ''.join(initials)
print(to_initials("Kelvin Bridges")) # => "KB"
print(to_initials("Michaela Yamamoto")) # => "MY"
print(to_initials("Mary La Grange")) # => "MLG"
I'm trying to create a method that takes the first letter from each name and prints the initials. Is there a simpler way to write this?

I don't think you can do more than leave out the intermediate variable and using a generator expression instead of the list comprehension (i.e. leaving out the square brackets). Other than that, it seems like a perfectly fine simple function!
def to_initials(name):
return ''.join(x[0] for x in name.split())

Related

Scala, user input till only newline is given

I have tried to get multiple user inputs to print them in Scala IDE.
I have tried the this piece of code
println(scala.io.StdIn.readLine())
which works, as the IDE takes my input and then print it in the line but this works only for a single input.
I want the code to take multiple inputs till only newline is entered. example,
1
2
3
so i decided we needed an iterator for the input, which led me to try the following 2 lines of code seperately
var in = Iterator.continually{ scala.io.StdIn.readLine() }.takeWhile { x => x != null}
and
var in = io.Source.stdin.getLines().takeWhile { x => x != null}
Unfortunately none of them worked as the IDE is not taking my input at all.
You're really close.
val in = Iterator.continually(io.StdIn.readLine).takeWhile(_.nonEmpty).toList
This will read input until an empty string is entered and saves the input in a List[String]. The reason for toList is because an Iterator element doesn't become real until next is called on it, so readLine won't be called until the next element is required. The transition to List creates all the elements of the Iterator.
update
As #vossad01 has pointed out, this can be made safer for unexpected input.
val in = Iterator.continually(io.StdIn.readLine)
.takeWhile(Option(_).fold(false)(_.nonEmpty))
.toList

Ruby Optional Parameters method calling with one or two

The method should return words multiple times. The method should take 2 paramters word and n = number times word should be printed. But I want the second parameter to be optional. I can call the method with single parameter and it should return the same word. If second parameter used then it should return the same word that many times.
def repeat(word,n)
n.times {word}
end
p repeat("abc", 2) <- this works
but what if I only want
p repeat("abc")
Old question, but I had a similar problem today and solved it like this:
def repeat(word, n=1)
n.times {word}
end
If you call it like this:
p repeat("abc") it will only repeat it once, but you can pass in a value for n it will repeat however many times you want. If you want it to print out the actual word, this slight modification to the OP's method will do that.
def repeat(word, n=1)
n.times {puts word}
end
and call it with repeat("abc") or repeat("abc", 2)

Error in recursive list logic

I am trying to build a list in scala that given input (length,and a function) the output would be a list from 0 up to that length-1.
for example:
listMaker(3,f) = List(0,1,2)
so far I have created a helper class that takes 2 int and returns a list in that range.
the listMaker function is as follows:
def listMaker[A](length:Int, f:Int =>A):List[A] = length match{
case 0 => List()
case _ => listMaker(length,f)
}
my f function just takes a variable x and returns that:
def f(x:Int)=x
the comment below makes sense, but it still gets me errors. I think the edited code is an easier way to get where I would like to
However, now I get an infinite loop. What part of the logic am I missing?
A recursive function typically has to gradually "bite off" pieces of the input data until there is nothing left - otherwise it can never terminate.
What this means in your particular case is that length must decrease on each recursive call until it reaches zero.
def listMaker[A](length:Int, f:Int =>A):List[A] = length match{
case 0 => List()
case _ => listMaker(length,f)
}
But you are not reducing length - you are passing it unchanged to the next recursive call, so, your function cannot terminate.
(There are other problems too - you need to build up your result list as you recurse, but your current code simply returns an empty list. I assume this is a learning exercise, so I'm not supplying working code...).

Perl - Pattern contains new line

I am trying to grab all functions from a C file in a perl script.
Pattern example :
function return type
function name (function parameters)
{
So far I have: m/^(.*)\((.*)\)/
But this grabs functions inside as well, such as if statements, so I was hoping to match for the { as well since that would eliminate all internal functions but m/^(.*)\((.*)\)/\n\{/
doesn't work.
How do I match for the \n{ i.e the { in the next line, so that I can catch
add(int a, int b)
{
... but avoid, say
if(a = b)
Have a look at C::Scan over at CPAN
There are no asterisks you want to match in the C source. Therefore, remove the backslashes before asterisks in the pattern.
The following might be closer to what you want:
m/^(.*?\(.*?\))\s*\n{/m

Best way to create generic/method consistency for sort.data.frame?

I've finally decided to put the sort.data.frame method that's floating around the internet into an R package. It just gets requested too much to be left to an ad hoc method of distribution.
However, it's written with arguments that make it incompatible with the generic sort function:
sort(x,decreasing,...)
sort.data.frame(form,dat)
If I change sort.data.frame to take decreasing as an argument as in sort.data.frame(form,decreasing,dat) and discard decreasing, then it loses its simplicity because you'll always have to specify dat= and can't really use positional arguments. If I add it to the end as in sort.data.frame(form,dat,decreasing), then the order doesn't match with the generic function. If I hope that decreasing gets caught up in the dots `sort.data.frame(form,dat,...), then when using position-based matching I believe the generic function will assign the second position to decreasing and it will get discarded. What's the best way to harmonize these two functions?
The full function is:
# Sort a data frame
sort.data.frame <- function(form,dat){
# Author: Kevin Wright
# http://tolstoy.newcastle.edu.au/R/help/04/09/4300.html
# Some ideas from Andy Liaw
# http://tolstoy.newcastle.edu.au/R/help/04/07/1076.html
# Use + for ascending, - for decending.
# Sorting is left to right in the formula
# Useage is either of the following:
# sort.data.frame(~Block-Variety,Oats)
# sort.data.frame(Oats,~-Variety+Block)
# If dat is the formula, then switch form and dat
if(inherits(dat,"formula")){
f=dat
dat=form
form=f
}
if(form[[1]] != "~") {
stop("Formula must be one-sided.")
}
# Make the formula into character and remove spaces
formc <- as.character(form[2])
formc <- gsub(" ","",formc)
# If the first character is not + or -, add +
if(!is.element(substring(formc,1,1),c("+","-"))) {
formc <- paste("+",formc,sep="")
}
# Extract the variables from the formula
vars <- unlist(strsplit(formc, "[\\+\\-]"))
vars <- vars[vars!=""] # Remove spurious "" terms
# Build a list of arguments to pass to "order" function
calllist <- list()
pos=1 # Position of + or -
for(i in 1:length(vars)){
varsign <- substring(formc,pos,pos)
pos <- pos+1+nchar(vars[i])
if(is.factor(dat[,vars[i]])){
if(varsign=="-")
calllist[[i]] <- -rank(dat[,vars[i]])
else
calllist[[i]] <- rank(dat[,vars[i]])
}
else {
if(varsign=="-")
calllist[[i]] <- -dat[,vars[i]]
else
calllist[[i]] <- dat[,vars[i]]
}
}
dat[do.call("order",calllist),]
}
Example:
library(datasets)
sort.data.frame(~len+dose,ToothGrowth)
Use the arrange function in plyr. It allows you to individually pick which variables should be in ascending and descending order:
arrange(ToothGrowth, len, dose)
arrange(ToothGrowth, desc(len), dose)
arrange(ToothGrowth, len, desc(dose))
arrange(ToothGrowth, desc(len), desc(dose))
It also has an elegant implementation:
arrange <- function (df, ...) {
ord <- eval(substitute(order(...)), df, parent.frame())
unrowname(df[ord, ])
}
And desc is just an ordinary function:
desc <- function (x) -xtfrm(x)
Reading the help for xtfrm is highly recommended if you're writing this sort of function.
There are a few problems there. sort.data.frame needs to have the same arguments as the generic, so at a minimum it needs to be
sort.data.frame(x, decreasing = FALSE, ...) {
....
}
To have dispatch work, the first argument needs to be the object dispatched on. So I would start with:
sort.data.frame(x, decreasing = FALSE, formula = ~ ., ...) {
....
}
where x is your dat, formula is your form, and we provide a default for formula to include everything. (I haven't studied your code in detail to see exactly what form represents.)
Of course, you don't need to specify decreasing in the call, so:
sort(ToothGrowth, formula = ~ len + dose)
would be how to call the function using the above specifications.
Otherwise, if you don't want sort.data.frame to be an S3 generic, call it something else and then you are free to have whatever arguments you want.
I agree with #Gavin that x must come first. I'd put the decreasing parameter after the formula though - since it probably isn't used that much, and hardly ever as a positional argument.
The formula argument would be used much more and therefore should be the second argument. I also strongly agree with #Gavin that it should be called formula, and not form.
sort.data.frame(x, formula = ~ ., decreasing = FALSE, ...) {
...
}
You might want to extend the decreasing argument to allow a logical vector where each TRUE/FALSE value corresponds to one column in the formula:
d <- data.frame(A=1:10, B=10:1)
sort(d, ~ A+B, decreasing=c(A=TRUE, B=FALSE)) # sort by decreasing A, increasing B