How to format a string in CLIPS? - clips

I need to format a string, but even if I copy a seemingly correct code, the CLIPS interpreter signals me an error.
(format nil "Integer: |% ld|" 12)
“I expect the output of "Integer: |12|" but the CLIPS interpreter signals me an error.

There should be no space between the % character and the format flag. Also the character 'l' is not a valid format flag.
CLIPS> (format nil "Integer: |%d|" 12)
"Integer: |12|"
CLIPS>

Related

Case-insensitive text list sorting

There is a list of "спсВыбора":
("ФайлыКаталоги" "Клиент Проверка Существования Каталога" "Клиент Проверка Существование Файла" "СтандартныеСтруктурыМодуля" "стндОбрОтв" "элКлючаОтветУспехОбрОтв" "элКлючаОтветОшибкаОбрОтв" "элКлючаОтветПроцедура" "элКлючаОтветМодуль" "стндОтчОтв")
To sort, use the command:
(setq спсВыбора (sort спсВыбора (lambda (a b) (string> a b))))
As a result, the list of "спсВыбора":
("элКлючаОтветУспехОбрОтв" "элКлючаОтветПроцедура" "элКлючаОтветОшибкаОбрОтв" "элКлючаОтветМодуль" "стндОтчОтв" "стндОбрОтв" "ФайлыКаталоги" "СтандартныеСтруктурыМодуля" "Клиент Проверка Существования Каталога" "Клиент Проверка Существование Файла")
Sorting takes into account the separate order of lower and upper case letters. Tell me how to sort the list by removing the case order. Example:
"caB" => "aBc"
Use string-collate-lessp as the predicate:
string-collate-lessp is a built-in function in ‘src/fns.c’.
(string-collate-lessp S1 S2 &optional LOCALE IGNORE-CASE)
Return t if first arg string is less than second in collation order.
Symbols are also allowed; their print names are used instead.
This function obeys the conventions for collation order in your
locale settings. For example, punctuation and whitespace characters
might be considered less significant for sorting:
(sort '("11" "12" "1 1" "1 2" "1.1" "1.2") 'string-collate-lessp)
=> ("11" "1 1" "1.1" "12" "1 2" "1.2")
The optional argument LOCALE, a string, overrides the setting of your
current locale identifier for collation. The value is system
dependent; a LOCALE "en_US.UTF-8" is applicable on POSIX systems,
while it would be, e.g., "enu_USA.1252" on MS-Windows systems.
If IGNORE-CASE is non-nil, characters are converted to lower-case
before comparing them.
To emulate Unicode-compliant collation on MS-Windows systems,
bind ‘w32-collate-ignore-punctuation’ to a non-nil value, since
the codeset part of the locale cannot be "UTF-8" on MS-Windows.
If your system does not support a locale environment, this function
behaves like ‘string-lessp’.
As you noticed, string< is case-sensitive. My suggestion in your case to obtain case-insensitive sorting would be to upcase/downcase operands of that comparator, so that it is effectively case-insensitive:
(setq спсВыбора (sort спсВыбора (lambda (a b) (string> (downcase a) (downcase b)))))
Note that that is reverse-alphabetical per your example.

Use variable padding in iteration directive in FORMAT

