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 1)

(format t "~
|#
 
 
 
 
 
 
 
1)
self album
YPP2/album/album1.lisp.txt · Last modified: 2014/10/23 23:33 (external edit)
CC Attribution-Noncommercial-Share Alike 4.0 International
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0