2024-02-11 12:34:21 +01:00
* Create lisp package
#+begin_src lisp
(defpackage user-research-app
2024-02-10 13:39:15 +01:00
(:use :cl)
(:import-from :dev.metalisp.sbt :with-page)
2024-02-11 12:34:21 +01:00
(:import-from :dev.metalisp.sbt/pattern/questionnaire :questionnaire))
#+end_src
#+RESULTS :
: #<PACKAGE "USER-RESEARCH-APP" >
* Demographics
2024-02-10 13:39:15 +01:00
2024-02-11 12:34:21 +01:00
#+name : demographics-survey
#+begin_src lisp :results output file :file-ext html
(in-package :user-research-app)
2024-02-10 13:39:15 +01:00
2024-02-11 12:34:21 +01:00
(defun generate-demographics-survey ()
2024-02-10 13:39:15 +01:00
"Generates an HTML page with questionnaires using questionnaire macros."
(with-output-to-string (spinneret:*html* )
2024-02-11 12:34:21 +01:00
(with-page (:title "Product Experience Survey" :main-con t)
2024-02-10 13:39:15 +01:00
(questionnaire "/submit"
(:ask "What is your age range?"
:group "demo-age-range"
:choices (:single "18-24" "25-34" "35-44" "45-54" "55+"))
(:ask "What is your gender?"
:group "demo-gender"
:choices (:single "Male" "Female" "Non-binary" "Prefer not to say" "Other" :text "Other"))
(:ask "What is your profession?"
:group "demo-profession"
:choices (:text "Profession"))
2024-02-11 12:34:21 +01:00
(:ask "What is your educational background?"
:group "demo-edu"
:choices (:text "Last Degree"))))))
(format t (generate-demographics-survey))
#+end_src
#+RESULTS : demographics-survey
[[file:demographics-survey.html ]]
* Geographics
#+name : geographics-survey
#+begin_src lisp :results output file :file-ext html
(in-package :user-research-app)
(defun generate-geographics-survey ()
"Generates an HTML page with questionnaires using questionnaire macros."
(with-output-to-string (spinneret:*html* )
(with-page (:title "Product Experience Survey" :main-con t)
(questionnaire "/submit"
(:ask "Where are you located?"
:group "geo-loca"
:choices (:text "Country"))
(:ask "Which timezone do you operate in?"
:group "geo-timezone"
:choices (:text "Timezone"))))))
(format t (generate-geographics-survey))
#+end_src
#+RESULTS : geographics-survey
[[file:geographics-survey.html ]]
* Behavioral
#+name : behavioral-survey
#+begin_src lisp :results output file :file-ext html
(in-package :user-research-app)
(defun generate-behavioral-survey ()
"Generates an HTML page with questionnaires using questionnaire macros."
(with-output-to-string (spinneret:*html* )
(with-page (:title "Product Experience Survey" :main-con t)
(questionnaire "/submit"
2024-02-10 13:39:15 +01:00
(:ask "How often do you use our software?"
2024-02-11 12:34:21 +01:00
:group "beh-useage"
2024-02-10 13:39:15 +01:00
:choices (:single "Daily" "Weekly" "Monthly" "Less frequently"))
(:ask "What features do you use the most?"
2024-02-11 12:34:21 +01:00
:group "beh-feature"
:choices (:multiple "Bookmarks" "KPI" "Contacts"))
(:ask "Have you used our software for along period of time?"
:group "beh-longuse"
:choices (:single "Yes" "No"))))))
(format t (generate-behavioral-survey))
#+end_src
#+RESULTS : behavioral-survey
[[file:behavioral-survey.html ]]
* Psychographics
#+name : psychographics-survey
#+begin_src lisp :results output file :file-ext html
(in-package :user-research-app)
(defun generate-psychographics-survey ()
"Generates an HTML page with questionnaires using questionnaire macros."
(with-output-to-string (spinneret:*html* )
(with-page (:title "Product Experience Survey" :main-con t)
(questionnaire "/submit"
(:ask "What do you value most in our software?"
:group "psy-value"
:choices (:text "Most value"))
(:ask "What motivates you to use our software?"
:group "psy-motivate"
:choices (:text "Your motivation"))))))
(format t (generate-psychographics-survey))
2024-02-10 13:39:15 +01:00
#+end_src
2024-02-10 19:52:54 +01:00
2024-02-11 12:34:21 +01:00
#+RESULTS : psychographics-survey
[[file:psychographics-survey.html ]]
2024-02-11 13:32:43 +01:00
* Needs/Challenges
#+name : nc-survey
#+begin_src lisp :results output file :file-ext html
(in-package :user-research-app)
(defun generate-nc-survey ()
"Generates an HTML page with questionnaires using questionnaire macros."
(with-output-to-string (spinneret:*html* )
(with-page (:title "Product Experience Survey" :main-con t)
(questionnaire "/submit"
(:ask "What challenges, if any, does our software help you overcome?"
:group "nc-challenges"
:choices (:text "Please describe"))
(:ask "How could we improve to better meet your needs?"
:group "nc-improve"
:choices (:single "Please describe"))))))
(format t (generate-nc-survey))
#+end_src
#+RESULTS : nc-survey
[[file:nc-survey.html ]]
* Technology Comfort Level
#+name : tcl-survey
#+begin_src lisp :results output file :file-ext html
(in-package :user-research-app)
(defun generate-tcl-survey ()
"Generates an HTML page with questionnaires using questionnaire macros."
(with-output-to-string (spinneret:*html* )
(with-page (:title "Product Experience Survey" :main-con t)
(questionnaire "/submit"
(:ask "How would you rate your comfort level with technology?"
:group "tcl-likeart"
:choices (:single "1 - Very Uncomfortable" "2 - Slightly Uncomfortable" "3 - Neutral" "4 - Quite Comfortable" "5 - Very Comfortable"))
(:ask "How frequently do you adopt new technologies?"
:group "tcl-adopt"
:choices (:single "1 - Always - I'm an early adopter." "2 - Often - I stay on top of technological advances and adopt them frequently." "3 - Sometimes - I adopt new technologies now and then." "4 - Rarely - I only adopt new technologies when it's necessary for work or other important tasks." "5 - Never - I avoid adopting new technologies unless absolutely required."))))))
(format t (generate-tcl-survey))
#+end_src
#+RESULTS : tcl-survey
[[file:tcl-survey.html ]]
2024-03-21 14:54:57 +01:00
* System Usability Scale
2024-05-20 11:04:48 +02:00
#+begin_src lisp :package :sus :tangle sus-survey.cl
(ql:quickload :dev.metalisp.sbt)
2024-05-17 17:14:56 +02:00
(defpackage sus
2024-05-20 21:52:48 +02:00
(:use #:common-lisp)
2024-05-20 11:04:48 +02:00
(:import-from hunchentoot #:define-easy-handler)
(:import-from hunchentoot #:easy-acceptor)
(:import-from hunchentoot #:post-parameters*)
(:import-from hunchentoot #:content-type*)
(:import-from hunchentoot #:*request* )
2024-05-17 17:14:56 +02:00
(:import-from spinneret #:*html* )
(:import-from dev.metalisp.sbt/form #:multi-form)
(:import-from dev.metalisp.sbt #:with-page)
(:import-from dev.metalisp.sbt #:find-l10n)
(:import-from dev.metalisp.sbt #:*l10n* )
(:import-from dev.metalisp.sbt/btn #:btn-primary))
2024-05-20 11:04:48 +02:00
#+end_src
2024-05-17 17:14:56 +02:00
2024-05-20 11:04:48 +02:00
#+RESULTS :
: #<PACKAGE "SUS" >
2024-05-17 17:14:56 +02:00
2024-05-20 11:04:48 +02:00
#+begin_src lisp :package :sus :tangle sus-survey.cl
(in-package #:sus)
2024-05-17 17:14:56 +02:00
(defun sus-form ()
(with-page (:title "SUS Form" :main-con t)
(:form :action "/submit"
:method "post"
(multi-form
(:ask "I’ d like to use this system frequently."
:group "sus-1"
2024-05-20 21:52:48 +02:00
:style "list-style:none;"
:choices (:single "1 Strongly Disagree"
"2 Disagree"
"3 Neither Agree nor Disagree"
"4 Agree"
"5 Strongly Agree"))
2024-05-17 17:14:56 +02:00
(:ask "The system is unnecessarily complex."
:group "sus-2"
2024-05-20 21:52:48 +02:00
:style "list-style:none;"
:choices (:single "1 Strongly Disagree"
"2 Disagree"
"3 Neither Agree nor Disagree"
"4 Agree"
"5 Strongly Agree"))
2024-05-17 17:14:56 +02:00
(:ask "The system is easy to use."
:group "sus-3"
2024-05-20 21:52:48 +02:00
:style "list-style:none;"
:choices (:single "1 Strongly Disagree"
"2 Disagree"
"3 Neither Agree nor Disagree"
"4 Agree"
"5 Strongly Agree"))
2024-05-17 17:14:56 +02:00
(:ask "I need the support of a technical person to use this system."
:group "sus-4"
2024-05-20 21:52:48 +02:00
:style "list-style:none;"
:choices (:single "1 Strongly Disagree"
"2 Disagree"
"3 Neither Agree nor Disagree"
"4 Agree"
"5 Strongly Agree"))
2024-05-17 17:14:56 +02:00
(:ask "The functions in this system are well integrated."
:group "sus-5"
2024-05-20 21:52:48 +02:00
:style "list-style:none;"
:choices (:single "1 Strongly Disagree"
"2 Disagree"
"3 Neither Agree nor Disagree"
"4 Agree"
"5 Strongly Agree"))
2024-05-17 17:14:56 +02:00
(:ask "There is too much inconsistency in this system."
:group "sus-6"
2024-05-20 21:52:48 +02:00
:style "list-style:none;"
:choices (:single "1 Strongly Disagree"
"2 Disagree"
"3 Neither Agree nor Disagree"
"4 Agree"
"5 Strongly Agree"))
2024-05-17 17:14:56 +02:00
(:ask "Most people would learn to use this system very quickly."
:group "sus-7"
2024-05-20 21:52:48 +02:00
:style "list-style:none;"
:choices (:single "1 Strongly Disagree"
"2 Disagree"
"3 Neither Agree nor Disagree"
"4 Agree"
"5 Strongly Agree"))
2024-05-17 17:14:56 +02:00
(:ask "The system is very awkward to use."
:group "sus-8"
2024-05-20 21:52:48 +02:00
:style "list-style:none;"
:choices (:single "1 Strongly Disagree"
"2 Disagree"
"3 Neither Agree nor Disagree"
"4 Agree"
"5 Strongly Agree"))
2024-05-17 17:14:56 +02:00
(:ask "I feel very confident using this system."
:group "sus-9"
2024-05-20 21:52:48 +02:00
:style "list-style:none;"
:choices (:single "1 Strongly Disagree"
"2 Disagree"
"3 Neither Agree nor Disagree"
"4 Agree"
"5 Strongly Agree"))
2024-05-17 17:14:56 +02:00
(:ask "I needed to learn a lot of things to get started with this system."
:group "sus-10"
2024-05-20 21:52:48 +02:00
:style "list-style:none;"
:choices (:single "1 Strongly Disagree"
"2 Disagree"
"3 Neither Agree nor Disagree"
"4 Agree"
"5 Strongly Agree")))
2024-05-17 17:14:56 +02:00
(btn-primary (:type "submit")
(find-l10n "submit" spinneret:*html-lang* *l10n* )))))
2024-05-20 11:04:48 +02:00
#+end_src
2024-05-17 17:14:56 +02:00
2024-05-20 11:04:48 +02:00
#+RESULTS :
: SUS-FORM
2024-05-17 17:14:56 +02:00
2024-05-20 11:04:48 +02:00
#+begin_src lisp :package :sus :tangle sus-survey.cl
(in-package #:sus)
(defstruct survey-app
2024-05-20 12:53:49 +02:00
response
2024-05-20 11:04:48 +02:00
acceptor)
2024-05-17 17:14:56 +02:00
2024-05-20 11:04:48 +02:00
(defun handle-acceptor (acceptor)
(lambda (action)
(case action
(start (hunchentoot:start acceptor))
(stop (hunchentoot:stop acceptor))
(restart (progn (hunchentoot:stop acceptor)
(hunchentoot:start acceptor))))))
2024-05-20 12:53:49 +02:00
(defvar *app1* (make-survey-app :response #P"survey-db.cl"
:acceptor (handle-acceptor (make-instance 'easy-acceptor
:port 8080))))
(defun load-response (app)
(with-open-file (stream (survey-app-response app)
2024-05-20 11:04:48 +02:00
:direction :input
:if-does-not-exist :create)
(if (= (file-length stream) 0)
'()
(read stream))))
2024-05-20 12:53:49 +02:00
(defun store-response (app responses)
(with-open-file (stream (survey-app-response app)
2024-05-20 11:04:48 +02:00
:direction :output
:if-exists :supersede)
(princ responses stream)))
2024-05-20 21:52:48 +02:00
(define-easy-handler (sus :uri "/") nil
(sus-form))
2024-05-20 11:04:48 +02:00
(define-easy-handler (submit :uri "/submit") nil
(setf (content-type*) "text/plain")
2024-05-20 21:52:48 +02:00
2024-05-20 11:04:48 +02:00
(let ((post-params (post-parameters* *request* ))
2024-05-20 12:53:49 +02:00
(stored-response (load-response *app1* )))
2024-05-20 21:52:48 +02:00
2024-05-20 11:04:48 +02:00
(if (= (length post-params) 10)
2024-05-20 12:53:49 +02:00
(let ((response stored-response))
2024-05-20 21:52:48 +02:00
(push post-params response)
2024-05-20 12:53:49 +02:00
(store-response *app1* (reverse response))
(format nil "~A" response))
2024-05-20 11:04:48 +02:00
(format nil "Please fill out all forms"))))
2024-05-20 21:52:48 +02:00
2024-05-20 11:04:48 +02:00
#+end_src
2024-05-17 17:14:56 +02:00
2024-05-20 11:04:48 +02:00
#+RESULTS :
: SUBMIT
#+name : example-sus-form-en
#+begin_src lisp :results output file :file-ext html :package :sus
2024-05-17 17:14:56 +02:00
(format t (sus-form))
#+end_src
2024-04-18 16:43:15 +02:00
2024-05-17 17:14:56 +02:00
#+RESULTS : example-sus-form-en
[[file:example-sus-form-en.html ]]
2024-03-21 14:54:57 +01:00
2024-05-20 11:04:48 +02:00
#+begin_src shell :results output
2024-05-17 17:14:56 +02:00
curl -X POST -d "arg1=value1&arg2=value2" http://localhost:8080/submit
2024-03-21 14:54:57 +01:00
#+end_src
2024-05-20 11:04:48 +02:00
#+RESULTS :