I am doing something like this
read_line_to_codes(user_input,Li1),nl,
write(Li1),nl,
atom_codes(A,Li1),
write(A),nl
So I am getting this output-
|: 'hello',18,19,'Bye'
[39,104,101,108,108,111,39,44,49,56,44,49,57,44,39,66,121,101,39]
'hello',18,19,'Bye'
But I want a list having this-L=['hello',18,19,'Bye']
How can I do this?
In SWI-Prologyou can use atomic_list_concat/3 with the first argument (a list) uninstantiated, the second argument the separatorn (',' in your case) and the third argument the atom you already have (A). Note that this use of atomic_list_concat/3 is not portable
E.g.:
atomic_list_concat(L, ',', A)
Related
I am working on a Automator service and in my situation I have stdin as
B-Funny Flash Nonfiction 202105131635 and I want to get to B-Funny Flash Nonfiction 202105131636 incriminating the "5" by 1 to "6".
I'd think I'd first want to separate the text from the number before doing the add 1 then rejoin them?
Would egrep or sed or awk be best?
Tips?
Bash has simple integer arithmetic built in.
str='B-Funny Flash Nonfiction 202105131635'
# parse into prefix and number
num=${str##*[!0-9]}
prefix=${str%$num}
echo "$prefix$((num+1))"
The parameter expansion ${var#pat} produces the value of the variable var with any prefix matching pat removed; % does the same for suffixes, and doubling the operator changes to matching the longest possible pattern match instead of the shortest. The pattern *[!0-9] matches a string which ends on a character which isn't a number; in this context, it retrieves the prefix, i.e. everything up to just before the first digit. (If your prefix could contain numbers, too, this needs tweaking. Probably switch to removing all digits from the end, then extracting the removed numbers; but I guess this will require an unattractive temporary variable.)
Finally, the secret sauce which evaluates an arithmetic expression is the $((...)) arithmetic context.
For more involved number crunching, try bc or Awk. In fact, this could be a one-liner in Awk:
awk '{ $NF +=1 }1' <<<"$str"
The here string passes the value as standard input to Awk, which increments the last field $NF. The final 1 is a common Awk shorthand for "print all input lines to output".
I don't know the bash tools well enough to give a cool one-line answer, so here is a python script instead.
Usage
Save the code in a file increment.py;
Make the file executable with chmod +x increment.py;
Run the script with ./increment.py blablabla 123.
Code
#!/usr/bin/env python3
import sys
def print_help(argv0):
print('increment numbers by 1')
print('example usage:')
print(' {} B-Funny Flash Nonfiction 202105131635'.format(argv0))
print(' B-Funny Flash Nonfiction 202105131636')
def main(argv):
if len(argv) < 2:
print_help(argv[0])
else:
for s in argv[1:]:
if s.isnumeric():
print(int(s) + 1, end=' ')
else:
print(s, end=' ')
print()
if __name__=='__main__':
main(sys.argv)
Explanation
In a python program called from the command-line, the command-line arguments are stored in the array sys.argv.
The first element of the array, with index 0, is the name that was used to call the program, most likely "./increment.py" in our case.
The remaining elements are the parameters that were passed to the program; the words "B-Funny", "Flash", "Nonfiction", "202105131635" in our case.
The for-loop for s in argv[1:]: iterates on the elements of argv, but starting with the element 1 (thus ignoring the element 0). Each of these elements is a string; the method .isnumeric is used to check whether this string represents a number or not. Refer to the documentation on .isnumeric.
If the string is not numeric, we print is as-is. If the string is numeric, we compute the number it represents by calling int(s), then we add 1, and we print the result.
Apart from that, the line if len(argv): checks whether argv contains at least two elements; if it doesn't, that means it only contains its element 0, which is "./increment.py"; in this case, instead of printing the arguments, the script calls the function print_help which explains how to use the program.
Finally, the bit about if __name__ == '__main__': is a python idiom to check whether the file increment.py was run as a program or as a module imported by another file. Refer to this question.
I have been banging around on google and drRacket trying to understand what the apostrophe ' before a procedure means in racket and how I could remove it. What I'm trying to do is take a + from inside a list i.e. '(+ 1 2). However, every time I do something like (first x) (where x is the list in the example) I receive '+ instead of just + (notice the apostrophe). How can I remove the apostrophe and what is its purpose?
The ' apostrophe, pronounced quote, mean that the stuff inside will be interpreted as data for an s-expression, not evaluated as code.
'x, 'hello, and '+ are all symbols, which are like strings with unique-identity properties. They contain only text, not "meaning", so the '+ symbol does not contain a reference to the + function.
If you use parentheses under a ' quote, it will create a list with all the elements also ' quoted. In other words, '(x y z) is equivalent to (list 'x 'y 'z). You can think of this as quote "distributing itself" over all the elements inside it.
In your case, '(+ 1 2) is equivalent to (list '+ '1 '2), which is the same as (list '+ 1 2) because numbers are already literal data.
In most cases, the best way to get rid of a ' quote is to not add one on the outside in the first place. Instead of '(+ 1 2) you could use list: (list + 1 2), or the more advanced forms ` quasiquote and , unquote: `(,+ 1 2). In either of these cases, the + never gets put under a quote in the first place. It never becomes a symbol like '+. The + outside of any quote has meaning as the addition function.
In other cases, you can't avoid having the symbol '+ because it comes from intrinsically textual data. In this case you can assign meaning to it with an interpreter. Somewhere in that interpreter you might want code like this
(match sym ['+ +] ['- -] ['* *] ['/ /] [_ (error "unrecognized symbol")])
Something is needed to assign meaning externally, because the symbol '+ does not have that meaning internally. You can either define the interpreter yourself or use an existing one such as eval, as long as all the meanings in the interpreter correspond exactly to what you intend.
When I write:
'(1 2 3)
I get a list:
(1 2 3)
When I write:
'some-symbol
I get:
some-symbol
When I write:
'('some-symbol)
I get:
((quote some-symbol))
I can of course write:
(list 'some-symbol)
and I get:
(some-symbol)
which is the desired output. Is it correct that I cannot quote a symbol in a list like:
'(some-symbol)
Is there some other shorthand for the list operator that I am missing?
Quote will quote the entire s-expression that follows. So, in that sense,
'(some-symbol)
will actually be a quoted list containing the symbol you're looking for.
The quote sign is a shorthand for (quote ...), so
'(some-symbol)
is equivalent to
(quote (some-symbol))
I'd like to replace every other (odd?) space with x. The result should be:
axb axb axb axb axb
I tried something like:
replace ("a b a b a b a b" , " " , "x")[position() mod 2 = 0]
-- but with no result.
First of all: fn:replace requires an XPath 2.0 (or XQuery) compatible query processor.
You cannot use fn:replace with an predicate like this. There is no array-like access to characters in XPath (like you're used to from eg. C). You probably could also solve this using fn:tokenize and a for-loop, but that's getting things rather complicated.
Your query did not return any result, as there is exactly one result (single element string sequence), but the predicate only returns every second.
Use a regular expression instead. This expression matches on non-space (\S) and space (\s) and replaces those patterns by a version with x in between. The star quantifier in the end is important for odd number of match groups (like in your example).
replace("a b a b a b a b" , "(\S+)\s+(\S+\s*)", "$1x$2")
I actually have a string called "cond". This is the content of that string:
"20 < 50"
I would like to insert it into a condition like this: (example)
if 20 < 50
return "Hello"
But that condition is a string, so I can't write this:
if cond
return "Hello"
So I would like to know if it is possible to convert a string to a condition to set in an "if" condition. And if it is possible, how can I do it ?
Thank you.
eval might just be your friend here:
>> eval('20 < 50')
=> true
However, eval will execute the arbitrary code inside its argument; you should be sure that your cond can't contain anything detrimental to your system's health!
One alternative to using eval is perhaps to write an evaluator (or use/modify an existing one, like this one by Sterling Camden).
As is his code requires you to write lt, gt, eq, and so on, instead of <, >, ==, ... . As noted in a comment in calc.rb:
# Equality and its clan (note we cannot use '==' or other two-character
# non-word operators, because of the way we parse the string. Non-word
# characters come in one at a time.
If you know the condition will always be basic like the example you provided, you can do this:
left, op, right = "20 < 50".split
cond = left.to_i.send(op.to_sym, right.to_i)