Menu
Coddy logo textTech

Система выдачи книг

Часть раздела Объектно-ориентированное программирование путешествия по GO на Coddy. Урок 100 из 107.

challenge icon

Задание

Легко

Давайте создадим систему выдачи книг для нашего проекта управления библиотекой! Вы создадите структуру Library, которая управляет коллекциями книг и пользователей, с методами для обработки операций выдачи и возврата — вместе с соответствующей валидацией.

Вы организуете свой код в четырех файлах:

  • book.go: Ваша структура Book из предыдущего урока с полями ID, Title, Author, ISBN и Available. Включите конструктор NewBook, который инициализирует книги как доступные.
  • user.go: Ваша структура User с полями ID, Name, Email и BorrowedBooks (срез ID книг). Включите конструктор NewUser, который инициализирует пользователей с пустым списком заимствованных книг.
  • library.go: Создайте структуру Library, которая хранит книги и пользователей в картах (ключами являются их ID). Создайте следующие компоненты:
    • Конструктор NewLibrary, который инициализирует пустые карты для книг и пользователей
    • Метод AddBook, который добавляет книгу в библиотеку
    • Метод AddUser, который добавляет пользователя в библиотеку
    • Метод Borrow, который принимает ID пользователя и ID книги, проверяет операцию, помечает книгу как недоступную, добавляет ID книги в список заимствованных книг пользователя и возвращает ошибку, если что-то пошло не так
    • Метод Return, который выполняет процесс, обратный выдаче — помечает книгу как доступную и удаляет ее из списка заимствованных книг пользователя

    Ваш метод Borrow должен возвращать следующие ошибки:

    • "user not found", если ID пользователя не существует
    • "book not found", если ID книги не существует
    • "book not available", если книга уже выдана

    Ваш метод Return должен возвращать следующие ошибки:

    • "user not found", если ID пользователя не существует
    • "book not found", если ID книги не существует
    • "book not borrowed", если книга уже доступна
  • main.go: Объедините все вместе, создав библиотеку, добавив книги и пользователей, а затем обработав операции выдачи/возврата.

    Считайте количество книг, затем для каждой книги считайте ее ID, название, автора и ISBN. Далее считайте количество пользователей, и для каждого пользователя считайте его ID, имя и email. Затем считайте количество операций, где каждая операция представляет собой либо borrow [userID] [bookID], либо return [userID] [bookID].

    Для каждой операции выведите либо OK в случае успеха, либо Error: [message] в случае неудачи.

Будут предоставлены следующие входные данные:

  • Количество книг, затем ID каждой книги, название, автор, ISBN (каждое на отдельной строке)
  • Количество пользователей, затем ID каждого пользователя, имя, email (каждое на отдельной строке)
  • Количество операций, затем каждая операция на отдельной строке

Например, при вводе:

2
B001
The Go Programming Language
Alan Donovan
978-0134190440
B002
Clean Code
Robert Martin
978-0132350884
1
U001
Alice Smith
alice@library.com
4
borrow U001 B001
borrow U001 B001
return U001 B001
borrow U002 B001

Ваш вывод должен быть:

OK
Error: book not available
OK
Error: user not found

И при вводе:

1
B100
Design Patterns
Gang of Four
978-0201633610
2
U001
Bob Jones
bob@email.com
U002
Carol White
carol@email.com
3
borrow U001 B100
borrow U002 B100
return U001 B100

Ваш вывод должен быть:

OK
Error: book not available
OK

И при вводе:

1
B001
Go in Action
William Kennedy
978-1617291784
1
U001
Dave Miller
dave@test.com
2
return U001 B001
borrow U001 B999

Ваш вывод должен быть:

Error: book not borrowed
Error: book not found

Обратите внимание, как Library выступает в роли центрального координатора — она проверяет все операции перед изменением состояния, гарантируя синхронизацию данных о книгах и пользователях. Использование получателей-указателей (pointer receivers) позволяет вашим методам изменять фактические данные, хранящиеся в картах!

Попробуйте сами

package main

import (
	"bufio"
	"fmt"
	"os"
	"strings"
)

func main() {
	reader := bufio.NewReader(os.Stdin)

	// Считать количество книг
	var numBooks int
	fmt.Scanln(&numBooks)

	// TODO: Создать новую библиотеку

	// TODO: Считать данные каждой книги (ID, Название, Автор, ISBN на отдельных строках)
	// и добавить их в библиотеку
	for i := 0; i < numBooks; i++ {
		id, _ := reader.ReadString('\n')
		id = strings.TrimSpace(id)
		title, _ := reader.ReadString('\n')
		title = strings.TrimSpace(title)
		author, _ := reader.ReadString('\n')
		author = strings.TrimSpace(author)
		isbn, _ := reader.ReadString('\n')
		isbn = strings.TrimSpace(isbn)

		// TODO: Создать книгу и добавить в библиотеку
	}

	// Считать количество пользователей
	var numUsers int
	fmt.Scanln(&numUsers)

	// TODO: Считать данные каждого пользователя (ID, Имя, Email на отдельных строках)
	// и добавить их в библиотеку
	for i := 0; i < numUsers; i++ {
		id, _ := reader.ReadString('\n')
		id = strings.TrimSpace(id)
		name, _ := reader.ReadString('\n')
		name = strings.TrimSpace(name)
		email, _ := reader.ReadString('\n')
		email = strings.TrimSpace(email)

		// TODO: Создать пользователя и добавить в библиотеку
	}

	// Считать количество операций
	var numOps int
	fmt.Scanln(&numOps)

	// TODO: Обработать каждую операцию
	// Формат: "borrow [userID] [bookID]" или "return [userID] [bookID]"
	for i := 0; i < numOps; i++ {
		line, _ := reader.ReadString('\n')
		line = strings.TrimSpace(line)
		parts := strings.Split(line, " ")

		// TODO: Разобрать операцию и вызвать соответствующий метод
		// Вывести "OK" в случае успеха или "Error: [message]" в случае ошибки
	}
}

Все уроки раздела Объектно-ориентированное программирование

Потренируйтесь самостоятельно: Онлайн-компилятор Go