#| 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 () ( (minute :type (integer 0)) (second :type (integer 0 59)) ))
get
(defmethod t-min ((self time-spec)) ;vrati hodnotu slotu (slot-value self 'minute)) (defmethod t-sec ((self time-spec)) (slot-value self 'second))
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 'minute) 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 'second) value) self) (defmethod time-in-seconds ((self time-spec)) ;(+ (* (slot-value self 'minute) 60) (slot-value self 'sec)));pouzit gettery!!! (+ (* (t-min self) 60) (t-sec self)))
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 (minute second) (floor value 60) (set-sec (set-min self minute) second)))
helper vytvori instanci a nastavi sloty minut a sekund
(defun make-time (minute second) (set-sec (set-min (make-instance 'time-spec) minute) second)) #| (defmethod set-time ((self time) x y) (if (>= y 59) (error "minuta musi mit do 59 sekund!") (setf (slot-value time 'minute) x (slot-value time 'second) y)) self) (defun make-time (x y) (set-time (make-instance 'time) x y)) |#
TRACK
(defclass track () ((length :initform (make-instance 'time-spec)) (name :initform ""))) (defmethod len ((self track)) (slot-value self 'lenght)) (defmethod name ((self track)) (slot-value self 'name)) (defmethod set-name ((self track) value) (unless (typep value 'string) ;TOTO funguje? Jo: (typep "abc" 'string) ;=> T (error "nazev neni spravne! jo vim ze musi byt retezec!")) (setf (slot-value self 'name) value) self) ;tady chybel taky self (defmethod set-len ((self track) value) (unless (typep value 'time-spec) (error "delka track neni time-spec!")) (setf (slot-value self 'length) value) self) (defmethod print-track ((self track)) (format t "~%Name:~s" (name self)) (format t "~%Time:~s: ~s" (t-min (len self)) (t-sec (len self))))
objekt tridy track OPRAVIT!!! misto slot-value pouzit set-name a set-len !!!
#| (defun make-track (name len) (let ((track (make-instance 'track))) (setf (slot-value track 'name) self) (setf (slot-value track 'len)) self)) |# (defun make-track (name len) (set-len (set-name (make-instance 'track) name) len))
ALBUM
(defclass album () ((name :initform "") (artist :initform "") (tracks :initform nil))) ;!!! POKUD to jde, jmenuje se getter stejne jako slot!!! ;(defmethod album-name ((self album)) (defmethod name ((self album)) (slot-value self 'name)) ;(defmethod album-author ((self album)) (defmethod artist ((self album)) (slot-value self 'artist)) ;(defmethod album-tracks ((self album)) (defmethod tracks ((self album)) (slot-value self 'tracks)) ;!!! settery se jmenuji jako slot + set- prefix!!! (defmethod set-name ((self album) value) (unless (typep value 'string) (error "nazev alba musi byt retezec!")) (setf (slot-value self 'name) value) self) ;(defmethod set-artist ((self artist) value) (defmethod set-artist ((self album) value) ;(unless (typep artist 'string) (unless (typep value 'string) (error "a zase a zase a zase nazev autora musi byt retezec!")) (setf (slot-value self 'artist) value) self) (defmethod set-tracks ((self album) value) (unless (every (lambda (e) (typep e 'track)) value) (error "neni seznam tracku!")) (setf (slot-value self 'tracks) (copy-list value)) ;Hmm, copy-list!!! 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 tracks-count ((self album)) (length (slot-value self 'tracks))) (defmethod print-album ((self album)) ;TODO (album-length self) ; delka alba (format t "Name: ~s Author: ~s" (name self) (artist self)) (format t "~%Number of tracks: ~s~%" (tracks-count self)) ;(dolist pres tracks) self)
helper:
(defun make-album (name artist tracks) (set-tracks (set-artist (set-name (make-instance 'album) name) artist) tracks)) (print-album (make-album "White album" "The Beatles" (list (make-track "Back in the U.S.S.R." (make-time 2 43)) (make-track "Dear Prudence" (make-time 3 56))))) #| |#