Creator prompt
The idea behind this presentation
DESIGN & RULES
Create a 16:9 presentation of 26 cards (22 main cards followed by 4 appendix cards) for a software engineering competition jury made of engineers and instructors. Language: English. Tone: confident, precise, technical but easy to follow.
Visual style: dark, modern "engineering blueprint" look. Deep navy or charcoal background, white text, ONE accent color (teal or amber) used consistently, clean sans-serif headings, monospace font only for code and identifiers. No stock photos of people. No AI-generated images that contain text or fake diagrams. Use abstract geometric shapes, icons and Gamma's native layouts (boxes, columns, tables, timelines, arrows) to build every diagram.
Layout rules: one idea per card. At most 5 short bullets per card, each under 14 words. Prefer tables, flows, comparisons and big numbers over paragraphs. Keep the layout consistent across cards and add small slide numbers. Do not add speaker notes.
Accuracy rules (very important): use ONLY the facts and numbers written in this brief. Do not invent statistics, dates, names, logos, awards, user counts or performance claims. If something is not in the brief, leave it out. Keep technical identifiers exactly as written (Container, ILibraryRepository, SqliteRepository, etc.). Do not invent presenter or team names; leave a small empty subtitle line on the title card.
CARD CONTENT (one block per card; "---" separates cards)
Card 1 - Title
Titans: Library Management System
Subtitle: A custom C++17 container, a layered application built on it, and SQLite persistence
(small empty line for presenter and team names)
---
Card 2 - The challenge
Part 1: build a generic container from scratch
- Insert at the beginning, the end and a specific position
- Remove by value or by position; search by value
- Sorting algorithms and iterators: begin, end, next, prev
Part 2: use it in a real application, a Library Management System
- Catalog, add and remove books, search, borrow, sort, statistics
Goal: combine C++, OOP, data structures, databases and design patterns
---
Card 3 - Our answer in one slide
Three columns:
1. Custom Container: doubly linked list, bidirectional iterators, stable merge sort
2. Library application: layered design, interchangeable search and sort strategies
3. SQLite persistence: data survives restarts; rules enforced in code and in the database
Big numbers across the bottom: 189 test cases | 209,475 assertions | 0 failures
---
Card 4 - Every requirement, mapped to code
Two-column table.
Container requirement -> where it lives
- Insert at beginning / end / position -> push_front, push_back, insert
- Remove by value / by position -> remove_value, remove_at
- Search by value -> find, find_if
- Sorting algorithms -> sort (merge sort), insertion_sort
- Iterators -> begin, end, next, prev and range-for
Application feature -> where it lives
- Book catalog (title, author, ISBN, genre, availability) -> Book
- Add and remove books -> add_book, remove_book
- Search by title, author, ISBN, genre -> search strategies
- Borrow and return -> borrow_book, return_book
- Sort by title, author, genre -> sort strategies
- Statistics: total, available, borrowed -> total_books, available_books, borrowed_books
Footer: the README traces each row to its code and tests
---
Card 5 - Architecture: layers
Draw stacked boxes, top to bottom:
Console UI (ConsoleApp, InputReader, Table)
-> LibraryService (Facade)
-> three boxes side by side: Strategies | Container<T> | Domain (Book, Member)
-> ILibraryRepository (interface)
-> two boxes: SqliteRepository | NullRepository
Caption: each layer talks only to the one below; storage is replaceable
---
Card 6 - The Container: a doubly linked list
Why a linked list:
- Push at both ends in O(1)
- Insert and remove by relinking, no shifting of elements
- Trade-off: access by position is O(n)
Table: push_front, push_back = O(1) | insert, remove_at, remove_value, at, find = O(n) | sort (merge) = O(n log n) | insertion_sort = O(n^2), O(n) if already sorted
Footnote: Rule of Five implemented: copy, move and destructor, no leaks
---
Card 7 - Iterators: begin, end, next, prev
- Bidirectional: move forward and backward
- Works with range-for and standard algorithms (std::find, std::accumulate, std::distance)
- Const and mutable iterators come from one template
- The iterator stores a pointer to its container, so --end() can reach the last element
- Misuse throws std::out_of_range instead of undefined behavior
Code snippet: for (const auto& book : service.books()) { ... }
---
Card 8 - Sorting: merge sort that relinks nodes
- No element is copied or moved; only pointers change
- Stable: equal keys keep their previous order
- Example: sort by title, then by genre; inside each genre, titles stay alphabetical
Measured: 1,000 random numbers need 8,708 comparisons (upper bound 10,000)
Measured: insertion sort on 1,000 already-sorted numbers needs 999 comparisons
---
Card 9 - Domain rules live in the domain
Book:
- The ISBN is the identity; hyphens and spaces are removed; 10 or 13 characters
- Title, author and genre are never blank
- No default constructor, so an invalid Book cannot exist
- A borrowed book cannot be borrowed again
Member:
- At most 5 books, no duplicates
- Stores ISBNs, not copies of books: one source of truth
---
Card 10 - Design patterns, each with a job
Table with three columns (Pattern | Job | Where):
- Iterator | walk the container without exposing nodes | Container iterators
- Strategy | swap sort and search criteria | TitleSort, AuthorSort, GenreSort; TitleSearch, AuthorSearch, IsbnSearch, GenreSearch
- Factory | turn "title" into the right strategy | SortStrategyFactory, SearchStrategyFactory
- Facade | one entry point for the whole library | LibraryService
- Repository | hide how data is stored | ILibraryRepository
- Null Object | run without a database in memory and in tests | NullRepository
- Dispatch table | menu is a list of label + function | ConsoleApp
---
Card 11 - Search that behaves
- Title and author: case-insensitive substring match
- Genre: exact match, so "fiction" does not return "Non-Fiction"
- ISBN: exact match after normalization; hyphens allowed
- Arabic text works (UTF-8)
- Search returns copies, so results can never modify the catalog
---
Card 12 - Correctness: rules that are always true
Four invariants:
- I1: ISBNs are unique and member ids are unique
- I2: a book is borrowed if and only if exactly one member holds it
- I3: every borrowed ISBN exists in the catalog
- I4: no member holds more than 5 books
Strong exception guarantee: a failed operation changes nothing
---
Card 13 - Write-ahead: database first, memory second
Flow with three boxes and arrows: Validate -> Write to the database -> Update memory
- If the database write fails, memory is untouched
- Documented gap: std::bad_alloc after a successful write (extremely rare)
---
Card 14 - Persistence with SQLite
Small diagram: books (1) --- (many) loans (many) --- (1) members
Three rules:
- Availability is derived from open loans, never stored
- A partial unique index allows only one open loan per book
- Every value is a bound parameter, so SQL injection is impossible
SQLite is bundled as a single source file: nothing to install
---
Card 15 - Safe restart
- At start-up the data is rebuilt through the same public API: add_member, add_book, borrow_book
- Every rule is checked again on load
- A hand-edited or corrupt database gives a clear error, not a broken state
- The sort order is not persisted
---
Card 16 - Console application
- Menu with 10 options: list, add, remove, search, borrow, return, sort, statistics, members, sample data
- /cancel aborts any prompt without changing data
- End of input exits cleanly (Ctrl+D on Linux and macOS, Ctrl+Z then Enter on Windows)
- Fuzz-tested with 2,000 random input lines
- Tables stay aligned with Arabic text
- Options: --db <file> or --db :memory:
---
Card 17 - Quality evidence
Big numbers: 189 test cases | 209,475 assertions | 0 failures
- Randomized stress tests and fuzz tests with fixed seeds
- AddressSanitizer and UBSan clean (Linux, gcc 13)
- Independent review injected 6 deliberate bugs: all 6 were caught by the tests
- CI workflow for Ubuntu, Windows and macOS
---
Card 18 - Performance, honestly
Container vs std::list (Release build, MSVC, Windows 11; numbers from docs/BENCHMARKS.md)
- Push, iterate and find: comparable
- Sort 100,000 random numbers: Container 11.4 ms, std::list 8.4 ms (std::list::sort is faster)
- Insertion sort on 100,000 already-sorted numbers: 0.367 ms (the O(n) best case)
Footer: timings depend on the machine; full tables in docs/BENCHMARKS.md
---
Card 19 - Live demo (section divider)
Title: Live demo
Table of steps (Step | What it proves):
1. Load sample data | demo data, safe to run twice
2. List books | aligned table, UTF-8
3. Search by title, genre and Arabic | Strategy pattern, genre exactness
4. Borrow a book, then borrow it again | domain rule, clear error message
5. Statistics | derived counts
6. Sort by title, descending, insertion sort | stable sorting through the Facade
7. Return a book, remove a book with confirmation | write-ahead flow
8. Restart the program | data persisted in SQLite
---
Card 20 - Limits and next steps
Honest limits:
- Not designed for several instances on the same database file; the view can be outdated, the data stays correct
- Sort order is not persisted
- Single-threaded
- Case-insensitive matching is ASCII only; Arabic compares by raw bytes
- No due dates or fines; ISBN checksum is not validated
Next steps: hash index for lookups, due dates and fines, loan history screen
---
Card 21 - Key takeaways
- C++ done properly: templates, RAII, Rule of Five, iterators
- Patterns used because each solves a real problem
- Data structures with complexity we measured
- Rules enforced in the domain and again in the database
- Tests that catch real bugs
---
Card 22 - Thank you
Questions?
https://github.com/ZOZ646/Library-Management-System
---
Card 23 - Appendix A: Complexity
Two tables.
Container: push_front / push_back O(1) | insert, remove_at, remove_value, at, find O(n) | sort O(n log n) | insertion_sort O(n^2), O(n) if sorted
LibraryService (b = books, m = members): total_books O(1) | available_books, borrowed_books O(b) | add_book, remove_book O(b) | borrow_book O(b + m) | return_book O(b + m) | search O(b) | sort O(n log n) merge, O(n^2) insertion
Footnote: database write cost not included
---
Card 24 - Appendix B: Anticipated questions
- Why a linked list? Cheap insertion and removal; the task asks for a custom container with iterators.
- Why merge sort? O(n log n) without random access; relinks nodes; stable.
- Why is availability not stored? It is derived from open loans: one source of truth.
- How is SQL injection prevented? Bound parameters, tested with a DROP TABLE input.
- What if the database fails during a borrow? Write-ahead: memory is untouched and the user sees an error.
- Why no hash index? Lookups are simple scans at library scale; a hash index is the first improvement.
---
Card 25 - Appendix C: Database schema
Show as a code block:
books(seq, isbn UNIQUE, title, author, genre)
members(seq, id UNIQUE, name)
loans(seq, book_isbn -> books, member_id -> members, borrowed_at, returned_at)
CREATE UNIQUE INDEX one_open_loan_per_book ON loans(book_isbn) WHERE returned_at IS NULL;
Note: closed loans are kept as history
---
Card 26 - Appendix D: Project structure
core/ Container (header-only) | domain/ Book, Member | service/ LibraryService, strategies | repository/ interface, SQLite, Null | ui/ console app | tests/ 18 test files | docs/ architecture, decisions, benchmarks, demo script | bench/ container benchmark | third_party/ SQLite, doctest | .github/ CI workflow