Задача продолжает идеи, заложенные в предыдущем ДЗ, но уже с использованием всех возможностей классов.
Нужно помочь перевести небольшую районную библиотеку в современный цифровой формат. Начнём с реализации нескольких классов:
- классы печатных изданий — книг, журналов;
- класс библиотеки, который позволит работать с печатными изданиями: хранить их, выдавать читателям, принимать обратно.
Печатные издания бывают разных видов, но между всеми книгами, сборниками и журналами есть много общего: у всех них есть название, год издания, страницы, они могут повреждаться с процессе использования.
-
Создайте базовый класс
PrintEditionItem
со свойствами:name
;releaseDate
;pagesCount
;state
;type
.
Конструктор класса должен принимать название (name
), дату выпуска (releaseDate
) и количество страниц (pagesCount
) в качестве аргумента. Состояние (state
) по умолчанию должно быть 100
, тип type
пока должен быть равен null
.
-
Испорченное издание можно подклеить и улучшить его состояние. Создайте метод
fix()
, увеличивающийstate
в полтора раза. Метод не должен принимать аргументы. -
Нельзя улучшить новое издание, также бесполезно подклеивать полностью уничтоженное. Чтобы лучше контролировать состояние книг, создайте «сеттер» для свойства
state
, принимающий в качестве аргумента новое состояние печатного издания (число).Если новое состояние меньше
0
, «сеттер» должен записать в свойствоstate
значение0
. Если новое состояние больше100
, должно быть записано значение100
. В остальных случаях в свойствоstate
должно быть записано переданное в «сеттер» значение. -
Создайте «геттер», который позволит читать значение свойства
state
.
Пример использования
const sherlock = new PrintEditionItem(
"Полное собрание повестей и рассказов о Шерлоке Холмсе в одном томе",
2019,
1008
);
console.log(sherlock.releaseDate); //2019
console.log(sherlock.state); //100
sherlock.fix();
console.log(sherlock.state); //100
-
Создайте класс
Magazine
, который будет наследоваться от классаPrintEditionItem
. Конструктор класса должен принимать такие же параметры, как и класс-родитель. От базового печатного издания журнал отличается только указанным типом. Значение свойстваtype
должно быть равно"magazine"
. -
Создайте класс
Book
, который наследуется от классаPrintEditionItem
. Конструктор класса должен принимать такие же параметры, как и класс-родитель, и имя автора книгиauthor
. Значение свойстваtype
должно быть равно"book"
. -
Создайте классы, которые наследуются от класса
Book
:NovelBook
— для романов,FantasticBook
— для фантастических произведений иDetectiveBook
— для детективов. Значения свойстваtype
должны быть равны"novel"
,"fantastic"
и"detective"
соответственно.
Пример использования
const picknick = new FantasticBook(
"Аркадий и Борис Стругацкие",
"Пикник на обочине",
1972,
168
);
console.log(picknick.author); //"Аркадий и Борис Стругацкие"
picknick.state = 10;
console.log(picknick.state); //10
picknick.fix();
console.log(picknick.state); //15
Теперь с помощью классов можно описать все возможные печатные издания, которые бывают в библиотеке. Пришло время подготовить саму библиотеку к работе в цифровом режиме — реализовать возможность хранить книги, выдавать их читателям и принимать обратно.
-
Создайте класс
Library
со свойствами:name
;books
.
Конструктор класса должен принимать название библиотеки
name
(строка). Значением свойстваbooks
должен быть пустой массив. -
Реализуйте метод
addBook(book)
, который в качестве аргумента будет принимать объект — книгу или журнал. Метод должен добавлять книгу в хранилищеbooks
, только если состояниеstate
книги больше30
. -
Создайте метод
findBookBy(type, value)
, который в качестве аргументов будет принимать ключ для проведения поиска (тип, автор, название, год выпуска и пр.) и искомое значение. Метод должен возвращать книгу в случае успеха иnull
, если запрошенная книга не была найдена. -
Создайте метод
giveBookByName(bookName)
, который в качестве аргумента будет принимать название книги, запрошенной читателем. Если запрошенная книга найдена, метод должен удалять книгу из хранилищаbooks
и возвращать её. Если книга не была найдена, метод должен возвращатьnull
.
Пример использования
const library = new Library("Библиотека имени Ленина");
library.addBook(
new DetectiveBook(
"Артур Конан Дойл",
"Полное собрание повестей и рассказов о Шерлоке Холмсе в одном томе",
2019,
1008
)
);
library.addBook(
new FantasticBook(
"Аркадий и Борис Стругацкие",
"Пикник на обочине",
1972,
168
)
);
library.addBook(new NovelBook("Герберт Уэллс", "Машина времени", 1895, 138));
library.addBook(new Magazine("Мурзилка", 1924, 60));
console.log(library.findBookBy("name", "Властелин колец")); //null
console.log(library.findBookBy("releaseDate", 1924).name); //"Мурзилка"
console.log("Количество книг до выдачи: " + library.books.length); //Количество книг до выдачи: 4
library.giveBookByName("Машина времени");
console.log("Количество книг после выдачи: " + library.books.length); //Количество книг после выдачи: 3
- Протестируйте корректность работы классов и методов, реализовав тестовый сценарий:
- создайте библиотеку;
- добавьте в библиотеку несколько печатных изданий разных типов;
- найдите книгу, изданную в 1919 году, или создайте её при необходимости;
- выдайте любую книгу;
- повредите выданную книгу;
- восстановите выданную книгу;
- попытайтесь добавить восстановленную книгу обратно в библиотеку.
Это задача со звёздочкой. Её выполнение не влияет на получение допуска к дипломной работе, но поможет усвоить пройденный материал.
Мы продолжаем совершенствовать журнал успеваемости студентов. Нужно преобразовать код прошлого ДЗ к классам. Реализуйте возможности:
- В конструкторе класса сохраняйте имя пользователя и создавайте свойство для хранения оценок.
В какой структуре хранить оценки по разным предметам?
Удобней всего хранить оценки в виде объекта, где свойством будет название предмета, а значением свойства — массив оценок по этому предмету. Начальным значением будет пустой объект.{
"физика": [4, 5, 5, 4],
"химия": [3, 4],
"литература": [4],
"информатика": [5, 5, 5]
}
- Метод
addMark
, который будет добавлять оценку по предмету.
- Валидируйте оценку. Она должна быть не меньше 2 и не больше 5. Если значение выходит за пределы этого диапазона, оценка не должна добавиться, и метод следует завершать.
- Проверьте наличие предмета. Если предмет отсутствует в свойстве
marks
, то добавляйте новое свойство, названием которого будет название предмета, а значением — пустой массив. - Добавляйте в массив оценок по переданному свойству новый элемент, который был получен аргументом метода.
- Метод
getAverageBySubject
, который будет возвращать среднюю оценку по одному предмету.- Проверьте наличие предмета среди оценок. Если предмет отсутствует, сразу возвращайте ноль.
- С помощью
reduce
посчитайте сумму оценок по одному предмету. - Возвращайте результат деления суммы оценок на их количество.
- Метод
getAverage
, который будет возвращать общую среднюю оценку по всем предметам.- Используйте метод
Object.keys
для получения всех названий предметов. - С помощью метода
reduce
или использования цикла перебирайте все предметы. Для каждого считайте среднюю оценку с помощью методаgetAverageBySubject
и суммируйте полученные значения. - Возвращайте результат деления суммы средних оценок на количество предметов.
- Используйте метод
Для решения задания нужно придумать структуру данных для хранения оценок по предметам. Это представляет наибольшую сложность. Работать должно, как в примере:
class Student {
// ваш код
}
const student = new Student("Олег Никифоров");
student.addMark(5, "химия");
student.addMark(5, "химия");
student.addMark(5, "физика");
student.addMark(4, "физика");
student.addMark(6, "физика"); // Оценка не добавится, так как больше 5
student.getAverageBySubject("физика"); // Средний балл по предмету физика 4.5
student.getAverageBySubject("биология"); // Вернёт 0, так как по такому предмету нет никаких оценок.
student.getAverage(); // Средний балл по всем предметам 4.75
- Реализованы все методы, в каждом из которых приведены примеры работы исключительных случаев: неверный формат оценки, несуществующий предмет и т. д.
- Возможно добавление оценки по любому предмету.
- Все тесты успешно выполняются.
- Соблюдается кодстайл.
- Решение загружено в форкнутый репозиторий GitHub.
- Решение опубликовано в GitHub Pages.
- Откройте файл
task.js
в вашем редакторе кода и выполните задание. - Проверьте соблюдение кодстайла. Форматируйте ваш код через форматтер https://codebeautify.org/jsviewer.
- Добавьте файл
task.js
в индексgit
с помощью командыgit add %file-path%
, где%file-path%
— путь до целевого файлаgit add ./5.classes/task.js
. - Сделайте коммит, используя команду
git commit -m '%comment%'
, где%comment%
— это произвольный комментарий к вашему коммитуgit commit -m 'Пятое задание полностью готово'
. - Опубликуйте код в репозиторий
homeworks
с помощью командыgit push -u origin main
. - На проверку пришлите 2 ссылки. На файл с решением (
task.js
) и на страницу GitHub Pages — страницу с автотестами:https://%USERNAME%.github.io/bjs-2-homeworks/5.classes
.
Никакие файлы прикреплять не нужно.
Все задачи обязательны к выполнению для получения зачёта. Можете прислать на проверку как каждую задачу по отдельности, так и все задачи вместе. Во время проверки по частям у вашей домашней работы будет статус «На доработке».
Любые вопросы по решению задач задавайте в чате учебной группы.