bob.el (1930B)
1 ;;; bob.el --- Bob exercise (exercism) 2 3 ;;; Commentary: 4 ;;; Bob implements categorical responses to queries. 5 6 ;;; Code: 7 8 (provide 'bob) 9 10 (require 'subr-x) 11 12 (defun is-all-caps(s) 13 "Determine whether a string, S, is all capitalized. Return nil if a string has no alpha characters." 14 (let ((case-fold-search nil)) ; make the regex case-sensitive 15 (and (not (string-match-p "[[:lower:]]" s)) 16 (not (equal (upcase s) (downcase s))) 17 (> (length s)0)))) 18 19 (defun is-forceful-question(formatted-query) 20 "Determine whether FORMATTED-QUERY is a forceful question; 21 i.e., all capitals and ending in a question mark." 22 (and (is-all-caps (substring formatted-query 0 -1)) 23 (is-question formatted-query))) 24 25 (defun is-question(formatted-query) 26 "Determine whether FORMATTED-QUERY is a question; 27 i.e., ending with a question mark." 28 (string-suffix-p "?" formatted-query)) 29 30 (defun is-shouting(formatted-query) 31 "Determine whether FORMATTED-QUERY is shouting; 32 i.e., either all capitals only or all capitals ending with an exclamation 33 mark." 34 (if (not (is-question formatted-query)) 35 (cond ((is-all-caps formatted-query) t) 36 ((and (is-all-caps (substring formatted-query 0 -1)) 37 (string-suffix-p "!" formatted-query)) t)))) 38 39 (defun is-silence(formatted-query) 40 "Determine whether FORMATTED-QUERY is silence; i.e., of zero length." 41 (= (length formatted-query) 0)) 42 43 (defun response-for(query) 44 "Determine the response to QUERY. 45 Begins by trimming whitespace, then checking the QUERY type on a 46 case-by-case basis." 47 (let ((formatted-query (string-trim query))) 48 (cond ((is-silence formatted-query) "Fine. Be that way!") 49 ((is-forceful-question formatted-query) 50 "Calm down, I know what I'm doing!") 51 ((is-shouting formatted-query) "Whoa, chill out!") 52 ((is-question formatted-query) "Sure.") 53 (t "Whatever.")))) 54 55 ;;; bob.el ends here