#| exec sbcl --noinform --load $0 --end-toplevel-options "$@" |# #| trida: time sloty: min, sec metody: set, get trida: track sloty: name, length metody: set, get, print trida: album sloty: artist, title, track metody: set, get ke vsemu + album-length + track-count (map car) + print album |#
TIME
(defclass time-spec () ( (min :type (integer 0)) (sec :type (integer 0 59)) ))
get note: getter pro min koliduje? s funkci pro minimum? (min 2 3 6 1) ⇒ 1
(defmethod t-min ((self time-spec)) ;vrati hodnotu slotu (slot-value self 'min)) (defmethod t-sec ((self time-spec)) (slot-value self 'sec))
kontrola je value nezaporny integer?
(defmethod set-min ((self time-spec) value) (unless (typep value '(integer 0)) (error "minuty: cele nezaporne cislo!")) (setf (slot-value self 'min) value) self)
je value integer 0-59?
(defmethod set-sec ((self time-spec) value) (unless (typep value '(integer 0 59)) (error "sekundy 0-59!")) (setf (slot-value self 'sec) value) self) (defmethod time-in-seconds ((self time-spec)) (+ (* (slot-value self 'min) 60) (slot-value self 'sec)))
je value integer? (modulo floor a multi/values)
(defmethod set-time-in-seconds ((self time-spec) value) (unless (typep value '(integer 0)) (error "sekundy zaporne!")) (multiple-value-bind (min sec) (floor value 60) (set-sec (set-min self min) sec)))
helper vytvori instanci a nastavi sloty minut a sekund
(defun make-time (min sec) (set-sec (set-min (make-instance 'time-spec) min) sec))
TRACK Tip: type-specifikace pro :type lze zjistit pomoci type-of, napr:
#| (type-of 123) ;=> (integer 0 ...) (type-of "string") ;=> (simple-array character ...) |# (defclass track () ( ;(length :type (make-instance 'time-spec)) ;NE :type!? ale :initform? (len :initform nil :type time-spec) ;(name :type "") ;#nelze, spise string? type specifikator? (name :initform nil :type '(simple-array character)) ))
oprava: gettery se jmenuji bez get- predponu – ale length zase koliduje!?
;(defmethod get-length ((self track)) (defmethod len ((self track)) (slot-value self 'len)) ;(defmethod get-name ((self track)) (defmethod name ((self track)) (slot-value self 'name))
NOTE: settery maji set- predponu, vraceji self
(defmethod set-name ((self track) name) (unless (typep name 'string) ;(error "nazev neni spravne!")) (error "nazev musi byt retezec!")) (setf (slot-value self 'name) self)) ;(defmethod set-length ((self track) min sec) ;;(set-time-in-seconds (get-length) min sec));nekolik chyb ; (set-time-in-seconds (length self) min sec));ale argument neni time-spec ani seconds!!! (defmethod set-len ((self track) value) (unless (typep value 'time-spec) (error "delka track neni time-spec!")) (setf (slot-value self 'len) value) self);vracime self!!!
lze i takto?
(defmethod set-len ((self track) (value time-spec)) ; vvvv------------------^^^^^^^^^^^^^^^^* netreba?, pouzijeme [[wp>Mutltiple_dispatch>multiple dispatch]]!? ;(unless (typep value 'time-spec) (error "delka track neni time-spec!")) (setf (slot-value self 'len) value) self);vracime self
nebo i dalsi multiple dispatch?
(defmethod set-len ((self track) (value integer)) ; vvvv------------------^^^^^^^^^^^^^^^^ typep kontrola netreba?, pouzijeme multi dispatch!? (setf (slot-value self 'len) (set-time-in-seconds (make-instance 'time-spec) value)) self);vracime self (defmethod print-track ((self track)) ;(format t "~%Name:~s" (get-name track)) (format t "~%Name:~s" (name self)) ;(format t "~%Time:~s: ~s" (t-min (get-length track)) (t-sec (get-length track)))) ;(format t "~%Time:~s: ~s" (t-min (len self)) (t-sec (len self)))) ;TODO: vracet self? TODO: tisknout 01:34 tj. printff %02d ;http://www.gigamonkeys.com/book/a-few-format-recipes.html (format t "~%Time:~2,'0d:~2,'0d" (t-min (len self)) (t-sec (len self)))) ;TODO: vracet self? TODO: tisknout 01:34 tj. printff %02d
objekt tridy track
(defun make-track (name length) ;(let ((track (make-instance 'track))) ; (setf (slot-value track 'name) self) ; (setf (slot-value track 'length)) ; self)) (set-len (set-name (make-instance 'track) name) length));vraci self #|testovani track: |# (defvar *track* (make-track "Nasrat55" (make-time 3 59))) (print-track *track*)
(make-track “chybny nasl. argument” “neni-time-spec!”) ;osetri :type ? OK!
#|
ALBUM
(defclass album () ((name :type "") (author :type "") (track :initform nil)));lepe tracks -- mnozne cislo, bude to seznam/list (defmethod get-album-name ((self album)) (slot-value self 'name)) (defmethod get-album-author ((self album)) (slot-value self 'author)) (defmethod get-album-tracks ((self album)) (slot-value self 'tracks)) (defmethod set-album-name ((self album) value) (unless (typep value 'string) (error "zase spatnej nazev!")) (setf (slot-value self 'name) value) self) (defmethod set-album-author ((self author) value) (unless (typep author 'string) (error "a zase a zase a zase")) (setf (slot-value self 'author) value) self) (defmethod set-album-tracks ((self album) value) (unless (every (lambda (e) (typep e 'track)) value) (error "neni seznam tracku!")) (setf (slot-value self 'tracks) (copy-list value)) self) (defmethod album-length ((self album)) (labels ((iter (tracks) (if (eq tracks '()) 0 (+ (t-sec (time-in-seconds (car tracks))) (iter (cdr tracks)))))) (iter (slot-value self 'tracks)))) (defmethod track-count ((self album)) (length (slot-value self 'tracks)))
????? (defmethod print-album 1)
(format t "~
|#