How to print comma-separated list with hamlet? - templates

With the hamlet templating language that comes with yesod, what is the best way of printing a comma-separated list?
E.g. assume this code which just prints one entry after another, how do I insert commas in between the elements? Or maybe even add an “and” before the last entry:
The values in the list are
$ forall entry <- list
#{entry}
and that is it.
Some templating languages such as Template Toolkit provide directives to detect the first or last iteration.

I don't think there's anything built-in like that. Fortunately, it's easy to use helper functions in Hamlet. For example, if your items are plain strings, you can just use Data.List.intercalate to add commas between them.
The values in the list are
#{intercalate ", " list}
and that is it.
If you want to do fancier things, you can write functions to work with Hamlet values. For example, here's a function which adds commas and "and" between the Hamlet values in a list.
commaify [x] = x
commaify [x, y] = [hamlet|^{x} and ^{y}|]
commaify (x:xs) = [hamlet|^{x}, ^{commaify xs}|]
This uses ^{...} syntax to insert one Hamlet value into another. Now, we can use this to write a comma-separated list of underlined words.
The values in the list are
^{commaify (map underline list)}
and that is it.
Here, underline is just a small helper function to produce something more interesting than plain text.
underline word = [hamlet|<u>#{word}|]
When rendered, this gives the following result.
The values in the list are <u>foo</u>, <u>bar</u> and <u>baz</u> and that is it.

Related

'list' object has no attribute 'replace' while trying to input "and" in a list

Write a program that prints a list with all the items separated by a comma and a space, with 'and' inserted before the last item. The above list would print 'apples, bananas, tofu, and cats'. But the program should be able to work with any list not just the one shown above. Because of this, I'll need to use a loop in case the list to print is shorter or longer than the above list. The program should work for all user inputs without "and" or commas if the list only contains one item.

Prolog find element in list of lists with preference

I have list of lists like:
L = [[Q,w,E,],[Q,w,Z,r],[A,s,D,f]]
I know the first two and I need to get the rest.
For example I have Q,w and I need to get Z,r or E,r.
I would like to somehow tell that with priority I always want that touple contain Z, but if doesnt exist give me E,r.
I tried:
member([Q,w,Z,VB],[[Q,w,E,o],[Q,w,Z,r],[A,s,D,f]]).
But that always give me Z = E, VB = o
First you need to know the difference in Prolog between an Atom and a Variable, you can read about their syntax here
Now, if you want a list of atoms that begin with an upper-case letter, you must enclose them in single quotes, otherwise prolog will interpret them as variables.
Now if you fix the syntax of your consult, you will get the following result:
?- member(['Q',w,Z,VB],[['Q',w,'E',o],['Q',w,'Z',r],['A',s,'D',f]]).
VB = o,
Z = 'E'
VB = r,
Z = 'Z'
false
Note how in this case I enclosed in single quote all atoms beginning with an upper-case letter, except for Z and VB in the first argument of the member/2 predicate, cause in this case they function as variables to be instanciated by prolog with the atoms needed to complete this case.

Subsetting a string based on pre- and suffix

I have a column with these type of names:
sp_O00168_PLM_HUMAM
sp_Q8N1D5_CA158_HUMAN
sp_Q15818_NPTX1_HUMAN
tr_Q6FGH5_Q6FGH5_HUMAN
sp_Q9UJ99_CAD22_HUMAN
I want to remove everything before, and including, the second _ and everything after, and including, the third _.
I do not which to remove based on number of characters, since this is not a fixed number.
The output should be:
PLM
CA158
NPTX1
Q6FGH5
CAD22
I have played around with these, but don't quite get it right..
library(stringer)
str_sub(x,-6,-1)
That’s not really a subset in programming terminology1, it’s a substring. In order to extract partial strings, you’d usually use regular expressions (pretty much regardless of language); in R, this is accessible via sub and other related functions:
pattern = '^.*_.*_([^_]*)_.*$'
result = sub(pattern, '\\1', strings)
1 Aside: taking a subset is, as the name says, a set operation, and sets are defined by having no duplicate elements and there’s no particular order to the elements. A string by contrast is a sequence which is a very different concept.
Another possible regular expression is this:
sub("^(?:.+_){2}(.+?)_.+", "\\1", vec)
# [1] "PLM" "CA158" "NPTX1" "Q6FGH5" "CAD22"
where vec is your vector of strings.
A visual explanation:
> gsub(".*_.*_(.*)_.*", "\\1", "sp_O00168_PLM_HUMAM")
[1] "PLM"

Can someone please explain to me how the pipe "|" character works in Prolog?

I have this code:
[a,b,[]]=[First,Second,Third|Fourth].
and it gives me the following output:
First = a, Second = b, Third = Fourth, Fourth = [].
I'd like to know how Third got assigned to Fourth.
The pipe character is very similar to the "consing dot" in Lisp. The variable after the pipe takes the entire remainder of the corresponding list.
So, here we expect Third to bind to the explicitly given empty list in the data. But there is nothing after that and so Fourth also binds empty.
Third being bound to Fourth is just an indirect way of Third being bound to empty.
See my answer here: https://stackoverflow.com/a/7559044/467473 for details on how Prolog lists are implemented.
Basically, a prolog list is a simple data structure. The empty list is denoted by the atom []. A non-empty list is the structure ./2. The left argument in this structure is the head of the list; the right argument is the tail of the list, which is another list (either the empty list [] or a non-empty list (./2).
The friendly list notation is just syntactic sugar on top of this. The expression [H|T] is exactly the same as the expression .(H,T). The expression [a,b|T] is exactly the same as .(a,.(b,T)). And the expression [a,b,c] is exactly the same as .(a,.(b,.(c,[]))).

Get regular expression matched positon?

Here is a string :
str1="ha,hihi,aaaaa,ok"
I want to get the position of "," in the str1,Which can count 3,8,14.
how can I get it in R ?
You get the desired vector using this expression:
as.integer(gregexpr(",", str1)[[1]])
The [[1]] will choose the first element of the resulting list. If str1 were a vector of a length other than 1, then gregexpr would result a list with that many items, one for each element of str1.
The as.integer will strip additional attributes, like the length of the matched text. In many situations you will be able to omit this, as other code will likely simply ignore those attributes. For output to the console it might be less confusing, though, so I included it in my answer.