======album1.lisp======
#|
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 ((self album))
(format t "~
|#