Is there a way to do something like the following?
(format t "~{~va~}" '("aa" "bb" "cc") 4)
I need to iterate through a list. Each element of that list should be padded with a variable number of spaces (specified at runtime, so I cannot use "~4a").
Or more generally, is there a way to refer to a specific argument in the argument list of FORMAT?
By nesting format function, you can do what you want.
(format t (format nil "~~{~~~Aa~~}" 4) '("aa" "bb" "cc"))
;; returns: aa bb cc
Here the inner format directive:
The nil as first argument, format returns a string.
(format nil "~~{~~~Aa~~}" 4)
;; returns: "~{~4a~}" - and this is exactly what you want to give
;; to the outer `format` as second argument!
You can of course write a function for this:
(defun format-by-padding-over (lst padding)
(format t (format nil "~~{~~~Aa~~}" padding) lst))
And then:
(format-by-padding-over '("aa" "bb" "cc") 4)
;; aa bb cc
;; NIL
I learned this trick here from #Sylwester (many thanks!).
You could also interleave the list with repetitions of the padding:
(format t "~{~va~}"
(mapcan (lambda (element)
(list 4 element))
list))
You can build the format control string using nested format functions, but then you have to take care about escaping tildes. When working with regular expressions (using CL-PPCRE), one can define regular expressions using trees, like (:alternation #\\ #\*), which helps preventing bugs and headaches related to escaping special characters. The same can be done with format strings, using format-string-builder, available in Quicklisp:
(lambda (v)
(make-format-string `((:map () (:str ,v)))))
Returns a closure, which can be used to build format strings:
(funcall * 10)
=> "~{~10a~}"

How to extract the last character of a string of unknown length?

I am writing a function that takes stringA and stringB as parameters and compares the first character of stringB with the last character of StringA. If they are equal, then the function returns true, else false is returned.
I have nearly the whole function ready, however I can't find a way to take the last character of stringA because its length is unknown. I checked the documentation and I found nothing. Any suggestions?
(cond
[(string=? (substring stringA ???) (substring stringB 0 2))"True"]
[else "False"])
You can get the last character position of a string using string-length (or rather one less than):
(string-ref str (sub1 (string-length str)))
Note that a character is different from a string of length 1. Thus the correct way to extract a character is with string-ref or the like, rather than substring.
It seems Chris answered your question. Just a reminder, to use the string-ref, which returns a character, you should use the comparison function char=? (or equal?).
I'd like to add another solution which I find more elaborate, but requires to download a collection from the planet racket (after installing package collections). Using the collections package, you can use the same function with any collection rather then just strings, using the (last ..) and (first ..) functions of the module.
(require data/collection)
(let ([stringA "abcd"]
[stringB "dcba"])
(cond
[(equal? (last stringA)
(first stringB)) "True"]
[else "False"]))
You could also use the SRFI-13 function string-take-right, which returns the last n characters of the argument string as a string.
every language has a length function for a string. in Racket I found this :
https://docs.racket-lang.org/reference/strings.html#%28def.%28%28quote.~23~25kernel%29._string-length%29%29
there is this : string-length str
so just run that it will give you the length and then you can extract the last character

Emacs Lisp: getting ascii value of character

I'd like to translate a character in Emacs to its numeric ascii code, similar to casting char a = 'a'; int i = (int)a in c. I've tried string-to-number and a few other functions, but none seem to make Emacs read the char as a number in the end.
What's the easiest way to do this?
To get the ascii-number which represents the character --as Drew said-- put a question mark before the character and evaluate that expression
?a ==> 97
Number appears in minibuffer, with C-u it's written behind expression.
Also the inverse works
(insert 97) will insert an "a" in the buffer.
BTW In some cases the character should be quoted
?\" will eval to 34
A character is a whole number in Emacs Lisp. There is no separate character data type.
Function string-to-char is built-in, and does what you want. (string-to-char "foo") is equivalent to (aref "foo" 0), which is #abo-abo's answer --- but it is coded in C.
String is an array.
(aref "foo" 0)

Regular expressions for password validation missing work

I need to validate a password that matches the following criteria:
Must be at least 6 characters long (?=.{6})
String contains a numbers(0-9) and least 1 uppercase letter(A-Z) and least 1 (-) character.
String not start and end with a - character (invalid : -ABCDE or ABCDE- etc..)
valid Strings
A-BCDE
ABC-DE
1B-CDE
1-BCDE
AB-CD1
ABCD-1
my regex
^.(?=.{6})(?=.\d)(?=.[A-Z])(?=.[-]).*$
demo url :
http://www.rubular.com/r/YHdPCjSW6P
invalid strings
ABCDEF (No - character must be one of at least 1 -)
-ABCDE (- the first character can not be)
ABCDE- (- the last character can not be)
A-BC-D (- can not be more than 1)
Would that work for you ?
^.*(?=.{6})(?=[^\-].*[a-zA-Z])[a-zA-Z0-9\-]{1,5}[^\-]$
See example here http://www.rubular.com/r/spfqXIVZyX
valid Strings
A-BCDE
ABC-DE
1B-CDE
1-BCDE
AB-CD1
ABCD-1
invalid strings
ABCDEF (No - character must be one of at least 1 -)
-ABCDE (- the first character can not be)
ABCDE- (- the last character can not be)
A-BC-D (- can not be more than 1)
my regex now
^.(?=.{6})(?=[^-].[a-zA-Z])[a-zA-Z0-9-]{1,5}[^-]$
demo url :
http://www.rubular.com/r/3Q6Ozs4aVB

Resources