app.ts 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. import {Book, Librarian, Logger as DamageLogger, Magazine} from './interfaces';
  2. import {Category} from './enums';
  3. import {ReferenceItem, UniversityLibrarian} from './classes';
  4. import {
  5. CalculateLateFees as CalcFee,
  6. MaxBooksAllowed,
  7. Purge
  8. } from './lib/utilityfunctions';
  9. import refBook from './encyclopedia';
  10. import {Books, LogAndReturn} from './generics';
  11. import Shelf from "./shelf";
  12. export function GetAllBooks(): Book[] {
  13. const books = [
  14. {
  15. author: 'James Joyce',
  16. available: true,
  17. category: Category.Fiction,
  18. id: 1,
  19. title: 'Ulysses',
  20. },
  21. {
  22. author: 'Ernest Hemingway',
  23. available: false,
  24. category: Category.Fiction,
  25. id: 2,
  26. title: 'A farewall to arms',
  27. },
  28. {
  29. author: 'Maya Angelou',
  30. available: true,
  31. category: Category.Poetry,
  32. id: 3,
  33. title: 'I know why the caged bird sings',
  34. },
  35. {
  36. author: 'Herman Melville',
  37. available: true,
  38. category: Category.Fiction,
  39. id: 4,
  40. title: 'Moby Dick',
  41. }
  42. ];
  43. return books;
  44. }
  45. export function LogFirstAvailable(books = GetAllBooks()): void {
  46. const numberOfBooks: number = books.length;
  47. let firstAvailable: string = '';
  48. for (let currentBook of books) {
  49. if (currentBook.available) {
  50. firstAvailable = currentBook.title;
  51. break;
  52. }
  53. }
  54. console.log(`Total number of books: ${numberOfBooks}.`);
  55. console.log(`First available: ${firstAvailable}.`);
  56. }
  57. export function CheckoutBooks(customer: string, ...bookIds: number[]): string[] {
  58. console.log(`Checking out books for ${customer}.`);
  59. let booksCheckedOut: string[] = [];
  60. for (let id of bookIds) {
  61. let book = GetBookById(id);
  62. if (book.available) {
  63. booksCheckedOut.push(book.title);
  64. }
  65. }
  66. return booksCheckedOut;
  67. }
  68. export function CreateCustomer(name: string, age?: number, city?: string) {
  69. console.log(`Name: ${name}.`);
  70. if (age) {
  71. console.log(`Age: ${age}.`);
  72. }
  73. if (city) {
  74. console.log(`City: ${city}.`);
  75. }
  76. }
  77. export function CreateCustomerId(chars: string, nums: number): string {
  78. return chars + nums;
  79. }
  80. export function GetBookTitlesByCategory(categoryFilter: Category = Category.Fiction): Array<string> {
  81. console.log(`Getting books in category: ${Category[categoryFilter]}.`);
  82. const allBooks = GetAllBooks();
  83. const filteredTitles: string[] = [];
  84. for (let currentBook of allBooks) {
  85. if (currentBook.category === categoryFilter) {
  86. filteredTitles.push(currentBook.title);
  87. }
  88. }
  89. return filteredTitles;
  90. }
  91. export function GetBookById(id: number): Book {
  92. const allBooks = GetAllBooks();
  93. return allBooks.filter(book => book.id === id)[0];
  94. }
  95. export function LogBookTitles(titles: string[]): void {
  96. for (let title of titles) {
  97. console.log(title);
  98. }
  99. }
  100. // Note: no implementation.
  101. export function GetTitles(author: string): string[];
  102. export function GetTitles(available: boolean): string[];
  103. // Now an implementation:
  104. export function GetTitles(bookProperty: any): string[] {
  105. const allBooks = GetAllBooks();
  106. const foundTitles: Array<string> = [];
  107. if (typeof bookProperty == 'string') {
  108. // get books by author, add to foundTitles
  109. for (let book of allBooks) {
  110. if (book.author === bookProperty) {
  111. foundTitles.push(book.title);
  112. }
  113. }
  114. }
  115. else if (typeof bookProperty === 'boolean') {
  116. // get available books, add to foundTitles
  117. for (let book of allBooks) {
  118. if (book.available === bookProperty) {
  119. foundTitles.push(book.title);
  120. }
  121. }
  122. }
  123. else {
  124. throw new Error('Invalid property type: ' + typeof bookProperty);
  125. }
  126. return foundTitles;
  127. }
  128. export function PrintBook(book: Book): void {
  129. console.log(`${book.title} by ${book.author}.`);
  130. }
  131. //******************************************************************************
  132. function bookDemo() {
  133. let myBook: Book = {
  134. author: 'Jane Austen',
  135. available: true,
  136. category: Category.Fiction,
  137. // copies: 3,
  138. id: 5,
  139. pages: 250,
  140. title: 'Pride and prejudice',
  141. // year: '1813',
  142. markDamaged: reason => console.log(`Damaged: ${reason}.`),
  143. };
  144. PrintBook(myBook);
  145. myBook.markDamaged!('Torn back cover');
  146. let logDamage: DamageLogger = reason => console.log(`Damage reported: ${reason}.`);
  147. logDamage('Coffee stains');
  148. }
  149. function classDemo() {
  150. let favoriteLibrarian: Librarian = new UniversityLibrarian();
  151. favoriteLibrarian.name = 'Sharon';
  152. favoriteLibrarian.assistCustomer('Lynda');
  153. // let ref: ReferenceItem = new ReferenceItem('Facts and Figures', 2016);
  154. // ref.publisher = 'Random Data publisher';
  155. // ref.printItem();
  156. // console.log(ref.publisher);
  157. let Newspaper = class extends ReferenceItem {
  158. printCitation(): void {
  159. console.log(`Newspaper: ${this.title}.`);
  160. }
  161. };
  162. let myPaper = new Newspaper('The gazette', 2016);
  163. myPaper.printCitation();
  164. class Novel extends class { title: string } {
  165. mainCharacter: string;
  166. }
  167. let favoriteNovel = new Novel();
  168. favoriteNovel.mainCharacter = 'Hero';
  169. favoriteNovel.title = 'Plot';
  170. console.log(favoriteNovel);
  171. }
  172. function importDemo() {
  173. let fee = CalcFee(10);
  174. let max = MaxBooksAllowed(12);
  175. console.log(`Fee: ${fee}, max books: ${max}.`);
  176. let ref = new refBook('Fact Book', 2016, 1);
  177. console.log(ref);
  178. }
  179. function genericFunctionDemo() {
  180. LogAndReturn(false);
  181. LogAndReturn(42);
  182. LogAndReturn({ a: []});
  183. interface Magazine { title: string }
  184. let someString: string = LogAndReturn<string>('log this');
  185. console.log('Returned: ', someString);
  186. let newMag: Magazine = { title: 'Web dev monthly' };
  187. let someMag: Magazine = LogAndReturn<Magazine>(newMag);
  188. console.log('Returned mag', someMag);
  189. }
  190. function getBooksInventory(): Books {
  191. return [
  192. {
  193. author: 'K & R',
  194. available: true,
  195. category: Category.Software,
  196. id: 10,
  197. title: 'The C programming language',
  198. },
  199. {
  200. author: 'Steve McConnell',
  201. available: true,
  202. category: Category.Software,
  203. id: 11,
  204. title: 'Code Complete',
  205. },
  206. {
  207. author: 'A. B.',
  208. available: true,
  209. category: Category.Software,
  210. id: 12,
  211. title: '8-Bit graphics with Cobol',
  212. },
  213. {
  214. author: 'C. D.',
  215. available: true,
  216. category: Category.Software,
  217. id: 13,
  218. title: 'Cool autoexec.bat scripts',
  219. }
  220. ];
  221. }
  222. function getMagazinesInventory(): Array<Magazine> {
  223. return [
  224. {
  225. title: 'Programming Language Monthly',
  226. publisher: 'Code Mags',
  227. },
  228. {
  229. publisher: 'College Press',
  230. title: 'Literary Fiction Quarterly',
  231. },
  232. {
  233. publisher: 'GSU',
  234. title: 'Five Points',
  235. }
  236. ];
  237. }
  238. function purgedemo() {
  239. let inventory: Array<Book> = getBooksInventory();
  240. // Inventory is accepted because Books is an alias for Array<Book>, so the
  241. // signature actually matches.
  242. let purgedBooks: Books = Purge(inventory);
  243. // Note that purgedBooks uses the aliases type after the assignment.
  244. purgedBooks.forEach(book => console.log(book.title));
  245. let purgedNums: Array<number> = Purge<number>([1, 2, 3, 4]);
  246. console.log(purgedNums);
  247. }
  248. function genericClassDemo() {
  249. let bookShelf: Shelf<Book> = new Shelf<Book>();
  250. getBooksInventory().forEach(book => bookShelf.add(book));
  251. let firstBook: Book = bookShelf.getFirst();
  252. console.log(firstBook);
  253. let magazineShelf: Shelf<Magazine> = new Shelf<Magazine>();
  254. getMagazinesInventory().forEach(mag => magazineShelf.add(mag));
  255. let firstMagazine: Magazine = magazineShelf.getFirst();
  256. console.log(firstMagazine);
  257. // No longer works after constraining Shelf<T extends ShelfItem>.
  258. // let numberShelf: Shelf<number> = new Shelf<number>();
  259. // [5, 10, 15].forEach(num => numberShelf.add(num));
  260. // console.log(numberShelf);
  261. magazineShelf.printTitles();
  262. // Since bookShelf is Shelf<Book>, softwareBook is a Book.
  263. let softwareBook = bookShelf.find('Code Complete');
  264. console.log(`${softwareBook.title} (${softwareBook.author})`);
  265. }
  266. false && bookDemo();
  267. false && classDemo();
  268. false && importDemo();
  269. false && genericFunctionDemo();
  270. false && purgedemo();
  271. genericClassDemo();