* Create lisp package #+begin_src lisp (defpackage user-research-app (:use :cl) (:import-from :dev.metalisp.sbt :with-page) (:import-from :dev.metalisp.sbt/pattern/questionnaire :questionnaire)) #+end_src #+RESULTS: : # * Demographics #+name: demographics-survey #+begin_src lisp :results output file :file-ext html (in-package :user-research-app) (defun generate-demographics-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 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")) (: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" (:ask "How often do you use our software?" :group "beh-useage" :choices (:single "Daily" "Weekly" "Monthly" "Less frequently")) (:ask "What features do you use the most?" :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)) #+end_src #+RESULTS: psychographics-survey [[file:psychographics-survey.html]] * 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]] * System Usability Scale #+begin_src lisp :package :sus :tangle sus-survey.cl (ql:quickload :dev.metalisp.sbt) (defpackage sus (:use #:common-lisp) (: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*) (: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)) #+end_src #+RESULTS: : # #+begin_src lisp :package :sus :tangle sus-survey.cl (in-package #:sus) (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" :style "list-style:none;" :choices (:single "1 Strongly Disagree" "2 Disagree" "3 Neither Agree nor Disagree" "4 Agree" "5 Strongly Agree")) (:ask "The system is unnecessarily complex." :group "sus-2" :style "list-style:none;" :choices (:single "1 Strongly Disagree" "2 Disagree" "3 Neither Agree nor Disagree" "4 Agree" "5 Strongly Agree")) (:ask "The system is easy to use." :group "sus-3" :style "list-style:none;" :choices (:single "1 Strongly Disagree" "2 Disagree" "3 Neither Agree nor Disagree" "4 Agree" "5 Strongly Agree")) (:ask "I need the support of a technical person to use this system." :group "sus-4" :style "list-style:none;" :choices (:single "1 Strongly Disagree" "2 Disagree" "3 Neither Agree nor Disagree" "4 Agree" "5 Strongly Agree")) (:ask "The functions in this system are well integrated." :group "sus-5" :style "list-style:none;" :choices (:single "1 Strongly Disagree" "2 Disagree" "3 Neither Agree nor Disagree" "4 Agree" "5 Strongly Agree")) (:ask "There is too much inconsistency in this system." :group "sus-6" :style "list-style:none;" :choices (:single "1 Strongly Disagree" "2 Disagree" "3 Neither Agree nor Disagree" "4 Agree" "5 Strongly Agree")) (:ask "Most people would learn to use this system very quickly." :group "sus-7" :style "list-style:none;" :choices (:single "1 Strongly Disagree" "2 Disagree" "3 Neither Agree nor Disagree" "4 Agree" "5 Strongly Agree")) (:ask "The system is very awkward to use." :group "sus-8" :style "list-style:none;" :choices (:single "1 Strongly Disagree" "2 Disagree" "3 Neither Agree nor Disagree" "4 Agree" "5 Strongly Agree")) (:ask "I feel very confident using this system." :group "sus-9" :style "list-style:none;" :choices (:single "1 Strongly Disagree" "2 Disagree" "3 Neither Agree nor Disagree" "4 Agree" "5 Strongly Agree")) (:ask "I needed to learn a lot of things to get started with this system." :group "sus-10" :style "list-style:none;" :choices (:single "1 Strongly Disagree" "2 Disagree" "3 Neither Agree nor Disagree" "4 Agree" "5 Strongly Agree"))) (btn-primary (:type "submit") (find-l10n "submit" spinneret:*html-lang* *l10n*))))) #+end_src #+RESULTS: : SUS-FORM #+begin_src lisp :package :sus :tangle sus-survey.cl (in-package #:sus) (defstruct survey-app response acceptor) (defun handle-acceptor (acceptor) (lambda (action) (case action (start (hunchentoot:start acceptor)) (stop (hunchentoot:stop acceptor)) (restart (progn (hunchentoot:stop acceptor) (hunchentoot:start acceptor)))))) (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) :direction :input :if-does-not-exist :create) (if (= (file-length stream) 0) '() (read stream)))) (defun store-response (app responses) (with-open-file (stream (survey-app-response app) :direction :output :if-exists :supersede) (princ responses stream))) (define-easy-handler (sus :uri "/") nil (sus-form)) (define-easy-handler (submit :uri "/submit") nil (setf (content-type*) "text/plain") (let ((post-params (post-parameters* *request*)) (stored-response (load-response *app1*))) (if (= (length post-params) 10) (let ((response stored-response)) (push post-params response) (store-response *app1* (reverse response)) (format nil "~A" response)) (format nil "Please fill out all forms")))) #+end_src #+RESULTS: : SUBMIT #+name: example-sus-form-en #+begin_src lisp :results output file :file-ext html :package :sus (format t (sus-form)) #+end_src #+RESULTS: example-sus-form-en [[file:example-sus-form-en.html]] #+begin_src shell :results output curl -X POST -d "arg1=value1&arg2=value2" http://localhost:8080/submit #+end_src #+RESULTS: