From b0b1c955c37556a0f31c90298be49880a9bd5742 Mon Sep 17 00:00:00 2001 From: sue-t-boyd Date: Sat, 9 Mar 2024 13:17:41 -0800 Subject: [PATCH 01/10] Faster author2 search --- bookworm/search_wrapper.py | 43 +++++++++---------- bookworm/tests/test_search.py | 56 ++++++++++++------------- bookworm/tests/test_search_wrapper.py | 59 ++++++++++----------------- 3 files changed, 69 insertions(+), 89 deletions(-) diff --git a/bookworm/search_wrapper.py b/bookworm/search_wrapper.py index d8386d4..1698742 100644 --- a/bookworm/search_wrapper.py +++ b/bookworm/search_wrapper.py @@ -14,7 +14,7 @@ filter_ratings(results, min_ave_ratings, min_num_rating) Filters serach results by user ratings prefrences. -select_search(df, search_mode, search_value, min_ave_rating, +select_search(search_mode, search_value, min_ave_rating, min_num_ratings, num_book=10) Selects and implements search based on user search mode. @@ -53,6 +53,19 @@ def assemble_data(path1, path2, path3, path4): df = pd.concat([df1, df2, df3, df4], ignore_index=True) return df +def assemble_embeddings_data(): + """ + Functions that assembles the data with embeddings + """ + # Create file paths + + path_root = "data/complete_w_embeddings/complete_w_embeddings.csv" + path1 = path_root + "_part_1.csv" + path2 = path_root + "_part_2.csv" + path3 = path_root + "_part_3.csv" + path4 = path_root + "_part_4.csv" + return assemble_data(path1, path2, path3, path4) + # Filter def filter_ratings(results, min_ave_ratings, min_num_rating): @@ -87,13 +100,11 @@ def filter_ratings(results, min_ave_ratings, min_num_rating): results_filtered = subset_df return results_filtered -def select_search(df, search_mode, search_value, num_books=10): +def select_search(search_mode, search_value, num_books=10): """ Selects and implements search based on user search mode. Parameters: - df: pandas.DataFrame - The dataframe to perform the search on. search_mode: str The mode of search ('Author2', 'Title', 'Plot', 'Genre'). search_value: str @@ -103,16 +114,19 @@ def select_search(df, search_mode, search_value, num_books=10): Returns: pandas.DataFrame - A dataframe of filtered search results. + A dataframe of search results. """ if search_mode == "Author2": + df = pd.read_csv("data/complete_w_ratings.csv") results = search.author2_search(df, search_value, num_books=max(num_books * 2, 20)) elif search_mode == "Title": + df = assemble_embeddings_data() results = search.semantic_search(df, search_value, ["book_title"], num_books=max(num_books * 2, 20)) elif search_mode == "Plot": + df = assemble_embeddings_data() results = search.plot_semantic_search(df, search_value, num_books=max(num_books * 2, 20)) elif search_mode == "Genre": @@ -122,7 +136,9 @@ def select_search(df, search_mode, search_value, num_books=10): genre_df = pd.read_csv("data/genre.csv") results = search.genre_search(genre_df, search_value, num_books=max(num_books * 2, 20)) + else: # Default to keyword search on all columns for other modes + df = pd.read_csv("data/complete_w_ratings.csv") results = search.keyword_search(df, search_value, num_books=max(num_books * 2, 20)) @@ -145,24 +161,9 @@ def search_wrapper(search_mode, search_value, min_ave_rating, Returns A dataframe of filtered search results. """ - # assemble data - try: - path_root = "bookworm/data/complete_w_embeddings/complete_w_embeddings.csv" - path1 = path_root + "_part_1.csv" - path2 = path_root + "_part_2.csv" - path3 = path_root + "_part_3.csv" - path4 = path_root + "_part_4.csv" - df = assemble_data(path1, path2, path3, path4) - except FileNotFoundError: - path_root = "data/complete_w_embeddings/complete_w_embeddings.csv" - path1 = path_root + "_part_1.csv" - path2 = path_root + "_part_2.csv" - path3 = path_root + "_part_3.csv" - path4 = path_root + "_part_4.csv" - df = assemble_data(path1, path2, path3, path4) # search - results = select_search(df, search_mode, search_value, num_books) + results = select_search(search_mode, search_value, num_books) #filter results_filtered = filter_ratings(results, min_ave_rating, min_num_ratings) diff --git a/bookworm/tests/test_search.py b/bookworm/tests/test_search.py index 4086259..10a5c02 100644 --- a/bookworm/tests/test_search.py +++ b/bookworm/tests/test_search.py @@ -77,15 +77,11 @@ def setUp(self): """ Creates and loads teating data. """ - try: - f = "data/test_data/test_data_w_embeddings.csv" - self.test_dat = pd.read_csv(f) - except ImportError: - f = "bookworm/data/test_data/test_data_w_embeddings.csv" - self.test_dat = pd.read_csv(f) - - - self.test_dat_filled = HelperFunctions.fill_na(self.test_dat) + f_embed = "data/test_data/test_data_w_embeddings.csv" + self.test_dat_e = pd.read_csv(f_embed) + f_ratings = "data/test_data/test_data.csv" + self.test_dat_r = pd.read_csv(f_ratings) + self.test_dat_filled = HelperFunctions.fill_na(self.test_dat_e) unfilled_data = {'author': ['Author1', None, 'Author3'], 'book_title': ['Book1', None, 'Book3'], @@ -116,7 +112,7 @@ def test_parse_genres_full(self): Using book-ID = 4081 from test_data, expected result is "Science Fiction, Speculative fiction". """ - df = self.test_dat + df = self.test_dat_e val_to_parse = df[df["book_id"] == 4081]["genre"][0] results = HelperFunctions.parse_genres(val_to_parse) expected = "Science Fiction, Speculative fiction" @@ -158,7 +154,7 @@ def test_query_to_index_smoke(self): """ query = "Book of Job" columns = ["book_title"] - index = HelperFunctions.query_to_index(self.test_dat, query, columns) + index = HelperFunctions.query_to_index(self.test_dat_e, query, columns) self.assertIsInstance(index, np.int64) @patch("search.HelperFunctions.fill_na") @@ -168,8 +164,8 @@ def test_query_to_index_calls_fill_na(self, mock_fill_na): """ mock_fill_na.return_value = self.test_dat_filled columns = ["book_title"] - HelperFunctions.query_to_index(self.test_dat, "dog", columns) - mock_fill_na.assert_called_once_with(self.test_dat) + HelperFunctions.query_to_index(self.test_dat_e, "dog", columns) + mock_fill_na.assert_called_once_with(self.test_dat_e) def test_query_exact(self): @@ -183,27 +179,27 @@ def test_query_exact(self): columns = ["book_title", "author", "genre"] for col in columns: for idx in [0, 10]: - query = self.test_dat[col][idx] + query = self.test_dat_e[col][idx] expected = idx - result = HelperFunctions.query_to_index(self.test_dat, + result = HelperFunctions.query_to_index(self.test_dat_e, query, [col]) self.assertEqual(result, expected) class TestSearch(unittest.TestCase): + """ Test cases for the Search Functions in Test Module """ + def setUp(self): """ - Creates and loads testing data. + Creates and loads teating data. """ - try: - f = "data/test_data/test_data_w_embeddings.csv" - self.test_dat = pd.read_csv(f) - except ImportError: - f = "bookworm/data/test_data/test_data_w_embeddings.csv" - self.test_dat = pd.read_csv(f) + f_embed = "data/test_data/test_data_w_embeddings.csv" + self.test_dat_e = pd.read_csv(f_embed) + f_ratings = "data/test_data/test_data.csv" + self.test_dat_r = pd.read_csv(f_ratings) def test_keyword_exact(self): @@ -215,8 +211,8 @@ def test_keyword_exact(self): we expect the first book returned to be the exact match. """ for idx in range(2): - query = self.test_dat["book_title"][idx] - books = search.keyword_search(self.test_dat, query, num_books=10) + query = self.test_dat_e["book_title"][idx] + books = search.keyword_search(self.test_dat_e, query, num_books=10) results = books.iloc[0]["book_title"] expected = query self.assertEqual(results, expected) @@ -233,8 +229,8 @@ def test_author2_search_exact(self): """ for idx in [0,3,4,5,7,8,9]: #exclude rows with nan author - query = self.test_dat["author"][idx] - books = search.author2_search(self.test_dat, query, num_books=10) + query = self.test_dat_r["author"][idx] + books = search.author2_search(self.test_dat_r, query, num_books=10) for idx2 in range(books.shape[0]): results = books.iloc[idx2]["author"] expected = query @@ -248,7 +244,7 @@ def test_author2_search_close(self): book return is by "J.R.R. Tolkien" as listed in test data. """ query = "JRR Tolkien" - books = search.author2_search(self.test_dat, query, num_books=10) + books = search.author2_search(self.test_dat_r, query, num_books=10) results = books.iloc[0]["author"] expected = "J. R. R. Tolkien" self.assertEqual(results, expected) @@ -259,7 +255,7 @@ def test_author2_search_nomatch(self): """ query = "gribnif blah blah blah" with self.assertRaises(ValueError): - search.author2_search(self.test_dat, query, num_books=10) + search.author2_search(self.test_dat_r, query, num_books=10) def test_plot_semantic(self): """ @@ -271,9 +267,9 @@ def test_plot_semantic(self): """ query = "A man paints a tree." - books = search.plot_semantic_search(self.test_dat, query, num_books=10) + books = search.plot_semantic_search(self.test_dat_e, query, num_books=10) results = books.iloc[0]["book_id"] - expected = self.test_dat.iloc[7]["book_id"] # 7 = idx for Leaf by Niggle + expected = self.test_dat_e.iloc[7]["book_id"] # 7 = idx for Leaf by Niggle # print(self.test_dat[self.test_dat["book_id"] == 18560]) self.assertEqual(results, expected) diff --git a/bookworm/tests/test_search_wrapper.py b/bookworm/tests/test_search_wrapper.py index e03eba1..2c2a7a5 100644 --- a/bookworm/tests/test_search_wrapper.py +++ b/bookworm/tests/test_search_wrapper.py @@ -5,8 +5,8 @@ This module contains unit tests for the search and filter functions implemented in the search_warpper.py module. -The tests are organized into four Test Classes each corresponding to a -function in the search modules to be tested. +The tests are organized into four Test Classes each corresponding to the +functions in search modules to be tested. Tests in Class TestFilter ========================== @@ -83,12 +83,11 @@ def setUp(self): """ Creates and loads testing data. """ - try: - f = "data/test_data/test_data_w_embeddings.csv" - self.test_dat = pd.read_csv(f) - except ImportError: - f = "bookworm/data/test_data/test_data_w_embeddings.csv" - self.test_dat = pd.read_csv(f) + f_embed = "data/test_data/test_data_w_embeddings.csv" + self.test_dat_e = pd.read_csv(f_embed) + f_ratings = "data/test_data/test_data.csv" + self.test_dat_r = pd.read_csv(f_ratings) + def test_filter_min_ave_ratings(self): """ @@ -97,9 +96,9 @@ def test_filter_min_ave_ratings(self): Using test data as input and setting average ratings filter to 6 should result in 2 entries remaining after filtering. """ - test_dat = self.test_dat - results = search_wrapper.filter_ratings(test_dat, 6, 0) - self.assertEqual(results.shape[0], 2) + for test_dat in [self.test_dat_e, self.test_dat_r]: + results = search_wrapper.filter_ratings(test_dat, 6, 0) + self.assertEqual(results.shape[0], 2) def test_filter_min_num_ratings(self): """ @@ -108,9 +107,9 @@ def test_filter_min_num_ratings(self): Using test dat as input and setting number of ratings filter to 6 should result in 1 entry remaining after filtering. """ - test_dat = self.test_dat - results = search_wrapper.filter_ratings(test_dat, 0, 6) - self.assertEqual(results.shape[0], 1) + for test_dat in [self.test_dat_e, self.test_dat_r]: + results = search_wrapper.filter_ratings(test_dat, 0, 6) + self.assertEqual(results.shape[0], 1) def test_filter_no_mins(self): """ @@ -120,9 +119,9 @@ def test_filter_no_mins(self): filter to zero should return data in same shape as original data. """ - test_dat = self.test_dat - results = search_wrapper.filter_ratings(test_dat, 0, 0) - self.assertEqual(results.shape[0], test_dat.shape[0]) + for test_dat in [self.test_dat_e, self.test_dat_r]: + results = search_wrapper.filter_ratings(test_dat, 0, 0) + self.assertEqual(results.shape[0], test_dat.shape[0]) def test_filter_missing_col1(self): """ @@ -147,27 +146,14 @@ def test_filter_missing_col2(self): class TestSelectSearch(unittest.TestCase): """Test cases for the filter_ratings function""" - - def setUp(self): - """ - Creates and loads testing data. - """ - try: - f = "data/test_data/test_data_w_embeddings.csv" - self.test_dat = pd.read_csv(f) - except ImportError: - f = "bookworm/data/test_data/test_data_w_embeddings.csv" - self.test_dat = pd.read_csv(f) - - @mock.patch("search.author2_search") def test_select_search_author2(self, mock_author2_search): """ Confirm correct search function called for search_mode Author2 """ - test_dat = self.test_dat + mock_author2_search.return_value = "Author2 search performed" - results = search_wrapper.select_search(test_dat, "Author2", + results = search_wrapper.select_search("Author2", "J. R. Tolkien") self.assertEqual(results, "Author2 search performed") @@ -176,9 +162,8 @@ def test_select_search_title(self, mock_semantic_search): """ Confirm correct search function called for search_mode Title """ - test_dat = self.test_dat mock_semantic_search.return_value = "Semantic search performed" - results = search_wrapper.select_search(test_dat, "Title", + results = search_wrapper.select_search("Title", "Wolves of the Calla") self.assertEqual(results, "Semantic search performed") @@ -187,9 +172,8 @@ def test_select_search_plot(self, mock_plot_semantic_search): """ Confirm correct search function called for search_mode Plot """ - test_dat = self.test_dat mock_plot_semantic_search.return_value = "Plot search performed" - results = search_wrapper.select_search(test_dat, "Plot", + results = search_wrapper.select_search("Plot", "J. R. Tolkien") self.assertEqual(results, "Plot search performed") @@ -210,9 +194,8 @@ def test_select_search_genre(self, mock_keyword_search): """ Confirm correct search function called for search_mode genre """ - test_dat = self.test_dat mock_keyword_search.return_value = "Genre search performed" - results = search_wrapper.select_search(test_dat, "Genre", + results = search_wrapper.select_search("Genre", "J. R. Tolkien") self.assertEqual(results, "Genre search performed") From 3d10c09cba14c42448f429e5d44c1617365a23ca Mon Sep 17 00:00:00 2001 From: sue-t-boyd Date: Sat, 9 Mar 2024 15:52:29 -0800 Subject: [PATCH 02/10] Add tests for genre search --- bookworm/data/test_data/test_genre.csv | 31 +++++++++++++ bookworm/search.py | 3 +- bookworm/tests/test_search.py | 60 ++++++++++++++++++++++---- 3 files changed, 83 insertions(+), 11 deletions(-) create mode 100644 bookworm/data/test_data/test_genre.csv diff --git a/bookworm/data/test_data/test_genre.csv b/bookworm/data/test_data/test_genre.csv new file mode 100644 index 0000000..c599ff0 --- /dev/null +++ b/bookworm/data/test_data/test_genre.csv @@ -0,0 +1,31 @@ +,Unnamed: 0,book_id,book_title,author,publication_date,genre,summary,ISBN,Image_URL,ISBN_new,isbn_13,Book-Rating,RatingCount,generic_genre +0,0,4081,Blade Runner 3: Replicant Night,K. W. Jeter,1996-10-01,Science Fiction," Living on Mars, Deckard is acting as a consultant to a movie crew filming the story of his Blade Runner days. He finds himself drawn into a mission on behalf of the replicants he was once assigned to kill. Meanwhile, the mystery surrounding the beginnings of the Tyrell Corporation is being dragged out into the light.",9780752808628,http://books.google.com/books/content?id=ccl_NwAACAAJ&printsec=frontcover&img=1&zoom=1&source=gbs_api,9780752808628,9780752808628,,,Science Fiction +1,0,4081,Blade Runner 3: Replicant Night,K. W. Jeter,1996-10-01,Speculative fiction," Living on Mars, Deckard is acting as a consultant to a movie crew filming the story of his Blade Runner days. He finds himself drawn into a mission on behalf of the replicants he was once assigned to kill. Meanwhile, the mystery surrounding the beginnings of the Tyrell Corporation is being dragged out into the light.",9780752808628,http://books.google.com/books/content?id=ccl_NwAACAAJ&printsec=frontcover&img=1&zoom=1&source=gbs_api,9780752808628,9780752808628,,,Science Fiction +2,4,4386,Book of Job,,,Religious text," The book of Job tells the story of an extremely righteous man named Job, who is very prosperous and has seven sons and three daughters. Constantly fearing that his sons may have sinned and ""cursed God in their hearts"", he habitually offers burnt offerings as a pardon for their sins. The ""sons of God"" and Satan (literally ""the Adversary"") present themselves to God, and God asks Satan his opinion on Job. Satan answers that Job is pious only because God has put a ""wall around"" him and ""blessed"" his favourite servant with prosperity, but if God were to stretch out his hand and strike everything that Job had, then he would surely curse God. God gives Satan permission to test Job's righteousness. All Job's possessions are destroyed: 500 yoke of oxen and 500 donkeys carried off by Sabeans; 7,000 sheep burned up by 'The fire of God which fell from the sky'; 3,000 camels stolen by the Chaldeans; and the house of the firstborn destroyed by a mighty wind, killing Job's ten children. Still Job does not curse God, but instead shaves his head, tears his clothes, and says, ""Naked I came out of my mother's womb, and naked shall I return: Lord has given, and Lord has taken away; blessed be the name of Lord."" As Job endures these calamities without reproaching God, Satan solicits permission to afflict his person as well, and God says, ""Behold, he is in your hand, but don't touch his life."" Satan, therefore, smites him with dreadful boils, and Job, seated in ashes, scrapes his skin with broken pottery. His wife prompts him to ""curse God, and die,"" but Job answers, ""You speak as one of the foolish speaks. Moreover, shall we receive good from God and shall not receive evil?"" Three friends of Job, Eliphaz the Temanite, Bildad the Shuhite and Zophar the Naamathite, come to console him. (A fourth, Elihu the Buzite (Heb: Alieua ben Barakal the Buzite), begins talking in Chapter 32 and plays a significant role in the dialogue, but his arrival is not described.) The friends spend seven days sitting on the ground with Job, without saying anything to him because they see that he is suffering and in much pain. Job at last breaks his silence and ""curses the day he was born."" God responds saying that there are so many things Job does not know about how this world was formed or how nature works, that Job should consider God as being greater than the thunderstorm and strong enough to pull in the leviathan with a fish-hook. God then rebukes the three friends and says, ""I am angry with you... you have not spoken of me what is right."" The story ends with Job restored to health, with a new family and twice as much livestock.",9780880992985,http://books.google.com/books/content?id=3cZO0cTOOTMC&printsec=frontcover&img=1&zoom=1&edge=curl&source=gbs_api,9780880992985,9780880992985,,,Other +3,8,6630,Chapterhouse Dune,Frank Herbert,1985-04,Science Fiction," The situation is desperate for the Bene Gesserit as they find themselves the targets of the Honored Matres, whose conquest of the Old Empire is almost complete. The Matres are seeking to assimilate the technology and developed methods of the Bene Gesserit and exterminate the Sisterhood itself. Now in command of the Bene Gesserit, Mother Superior Darwi Odrade continues to develop her drastic, secret plan to overcome the Honored Matres. The Bene Gesserit are also terraforming the planet Chapterhouse to accommodate the all-important sandworms, whose native planet Dune had been destroyed by the Matres. Sheeana, in charge of the project, expects sandworms to appear soon. The Honored Matres have also destroyed the entire Bene Tleilax civilization, with Tleilaxu Master Scytale the only one of his kind left alive. In Bene Gesserit captivity, Scytale possesses the Tleilaxu secret of ghola production, which he has reluctantly traded for the Sisterhood's protection. The first ghola produced is that of their recently-deceased military genius, Miles Teg. The Bene Gesserit have two other prisoners on Chapterhouse: the latest Duncan Idaho ghola, and former Honored Matre Murbella, whom they have accepted as a novice despite their suspicion that she intends to escape back to the Honored Matres. Lampadas, a center for Bene Gesserit education, has been destroyed by the Honored Matres. The planet's Chancellor, Reverend Mother Lucilla, manages to escape carrying the shared-minds of millions of Reverend Mothers. Lucilla is forced to land on Gammu where she seeks refuge with an underground group of Jews. The Rabbi gives Lucilla sanctuary, but to save his organization he must deliver her to the Matres. Before doing so, he reveals Rebecca, a ""wild"" Reverend Mother who has gained her Other Memory without Bene Gesserit training. Lucilla shares minds with Rebecca, who promises to take the memories of Lampadas safely back to the Sisterhood. Lucilla is then ""betrayed"", and taken before the Great Honored Matre Dama, who tries to persuade her to join the Honored Matres, preserving her life in exchange for Bene Gesserit secrets. Lucilla refuses, and Dama ultimately kills her. Back on Chapterhouse, Odrade confronts Duncan and forces him to admit that he is a Mentat, proving that he retains the memories of his many ghola lives. He does not reveal his mysterious visions of two people. Meanwhile, Murbella collapses under the pressure of Bene Gesserit training, giving in to ""word weapons"" that the Bene Gesserit had planted to undermine her earlier Honored Matre identity. Murbella realizes that she wants to be Bene Gesserit. Odrade believes that the Bene Gesserit made a mistake in fearing emotion, and that in order to evolve, the Bene Gesserit must learn to accept emotions. Odrade permits Duncan to watch Murbella undergo the spice agony, making him the first man ever to do so. Murbella survives the ordeal and becomes a Reverend Mother. Odrade then confronts Sheeana, discovering that Duncan and Sheeana have been allied together for some time. Sheeana does not reveal that they have been considering the option of reawakening Teg's memory through Imprinting, nor does Odrade discover that Sheeana has the keys to Duncan's no-ship prison. Odrade continues molding Scytale, with Sheeana showing him a baby sandworm, the Bene Gesserit's own long term supply of spice, and destroying Scytale's main bargaining card. Finally, Teg is awakened by Sheeana using imprinting techniques. Odrade appoints him again as Bashar of the military forces of the Sisterhood for the assault on the Honored Matres. Odrade next calls a meeting of all the Bene Gesserit, announcing her plan to attack the Honored Matres. She tells them that this attack will be led by Teg. She also announces candidates to succeed her as Mother Superior; she will share her memories with Murbella and Sheeana before she leaves. Odrade then goes to meet the Great Honored Matre. Under cover of Odrade's diplomacy, the Bene Gesserit forces under Teg attack Gammu with tremendous force. Teg uses his secret ability to see no-ships to secure control of the system. Survivors of the attack flee to Junction, and Teg follows them there and carries all with him. Victory for the Bene Gesserit seems inevitable. In the midst of this battle, the Jews (including Rebecca with her precious memories) take refuge with the Bene Gesserit fleet. Logno — chief advisor to Dama — assassinates Dama with poison and assumes control of the Honored Matres. Her first act surprises Odrade greatly. Too late Odrade and Teg realize they have fallen into a trap, and the Honored Matres use a mysterious weapon to turn defeat into victory, as well as capturing Odrade. Murbella saves as much of the Bene Gesserit force as she can and they begin to withdraw to Chapterhouse. Odrade, however, had planned for the possible failure of the Bene Gesserit attack and left Murbella instructions for a last desperate gamble. Murbella pilots a small craft down to the surface, announcing herself as an Honored Matre who, in the confusion, has managed to escape the Bene Gesserit with all their secrets. She arrives on the planet and is taken to the Great Honored Matre. Unable to control her anger, Logno attacks but is killed by Murbella. Awed by her physical prowess, the remaining Honored Matres are forced to accept her as their new leader. Odrade is also killed in the melee and Murbella shares memories with her, thereby also becoming Reverend Mother Superior. Murbella's ascension to leadership is not accepted as victory by all the Bene Gesserit. Some flee Chapterhouse, notably Sheeana, who has a vision of her own, and is joined by Duncan. The two escape in the giant no-ship, with Scytale, Teg and the Jews. Murbella recognizes their plan at the last minute, but is powerless to stop them. Watching this escape with interest are Daniel and Marty, the observers Duncan had been having visions of. The story ends on a cliffhanger with several questions left unanswered regarding the merging of the Honored Matres and Bene Gesserit, the fates of those on the escaped no-ship (including the role of Scytale, the development of Idaho and Teg, and the role of the Jews), the identity of the god-like characters in the book's final chapter and the ultimate mystery of what chased the Honored Matres back into the Old Empire.",9780441102679,http://books.google.com/books/content?id=ryot4Ag2GGQC&printsec=frontcover&img=1&zoom=1&edge=curl&source=gbs_api,9780441102679,9780441102679,7.916666666666667,24.0,Science Fiction +4,8,6630,Chapterhouse Dune,Frank Herbert,1985-04,Speculative fiction," The situation is desperate for the Bene Gesserit as they find themselves the targets of the Honored Matres, whose conquest of the Old Empire is almost complete. The Matres are seeking to assimilate the technology and developed methods of the Bene Gesserit and exterminate the Sisterhood itself. Now in command of the Bene Gesserit, Mother Superior Darwi Odrade continues to develop her drastic, secret plan to overcome the Honored Matres. The Bene Gesserit are also terraforming the planet Chapterhouse to accommodate the all-important sandworms, whose native planet Dune had been destroyed by the Matres. Sheeana, in charge of the project, expects sandworms to appear soon. The Honored Matres have also destroyed the entire Bene Tleilax civilization, with Tleilaxu Master Scytale the only one of his kind left alive. In Bene Gesserit captivity, Scytale possesses the Tleilaxu secret of ghola production, which he has reluctantly traded for the Sisterhood's protection. The first ghola produced is that of their recently-deceased military genius, Miles Teg. The Bene Gesserit have two other prisoners on Chapterhouse: the latest Duncan Idaho ghola, and former Honored Matre Murbella, whom they have accepted as a novice despite their suspicion that she intends to escape back to the Honored Matres. Lampadas, a center for Bene Gesserit education, has been destroyed by the Honored Matres. The planet's Chancellor, Reverend Mother Lucilla, manages to escape carrying the shared-minds of millions of Reverend Mothers. Lucilla is forced to land on Gammu where she seeks refuge with an underground group of Jews. The Rabbi gives Lucilla sanctuary, but to save his organization he must deliver her to the Matres. Before doing so, he reveals Rebecca, a ""wild"" Reverend Mother who has gained her Other Memory without Bene Gesserit training. Lucilla shares minds with Rebecca, who promises to take the memories of Lampadas safely back to the Sisterhood. Lucilla is then ""betrayed"", and taken before the Great Honored Matre Dama, who tries to persuade her to join the Honored Matres, preserving her life in exchange for Bene Gesserit secrets. Lucilla refuses, and Dama ultimately kills her. Back on Chapterhouse, Odrade confronts Duncan and forces him to admit that he is a Mentat, proving that he retains the memories of his many ghola lives. He does not reveal his mysterious visions of two people. Meanwhile, Murbella collapses under the pressure of Bene Gesserit training, giving in to ""word weapons"" that the Bene Gesserit had planted to undermine her earlier Honored Matre identity. Murbella realizes that she wants to be Bene Gesserit. Odrade believes that the Bene Gesserit made a mistake in fearing emotion, and that in order to evolve, the Bene Gesserit must learn to accept emotions. Odrade permits Duncan to watch Murbella undergo the spice agony, making him the first man ever to do so. Murbella survives the ordeal and becomes a Reverend Mother. Odrade then confronts Sheeana, discovering that Duncan and Sheeana have been allied together for some time. Sheeana does not reveal that they have been considering the option of reawakening Teg's memory through Imprinting, nor does Odrade discover that Sheeana has the keys to Duncan's no-ship prison. Odrade continues molding Scytale, with Sheeana showing him a baby sandworm, the Bene Gesserit's own long term supply of spice, and destroying Scytale's main bargaining card. Finally, Teg is awakened by Sheeana using imprinting techniques. Odrade appoints him again as Bashar of the military forces of the Sisterhood for the assault on the Honored Matres. Odrade next calls a meeting of all the Bene Gesserit, announcing her plan to attack the Honored Matres. She tells them that this attack will be led by Teg. She also announces candidates to succeed her as Mother Superior; she will share her memories with Murbella and Sheeana before she leaves. Odrade then goes to meet the Great Honored Matre. Under cover of Odrade's diplomacy, the Bene Gesserit forces under Teg attack Gammu with tremendous force. Teg uses his secret ability to see no-ships to secure control of the system. Survivors of the attack flee to Junction, and Teg follows them there and carries all with him. Victory for the Bene Gesserit seems inevitable. In the midst of this battle, the Jews (including Rebecca with her precious memories) take refuge with the Bene Gesserit fleet. Logno — chief advisor to Dama — assassinates Dama with poison and assumes control of the Honored Matres. Her first act surprises Odrade greatly. Too late Odrade and Teg realize they have fallen into a trap, and the Honored Matres use a mysterious weapon to turn defeat into victory, as well as capturing Odrade. Murbella saves as much of the Bene Gesserit force as she can and they begin to withdraw to Chapterhouse. Odrade, however, had planned for the possible failure of the Bene Gesserit attack and left Murbella instructions for a last desperate gamble. Murbella pilots a small craft down to the surface, announcing herself as an Honored Matre who, in the confusion, has managed to escape the Bene Gesserit with all their secrets. She arrives on the planet and is taken to the Great Honored Matre. Unable to control her anger, Logno attacks but is killed by Murbella. Awed by her physical prowess, the remaining Honored Matres are forced to accept her as their new leader. Odrade is also killed in the melee and Murbella shares memories with her, thereby also becoming Reverend Mother Superior. Murbella's ascension to leadership is not accepted as victory by all the Bene Gesserit. Some flee Chapterhouse, notably Sheeana, who has a vision of her own, and is joined by Duncan. The two escape in the giant no-ship, with Scytale, Teg and the Jews. Murbella recognizes their plan at the last minute, but is powerless to stop them. Watching this escape with interest are Daniel and Marty, the observers Duncan had been having visions of. The story ends on a cliffhanger with several questions left unanswered regarding the merging of the Honored Matres and Bene Gesserit, the fates of those on the escaped no-ship (including the role of Scytale, the development of Idaho and Teg, and the role of the Jews), the identity of the god-like characters in the book's final chapter and the ultimate mystery of what chased the Honored Matres back into the Old Empire.",9780441102679,http://books.google.com/books/content?id=ryot4Ag2GGQC&printsec=frontcover&img=1&zoom=1&edge=curl&source=gbs_api,9780441102679,9780441102679,7.916666666666667,24.0,Science Fiction +5,8,6630,Chapterhouse Dune,Frank Herbert,1985-04,Children's literature," The situation is desperate for the Bene Gesserit as they find themselves the targets of the Honored Matres, whose conquest of the Old Empire is almost complete. The Matres are seeking to assimilate the technology and developed methods of the Bene Gesserit and exterminate the Sisterhood itself. Now in command of the Bene Gesserit, Mother Superior Darwi Odrade continues to develop her drastic, secret plan to overcome the Honored Matres. The Bene Gesserit are also terraforming the planet Chapterhouse to accommodate the all-important sandworms, whose native planet Dune had been destroyed by the Matres. Sheeana, in charge of the project, expects sandworms to appear soon. The Honored Matres have also destroyed the entire Bene Tleilax civilization, with Tleilaxu Master Scytale the only one of his kind left alive. In Bene Gesserit captivity, Scytale possesses the Tleilaxu secret of ghola production, which he has reluctantly traded for the Sisterhood's protection. The first ghola produced is that of their recently-deceased military genius, Miles Teg. The Bene Gesserit have two other prisoners on Chapterhouse: the latest Duncan Idaho ghola, and former Honored Matre Murbella, whom they have accepted as a novice despite their suspicion that she intends to escape back to the Honored Matres. Lampadas, a center for Bene Gesserit education, has been destroyed by the Honored Matres. The planet's Chancellor, Reverend Mother Lucilla, manages to escape carrying the shared-minds of millions of Reverend Mothers. Lucilla is forced to land on Gammu where she seeks refuge with an underground group of Jews. The Rabbi gives Lucilla sanctuary, but to save his organization he must deliver her to the Matres. Before doing so, he reveals Rebecca, a ""wild"" Reverend Mother who has gained her Other Memory without Bene Gesserit training. Lucilla shares minds with Rebecca, who promises to take the memories of Lampadas safely back to the Sisterhood. Lucilla is then ""betrayed"", and taken before the Great Honored Matre Dama, who tries to persuade her to join the Honored Matres, preserving her life in exchange for Bene Gesserit secrets. Lucilla refuses, and Dama ultimately kills her. Back on Chapterhouse, Odrade confronts Duncan and forces him to admit that he is a Mentat, proving that he retains the memories of his many ghola lives. He does not reveal his mysterious visions of two people. Meanwhile, Murbella collapses under the pressure of Bene Gesserit training, giving in to ""word weapons"" that the Bene Gesserit had planted to undermine her earlier Honored Matre identity. Murbella realizes that she wants to be Bene Gesserit. Odrade believes that the Bene Gesserit made a mistake in fearing emotion, and that in order to evolve, the Bene Gesserit must learn to accept emotions. Odrade permits Duncan to watch Murbella undergo the spice agony, making him the first man ever to do so. Murbella survives the ordeal and becomes a Reverend Mother. Odrade then confronts Sheeana, discovering that Duncan and Sheeana have been allied together for some time. Sheeana does not reveal that they have been considering the option of reawakening Teg's memory through Imprinting, nor does Odrade discover that Sheeana has the keys to Duncan's no-ship prison. Odrade continues molding Scytale, with Sheeana showing him a baby sandworm, the Bene Gesserit's own long term supply of spice, and destroying Scytale's main bargaining card. Finally, Teg is awakened by Sheeana using imprinting techniques. Odrade appoints him again as Bashar of the military forces of the Sisterhood for the assault on the Honored Matres. Odrade next calls a meeting of all the Bene Gesserit, announcing her plan to attack the Honored Matres. She tells them that this attack will be led by Teg. She also announces candidates to succeed her as Mother Superior; she will share her memories with Murbella and Sheeana before she leaves. Odrade then goes to meet the Great Honored Matre. Under cover of Odrade's diplomacy, the Bene Gesserit forces under Teg attack Gammu with tremendous force. Teg uses his secret ability to see no-ships to secure control of the system. Survivors of the attack flee to Junction, and Teg follows them there and carries all with him. Victory for the Bene Gesserit seems inevitable. In the midst of this battle, the Jews (including Rebecca with her precious memories) take refuge with the Bene Gesserit fleet. Logno — chief advisor to Dama — assassinates Dama with poison and assumes control of the Honored Matres. Her first act surprises Odrade greatly. Too late Odrade and Teg realize they have fallen into a trap, and the Honored Matres use a mysterious weapon to turn defeat into victory, as well as capturing Odrade. Murbella saves as much of the Bene Gesserit force as she can and they begin to withdraw to Chapterhouse. Odrade, however, had planned for the possible failure of the Bene Gesserit attack and left Murbella instructions for a last desperate gamble. Murbella pilots a small craft down to the surface, announcing herself as an Honored Matre who, in the confusion, has managed to escape the Bene Gesserit with all their secrets. She arrives on the planet and is taken to the Great Honored Matre. Unable to control her anger, Logno attacks but is killed by Murbella. Awed by her physical prowess, the remaining Honored Matres are forced to accept her as their new leader. Odrade is also killed in the melee and Murbella shares memories with her, thereby also becoming Reverend Mother Superior. Murbella's ascension to leadership is not accepted as victory by all the Bene Gesserit. Some flee Chapterhouse, notably Sheeana, who has a vision of her own, and is joined by Duncan. The two escape in the giant no-ship, with Scytale, Teg and the Jews. Murbella recognizes their plan at the last minute, but is powerless to stop them. Watching this escape with interest are Daniel and Marty, the observers Duncan had been having visions of. The story ends on a cliffhanger with several questions left unanswered regarding the merging of the Honored Matres and Bene Gesserit, the fates of those on the escaped no-ship (including the role of Scytale, the development of Idaho and Teg, and the role of the Jews), the identity of the god-like characters in the book's final chapter and the ultimate mystery of what chased the Honored Matres back into the Old Empire.",9780441102679,http://books.google.com/books/content?id=ryot4Ag2GGQC&printsec=frontcover&img=1&zoom=1&edge=curl&source=gbs_api,9780441102679,9780441102679,7.916666666666667,24.0,Children's Literature +6,8,6630,Chapterhouse Dune,Frank Herbert,1985-04,Fiction," The situation is desperate for the Bene Gesserit as they find themselves the targets of the Honored Matres, whose conquest of the Old Empire is almost complete. The Matres are seeking to assimilate the technology and developed methods of the Bene Gesserit and exterminate the Sisterhood itself. Now in command of the Bene Gesserit, Mother Superior Darwi Odrade continues to develop her drastic, secret plan to overcome the Honored Matres. The Bene Gesserit are also terraforming the planet Chapterhouse to accommodate the all-important sandworms, whose native planet Dune had been destroyed by the Matres. Sheeana, in charge of the project, expects sandworms to appear soon. The Honored Matres have also destroyed the entire Bene Tleilax civilization, with Tleilaxu Master Scytale the only one of his kind left alive. In Bene Gesserit captivity, Scytale possesses the Tleilaxu secret of ghola production, which he has reluctantly traded for the Sisterhood's protection. The first ghola produced is that of their recently-deceased military genius, Miles Teg. The Bene Gesserit have two other prisoners on Chapterhouse: the latest Duncan Idaho ghola, and former Honored Matre Murbella, whom they have accepted as a novice despite their suspicion that she intends to escape back to the Honored Matres. Lampadas, a center for Bene Gesserit education, has been destroyed by the Honored Matres. The planet's Chancellor, Reverend Mother Lucilla, manages to escape carrying the shared-minds of millions of Reverend Mothers. Lucilla is forced to land on Gammu where she seeks refuge with an underground group of Jews. The Rabbi gives Lucilla sanctuary, but to save his organization he must deliver her to the Matres. Before doing so, he reveals Rebecca, a ""wild"" Reverend Mother who has gained her Other Memory without Bene Gesserit training. Lucilla shares minds with Rebecca, who promises to take the memories of Lampadas safely back to the Sisterhood. Lucilla is then ""betrayed"", and taken before the Great Honored Matre Dama, who tries to persuade her to join the Honored Matres, preserving her life in exchange for Bene Gesserit secrets. Lucilla refuses, and Dama ultimately kills her. Back on Chapterhouse, Odrade confronts Duncan and forces him to admit that he is a Mentat, proving that he retains the memories of his many ghola lives. He does not reveal his mysterious visions of two people. Meanwhile, Murbella collapses under the pressure of Bene Gesserit training, giving in to ""word weapons"" that the Bene Gesserit had planted to undermine her earlier Honored Matre identity. Murbella realizes that she wants to be Bene Gesserit. Odrade believes that the Bene Gesserit made a mistake in fearing emotion, and that in order to evolve, the Bene Gesserit must learn to accept emotions. Odrade permits Duncan to watch Murbella undergo the spice agony, making him the first man ever to do so. Murbella survives the ordeal and becomes a Reverend Mother. Odrade then confronts Sheeana, discovering that Duncan and Sheeana have been allied together for some time. Sheeana does not reveal that they have been considering the option of reawakening Teg's memory through Imprinting, nor does Odrade discover that Sheeana has the keys to Duncan's no-ship prison. Odrade continues molding Scytale, with Sheeana showing him a baby sandworm, the Bene Gesserit's own long term supply of spice, and destroying Scytale's main bargaining card. Finally, Teg is awakened by Sheeana using imprinting techniques. Odrade appoints him again as Bashar of the military forces of the Sisterhood for the assault on the Honored Matres. Odrade next calls a meeting of all the Bene Gesserit, announcing her plan to attack the Honored Matres. She tells them that this attack will be led by Teg. She also announces candidates to succeed her as Mother Superior; she will share her memories with Murbella and Sheeana before she leaves. Odrade then goes to meet the Great Honored Matre. Under cover of Odrade's diplomacy, the Bene Gesserit forces under Teg attack Gammu with tremendous force. Teg uses his secret ability to see no-ships to secure control of the system. Survivors of the attack flee to Junction, and Teg follows them there and carries all with him. Victory for the Bene Gesserit seems inevitable. In the midst of this battle, the Jews (including Rebecca with her precious memories) take refuge with the Bene Gesserit fleet. Logno — chief advisor to Dama — assassinates Dama with poison and assumes control of the Honored Matres. Her first act surprises Odrade greatly. Too late Odrade and Teg realize they have fallen into a trap, and the Honored Matres use a mysterious weapon to turn defeat into victory, as well as capturing Odrade. Murbella saves as much of the Bene Gesserit force as she can and they begin to withdraw to Chapterhouse. Odrade, however, had planned for the possible failure of the Bene Gesserit attack and left Murbella instructions for a last desperate gamble. Murbella pilots a small craft down to the surface, announcing herself as an Honored Matre who, in the confusion, has managed to escape the Bene Gesserit with all their secrets. She arrives on the planet and is taken to the Great Honored Matre. Unable to control her anger, Logno attacks but is killed by Murbella. Awed by her physical prowess, the remaining Honored Matres are forced to accept her as their new leader. Odrade is also killed in the melee and Murbella shares memories with her, thereby also becoming Reverend Mother Superior. Murbella's ascension to leadership is not accepted as victory by all the Bene Gesserit. Some flee Chapterhouse, notably Sheeana, who has a vision of her own, and is joined by Duncan. The two escape in the giant no-ship, with Scytale, Teg and the Jews. Murbella recognizes their plan at the last minute, but is powerless to stop them. Watching this escape with interest are Daniel and Marty, the observers Duncan had been having visions of. The story ends on a cliffhanger with several questions left unanswered regarding the merging of the Honored Matres and Bene Gesserit, the fates of those on the escaped no-ship (including the role of Scytale, the development of Idaho and Teg, and the role of the Jews), the identity of the god-like characters in the book's final chapter and the ultimate mystery of what chased the Honored Matres back into the Old Empire.",9780441102679,http://books.google.com/books/content?id=ryot4Ag2GGQC&printsec=frontcover&img=1&zoom=1&edge=curl&source=gbs_api,9780441102679,9780441102679,7.916666666666667,24.0,Fiction +7,10,8757,Darwin's Dangerous Idea,Daniel Dennett,1995,Philosophy," ""Starting in the Middle"", Part I of Darwin's Dangerous Idea, gets its name from a quote by Willard Van Orman Quine: ""Analyze theory-building how we will, we all must start in the middle. Our conceptual firsts are middle-sized, middle-distance objects, and our introduction to them and to everything comes midway in the cultural evolution of the race."" The first chapter ""Tell Me Why"" is named after a song. Before Charles Darwin, God was seen as the ultimate cause of all design, or the ultimate answer to 'why?' questions. John Locke argued for the primacy of mind before matter, and David Hume, while exposing problems with Locke's view, could not see any alternative. Darwin provided just such an alternative: evolution. Besides providing evidence of common descent, he introduced a mechanism to explain it: natural selection. According to Dennett, natural selection is a mindless, mechanical and algorithmic process—Darwin's dangerous idea. The third chapter introduces the concept of ""skyhooks"" and ""cranes"" (see below). He suggests that resistance to Darwinism is based on a desire for skyhooks, which do not really exist. According to Dennett, good reductionists explain apparent design without skyhooks; greedy reductionists try to explain it without cranes. Chapter 4 looks at the tree of life, such as how it can be visualized and some crucial events in life's history. The next chapter concerns the possible and the actual, using the 'Library of Mendel' (the space of all logically possible genomes) as a conceptual aid. In the last chapter of part I, Dennett treats human artifacts and culture as a branch of a unified Design Space. Descent or homology can be detected by shared design features that would be unlikely to appear independently. However, there are also ""Forced Moves"" or ""Good Tricks"" that will be discovered repeatedly, either by natural selection (see convergent evolution) or human investigation. The first chapter of part II, ""Darwinian Thinking in Biology"", asserts that life originated without any skyhooks, and the orderly world we know is the result of a blind and undirected shuffle through chaos. The eighth chapter's message is conveyed by its title, ""Biology is Engineering""; biology is the study of design, function, construction and operation. However, there are some important differences between biology and engineering. Related to the engineering concept of optimization, the next chapter deals with adaptationism, which Dennett endorses, calling Gould and Lewontin's ""refutation"" of it an illusion. Dennett thinks adaptationism is, in fact, the best way of uncovering constraints. The tenth chapter, entitled ""Bully for Brontosaurus"", is an extended critique of Stephen Jay Gould, who Dennett feels has created a distorted view of evolution with his popular writings; his ""self-styled revolutions"" against adaptationism, gradualism and other orthodox Darwinism all being false alarms. The final chapter of part II dismisses directed mutation, the inheritance of acquired traits and Teilhard's ""Omega Point"", and insists that other controversies and hypotheses (like the unit of selection and Panspermia) have no dire consequences for orthodox Darwinism. ""Mind, Meaning, Mathematics and Morality"" is the name of Part III, which begins with a quote from Nietzsche. Chapter 12, ""The Cranes of Culture"", discusses cultural evolution. It asserts that the meme has a role to play in our understanding of culture, and that it allows humans, alone among animals, to ""transcend"" our selfish genes. ""Losing Our Minds to Darwin"" follows, a chapter about the evolution of brains, minds and language. Dennett criticizes Noam Chomsky's perceived resistance to the evolution of language, its modeling by artificial intelligence, and reverse engineering. The evolution of meaning is then discussed, and Dennett uses a series of thought experiments to persuade the reader that meaning is the product of meaningless, algorithmic processes. Chapter 15 asserts that Gödel's Theorem does not make certain sorts of artificial intelligence impossible. Dennett extends his criticism to Roger Penrose. The subject then moves on to the origin and evolution of morality, beginning with Thomas Hobbes (who Dennett calls ""the first sociobiologist"") and Friedrich Nietzsche. He concludes that only an evolutionary analysis of ethics makes sense, though he cautions against some varieties of 'greedy ethical reductionism'. Before moving to the next chapter, he discusses some sociobiology controversies. The penultimate chapter, entitled ""Redesigning Morality"", begins by asking if ethics can be 'naturalized'. Dennett does not believe there is much hope of discovering an algorithm for doing the right thing, but expresses optimism in our ability to design and redesign our approach to moral problems. In ""The Future of an Idea"", the book's last chapter, Dennett praises biodiversity, including cultural diversity. In closing, he uses Beauty and the Beast as an analogy; although Darwin's idea may seem dangerous, it is actually quite beautiful.",9781439126295,http://books.google.com/books/content?id=Y77BAwAAQBAJ&printsec=frontcover&img=1&zoom=1&edge=curl&source=gbs_api,9781439126295,9781439126295,,,Philosophy +8,10,8757,Darwin's Dangerous Idea,Daniel Dennett,1995,Science," ""Starting in the Middle"", Part I of Darwin's Dangerous Idea, gets its name from a quote by Willard Van Orman Quine: ""Analyze theory-building how we will, we all must start in the middle. Our conceptual firsts are middle-sized, middle-distance objects, and our introduction to them and to everything comes midway in the cultural evolution of the race."" The first chapter ""Tell Me Why"" is named after a song. Before Charles Darwin, God was seen as the ultimate cause of all design, or the ultimate answer to 'why?' questions. John Locke argued for the primacy of mind before matter, and David Hume, while exposing problems with Locke's view, could not see any alternative. Darwin provided just such an alternative: evolution. Besides providing evidence of common descent, he introduced a mechanism to explain it: natural selection. According to Dennett, natural selection is a mindless, mechanical and algorithmic process—Darwin's dangerous idea. The third chapter introduces the concept of ""skyhooks"" and ""cranes"" (see below). He suggests that resistance to Darwinism is based on a desire for skyhooks, which do not really exist. According to Dennett, good reductionists explain apparent design without skyhooks; greedy reductionists try to explain it without cranes. Chapter 4 looks at the tree of life, such as how it can be visualized and some crucial events in life's history. The next chapter concerns the possible and the actual, using the 'Library of Mendel' (the space of all logically possible genomes) as a conceptual aid. In the last chapter of part I, Dennett treats human artifacts and culture as a branch of a unified Design Space. Descent or homology can be detected by shared design features that would be unlikely to appear independently. However, there are also ""Forced Moves"" or ""Good Tricks"" that will be discovered repeatedly, either by natural selection (see convergent evolution) or human investigation. The first chapter of part II, ""Darwinian Thinking in Biology"", asserts that life originated without any skyhooks, and the orderly world we know is the result of a blind and undirected shuffle through chaos. The eighth chapter's message is conveyed by its title, ""Biology is Engineering""; biology is the study of design, function, construction and operation. However, there are some important differences between biology and engineering. Related to the engineering concept of optimization, the next chapter deals with adaptationism, which Dennett endorses, calling Gould and Lewontin's ""refutation"" of it an illusion. Dennett thinks adaptationism is, in fact, the best way of uncovering constraints. The tenth chapter, entitled ""Bully for Brontosaurus"", is an extended critique of Stephen Jay Gould, who Dennett feels has created a distorted view of evolution with his popular writings; his ""self-styled revolutions"" against adaptationism, gradualism and other orthodox Darwinism all being false alarms. The final chapter of part II dismisses directed mutation, the inheritance of acquired traits and Teilhard's ""Omega Point"", and insists that other controversies and hypotheses (like the unit of selection and Panspermia) have no dire consequences for orthodox Darwinism. ""Mind, Meaning, Mathematics and Morality"" is the name of Part III, which begins with a quote from Nietzsche. Chapter 12, ""The Cranes of Culture"", discusses cultural evolution. It asserts that the meme has a role to play in our understanding of culture, and that it allows humans, alone among animals, to ""transcend"" our selfish genes. ""Losing Our Minds to Darwin"" follows, a chapter about the evolution of brains, minds and language. Dennett criticizes Noam Chomsky's perceived resistance to the evolution of language, its modeling by artificial intelligence, and reverse engineering. The evolution of meaning is then discussed, and Dennett uses a series of thought experiments to persuade the reader that meaning is the product of meaningless, algorithmic processes. Chapter 15 asserts that Gödel's Theorem does not make certain sorts of artificial intelligence impossible. Dennett extends his criticism to Roger Penrose. The subject then moves on to the origin and evolution of morality, beginning with Thomas Hobbes (who Dennett calls ""the first sociobiologist"") and Friedrich Nietzsche. He concludes that only an evolutionary analysis of ethics makes sense, though he cautions against some varieties of 'greedy ethical reductionism'. Before moving to the next chapter, he discusses some sociobiology controversies. The penultimate chapter, entitled ""Redesigning Morality"", begins by asking if ethics can be 'naturalized'. Dennett does not believe there is much hope of discovering an algorithm for doing the right thing, but expresses optimism in our ability to design and redesign our approach to moral problems. In ""The Future of an Idea"", the book's last chapter, Dennett praises biodiversity, including cultural diversity. In closing, he uses Beauty and the Beast as an analogy; although Darwin's idea may seem dangerous, it is actually quite beautiful.",9781439126295,http://books.google.com/books/content?id=Y77BAwAAQBAJ&printsec=frontcover&img=1&zoom=1&edge=curl&source=gbs_api,9781439126295,9781439126295,,,Science +9,11,11745,Farmer Giles of Ham,J. R. R. Tolkien,,Fantasy," Farmer Giles (Ægidius Ahenobarbus Julius Agricola de Hammo, ""Giles Bronze-beard Julius Farmer of Ham"") is not a hero. He is fat and red-bearded and enjoys a slow, comfortable life. But a rather deaf and short-sighted giant blunders on to his land, and Giles manages to ward him away with a blunderbuss shot in his general direction. The people of the village cheer: Farmer Giles has become a hero. His reputation spreads across the kingdom, and he is rewarded by the King with a sword named Caudimordax (""Tailbiter"")—which turns out to be a powerful weapon against dragons. The giant, on returning home, relates to his friends that there are no more knights in the Middle Kingdom, just stinging flies—actually the scrap metal shot from the blunderbuss—and this entices a dragon, Chrysophylax Dives, to investigate the area. The terrified neighbours all expect the accidental hero Farmer Giles to deal with him. The story parodies the great dragon-slaying traditions. The knights sent by the King to pursue the dragon are useless fops, more intent on ""precedence and etiquette"" than on the huge dragon footprints littering the landscape. The only part of a 'dragon' they know is the annual celebratory dragon-tail cake. Giles by contrast clearly recognizes the danger, and resents being sent along to face it. But hapless farmers can be forced to become heroes, and Giles shrewdly makes the best of the situation.",9780008641566,http://books.google.com/books/content?id=TjezEAAAQBAJ&printsec=frontcover&img=1&zoom=1&source=gbs_api,9780008641566,9780008641566,,,Fantasy +10,11,11745,Farmer Giles of Ham,J. R. R. Tolkien,,Fiction," Farmer Giles (Ægidius Ahenobarbus Julius Agricola de Hammo, ""Giles Bronze-beard Julius Farmer of Ham"") is not a hero. He is fat and red-bearded and enjoys a slow, comfortable life. But a rather deaf and short-sighted giant blunders on to his land, and Giles manages to ward him away with a blunderbuss shot in his general direction. The people of the village cheer: Farmer Giles has become a hero. His reputation spreads across the kingdom, and he is rewarded by the King with a sword named Caudimordax (""Tailbiter"")—which turns out to be a powerful weapon against dragons. The giant, on returning home, relates to his friends that there are no more knights in the Middle Kingdom, just stinging flies—actually the scrap metal shot from the blunderbuss—and this entices a dragon, Chrysophylax Dives, to investigate the area. The terrified neighbours all expect the accidental hero Farmer Giles to deal with him. The story parodies the great dragon-slaying traditions. The knights sent by the King to pursue the dragon are useless fops, more intent on ""precedence and etiquette"" than on the huge dragon footprints littering the landscape. The only part of a 'dragon' they know is the annual celebratory dragon-tail cake. Giles by contrast clearly recognizes the danger, and resents being sent along to face it. But hapless farmers can be forced to become heroes, and Giles shrewdly makes the best of the situation.",9780008641566,http://books.google.com/books/content?id=TjezEAAAQBAJ&printsec=frontcover&img=1&zoom=1&source=gbs_api,9780008641566,9780008641566,,,Fiction +11,12,12653,God Emperor of Dune,Frank Herbert,1981-05-28,Science Fiction," The seemingly immortal God Emperor Leto II has ruled his Empire for more than 3,500 years, his lifespan lengthened due to his decision in Children of Dune to merge his human body with sandtrout, the haploid phase of the giant sandworms of Arrakis. His continued evolution has slowly transformed him, altering his human form into what he calls a ""pre-worm."" His body has come to resemble a small version of the ancient sandworms of Arrakis — ribbed, elongated, and covered in scaly sandtrout; his face remains, as do his hands and arms, but his legs and feet have atrophied to be of no use whatsoever and he moves from place to place on a large cart of Ixian manufacture. It is later revealed that his brain has gradually diffused into the rest of his body, becoming a series of nodes throughout his whole form. This distribution of internal organs and his sandtrout skin makes him virtually impervious to harm, even allowing him to survive lasgun fire, but like a sandworm his biology is very vulnerable to water. During his long reign, Leto has enforced a state of peace throughout his empire, both through tight control of his enormous (but limited) hoard of the spice melange and the military might of his Fish Speaker army. The old Imperium is basically non-existent; the Landsraad has ceased to exist, and only a few remnants of the Great Houses survive. The Bene Gesserit and Spacing Guild have endured, although both have been forced to adapt to Leto's absolute control over melange and his powerful prescience, and CHOAM has been reduced to a shadow of its former self. His reign is considered by many to be depraved and despotic, but he is confident that his actions will ensure the survival of the human race. Leto's enforced peace brings stagnation to the galaxy; he himself battles an incessant struggle with boredom and loneliness that overwhelms him because of his everlasting life, close-to-absolute prescience, a loss of vulnerability which renders him incapable of physical intimacy, and his perception of the passage of time in great lengths (as decades may pass without him realizing it). Few people realize the burden that he carries as he deems subjects useful as long as they serve a purpose to the ""Golden Path"" (the end justifying the means). Leto maintains a small and reclusive system of government, and as God, he chooses not to share the inner workings and purpose of his decisions or any sympathy for his cause, as he knows that humanity would not be able to grasp the concept. As his father before him, Leto is utterly incapable of foreseeing his own demise, and concludes that whatever he cannot see and perceive — and thus control — is connected to his eventual death; ironically, this amuses him since it is one of the few things that still brings surprise to his otherwise dull existence. Leto has employed a series of gholas grown from the cells of Duncan Idaho, the faithful Swordmaster of House Atreides. Duncan functions both as the captain of Leto's guard, and as a familiar face to calm Leto in his moments of distress. They remind Leto of his family, and he feels that he owes Duncan for his service and devotion to House Atreides. The vast majority of these gholas are made under Leto's instructions of preserving the original Idaho without enhancements; Idaho's masterful abilities, thus, are dwarfed by thousands of years of genetic manipulation displayed by Leto's servants. Over the centuries, a significant number of the gholas have attempted to assassinate Leto through various means after struggling with the conflict between their intense loyalty to House Atreides, and the moral disgust triggered by the repression and stagnation Leto has forced upon the Empire. These feelings, compounded with the uneasy doubt caused by being millennia out of their own time, drives some of the Duncan Idaho gholas insane. Even when he doesn't ask for a new ghola, or considering the circumstances surrounding the previous Idaho's demise, the Tleilaxu usually send one anyway as a token for their survival. Leto's ""Golden Path,"" as he calls it, is a millennia-spanning attempt to produce a human who is invisible to a watcher gifted with prescience. This breeding plan, begun with the marriage of Leto's twin sister Ghanima to Farad'n Corrino, has resulted in Leto's majordomo Moneo Atreides and his daughter Siona. Moneo has served Leto faithfully for the majority of his life, having been a rebel until he was shown the Golden Path in a test by Leto. Siona is the leader of a group of rebels seeking to overthrow the God Emperor, and locate his hidden hoard of melange. Unbeknownst to Siona, Nayla — her close friend and de facto bodyguard — worships Leto, and is under orders to protect and obey Siona in all things while reporting on her rebellious activities. Although Leto knows the important purpose of Siona, as long as she doesn't serve the ""Golden Path"" she would be expendable, and he would have to take measures for the breeding paths that he would have to take to replace her. During a raid on his Citadel, Siona and her friends steal, among other things, a series of excerpts from Leto's private journal. Unknown to them, Leto is aware of their activities and allows them to continue. In perusing some of the items and documents stolen from the Citadel, Siona learns that Leto remains capable of love, and plots to use this as a weapon against him. At the same time, the new Ixian ambassador, Hwi Noree, is sent to the court of the God Emperor. Immediately entranced by her beauty, grace, and purity, Leto begins to be tortured by the knowledge that he and Hwi are separated by his continued transformation. For her part, Hwi desires nothing more than to serve the God Emperor, and she quickly becomes a confidante, finally expressing her love of Leto. The latest incarnation of Duncan is also captivated by Hwi's beauty, but is rebuffed by Leto, who warns that Hwi is his alone. Because of his intense feelings for Hwi and the fact that she had never appeared in his prescient visions, Leto realizes that she is a trap, trained and sent by the Ixians to weaken him. However, he is unable to send her away, and she gladly accepts his offer to remain. It is revealed that Hwi had been grown inside an Ixian no-room — a device that shields its occupants from prescient view — from cells of a former Ixian ambassador, Malky, who had been a cynical and roguish friend of the God Emperor. Through discussions with Moneo and Leto, Duncan learns about Leto's transformation, the Fish Speakers, and the oppressive measures Leto takes to maintain his absolute control over the Empire. He begins to grow more agitated and restless, though he continues in his duties, defending the God Emperor from an attack by Tleilaxu Face Dancers. Duncan struggles with feelings of inadequacy, and the confusion and disorientation that result from existing in a time alien to him. Duncan meets Siona, and though the two of them are coldly formal to one another, they eventually unite to kill Leto and end his tyrannical rule over mankind. Leto and Hwi decide to marry, and lead a wedding procession from Leto's Little Citadel to Tuono Village, where Duncan and Siona have been sent. While crossing the Idaho River, Siona orders Nayla to cut the supports of the bridge with a lasgun, spilling Moneo, Hwi, Leto, and a number of courtiers into the jagged rocks in the canyon below. Nayla obeys, despite her fanaticism toward the God Emperor, believing that the instructions are a test of her loyalty. Leto survives the fall, but is immersed in water, and his body begins to dissolve, just as did the sandworms of ancient Dune. In a final conversation with Siona and Duncan, Leto reveals that Siona is the embodiment of the Golden Path, a human completely shielded from prescient view. He explains that humanity is now free from the domination of oracles, free to scatter throughout the universe, never again to face complete domination. After revealing the location of his secret spice hoard, Leto dies, leaving Duncan and Siona to face the task of managing the empire.",9780425072721,http://books.google.com/books/content?id=_G5wTikjQlYC&printsec=frontcover&img=1&zoom=1&source=gbs_api,9780425072721,9780425072721,5.0,2.0,Science Fiction +12,12,12653,God Emperor of Dune,Frank Herbert,1981-05-28,Speculative fiction," The seemingly immortal God Emperor Leto II has ruled his Empire for more than 3,500 years, his lifespan lengthened due to his decision in Children of Dune to merge his human body with sandtrout, the haploid phase of the giant sandworms of Arrakis. His continued evolution has slowly transformed him, altering his human form into what he calls a ""pre-worm."" His body has come to resemble a small version of the ancient sandworms of Arrakis — ribbed, elongated, and covered in scaly sandtrout; his face remains, as do his hands and arms, but his legs and feet have atrophied to be of no use whatsoever and he moves from place to place on a large cart of Ixian manufacture. It is later revealed that his brain has gradually diffused into the rest of his body, becoming a series of nodes throughout his whole form. This distribution of internal organs and his sandtrout skin makes him virtually impervious to harm, even allowing him to survive lasgun fire, but like a sandworm his biology is very vulnerable to water. During his long reign, Leto has enforced a state of peace throughout his empire, both through tight control of his enormous (but limited) hoard of the spice melange and the military might of his Fish Speaker army. The old Imperium is basically non-existent; the Landsraad has ceased to exist, and only a few remnants of the Great Houses survive. The Bene Gesserit and Spacing Guild have endured, although both have been forced to adapt to Leto's absolute control over melange and his powerful prescience, and CHOAM has been reduced to a shadow of its former self. His reign is considered by many to be depraved and despotic, but he is confident that his actions will ensure the survival of the human race. Leto's enforced peace brings stagnation to the galaxy; he himself battles an incessant struggle with boredom and loneliness that overwhelms him because of his everlasting life, close-to-absolute prescience, a loss of vulnerability which renders him incapable of physical intimacy, and his perception of the passage of time in great lengths (as decades may pass without him realizing it). Few people realize the burden that he carries as he deems subjects useful as long as they serve a purpose to the ""Golden Path"" (the end justifying the means). Leto maintains a small and reclusive system of government, and as God, he chooses not to share the inner workings and purpose of his decisions or any sympathy for his cause, as he knows that humanity would not be able to grasp the concept. As his father before him, Leto is utterly incapable of foreseeing his own demise, and concludes that whatever he cannot see and perceive — and thus control — is connected to his eventual death; ironically, this amuses him since it is one of the few things that still brings surprise to his otherwise dull existence. Leto has employed a series of gholas grown from the cells of Duncan Idaho, the faithful Swordmaster of House Atreides. Duncan functions both as the captain of Leto's guard, and as a familiar face to calm Leto in his moments of distress. They remind Leto of his family, and he feels that he owes Duncan for his service and devotion to House Atreides. The vast majority of these gholas are made under Leto's instructions of preserving the original Idaho without enhancements; Idaho's masterful abilities, thus, are dwarfed by thousands of years of genetic manipulation displayed by Leto's servants. Over the centuries, a significant number of the gholas have attempted to assassinate Leto through various means after struggling with the conflict between their intense loyalty to House Atreides, and the moral disgust triggered by the repression and stagnation Leto has forced upon the Empire. These feelings, compounded with the uneasy doubt caused by being millennia out of their own time, drives some of the Duncan Idaho gholas insane. Even when he doesn't ask for a new ghola, or considering the circumstances surrounding the previous Idaho's demise, the Tleilaxu usually send one anyway as a token for their survival. Leto's ""Golden Path,"" as he calls it, is a millennia-spanning attempt to produce a human who is invisible to a watcher gifted with prescience. This breeding plan, begun with the marriage of Leto's twin sister Ghanima to Farad'n Corrino, has resulted in Leto's majordomo Moneo Atreides and his daughter Siona. Moneo has served Leto faithfully for the majority of his life, having been a rebel until he was shown the Golden Path in a test by Leto. Siona is the leader of a group of rebels seeking to overthrow the God Emperor, and locate his hidden hoard of melange. Unbeknownst to Siona, Nayla — her close friend and de facto bodyguard — worships Leto, and is under orders to protect and obey Siona in all things while reporting on her rebellious activities. Although Leto knows the important purpose of Siona, as long as she doesn't serve the ""Golden Path"" she would be expendable, and he would have to take measures for the breeding paths that he would have to take to replace her. During a raid on his Citadel, Siona and her friends steal, among other things, a series of excerpts from Leto's private journal. Unknown to them, Leto is aware of their activities and allows them to continue. In perusing some of the items and documents stolen from the Citadel, Siona learns that Leto remains capable of love, and plots to use this as a weapon against him. At the same time, the new Ixian ambassador, Hwi Noree, is sent to the court of the God Emperor. Immediately entranced by her beauty, grace, and purity, Leto begins to be tortured by the knowledge that he and Hwi are separated by his continued transformation. For her part, Hwi desires nothing more than to serve the God Emperor, and she quickly becomes a confidante, finally expressing her love of Leto. The latest incarnation of Duncan is also captivated by Hwi's beauty, but is rebuffed by Leto, who warns that Hwi is his alone. Because of his intense feelings for Hwi and the fact that she had never appeared in his prescient visions, Leto realizes that she is a trap, trained and sent by the Ixians to weaken him. However, he is unable to send her away, and she gladly accepts his offer to remain. It is revealed that Hwi had been grown inside an Ixian no-room — a device that shields its occupants from prescient view — from cells of a former Ixian ambassador, Malky, who had been a cynical and roguish friend of the God Emperor. Through discussions with Moneo and Leto, Duncan learns about Leto's transformation, the Fish Speakers, and the oppressive measures Leto takes to maintain his absolute control over the Empire. He begins to grow more agitated and restless, though he continues in his duties, defending the God Emperor from an attack by Tleilaxu Face Dancers. Duncan struggles with feelings of inadequacy, and the confusion and disorientation that result from existing in a time alien to him. Duncan meets Siona, and though the two of them are coldly formal to one another, they eventually unite to kill Leto and end his tyrannical rule over mankind. Leto and Hwi decide to marry, and lead a wedding procession from Leto's Little Citadel to Tuono Village, where Duncan and Siona have been sent. While crossing the Idaho River, Siona orders Nayla to cut the supports of the bridge with a lasgun, spilling Moneo, Hwi, Leto, and a number of courtiers into the jagged rocks in the canyon below. Nayla obeys, despite her fanaticism toward the God Emperor, believing that the instructions are a test of her loyalty. Leto survives the fall, but is immersed in water, and his body begins to dissolve, just as did the sandworms of ancient Dune. In a final conversation with Siona and Duncan, Leto reveals that Siona is the embodiment of the Golden Path, a human completely shielded from prescient view. He explains that humanity is now free from the domination of oracles, free to scatter throughout the universe, never again to face complete domination. After revealing the location of his secret spice hoard, Leto dies, leaving Duncan and Siona to face the task of managing the empire.",9780425072721,http://books.google.com/books/content?id=_G5wTikjQlYC&printsec=frontcover&img=1&zoom=1&source=gbs_api,9780425072721,9780425072721,5.0,2.0,Science Fiction +13,12,12653,God Emperor of Dune,Frank Herbert,1981-05-28,Children's literature," The seemingly immortal God Emperor Leto II has ruled his Empire for more than 3,500 years, his lifespan lengthened due to his decision in Children of Dune to merge his human body with sandtrout, the haploid phase of the giant sandworms of Arrakis. His continued evolution has slowly transformed him, altering his human form into what he calls a ""pre-worm."" His body has come to resemble a small version of the ancient sandworms of Arrakis — ribbed, elongated, and covered in scaly sandtrout; his face remains, as do his hands and arms, but his legs and feet have atrophied to be of no use whatsoever and he moves from place to place on a large cart of Ixian manufacture. It is later revealed that his brain has gradually diffused into the rest of his body, becoming a series of nodes throughout his whole form. This distribution of internal organs and his sandtrout skin makes him virtually impervious to harm, even allowing him to survive lasgun fire, but like a sandworm his biology is very vulnerable to water. During his long reign, Leto has enforced a state of peace throughout his empire, both through tight control of his enormous (but limited) hoard of the spice melange and the military might of his Fish Speaker army. The old Imperium is basically non-existent; the Landsraad has ceased to exist, and only a few remnants of the Great Houses survive. The Bene Gesserit and Spacing Guild have endured, although both have been forced to adapt to Leto's absolute control over melange and his powerful prescience, and CHOAM has been reduced to a shadow of its former self. His reign is considered by many to be depraved and despotic, but he is confident that his actions will ensure the survival of the human race. Leto's enforced peace brings stagnation to the galaxy; he himself battles an incessant struggle with boredom and loneliness that overwhelms him because of his everlasting life, close-to-absolute prescience, a loss of vulnerability which renders him incapable of physical intimacy, and his perception of the passage of time in great lengths (as decades may pass without him realizing it). Few people realize the burden that he carries as he deems subjects useful as long as they serve a purpose to the ""Golden Path"" (the end justifying the means). Leto maintains a small and reclusive system of government, and as God, he chooses not to share the inner workings and purpose of his decisions or any sympathy for his cause, as he knows that humanity would not be able to grasp the concept. As his father before him, Leto is utterly incapable of foreseeing his own demise, and concludes that whatever he cannot see and perceive — and thus control — is connected to his eventual death; ironically, this amuses him since it is one of the few things that still brings surprise to his otherwise dull existence. Leto has employed a series of gholas grown from the cells of Duncan Idaho, the faithful Swordmaster of House Atreides. Duncan functions both as the captain of Leto's guard, and as a familiar face to calm Leto in his moments of distress. They remind Leto of his family, and he feels that he owes Duncan for his service and devotion to House Atreides. The vast majority of these gholas are made under Leto's instructions of preserving the original Idaho without enhancements; Idaho's masterful abilities, thus, are dwarfed by thousands of years of genetic manipulation displayed by Leto's servants. Over the centuries, a significant number of the gholas have attempted to assassinate Leto through various means after struggling with the conflict between their intense loyalty to House Atreides, and the moral disgust triggered by the repression and stagnation Leto has forced upon the Empire. These feelings, compounded with the uneasy doubt caused by being millennia out of their own time, drives some of the Duncan Idaho gholas insane. Even when he doesn't ask for a new ghola, or considering the circumstances surrounding the previous Idaho's demise, the Tleilaxu usually send one anyway as a token for their survival. Leto's ""Golden Path,"" as he calls it, is a millennia-spanning attempt to produce a human who is invisible to a watcher gifted with prescience. This breeding plan, begun with the marriage of Leto's twin sister Ghanima to Farad'n Corrino, has resulted in Leto's majordomo Moneo Atreides and his daughter Siona. Moneo has served Leto faithfully for the majority of his life, having been a rebel until he was shown the Golden Path in a test by Leto. Siona is the leader of a group of rebels seeking to overthrow the God Emperor, and locate his hidden hoard of melange. Unbeknownst to Siona, Nayla — her close friend and de facto bodyguard — worships Leto, and is under orders to protect and obey Siona in all things while reporting on her rebellious activities. Although Leto knows the important purpose of Siona, as long as she doesn't serve the ""Golden Path"" she would be expendable, and he would have to take measures for the breeding paths that he would have to take to replace her. During a raid on his Citadel, Siona and her friends steal, among other things, a series of excerpts from Leto's private journal. Unknown to them, Leto is aware of their activities and allows them to continue. In perusing some of the items and documents stolen from the Citadel, Siona learns that Leto remains capable of love, and plots to use this as a weapon against him. At the same time, the new Ixian ambassador, Hwi Noree, is sent to the court of the God Emperor. Immediately entranced by her beauty, grace, and purity, Leto begins to be tortured by the knowledge that he and Hwi are separated by his continued transformation. For her part, Hwi desires nothing more than to serve the God Emperor, and she quickly becomes a confidante, finally expressing her love of Leto. The latest incarnation of Duncan is also captivated by Hwi's beauty, but is rebuffed by Leto, who warns that Hwi is his alone. Because of his intense feelings for Hwi and the fact that she had never appeared in his prescient visions, Leto realizes that she is a trap, trained and sent by the Ixians to weaken him. However, he is unable to send her away, and she gladly accepts his offer to remain. It is revealed that Hwi had been grown inside an Ixian no-room — a device that shields its occupants from prescient view — from cells of a former Ixian ambassador, Malky, who had been a cynical and roguish friend of the God Emperor. Through discussions with Moneo and Leto, Duncan learns about Leto's transformation, the Fish Speakers, and the oppressive measures Leto takes to maintain his absolute control over the Empire. He begins to grow more agitated and restless, though he continues in his duties, defending the God Emperor from an attack by Tleilaxu Face Dancers. Duncan struggles with feelings of inadequacy, and the confusion and disorientation that result from existing in a time alien to him. Duncan meets Siona, and though the two of them are coldly formal to one another, they eventually unite to kill Leto and end his tyrannical rule over mankind. Leto and Hwi decide to marry, and lead a wedding procession from Leto's Little Citadel to Tuono Village, where Duncan and Siona have been sent. While crossing the Idaho River, Siona orders Nayla to cut the supports of the bridge with a lasgun, spilling Moneo, Hwi, Leto, and a number of courtiers into the jagged rocks in the canyon below. Nayla obeys, despite her fanaticism toward the God Emperor, believing that the instructions are a test of her loyalty. Leto survives the fall, but is immersed in water, and his body begins to dissolve, just as did the sandworms of ancient Dune. In a final conversation with Siona and Duncan, Leto reveals that Siona is the embodiment of the Golden Path, a human completely shielded from prescient view. He explains that humanity is now free from the domination of oracles, free to scatter throughout the universe, never again to face complete domination. After revealing the location of his secret spice hoard, Leto dies, leaving Duncan and Siona to face the task of managing the empire.",9780425072721,http://books.google.com/books/content?id=_G5wTikjQlYC&printsec=frontcover&img=1&zoom=1&source=gbs_api,9780425072721,9780425072721,5.0,2.0,Children's Literature +14,12,12653,God Emperor of Dune,Frank Herbert,1981-05-28,Fiction," The seemingly immortal God Emperor Leto II has ruled his Empire for more than 3,500 years, his lifespan lengthened due to his decision in Children of Dune to merge his human body with sandtrout, the haploid phase of the giant sandworms of Arrakis. His continued evolution has slowly transformed him, altering his human form into what he calls a ""pre-worm."" His body has come to resemble a small version of the ancient sandworms of Arrakis — ribbed, elongated, and covered in scaly sandtrout; his face remains, as do his hands and arms, but his legs and feet have atrophied to be of no use whatsoever and he moves from place to place on a large cart of Ixian manufacture. It is later revealed that his brain has gradually diffused into the rest of his body, becoming a series of nodes throughout his whole form. This distribution of internal organs and his sandtrout skin makes him virtually impervious to harm, even allowing him to survive lasgun fire, but like a sandworm his biology is very vulnerable to water. During his long reign, Leto has enforced a state of peace throughout his empire, both through tight control of his enormous (but limited) hoard of the spice melange and the military might of his Fish Speaker army. The old Imperium is basically non-existent; the Landsraad has ceased to exist, and only a few remnants of the Great Houses survive. The Bene Gesserit and Spacing Guild have endured, although both have been forced to adapt to Leto's absolute control over melange and his powerful prescience, and CHOAM has been reduced to a shadow of its former self. His reign is considered by many to be depraved and despotic, but he is confident that his actions will ensure the survival of the human race. Leto's enforced peace brings stagnation to the galaxy; he himself battles an incessant struggle with boredom and loneliness that overwhelms him because of his everlasting life, close-to-absolute prescience, a loss of vulnerability which renders him incapable of physical intimacy, and his perception of the passage of time in great lengths (as decades may pass without him realizing it). Few people realize the burden that he carries as he deems subjects useful as long as they serve a purpose to the ""Golden Path"" (the end justifying the means). Leto maintains a small and reclusive system of government, and as God, he chooses not to share the inner workings and purpose of his decisions or any sympathy for his cause, as he knows that humanity would not be able to grasp the concept. As his father before him, Leto is utterly incapable of foreseeing his own demise, and concludes that whatever he cannot see and perceive — and thus control — is connected to his eventual death; ironically, this amuses him since it is one of the few things that still brings surprise to his otherwise dull existence. Leto has employed a series of gholas grown from the cells of Duncan Idaho, the faithful Swordmaster of House Atreides. Duncan functions both as the captain of Leto's guard, and as a familiar face to calm Leto in his moments of distress. They remind Leto of his family, and he feels that he owes Duncan for his service and devotion to House Atreides. The vast majority of these gholas are made under Leto's instructions of preserving the original Idaho without enhancements; Idaho's masterful abilities, thus, are dwarfed by thousands of years of genetic manipulation displayed by Leto's servants. Over the centuries, a significant number of the gholas have attempted to assassinate Leto through various means after struggling with the conflict between their intense loyalty to House Atreides, and the moral disgust triggered by the repression and stagnation Leto has forced upon the Empire. These feelings, compounded with the uneasy doubt caused by being millennia out of their own time, drives some of the Duncan Idaho gholas insane. Even when he doesn't ask for a new ghola, or considering the circumstances surrounding the previous Idaho's demise, the Tleilaxu usually send one anyway as a token for their survival. Leto's ""Golden Path,"" as he calls it, is a millennia-spanning attempt to produce a human who is invisible to a watcher gifted with prescience. This breeding plan, begun with the marriage of Leto's twin sister Ghanima to Farad'n Corrino, has resulted in Leto's majordomo Moneo Atreides and his daughter Siona. Moneo has served Leto faithfully for the majority of his life, having been a rebel until he was shown the Golden Path in a test by Leto. Siona is the leader of a group of rebels seeking to overthrow the God Emperor, and locate his hidden hoard of melange. Unbeknownst to Siona, Nayla — her close friend and de facto bodyguard — worships Leto, and is under orders to protect and obey Siona in all things while reporting on her rebellious activities. Although Leto knows the important purpose of Siona, as long as she doesn't serve the ""Golden Path"" she would be expendable, and he would have to take measures for the breeding paths that he would have to take to replace her. During a raid on his Citadel, Siona and her friends steal, among other things, a series of excerpts from Leto's private journal. Unknown to them, Leto is aware of their activities and allows them to continue. In perusing some of the items and documents stolen from the Citadel, Siona learns that Leto remains capable of love, and plots to use this as a weapon against him. At the same time, the new Ixian ambassador, Hwi Noree, is sent to the court of the God Emperor. Immediately entranced by her beauty, grace, and purity, Leto begins to be tortured by the knowledge that he and Hwi are separated by his continued transformation. For her part, Hwi desires nothing more than to serve the God Emperor, and she quickly becomes a confidante, finally expressing her love of Leto. The latest incarnation of Duncan is also captivated by Hwi's beauty, but is rebuffed by Leto, who warns that Hwi is his alone. Because of his intense feelings for Hwi and the fact that she had never appeared in his prescient visions, Leto realizes that she is a trap, trained and sent by the Ixians to weaken him. However, he is unable to send her away, and she gladly accepts his offer to remain. It is revealed that Hwi had been grown inside an Ixian no-room — a device that shields its occupants from prescient view — from cells of a former Ixian ambassador, Malky, who had been a cynical and roguish friend of the God Emperor. Through discussions with Moneo and Leto, Duncan learns about Leto's transformation, the Fish Speakers, and the oppressive measures Leto takes to maintain his absolute control over the Empire. He begins to grow more agitated and restless, though he continues in his duties, defending the God Emperor from an attack by Tleilaxu Face Dancers. Duncan struggles with feelings of inadequacy, and the confusion and disorientation that result from existing in a time alien to him. Duncan meets Siona, and though the two of them are coldly formal to one another, they eventually unite to kill Leto and end his tyrannical rule over mankind. Leto and Hwi decide to marry, and lead a wedding procession from Leto's Little Citadel to Tuono Village, where Duncan and Siona have been sent. While crossing the Idaho River, Siona orders Nayla to cut the supports of the bridge with a lasgun, spilling Moneo, Hwi, Leto, and a number of courtiers into the jagged rocks in the canyon below. Nayla obeys, despite her fanaticism toward the God Emperor, believing that the instructions are a test of her loyalty. Leto survives the fall, but is immersed in water, and his body begins to dissolve, just as did the sandworms of ancient Dune. In a final conversation with Siona and Duncan, Leto reveals that Siona is the embodiment of the Golden Path, a human completely shielded from prescient view. He explains that humanity is now free from the domination of oracles, free to scatter throughout the universe, never again to face complete domination. After revealing the location of his secret spice hoard, Leto dies, leaving Duncan and Siona to face the task of managing the empire.",9780425072721,http://books.google.com/books/content?id=_G5wTikjQlYC&printsec=frontcover&img=1&zoom=1&source=gbs_api,9780425072721,9780425072721,5.0,2.0,Fiction +15,15,20361,Moonfleet,J. Meade Falkner,1898,Adventure novel," In 1757, Moonfleet is a small village near the sea in the south of England. It gets its name from a formerly prominent local family, the Mohunes, whose coat of arms included a symbol shaped like a capital 'Y'. John Trenchard is an orphan who lives with his aunt, Miss Arnold. Other notable residents are the sexton Mr Ratsey who is friendly to John, Parson Glennie, the local clergyman who also teaches in the village school, Elzevir Block, the landlord of the local inn, called the Mohune Arms but nicknamed the Why Not? because of its sign with the Mohune 'Y', and Mr Maskew, the unpopular local magistrate and his beautiful daughter, Grace. Village legend tells of the notorious Colonel John ""Blackbeard"" Mohune who is buried in the family crypt under the church. He is reputed to have stolen a diamond from King Charles I and hidden it. His ghost is said to wander at night looking for it and the mysterious lights in the churchyard are attributed to his activities. As the main part of the story opens, Block's youthful son, David, has just been killed by Maskew during an attack by the authorities on a smuggling boat. One night a bad storm hits the village and there is a flood. While attending the Sunday service at church, John hears strange sounds from the crypt below. He thinks it is the sound of the coffins of the Mohune family. The next day, he finds Elzevir and Ratsey against the south wall of the church. They claim to be checking for damage from the storm, but John suspects they are searching for Blackbeard's ghost. Later John finds a large sinkhole has opened in the ground by a grave. He follows the passage and finds himself in the crypt with coffins on shelves and casks on the floor. He realises his friends are smugglers and this is their hiding place. He has to hide behind a coffin when he hears Ratsey and Elzevir coming. When they leave, they fill in the hole, inadvertently trapping him. John finds a locket in a coffin which holds a piece of paper with verses from the Bible. John eventually passes out after drinking too much of the wine while trying to quench his thirst, having not eaten or drunk for days. Later he wakes up in the Why Not? Inn- he has been rescued by Elzevir and Ratsey. When he is better, he returns to his Aunt's house, but she, suspecting him of drunken behaviour, throws him out. Fortunately, Elzevir takes him in. But when Block's lease on the Why Not? comes up for renewal, Maskew bids against him in the auction and wins. Block must leave the inn and Moonfleet but plans one last smuggling venture. John feels honour-bound to go with him, and sadly, says goodbye to Grace Maskew, whom he loves and has been seeing in secret, and gets his mother's prayer book as a good luck charm. The excisemen and Maskew are aware of the planned smuggling run but do not know exactly where it will occur. During the landing Maskew appears and is caught by the smugglers. Elzevir is bent on vengeance for his son by killing Maskew, and while the rest land the cargo and leave, he and John keep watch over Maskew. Just as Block prepares to shoot Maskew the excisemen attack. They kill Maskew and wound John. Block carries John away to safety and they hide in some old quarries. While there, John inadvertently finds out that the verses from Blackbeard's locket contain a code which will reveal the location of his famous diamond. Once John's wound heals, he and Block decide to recover the diamond from Carisbrooke Castle. After a suspenseful scene in the well where the jewel is hidden, they succeed and escape to Holland where they try to sell it to a Jewish diamond merchant named Crispin Aldobrand. The merchant cheats them, claiming the diamond is fake. Elzevir falls for the deceit and angrily throws the diamond out of the window. John, however, knows they have been duped, and suggests they try to recover the diamond through burglary. The attempt fails and, they are arrested and sentenced to prison. John curses the merchant for his lies. John and Elzevir go to prison for life. Eventually they are separated. Then, unexpectedly, ten years later, their paths cross again. They are being transported, and board a ship. A storm blows up, and by a strong coincidence, John and Elzevir find themselves near Moonfleet. They throw themselves into the sea and start to swim to shore. Elzevir helps John to safety, but is himself dragged under by the tide and drowned. So John ends up back where his whole adventure started, in the Why Not?, and is reunited with Ratsy. He is also reunited with Grace. She is now a rich young lady, having inherited her father's money. However, she is still in love with John, and they decide to marry. John tells her about the diamond and his life in prison. He regrets having lost everything, but then Parson Glennie receives a letter from Aldobrand. The merchant suffered a guilty conscience, and in an attempt to make amends, has bequeathed the worth of the diamond to John. John gives the money to the village, and new almshouses are built, and the school and the church renovated. John marries Grace and becomes Lord of the Manor and Justice of the Peace. Their three children grow up and their sons leave home, including their first-born son, Elzevir. But John and Grace themselves have no plans to leave their beloved Moonfleet ever again. A feature of the narrative is a continuing reference to the boardgame of backgammon which is played by the patrons of the Why Not? on an antique board which bears a Latin inscription Ita in vita ut in lusu alae pessima jactura arte corrigenda est (translated in the book as As in life, so in a game of hazard, skill will make something of the worst of throws). This inscription provides a moralistic metaphor to the story of the orphan boy who in the end overcomes his travails.",9788026898108,http://books.google.com/books/content?id=btGSDwAAQBAJ&printsec=frontcover&img=1&zoom=1&edge=curl&source=gbs_api,9788026898108,9788026898108,,,Adventure +16,18,38114,Keep the Aspidistra Flying,George Orwell,1936,Novel," Gordon Comstock has 'declared war' on what he sees as an 'overarching dependence' on money by leaving a promising job as a copywriter for an advertising company called 'New Albion'—at which he shows great dexterity—and taking a low-paying job instead, ostensibly so he can write poetry. Coming from a respectable family background in which the inherited wealth has now become dissipated, Gordon resents having to work for a living. The 'war' (and the poetry), however, aren't going particularly well and, under the stress of his 'self-imposed exile' from affluence, Gordon has become absurd, petty and deeply neurotic. Comstock lives in a bedsit in London and earns enough to live, without luxuries, in a small bookshop owned by a Scot, McKechnie. He works intermittently at a magnum opus describing a day in London he plans to call London Pleasures; meanwhile, his only published work, a slim volume of poetry entitled Mice, collects dust on the remainder shelf. He is simultaneously content with his meagre existence and also disdainful of it. He lives without financial ambition and the need for a 'good job,' but his living conditions are uncomfortable and his job is boring. Comstock is 'obsessed' by what he sees as a pervasion of money (the 'Money God', as he calls it) behind social relationships, feeling sure that women would find him more attractive if he were better off. At the beginning of the novel, he senses that his girlfriend Rosemary Waterlow (whom he met at The Albion, and who continues to work there), is dissatisfied with him because of his poverty. An example of his financial embarrassment is when he is desperate for a pint of beer at his local pub, but has run out of pocket money and is ashamed to cadge a drink off his fellow lodger, Flaxman. One of Comstock's last remaining friends, Philip Ravelston, a Marxist who publishes a magazine called Anti-Christ, agrees with Comstock in principle, but is comfortably well-off himself and this causes strains when the practical miseries of Comstock's life become apparent. He does, however, endeavour to publish some of Comstock's work and his efforts had resulted in Mice being published via one of his publisher contacts (unbeknownst to Comstock). Gordon and Rosemary have little time together—she works late and lives in a hostel, and his 'bitch of a landlady' forbids female visitors to her tenants. Then one evening, having headed southward and having been thinking about women, - this women business in general, and Rosemary in particular, - he happens to see Rosemary in a street market. Rosemary won't have sex with him but she wants to spend a Sunday with him, right out in the country, near Burnham Beeches. At their parting, as he takes the tram from Tottenham Court Road back to his bedsit, he is happy and feels that somehow it is agreed between them that Rosemary is going to be his mistress. However, what is intended to be a pleasant day out away from London's grime turns into a disaster when, though hungry, they opt to pass by a 'rather low-looking' pub, and can then not find another pub, and are forced to eat an unappetizing lunch at a fancy, overpriced hotel instead. Gordon has to pay the bill with all the money he had set aside for their jaunt and worries about having to borrow money from Rosemary. At the critical moment when he is about to take her virginity, she raises the issue of contraception and his interest flags. He rails at her; ""Money again, you see! [-] You say you can't have a baby. You mean you daren't; because you'd lose your job and I've got no money and all of us would starve."" Having sent a poem to an American publication, Gordon suddenly receives from them a cheque worth ten pounds — a considerable sum for him at the time. He intends to set aside half for his sister Julia, who has always been there to lend him money and support. He treats Rosemary and Ravelston to dinner, which begins well, but the evening deteriorates as it proceeds. Gordon, drunk, tries to force himself upon Rosemary but she angrily rebukes him and leaves. Gordon continues drinking, drags Ravelston with him to visit a pair of prostitutes, and ends up broke and in a police cell the next morning. He is guilt-ridden over the thought of being unable to pay his sister back the money he owes her, because his £5 note is gone, given to, or stolen by, one of the tarts. Ravelston pays Gordon's fine after a brief appearance before the magistrate, but a reporter hears about the case, and writes about it in the local paper. The ensuing publicity results in Gordon losing his job at the bookshop, and, consequently, his relatively 'comfortable' lifestyle. As Gordon searches for another job, his life deteriorates, and his poetry stagnates. After living with his friend Ravelston, and his girlfriend Hermione, during his time of unemployment, Gordon ends up working at another book shop and cheap two-penny lending library, this time in Lambeth, owned by the sinister Mr. Cheeseman, for an even smaller wage of 30 shillings a week. This is 10 shillings less than he was earning before, but Gordon is satisfied; ""The job would do. There was no trouble about a job like this; no room for ambition, no effort, no hope."" Determined to sink to the lowest level of society Gordon takes a furnished bed-sitting-room in a filthy alley parallel to Lambeth Cut. Julie and Rosemary, ""in feminine league against him"", both seek to get Gordon to go back to his 'good' job at the New Albion advertising agency. Rosemary, having avoided Gordon for some time, suddenly comes to visit him one day at his dismal lodgings. Despite his terrible poverty and shabbiness, they make love but it is without any emotion or passion. Later, Rosemary drops in one day unexpectedly at the library, having not been in touch with Gordon for some time, and tells him that she is pregnant. Gordon is presented with the choice between leaving Rosemary to a life of social shame at the hands of her family—since both of them reject the idea of an abortion—or marrying her and returning to a life of respectability by taking back the job he once so deplored at the New Albion with its £4 weekly salary. He chooses Rosemary and respectability and then experiences a feeling of relief at having abandoned his anti-money principles with such comparative ease. After two years of abject failure and poverty, he throws his poetic work London Pleasures down a drain, marries Rosemary, resumes his advertising career, and plunges into a campaign to promote a new product to prevent foot odour. In his lonely walks around mean streets, aspidistras seem to appear in every lower-middle class window. As the book closes, Gordon wins an argument with Rosemary to install an aspidistra in their new small but comfortable flat off the Edgware Road.",9780198858317,http://books.google.com/books/content?id=gxUOEAAAQBAJ&printsec=frontcover&img=1&zoom=1&edge=curl&source=gbs_api,9780198858317,9780198858317,,,Novel +17,19,38279,"Lions' Commentary on UNIX 6th Edition, with Source Code",John Lions,1996,Computer Science," Unix Operating System Source Code Level Six is the kernel source code, lightly edited by Lions to better separate the functionality — system initialization and process management, interrupts and system calls, basic I/O, file systems and pipes and character devices. All procedures and symbols are listed alphabetically with a cross reference. The code as presented will run on a PDP-11/40 with RK-05 disk drive, LP-11 line printer interface, PCL-11 paper tape writer and KL-11 terminal interface, or a suitable PDP-11 emulator, such as SIMH. A Commentary on the Unix Operating System starts with notes on Unix and other useful documentation (the Unix manual pages, DEC hardware manuals and so on), a section on the architecture of the PDP-11 and a chapter on how to read C programs. The source commentary follows, divided into the same sections as the code. The book ends with suggested exercises for the student. As Lions explains, this commentary supplements the comments in the source. It is possible to understand the code without the extra commentary, and the reader is advised to do so and only read the notes as needed. The commentary also remarks on how the code might be improved.",9781573980135,http://books.google.com/books/content?id=OlZ3QgAACAAJ&printsec=frontcover&img=1&zoom=1&source=gbs_api,9781573980135,9781573980135,,,Other +18,20,38615,The Myth of Sisyphus,Albert Camus,1942,Existentialism," The essay is dedicated to Pascal Pia and is organized in four chapters and one appendix. Camus undertakes to answer what he considers to be the only question of philosophy that matters: Does the realization of the meaninglessness and absurdity of life necessarily require suicide? He begins by describing the absurd condition: much of our life is built on the hope for tomorrow yet tomorrow brings us closer to death and is the ultimate enemy; people live as if they didn't know about the certainty of death; once stripped of its common romanticisms, the world is a foreign, strange and inhuman place; true knowledge is impossible and rationality and science cannot explain the world: their stories ultimately end in meaningless abstractions, in metaphors. ""From the moment absurdity is recognized, it becomes a passion, the most harrowing of all."" It is not the world that is absurd, nor human thought: the absurd arises when the human need to understand meets the unreasonableness of the world, when ""my appetite for the absolute and for unity"" meets the inability of ""reducing this world to a rational and reasonable principle."" He then characterizes a number of philosophies that describe and attempt to deal with this feeling of the absurd, by Heidegger, Jaspers, Shestov, Kierkegaard, and Husserl. All of these, he claims, commit ""philosophical suicide"" by reaching conclusions that contradict the original absurd position, either by abandoning reason and turning to God, as in the case of Kierkegaard and Shestov, or by elevating reason and ultimately arriving at ubiquitous Platonic forms and an abstract god, as in the case of Husserl. For Camus, who set out to take the absurd seriously and follow it to its final conclusions, these ""leaps"" cannot convince. Taking the absurd seriously means acknowledging the contradiction between the desire of human reason and the unreasonable world. Suicide, then, also must be rejected: without man, the absurd cannot exist. The contradiction must be lived; reason and its limits must be acknowledged, without false hope. However, the absurd can never be accepted: it requires constant confrontation, constant revolt. While the question of human freedom in the metaphysical sense loses interest to the absurd man, he gains freedom in a very concrete sense: no longer bound by hope for a better future or eternity, without a need to pursue life's purpose or to create meaning, ""he enjoys a freedom with regard to common rules"". To embrace the absurd implies embracing all that the unreasonable world has to offer. Without a meaning in life, there is no scale of values. ""What counts is not the best living but the most living."" Thus, Camus arrives at three consequences from the full acknowledging of the absurd: revolt, freedom and passion. How should the absurd man live? Clearly, no ethical rules apply, as they are all based on higher powers or on justification. ""Integrity has no need of rules."" 'Everything is permitted' ""is not an outburst of relief or of joy, but rather a bitter acknowledgment of a fact."" Camus then goes on to present examples of the absurd life. He begins with Don Juan, the serial seducer who lives the passionate life to the fullest. ""There is no noble love but that which recognizes itself to be both short-lived and exceptional."" The next example is the actor, who depicts ephemeral lives for ephemeral fame. ""He demonstrates to what degree appearing creates being."" ""In those three hours he travels the whole course of the dead-end path that the man in the audience takes a lifetime to cover."" Camus' third example of the absurd man is the conqueror, the warrior who forgoes all promises of eternity to affect and engage fully in human history. He chooses action over contemplation, aware of the fact that nothing can last and no victory is final. Here Camus explores the absurd creator or artist. Since explanation is impossible, absurd art is restricted to a description of the myriad experiences in the world. ""If the world were clear, art would not exist."" Absurd creation, of course, also must refrain from judging and from alluding to even the slightest shadow of hope. He then analyzes the work of Dostoyevsky in this light, especially The Diary of a Writer, The Possessed and The Brothers Karamazov. All these works start from the absurd position, and the first two explore the theme of philosophical suicide. But both The Diary and his last novel, The Brothers Karamazov, ultimately find a path to hope and faith and thus fail as truly absurd creations. In the last chapter, Camus outlines the legend of Sisyphus who defied the gods and put Death in chains so that no human needed to die. When Death was eventually liberated and it came time for Sisyphus himself to die, he concocted a deceit which let him escape from the underworld. Finally captured, the gods decided on his punishment: for all eternity, he would have to push a rock up a mountain; upon reaching the top, the rock would roll down again leaving Sisyphus to start over. Camus sees Sisyphus as the absurd hero who lives life to the fullest, hates death and is condemned to a meaningless task. Camus presents Sisyphus's ceaseless and pointless toil as a metaphor for modern lives spent working at futile jobs in factories and offices. ""The workman of today works every day in his life at the same tasks, and this fate is no less absurd. But it is tragic only at the rare moments when it becomes conscious."" Camus is interested in Sisyphus' thoughts when marching down the mountain, to start anew. This is the truly tragic moment, when the hero becomes conscious of his wretched condition. He does not have hope, but ""[t]here is no fate that cannot be surmounted by scorn."" Acknowledging the truth will conquer it; Sisyphus, just like the absurd man, keeps pushing. Camus claims that when Sisyphus acknowledges the futility of his task and the certainty of his fate, he is freed to realize the absurdity of his situation and to reach a state of contented acceptance. With a nod to the similarly cursed Greek hero Oedipus, Camus concludes that ""all is well,"" indeed, that ""[o]ne must imagine Sisyphus happy."" The essay contains an appendix titled ""Hope and the Absurd in the work of Franz Kafka"". While Camus acknowledges that Kafka's work represents an exquisite description of the absurd condition, he maintains that Kafka fails as an absurd writer because his work retains a glimmer of hope.",9780679733737,http://books.google.com/books/content?id=SWs0MhTn05IC&printsec=frontcover&img=1&zoom=1&edge=curl&source=gbs_api,9780679733737,9780679733737,8.0,4.0,Other +19,22,42572,The Eye of the World,Robert Jordan,1990-01-15,Speculative fiction," The Eye of the World revolves around the lives of a group of young people from Emond's Field in The Two Rivers district: Rand al'Thor, Matrim (Mat) Cauthon, Perrin Aybara, Egwene al'Vere, and Nynaeve al'Meara. Emond's Field is unexpectedly attacked by Dark forces—bestial Trollocs and a Myrddraal who seem to specifically target Rand, Mat and Perrin. Hoping to save their village from further attacks, the young men and Egwene flee the village accompanied by an Aes Sedai named Moiraine Damodred, her WarderAl'Lan Mandragoran and a Gleeman Thom Merrilin. They are later joined by Nynaeve al'Meara, the Wisdom of Emond's Field. Pursued by ever-increasing numbers of Trollocs and Myrddraal, the travellers are forced to take refuge in the abandoned city of Shadar Logoth, a place even the dark forces are reluctant to enter because of the evil Mashadar that resides there. While escaping the city the travelers are separated. Rand, Mat and Thom make their way by boat to Whitebridge where Thom is apparently killed while allowing Rand and Mat to escape a Myrddraal. In Caemlyn Rand befriends an Ogier named Loial. While exploring the city and trying to catch a glimpse of the recently captured False Dragon, Rand falls into the palace gardens. Once there he meets Elayne Trakand, heir apparent to the throne of Andor and her brothers Gawyn and Galad Damodred. Rand is taken before Queen Morgase and her Aes Sedai advisor, Elaida who foretells that Rand is dangerous. Queen Morgase, however, decides to let Rand go free. Meanwhile Egwene and Perrin travel separately to Caemlyn in the company of Elyas Machera, a man who can communicate with wolves and who claims that Perrin can do the same. The three run afoul of a legion of the Children of the Light. Perrin kills two Whitecloaks after witnessing the death of a wolf at their hands and is sentenced to death. Moiraine, Lan and Nynaeve rescue Egwene and Perrin from the Whitecloaks in time to escape their fate. Together they travel to Caemlyn where they are reunited with Rand and Mat. Rand tells Moiraine that Mat has been suspicious and withdrawn, and Moiraine diagnoses Mat's ""sickness"" as the corrupting influence of a ruby dagger Mat took from Shadar Logoth. Moiraine says that Mat must travel to Tar Valon in order to be healed. Loial warns Moiraine of a threat to the Eye of the World, which is confirmed by vivid and disturbing dreams Mat, Rand and Perrin have had. The Eye of the World was created by Aes Sedai who sacrificed themselves to create a pool of Saidin untouched by the Dark One's taint, and is hidden in the Blight. The Eye of the World is protected by Someshta (the Green Man) and contains one of the seven seals on the Dark One's prison, the Dragon banner of Lews Therin Telamon and the Horn of Valere. Loial guides the group through the Ways (passageways built by the male Aes Sedai during the Breaking of the World, which are now tainted by the same evil that tainted Saidin) in order to reach the Eye of the World. The group enters the Blight, in search of the Eye of the World guided by The Green Man. The Eye is revealed to be a pool of Saidin, pure and untainted. The companions are confronted by the Forsaken Aginor and Balthamel. Balthamel dies at the hand of the Green Man and Aginor and Rand battle for control of the Eye of the World. Rand defeats Aginor and guided by blind luck uses the pure Saidin to decimate the Trolloc army and defeat Ba'alzamon. Afterwards Rand realizes to his own horror that he has channeled the One Power and is therefore condemned to a fate of insanity and horrific death. It is revealed that Moiraine believes Rand is the Dragon Reborn.",9781857230765,http://books.google.com/books/content?id=6wkYngEACAAJ&printsec=frontcover&img=1&zoom=1&source=gbs_api,9781857230765,9781857230765,8.333333333333334,3.0,Science Fiction +20,22,42572,The Eye of the World,Robert Jordan,1990-01-15,Fantasy," The Eye of the World revolves around the lives of a group of young people from Emond's Field in The Two Rivers district: Rand al'Thor, Matrim (Mat) Cauthon, Perrin Aybara, Egwene al'Vere, and Nynaeve al'Meara. Emond's Field is unexpectedly attacked by Dark forces—bestial Trollocs and a Myrddraal who seem to specifically target Rand, Mat and Perrin. Hoping to save their village from further attacks, the young men and Egwene flee the village accompanied by an Aes Sedai named Moiraine Damodred, her WarderAl'Lan Mandragoran and a Gleeman Thom Merrilin. They are later joined by Nynaeve al'Meara, the Wisdom of Emond's Field. Pursued by ever-increasing numbers of Trollocs and Myrddraal, the travellers are forced to take refuge in the abandoned city of Shadar Logoth, a place even the dark forces are reluctant to enter because of the evil Mashadar that resides there. While escaping the city the travelers are separated. Rand, Mat and Thom make their way by boat to Whitebridge where Thom is apparently killed while allowing Rand and Mat to escape a Myrddraal. In Caemlyn Rand befriends an Ogier named Loial. While exploring the city and trying to catch a glimpse of the recently captured False Dragon, Rand falls into the palace gardens. Once there he meets Elayne Trakand, heir apparent to the throne of Andor and her brothers Gawyn and Galad Damodred. Rand is taken before Queen Morgase and her Aes Sedai advisor, Elaida who foretells that Rand is dangerous. Queen Morgase, however, decides to let Rand go free. Meanwhile Egwene and Perrin travel separately to Caemlyn in the company of Elyas Machera, a man who can communicate with wolves and who claims that Perrin can do the same. The three run afoul of a legion of the Children of the Light. Perrin kills two Whitecloaks after witnessing the death of a wolf at their hands and is sentenced to death. Moiraine, Lan and Nynaeve rescue Egwene and Perrin from the Whitecloaks in time to escape their fate. Together they travel to Caemlyn where they are reunited with Rand and Mat. Rand tells Moiraine that Mat has been suspicious and withdrawn, and Moiraine diagnoses Mat's ""sickness"" as the corrupting influence of a ruby dagger Mat took from Shadar Logoth. Moiraine says that Mat must travel to Tar Valon in order to be healed. Loial warns Moiraine of a threat to the Eye of the World, which is confirmed by vivid and disturbing dreams Mat, Rand and Perrin have had. The Eye of the World was created by Aes Sedai who sacrificed themselves to create a pool of Saidin untouched by the Dark One's taint, and is hidden in the Blight. The Eye of the World is protected by Someshta (the Green Man) and contains one of the seven seals on the Dark One's prison, the Dragon banner of Lews Therin Telamon and the Horn of Valere. Loial guides the group through the Ways (passageways built by the male Aes Sedai during the Breaking of the World, which are now tainted by the same evil that tainted Saidin) in order to reach the Eye of the World. The group enters the Blight, in search of the Eye of the World guided by The Green Man. The Eye is revealed to be a pool of Saidin, pure and untainted. The companions are confronted by the Forsaken Aginor and Balthamel. Balthamel dies at the hand of the Green Man and Aginor and Rand battle for control of the Eye of the World. Rand defeats Aginor and guided by blind luck uses the pure Saidin to decimate the Trolloc army and defeat Ba'alzamon. Afterwards Rand realizes to his own horror that he has channeled the One Power and is therefore condemned to a fate of insanity and horrific death. It is revealed that Moiraine believes Rand is the Dragon Reborn.",9781857230765,http://books.google.com/books/content?id=6wkYngEACAAJ&printsec=frontcover&img=1&zoom=1&source=gbs_api,9781857230765,9781857230765,8.333333333333334,3.0,Fantasy +21,22,42572,The Eye of the World,Robert Jordan,1990-01-15,High fantasy," The Eye of the World revolves around the lives of a group of young people from Emond's Field in The Two Rivers district: Rand al'Thor, Matrim (Mat) Cauthon, Perrin Aybara, Egwene al'Vere, and Nynaeve al'Meara. Emond's Field is unexpectedly attacked by Dark forces—bestial Trollocs and a Myrddraal who seem to specifically target Rand, Mat and Perrin. Hoping to save their village from further attacks, the young men and Egwene flee the village accompanied by an Aes Sedai named Moiraine Damodred, her WarderAl'Lan Mandragoran and a Gleeman Thom Merrilin. They are later joined by Nynaeve al'Meara, the Wisdom of Emond's Field. Pursued by ever-increasing numbers of Trollocs and Myrddraal, the travellers are forced to take refuge in the abandoned city of Shadar Logoth, a place even the dark forces are reluctant to enter because of the evil Mashadar that resides there. While escaping the city the travelers are separated. Rand, Mat and Thom make their way by boat to Whitebridge where Thom is apparently killed while allowing Rand and Mat to escape a Myrddraal. In Caemlyn Rand befriends an Ogier named Loial. While exploring the city and trying to catch a glimpse of the recently captured False Dragon, Rand falls into the palace gardens. Once there he meets Elayne Trakand, heir apparent to the throne of Andor and her brothers Gawyn and Galad Damodred. Rand is taken before Queen Morgase and her Aes Sedai advisor, Elaida who foretells that Rand is dangerous. Queen Morgase, however, decides to let Rand go free. Meanwhile Egwene and Perrin travel separately to Caemlyn in the company of Elyas Machera, a man who can communicate with wolves and who claims that Perrin can do the same. The three run afoul of a legion of the Children of the Light. Perrin kills two Whitecloaks after witnessing the death of a wolf at their hands and is sentenced to death. Moiraine, Lan and Nynaeve rescue Egwene and Perrin from the Whitecloaks in time to escape their fate. Together they travel to Caemlyn where they are reunited with Rand and Mat. Rand tells Moiraine that Mat has been suspicious and withdrawn, and Moiraine diagnoses Mat's ""sickness"" as the corrupting influence of a ruby dagger Mat took from Shadar Logoth. Moiraine says that Mat must travel to Tar Valon in order to be healed. Loial warns Moiraine of a threat to the Eye of the World, which is confirmed by vivid and disturbing dreams Mat, Rand and Perrin have had. The Eye of the World was created by Aes Sedai who sacrificed themselves to create a pool of Saidin untouched by the Dark One's taint, and is hidden in the Blight. The Eye of the World is protected by Someshta (the Green Man) and contains one of the seven seals on the Dark One's prison, the Dragon banner of Lews Therin Telamon and the Horn of Valere. Loial guides the group through the Ways (passageways built by the male Aes Sedai during the Breaking of the World, which are now tainted by the same evil that tainted Saidin) in order to reach the Eye of the World. The group enters the Blight, in search of the Eye of the World guided by The Green Man. The Eye is revealed to be a pool of Saidin, pure and untainted. The companions are confronted by the Forsaken Aginor and Balthamel. Balthamel dies at the hand of the Green Man and Aginor and Rand battle for control of the Eye of the World. Rand defeats Aginor and guided by blind luck uses the pure Saidin to decimate the Trolloc army and defeat Ba'alzamon. Afterwards Rand realizes to his own horror that he has channeled the One Power and is therefore condemned to a fate of insanity and horrific death. It is revealed that Moiraine believes Rand is the Dragon Reborn.",9781857230765,http://books.google.com/books/content?id=6wkYngEACAAJ&printsec=frontcover&img=1&zoom=1&source=gbs_api,9781857230765,9781857230765,8.333333333333334,3.0,Fantasy +22,23,42573,The Great Hunt,Robert Jordan,1990-11-15,Speculative fiction," Ba'alzamon presides over a clandestine meeting as Shadow forces plot their actions and Shaitan’s return. In addition to Forsaken and Darkfriends, the meeting includes two Aes Sedai, one of whom we come to know as Liandrin. The prologue shows how deep Ba'alzamon's influence has gone, even in places the protagonists believe to be safe. Following the events in The Eye of the World, the protagonists rest at Fort Fal Dara in Shienar, where the White Tower’s Amyrlin Seat, Siuan Sanche, visits. Siuan reminisces and plots with fellow Aes Sedai Moiraine Damodred and Verin. Rand al'Thor meets Siuan. Siuan tells Rand that he is the Dragon Reborn, which Rand denies. Mat's condition worsens as he is symbiotically attached to a tainted parasitic dagger. Lan Mandragoran further instructs Rand in swordfighting. Powerful Darkfriend Padan Fain is imprisoned in the Fal Dara dungeon. Darkforces attack the city, freeing their leader Padan Fain and stealing the Horn of Valere and the tainted dagger that Mat needs to survive. Rand, Perrin Aybara, and Mat accompany a Shienaran party southbound in pursuit of the horn and dagger. Shienaran Lord Ingtar heads the group, which includes skilled tracker Hurin. Fain’s fleeing darkforce includes trollocs, myrddraal, and darkfriends. Nynaeve al'Meara and Egwene al'Vere accompany Moraine to Tar Valon for Aes Sedai training. Andoran Princess Elayne and clairvoyant Min arrive at Tar Valon as well. At Tar Valon's White Tower, Nynaeve passes the test to become Accepted, a rank in the White Tower below Aes Sedai and above a Novice. Rand, Loial and Hurin are separated from the Shienaran party and transported to an alternate world via a portal stone, a world similar to their own but where the land appears deserted and distorted. Rand suspects that he activated the portal stone by unconsciously channeling saidin in his sleep, although Egwene dreams that a mysterious woman is responsible. Rand's struggle to accept his channeling ability is a recurring element in the novel. In the Portal Stone world, Rand meets Ba'alzamon and has a heron branded into his palm in a fight. Later, they find another portal stone with the help of a mysterious woman called Selene. Rand is able to use the Stone to return to their own world, albeit much farther ahead than either Fain's or Ingtar's group. By hiding and waiting for the Darkfriends to catch up, they manage to sneak into Fain's camp and recover both Horn and dagger. At a loss to explain Rand's disappearance, Lord Ingtar's group continues tracking Padan Fain with the aid of Perrin. Perrin pretends to be another sniffer like Hurin, but secretly uses his wolf senses to smell and track and also ask nearby wolves which way Padan Fain's group went. Rand's party journeys to Cairhien, and Selene leaves their party without warning. Arriving in the city, Rand finds gleeman Thom Merrilin, whom he thought dead after an encounter with a myrddraal in The Eye of the World. Rand and Loial are attacked by trollocs and, during their escape, destroy the Chapter House of the Illuminator's Guild, a society of people who are extremely protective of their knowledge of fireworks. The Horn and dagger are once again lost. Later on Thom's apprentice and lover, Dena, is murdered for Thom's involvement with Rand. With the aid of Perrin, Ingtar's group is successfully reunited with Rand, and they learn that the Horn has been taken to Toman Head, at the port city of Falme. Hoping to get there faster, Rand tries to lead them through a portal stone. While successful, during his attempt the stone malfunctions and the group ends up losing time. As these events unfold, action also takes place on the other side of the continent, where the invading Seanchan and their exotic beasts have occupied Falme. Whitecloak Geofram Bornhald, of the zealous religious group Children of the Light, is preparing forces to attack the Seanchan. At the White Tower, Liandrin tells Egwene and Nynaeve that Rand and his friends are in danger. They, along with Elayne and Min, travel with her to Toman Head via Waygate. When they arrive Min is captured by the Seanchan and Egwene is collared with an a'dam, a device used by the Seanchan to control women who can channel. Nynaeve and Elayne escape. At Falme, Rand, Ingtar and the others form a small party to reclaim the dagger and Horn of Valere, consisting of Ingtar, Hurin, Rand, Perrin, and an increasingly sickly Mat. Rand sneaks into the building where the Horn is being kept, and slays blademaster High Lord Turak of the Seanchan before escaping with the Horn and dagger. Ingtar reveals himself as a Darkfriend and furthermore, that he was responsible for letting in the attackers during the surprise attack at Fal Dara, but he redeems himself when he dies fighting for Rand's group. At the same time, Elayne and Nynaeve rescue Egwene from the Seanchan and attempt to flee the city. At this moment the Whitecloaks also choose to attack, leaving the heroes trapped between the Seanchan and the Whitecloaks. Desperately, Mat blows the Horn of Valere, summoning forth dead heroes who aid Mat's cause. The resurrected heroes include Artur Hawkwing. The Seanchan easily defeat the Whitecloaks. The resurrected Heroes then overwhelm the Seanchan, who retreat back to their ships and sail off as the resurrected heroes fade away. Finally, Rand duels with Ba'alzamon, while their images appear in the sky, drawing the attention of all. Rand is initially unable to penetrate Ba'alzamon's defenses. Rand then leaves himself open while employing a final fighting maneuver Lan had taught him. Ba'alzamon strikes Rand as Rand lands a killing counter-blow slaying Ba'alzamon. Rand is severely wounded. Selene is revealed to be Lanfear, one of the most powerful Forsaken.",9780812517729,http://books.google.com/books/content?id=tuspQELrwhIC&printsec=frontcover&img=1&zoom=1&edge=curl&source=gbs_api,9780812517729,9780812517729,8.541666666666666,24.0,Science Fiction +23,23,42573,The Great Hunt,Robert Jordan,1990-11-15,Fantasy," Ba'alzamon presides over a clandestine meeting as Shadow forces plot their actions and Shaitan’s return. In addition to Forsaken and Darkfriends, the meeting includes two Aes Sedai, one of whom we come to know as Liandrin. The prologue shows how deep Ba'alzamon's influence has gone, even in places the protagonists believe to be safe. Following the events in The Eye of the World, the protagonists rest at Fort Fal Dara in Shienar, where the White Tower’s Amyrlin Seat, Siuan Sanche, visits. Siuan reminisces and plots with fellow Aes Sedai Moiraine Damodred and Verin. Rand al'Thor meets Siuan. Siuan tells Rand that he is the Dragon Reborn, which Rand denies. Mat's condition worsens as he is symbiotically attached to a tainted parasitic dagger. Lan Mandragoran further instructs Rand in swordfighting. Powerful Darkfriend Padan Fain is imprisoned in the Fal Dara dungeon. Darkforces attack the city, freeing their leader Padan Fain and stealing the Horn of Valere and the tainted dagger that Mat needs to survive. Rand, Perrin Aybara, and Mat accompany a Shienaran party southbound in pursuit of the horn and dagger. Shienaran Lord Ingtar heads the group, which includes skilled tracker Hurin. Fain’s fleeing darkforce includes trollocs, myrddraal, and darkfriends. Nynaeve al'Meara and Egwene al'Vere accompany Moraine to Tar Valon for Aes Sedai training. Andoran Princess Elayne and clairvoyant Min arrive at Tar Valon as well. At Tar Valon's White Tower, Nynaeve passes the test to become Accepted, a rank in the White Tower below Aes Sedai and above a Novice. Rand, Loial and Hurin are separated from the Shienaran party and transported to an alternate world via a portal stone, a world similar to their own but where the land appears deserted and distorted. Rand suspects that he activated the portal stone by unconsciously channeling saidin in his sleep, although Egwene dreams that a mysterious woman is responsible. Rand's struggle to accept his channeling ability is a recurring element in the novel. In the Portal Stone world, Rand meets Ba'alzamon and has a heron branded into his palm in a fight. Later, they find another portal stone with the help of a mysterious woman called Selene. Rand is able to use the Stone to return to their own world, albeit much farther ahead than either Fain's or Ingtar's group. By hiding and waiting for the Darkfriends to catch up, they manage to sneak into Fain's camp and recover both Horn and dagger. At a loss to explain Rand's disappearance, Lord Ingtar's group continues tracking Padan Fain with the aid of Perrin. Perrin pretends to be another sniffer like Hurin, but secretly uses his wolf senses to smell and track and also ask nearby wolves which way Padan Fain's group went. Rand's party journeys to Cairhien, and Selene leaves their party without warning. Arriving in the city, Rand finds gleeman Thom Merrilin, whom he thought dead after an encounter with a myrddraal in The Eye of the World. Rand and Loial are attacked by trollocs and, during their escape, destroy the Chapter House of the Illuminator's Guild, a society of people who are extremely protective of their knowledge of fireworks. The Horn and dagger are once again lost. Later on Thom's apprentice and lover, Dena, is murdered for Thom's involvement with Rand. With the aid of Perrin, Ingtar's group is successfully reunited with Rand, and they learn that the Horn has been taken to Toman Head, at the port city of Falme. Hoping to get there faster, Rand tries to lead them through a portal stone. While successful, during his attempt the stone malfunctions and the group ends up losing time. As these events unfold, action also takes place on the other side of the continent, where the invading Seanchan and their exotic beasts have occupied Falme. Whitecloak Geofram Bornhald, of the zealous religious group Children of the Light, is preparing forces to attack the Seanchan. At the White Tower, Liandrin tells Egwene and Nynaeve that Rand and his friends are in danger. They, along with Elayne and Min, travel with her to Toman Head via Waygate. When they arrive Min is captured by the Seanchan and Egwene is collared with an a'dam, a device used by the Seanchan to control women who can channel. Nynaeve and Elayne escape. At Falme, Rand, Ingtar and the others form a small party to reclaim the dagger and Horn of Valere, consisting of Ingtar, Hurin, Rand, Perrin, and an increasingly sickly Mat. Rand sneaks into the building where the Horn is being kept, and slays blademaster High Lord Turak of the Seanchan before escaping with the Horn and dagger. Ingtar reveals himself as a Darkfriend and furthermore, that he was responsible for letting in the attackers during the surprise attack at Fal Dara, but he redeems himself when he dies fighting for Rand's group. At the same time, Elayne and Nynaeve rescue Egwene from the Seanchan and attempt to flee the city. At this moment the Whitecloaks also choose to attack, leaving the heroes trapped between the Seanchan and the Whitecloaks. Desperately, Mat blows the Horn of Valere, summoning forth dead heroes who aid Mat's cause. The resurrected heroes include Artur Hawkwing. The Seanchan easily defeat the Whitecloaks. The resurrected Heroes then overwhelm the Seanchan, who retreat back to their ships and sail off as the resurrected heroes fade away. Finally, Rand duels with Ba'alzamon, while their images appear in the sky, drawing the attention of all. Rand is initially unable to penetrate Ba'alzamon's defenses. Rand then leaves himself open while employing a final fighting maneuver Lan had taught him. Ba'alzamon strikes Rand as Rand lands a killing counter-blow slaying Ba'alzamon. Rand is severely wounded. Selene is revealed to be Lanfear, one of the most powerful Forsaken.",9780812517729,http://books.google.com/books/content?id=tuspQELrwhIC&printsec=frontcover&img=1&zoom=1&edge=curl&source=gbs_api,9780812517729,9780812517729,8.541666666666666,24.0,Fantasy +24,24,42574,A Crown of Swords,Robert Jordan,1996-05-15,Speculative fiction," A Crown of Swords has three primary plotlines: * Rand al'Thor, the Dragon Reborn, prepares to attack the Forsaken Sammael in Illian while enjoying life with his friend, Min Farshaw, and attempting to quell the rebellion by nobles in Cairhien, during which Padan Fain severely injures him with the Shadar Logoth dagger. After recovering, Rand, accompanied by Asha'man, attacks Illian and defeats Sammael in a duel of the One Power in Shadar Logoth, where Sammael is destroyed by Mashadar. Rand then takes the crown of Illian, formerly the Laurel Crown, but now called the Crown of Swords. * Egwene al'Vere and Siuan Sanche attempt to manipulate the Aes Sedai rebels in Salidar to move against Elaida's Aes Sedai in the White Tower in Tar Valon. After Egwene and Siuan investigate Siuan's suspicions about Myrelle, Egwene exploits the transfer of Lan's Warder bond from Moiraine to Myrelle in order to force Myrelle and Nisao to swear fealty to her. * In the city of Ebou Dar in Altara, Elayne Trakand, Nynaeve al'Meara, Aviendha, and Mat Cauthon search for a ter'angreal, the Bowl of the Winds, to break the unnatural heat brought on by the Dark One's manipulation of climate. They find it and enlist the help of the Kin and the Atha'an Miere, or Sea Folk. They also confront a Gholam. Mat is left behind after searching for Olver, and is caught in the fighting as the Seanchan invade Ebou Dar.",9781857234039,http://books.google.com/books/content?id=_rSqQgAACAAJ&printsec=frontcover&img=1&zoom=1&source=gbs_api,9781857234039,9781857234039,,,Science Fiction +25,24,42574,A Crown of Swords,Robert Jordan,1996-05-15,Fantasy," A Crown of Swords has three primary plotlines: * Rand al'Thor, the Dragon Reborn, prepares to attack the Forsaken Sammael in Illian while enjoying life with his friend, Min Farshaw, and attempting to quell the rebellion by nobles in Cairhien, during which Padan Fain severely injures him with the Shadar Logoth dagger. After recovering, Rand, accompanied by Asha'man, attacks Illian and defeats Sammael in a duel of the One Power in Shadar Logoth, where Sammael is destroyed by Mashadar. Rand then takes the crown of Illian, formerly the Laurel Crown, but now called the Crown of Swords. * Egwene al'Vere and Siuan Sanche attempt to manipulate the Aes Sedai rebels in Salidar to move against Elaida's Aes Sedai in the White Tower in Tar Valon. After Egwene and Siuan investigate Siuan's suspicions about Myrelle, Egwene exploits the transfer of Lan's Warder bond from Moiraine to Myrelle in order to force Myrelle and Nisao to swear fealty to her. * In the city of Ebou Dar in Altara, Elayne Trakand, Nynaeve al'Meara, Aviendha, and Mat Cauthon search for a ter'angreal, the Bowl of the Winds, to break the unnatural heat brought on by the Dark One's manipulation of climate. They find it and enlist the help of the Kin and the Atha'an Miere, or Sea Folk. They also confront a Gholam. Mat is left behind after searching for Olver, and is caught in the fighting as the Seanchan invade Ebou Dar.",9781857234039,http://books.google.com/books/content?id=_rSqQgAACAAJ&printsec=frontcover&img=1&zoom=1&source=gbs_api,9781857234039,9781857234039,,,Fantasy +26,25,42575,Winter's Heart,Robert Jordan,2000-11-07,Speculative fiction," Many of the events of Winter's Heart take place simultaneously with the events of the next book, Crossroads of Twilight. Perrin Aybara and his followers pursue the Shaido Aiel who kidnapped his wife, Faile Bashere. Elayne Trakand attempts to solidify her grip on the Lion Throne and put down rebellious nobles. Mat Cauthon, making his return to the series after his absence in the previous book, is trapped in the city of Ebou Dar in Altara, which is under Seanchan occupation. He plans his escape, but in the end, his plans are disrupted by the interference of a Seanchan noblewoman named Tuon, who is revealed as the Daughter of the Nine Moons, heir to the Seanchan Crystal Throne. Mat, having heard a prophecy about him marrying the Daughter of the Nine Moons, kidnaps Tuon instead of tying her up and leaving her behind. Rand al'Thor, the Dragon Reborn, is bonded as a Warder by Elayne Trakand, Aviendha, and Min Farshaw. He hunts down Asha'man traitors in Far Madding and kills most of them. Lan also kills Toram Riatin in a duel. Caught by guards, he is imprisoned for a short time but is set free by Cadsuane and the other Aes Sedai who followed him. Rand and Nynaeve al'Meara Travel to Shadar Logoth. There, defended by Cadsuane Melaidhrin's Aes Sedai and loyal Asha'man against the Forsaken, Rand and Nynaeve link and use the Choedan Kal to cleanse saidin of the Dark One's taint so that men who channel will no longer go mad. Whilst using so much of the One Power, the access key (of the female Choedan Kal) is destroyed. During the course of the events of the book, Rand al'Thor made an extraordinary claim: he believed he had discovered how to cleanse the Dark One's 3000-year-old taint on saidin. He discovered how to do this upon careful questioning of the Aelfinn, as well as of Herid Fel. His preparations bore great fruit when he and Nynaeve al'Meara used the two most powerful sa'angreal ever made (the Choedan Kal) to funnel the taint into Shadar Logoth. Rand al'Thor did this by creating a funnel of pure saidar and forcing saidin through the funnel. The evil in Shadar Logoth, which was born out of pure hate for the Shadow and the Dark One, attracted and reacted with the taint of saidin, and the two forces annihilated each other, removing the taint from saidin. In Knife of Dreams, it has been confirmed that saidin is clean, by both Aes Sedai and Asha'man. However, according to Jordan himself, though sane channelers no longer need to fear its destructive effects, it does not restore any already affected by it to their former selves (as far as madness is concerned, presumably the rotting sickness can now be cured). During the cleansing, a battle took place between the forces of light and the shadow. The forces of light under Cadsuane split into several groups of Aes Sedai and Asha'man linked to be ready for the upcoming attack. The Aes Sedai Sarene and Corele linked with the Asha'man Damer Flinn, while Elza (who is secretly Black Ajah) and Merise linked with Jahar (one of Merise's warders, wielding Callandor). Nesune, Beldeine, Daigian linked with Eben Hopwil. Verin and Kumira linked with a Sea Folk Windfinder Shalon. The former Damane Alivia fought without being linked, helped by a set of Angreal and Ter'angreal presumably made for battle, and by virtue of fact that she was (and is currently) the strongest and most experienced female channeler for the Light in the series thus far. The forces of the Shadow consisted of Cyndane (formerly Lanfear), Demandred, Osan'gar (formerly Aginor, who we find out has been masquerading as Corlan Dashiva, an Asha'man), Moghedien, Graendal and Aran'gar who was formerly Balthamel and now is in a female body but still channels saidin. During the fight, Osan'gar was killed by Elza (ironically a Black Ajah), Eben Hopwil by Aran'gar and Kumira by Graendal. It has also resulted in the utter destruction of the female Choedan Kal and its access key, which triggered the mass suicide of Amayar along the Islands of the Sea Folk, who believed the giant statue's destruction to signal the end of their Age of Illusion.",9781429960687,http://books.google.com/books/content?id=u9vGo30fXuEC&printsec=frontcover&img=1&zoom=1&edge=curl&source=gbs_api,9781429960687,9781429960687,,,Science Fiction +27,25,42575,Winter's Heart,Robert Jordan,2000-11-07,Fantasy," Many of the events of Winter's Heart take place simultaneously with the events of the next book, Crossroads of Twilight. Perrin Aybara and his followers pursue the Shaido Aiel who kidnapped his wife, Faile Bashere. Elayne Trakand attempts to solidify her grip on the Lion Throne and put down rebellious nobles. Mat Cauthon, making his return to the series after his absence in the previous book, is trapped in the city of Ebou Dar in Altara, which is under Seanchan occupation. He plans his escape, but in the end, his plans are disrupted by the interference of a Seanchan noblewoman named Tuon, who is revealed as the Daughter of the Nine Moons, heir to the Seanchan Crystal Throne. Mat, having heard a prophecy about him marrying the Daughter of the Nine Moons, kidnaps Tuon instead of tying her up and leaving her behind. Rand al'Thor, the Dragon Reborn, is bonded as a Warder by Elayne Trakand, Aviendha, and Min Farshaw. He hunts down Asha'man traitors in Far Madding and kills most of them. Lan also kills Toram Riatin in a duel. Caught by guards, he is imprisoned for a short time but is set free by Cadsuane and the other Aes Sedai who followed him. Rand and Nynaeve al'Meara Travel to Shadar Logoth. There, defended by Cadsuane Melaidhrin's Aes Sedai and loyal Asha'man against the Forsaken, Rand and Nynaeve link and use the Choedan Kal to cleanse saidin of the Dark One's taint so that men who channel will no longer go mad. Whilst using so much of the One Power, the access key (of the female Choedan Kal) is destroyed. During the course of the events of the book, Rand al'Thor made an extraordinary claim: he believed he had discovered how to cleanse the Dark One's 3000-year-old taint on saidin. He discovered how to do this upon careful questioning of the Aelfinn, as well as of Herid Fel. His preparations bore great fruit when he and Nynaeve al'Meara used the two most powerful sa'angreal ever made (the Choedan Kal) to funnel the taint into Shadar Logoth. Rand al'Thor did this by creating a funnel of pure saidar and forcing saidin through the funnel. The evil in Shadar Logoth, which was born out of pure hate for the Shadow and the Dark One, attracted and reacted with the taint of saidin, and the two forces annihilated each other, removing the taint from saidin. In Knife of Dreams, it has been confirmed that saidin is clean, by both Aes Sedai and Asha'man. However, according to Jordan himself, though sane channelers no longer need to fear its destructive effects, it does not restore any already affected by it to their former selves (as far as madness is concerned, presumably the rotting sickness can now be cured). During the cleansing, a battle took place between the forces of light and the shadow. The forces of light under Cadsuane split into several groups of Aes Sedai and Asha'man linked to be ready for the upcoming attack. The Aes Sedai Sarene and Corele linked with the Asha'man Damer Flinn, while Elza (who is secretly Black Ajah) and Merise linked with Jahar (one of Merise's warders, wielding Callandor). Nesune, Beldeine, Daigian linked with Eben Hopwil. Verin and Kumira linked with a Sea Folk Windfinder Shalon. The former Damane Alivia fought without being linked, helped by a set of Angreal and Ter'angreal presumably made for battle, and by virtue of fact that she was (and is currently) the strongest and most experienced female channeler for the Light in the series thus far. The forces of the Shadow consisted of Cyndane (formerly Lanfear), Demandred, Osan'gar (formerly Aginor, who we find out has been masquerading as Corlan Dashiva, an Asha'man), Moghedien, Graendal and Aran'gar who was formerly Balthamel and now is in a female body but still channels saidin. During the fight, Osan'gar was killed by Elza (ironically a Black Ajah), Eben Hopwil by Aran'gar and Kumira by Graendal. It has also resulted in the utter destruction of the female Choedan Kal and its access key, which triggered the mass suicide of Amayar along the Islands of the Sea Folk, who believed the giant statue's destruction to signal the end of their Age of Illusion.",9781429960687,http://books.google.com/books/content?id=u9vGo30fXuEC&printsec=frontcover&img=1&zoom=1&edge=curl&source=gbs_api,9781429960687,9781429960687,,,Fantasy +28,26,42906,The Queen of the Damned,Anne Rice,1988-10,Horror," Part One follows several different people over the same period of several days. Several of the characters appear in the two previous books, including Armand, Daniel (the ""boy reporter"" of Interview with the Vampire), Marius, Louis, Gabrielle and Santino. Each of the six chapters in Part One tells a different story about a different person or group of people. Two things unify these chapters: a series of dreams about red-haired twin sisters, and the fact that a powerful being is killing vampires around the world by means of spontaneous combustion. Pandora and Santino rescue Marius, having answered his telepathic call for help. Marius informs his rescuers that Akasha has been awakened by Lestat, or rather his rock music, for he has joined a rock band of mortals whose names are Alex, Larry and Tough Cookie. Having been awakened by Lestat's rebellious music, Akasha destroys her husband Enkil and plots to rule the world. Akasha is also revealed as the source of the attacks on other vampires. Part Two takes place at Lestat's concert. Jesse, a member of the secret Talamasca and relative of Maharet, is mortally injured while attending the concert, and is taken to Maharet's Sonoma compound where she is made into a vampire. The vampires from Part One later congregate in the Sonoma compound. The only vampires not present are Akasha and Lestat. Akasha has abducted Lestat and takes him as an unwilling consort to various locations in the world, inciting women to rise up and kill the men who have oppressed them. Part Three takes place at Maharet's home in a Sonoma forest. There Maharet tells the story of Akasha and the red-haired twins (who are, in fact, Maharet and her sister, Mekare) to Pandora, Jesse, Marius, Santino, Eric, Armand, Daniel, Louis and Gabrielle. Also present are Mael and Khayman, who already know the story. In Part Four, Akasha confronts the gathered vampires at Maharet's compound. There she explains her plans and offers the vampires a chance to be her ""angels"" in her New World Order. Akasha plans to kill 90 percent of the world's human men, and to establish a new Eden in which women will worship Akasha as a goddess. If the assembled vampires refuse to follow her, she will destroy them. The vampires refuse, but before Akasha can destroy them, Mekare enters. Mekare kills Akasha by severing her head. Mekare then consumes Akasha's brain and heart, thereby saving the lives of the remaining vampires and becoming the new Queen of the Damned. In Part Five, the vampires leave Maharet's compound and assemble at Armand's resort, the Night Island, (according to Anne Rice, inspired by Fire Island) in Florida to recover. They eventually go their separate ways (as told in The Tale of the Body Thief). Lestat takes Louis to see David Talbot in London. After their brief visit with Talbot they depart into the night, an incensed Louis and his angry words filling Lestat with glee. The Queen of the Damned, deals with the origins of vampires themselves. The mother of all vampires, Akasha, begins as a pre-Egyptian queen, in a land called Kemet (which will become Egypt), many thousands of years ago. During this time two powerful witches (Maharet and Mekare) live in the mountains of an unnamed region. The witches are able to communicate with invisible spirits and gain simple favors from them. During this period there is a bloodthirsty, invisible spirit known as Amel who continually asks the two witches if they need his assistance, although they prudently decline the offer. The witches' village is destroyed and they are incarcerated by the king and queen, who desire their knowledge. When the witches offend Akasha, the Queen condemns the twins. Enkil then orders his chief steward (who is Khayman as a mortal man) to rape the twins in his stead, which would prove their lack of power, before the eyes of the court. Afterward the witches are cast out into the desert. While making her way back home with a pregnant Maharet, Mekare curses the king and queen secretly with the bloodthirsty spirit. Eventually this spirit inflicts such torment on Akasha and Enkil that they again demand advice and help from the two witches. Conspirators, unhappy with the young king's policies, assassinate the royal couple in Khayman's house whilst they were attempting to exorcise Amel, who had been tormenting Khayman. While the king and queen lie dying, the evil spirit sees its chance to ensnare the soul of the dying queen and pulls it back into her body. The spirit combines itself with the flesh and blood of the queen, transforming her into a vampire. Akasha allows the king to drink her blood, which saves his life. They then order Khayman to find the witches and bring them back to Egypt so that they could use their knowledge of spirits to help them, as they feel guilty because of their thirst for blood. However, when the witches admit that they cannot help the monarchs, Akasha orders the mutilation of the witches: Maharet loses her eyes and Mekare her tongue. Afterward, Khayman, who had been turned into a vampire by Akasha, comes to the witches' cell and turns them too. The three flee together, but are caught by Akasha's soldiers. Khayman escapes, but Maharet and Mekare are further punished. The witches are put into two separate coffins which are then set afloat on two separate bodies of water. They are only reunited near the end of the novel Queen of the Damned. In Mekare's absence, Maharet returns to watch over her daughter and her descendants. Maharet's descendants become what she calls the Great Family. A maternal line, the Great Family includes every culture, religion, ethnicity, and race. The Great Family represents all humanity and shows the vampires what Akasha would destroy with the creation of her New World Order. As the source of all vampires, Akasha is connected to all vampires by the blood and spirit they collectively share. In an experiment by the first Keeper, Akasha and Enkil are exposed to sunlight when they are several thousand years old. This merely darkens their skin. However, the result on all other vampires is extreme, and many of the weakest vampires die, thus confirming the legend that anything that harms Akasha will also directly affect all of her progeny.",9780307575890,http://books.google.com/books/content?id=-xXaKrrBY40C&printsec=frontcover&img=1&zoom=1&edge=curl&source=gbs_api,9780307575890,9780307575890,,,Horror +29,26,42906,The Queen of the Damned,Anne Rice,1988-10,Supernatural," Part One follows several different people over the same period of several days. Several of the characters appear in the two previous books, including Armand, Daniel (the ""boy reporter"" of Interview with the Vampire), Marius, Louis, Gabrielle and Santino. Each of the six chapters in Part One tells a different story about a different person or group of people. Two things unify these chapters: a series of dreams about red-haired twin sisters, and the fact that a powerful being is killing vampires around the world by means of spontaneous combustion. Pandora and Santino rescue Marius, having answered his telepathic call for help. Marius informs his rescuers that Akasha has been awakened by Lestat, or rather his rock music, for he has joined a rock band of mortals whose names are Alex, Larry and Tough Cookie. Having been awakened by Lestat's rebellious music, Akasha destroys her husband Enkil and plots to rule the world. Akasha is also revealed as the source of the attacks on other vampires. Part Two takes place at Lestat's concert. Jesse, a member of the secret Talamasca and relative of Maharet, is mortally injured while attending the concert, and is taken to Maharet's Sonoma compound where she is made into a vampire. The vampires from Part One later congregate in the Sonoma compound. The only vampires not present are Akasha and Lestat. Akasha has abducted Lestat and takes him as an unwilling consort to various locations in the world, inciting women to rise up and kill the men who have oppressed them. Part Three takes place at Maharet's home in a Sonoma forest. There Maharet tells the story of Akasha and the red-haired twins (who are, in fact, Maharet and her sister, Mekare) to Pandora, Jesse, Marius, Santino, Eric, Armand, Daniel, Louis and Gabrielle. Also present are Mael and Khayman, who already know the story. In Part Four, Akasha confronts the gathered vampires at Maharet's compound. There she explains her plans and offers the vampires a chance to be her ""angels"" in her New World Order. Akasha plans to kill 90 percent of the world's human men, and to establish a new Eden in which women will worship Akasha as a goddess. If the assembled vampires refuse to follow her, she will destroy them. The vampires refuse, but before Akasha can destroy them, Mekare enters. Mekare kills Akasha by severing her head. Mekare then consumes Akasha's brain and heart, thereby saving the lives of the remaining vampires and becoming the new Queen of the Damned. In Part Five, the vampires leave Maharet's compound and assemble at Armand's resort, the Night Island, (according to Anne Rice, inspired by Fire Island) in Florida to recover. They eventually go their separate ways (as told in The Tale of the Body Thief). Lestat takes Louis to see David Talbot in London. After their brief visit with Talbot they depart into the night, an incensed Louis and his angry words filling Lestat with glee. The Queen of the Damned, deals with the origins of vampires themselves. The mother of all vampires, Akasha, begins as a pre-Egyptian queen, in a land called Kemet (which will become Egypt), many thousands of years ago. During this time two powerful witches (Maharet and Mekare) live in the mountains of an unnamed region. The witches are able to communicate with invisible spirits and gain simple favors from them. During this period there is a bloodthirsty, invisible spirit known as Amel who continually asks the two witches if they need his assistance, although they prudently decline the offer. The witches' village is destroyed and they are incarcerated by the king and queen, who desire their knowledge. When the witches offend Akasha, the Queen condemns the twins. Enkil then orders his chief steward (who is Khayman as a mortal man) to rape the twins in his stead, which would prove their lack of power, before the eyes of the court. Afterward the witches are cast out into the desert. While making her way back home with a pregnant Maharet, Mekare curses the king and queen secretly with the bloodthirsty spirit. Eventually this spirit inflicts such torment on Akasha and Enkil that they again demand advice and help from the two witches. Conspirators, unhappy with the young king's policies, assassinate the royal couple in Khayman's house whilst they were attempting to exorcise Amel, who had been tormenting Khayman. While the king and queen lie dying, the evil spirit sees its chance to ensnare the soul of the dying queen and pulls it back into her body. The spirit combines itself with the flesh and blood of the queen, transforming her into a vampire. Akasha allows the king to drink her blood, which saves his life. They then order Khayman to find the witches and bring them back to Egypt so that they could use their knowledge of spirits to help them, as they feel guilty because of their thirst for blood. However, when the witches admit that they cannot help the monarchs, Akasha orders the mutilation of the witches: Maharet loses her eyes and Mekare her tongue. Afterward, Khayman, who had been turned into a vampire by Akasha, comes to the witches' cell and turns them too. The three flee together, but are caught by Akasha's soldiers. Khayman escapes, but Maharet and Mekare are further punished. The witches are put into two separate coffins which are then set afloat on two separate bodies of water. They are only reunited near the end of the novel Queen of the Damned. In Mekare's absence, Maharet returns to watch over her daughter and her descendants. Maharet's descendants become what she calls the Great Family. A maternal line, the Great Family includes every culture, religion, ethnicity, and race. The Great Family represents all humanity and shows the vampires what Akasha would destroy with the creation of her New World Order. As the source of all vampires, Akasha is connected to all vampires by the blood and spirit they collectively share. In an experiment by the first Keeper, Akasha and Enkil are exposed to sunlight when they are several thousand years old. This merely darkens their skin. However, the result on all other vampires is extreme, and many of the weakest vampires die, thus confirming the legend that anything that harms Akasha will also directly affect all of her progeny.",9780307575890,http://books.google.com/books/content?id=-xXaKrrBY40C&printsec=frontcover&img=1&zoom=1&edge=curl&source=gbs_api,9780307575890,9780307575890,,,Other diff --git a/bookworm/search.py b/bookworm/search.py index fef99ef..068ee0a 100644 --- a/bookworm/search.py +++ b/bookworm/search.py @@ -42,7 +42,6 @@ """ import os - import ast import numpy as np from sklearn.feature_extraction.text import TfidfVectorizer @@ -151,7 +150,7 @@ def query_to_index(df, query, columns, vectorizer=None, num_idx=1): """ Maps query to the closest book index via keyword search. - Maps query based to the closes book in dataframe (df) + Maps query based to the closest book in dataframe (df) based on keyword search using given vectorizer(default is TfidfVectorizer). Then returns the index of that book in the dataframe. diff --git a/bookworm/tests/test_search.py b/bookworm/tests/test_search.py index 10a5c02..17a4910 100644 --- a/bookworm/tests/test_search.py +++ b/bookworm/tests/test_search.py @@ -36,17 +36,26 @@ Test Functions in TestSearch Class ====================================== -test_plot_semantic(self): - Test plot_semantic_search against expected result. +test_keyword_exact(self): + Confirms that exact match queries return expected match. -test_keyword_close(self): - Confirms that close match queries return expected match. +test_author2_search_exact(self): + Confirm author2_search returs books by that author only; exact match. -test_keyword_exact(self): - Confirms that exact match queries return expected match. - +test_author2_search_close(self): + Confirm author2_search returs books by that author only; close match. + +test_author2_search_nomatch(self): + Confirm error raised if no matching author. + +test_plot_semantic(self): + Test plot_semantic_search against expected result. +test_genre_one_shot(self): + Confirm genre search returns expected result. +test_genre_all: + Confirm sum of all genres is sum of all rows in data. Dependencies: - unittest: The built-in unit testing framework in Python. @@ -200,6 +209,8 @@ def setUp(self): self.test_dat_e = pd.read_csv(f_embed) f_ratings = "data/test_data/test_data.csv" self.test_dat_r = pd.read_csv(f_ratings) + f_genre = "data/test_data/test_genre.csv" + self.test_data_g = pd.read_csv(f_genre) def test_keyword_exact(self): @@ -207,7 +218,7 @@ def test_keyword_exact(self): Confirms that exact match queries return expected match Pattern test. In any case where the query string is an exact - and unique match to the title of a book in the datset + match to the title of a book in the datset we expect the first book returned to be the exact match. """ for idx in range(2): @@ -241,7 +252,7 @@ def test_author2_search_close(self): Confirm author2_search returs books by that author only; close match. One shot test. Search for author "JR Tolkien" to see if first - book return is by "J.R.R. Tolkien" as listed in test data. + book returned is by "J.R.R. Tolkien" as listed in test data. """ query = "JRR Tolkien" books = search.author2_search(self.test_dat_r, query, num_books=10) @@ -290,6 +301,37 @@ def test_plot_semantic(self): # expected = self.test_dat.iloc[7]["book_id"] # 7 = idx for Leaf by Niggle # self.assertEqual(results, expected) + def test_genre_one_shot(self): + """ + Confirm genre search returns expected result. + + Using test data, genre search for "Horrer" should return + one book, titled "The Queen of the Damned." + """ + df = self.test_data_g + query = "Horror" + results = search.genre_search(df, query).iloc[0]["book_title"] + expected = "The Queen of the Damned" + self.assertEqual(results,expected) + + def test_genre_all(self): + """ Confirm sum of all genres is sum of dataset. + + Iterates over the rows in the test data. Counts the number + of rows returned for each genre and sums the total. Expected + total sum is the number of rows in the genre dataset. + """ + df = self.test_data_g + all_genres = set(df["generic_genre"]) + count = 0 + for genre in all_genres: + results = search.genre_search(df, genre, num_books=df.shape[0]) + count += results.shape[0] + expected = df.shape[0] + self.assertEqual(count, expected) + + + if __name__ == '__main__': unittest.main() From 85c6c91edbd2dccbfe5c51909bfc68567b231155 Mon Sep 17 00:00:00 2001 From: sue-t-boyd Date: Sat, 9 Mar 2024 17:50:58 -0800 Subject: [PATCH 03/10] organize folders in scripts --- scripts/create_test_data/__init__.py | 7 ++++++ scripts/create_test_data/create_test_genre.py | 19 +++++++++++++++ .../embeddings_test_data.py | 23 +++++++++---------- 3 files changed, 37 insertions(+), 12 deletions(-) create mode 100644 scripts/create_test_data/__init__.py create mode 100644 scripts/create_test_data/create_test_genre.py rename scripts/{ => create_test_data}/embeddings_test_data.py (63%) diff --git a/scripts/create_test_data/__init__.py b/scripts/create_test_data/__init__.py new file mode 100644 index 0000000..65c9794 --- /dev/null +++ b/scripts/create_test_data/__init__.py @@ -0,0 +1,7 @@ +import os +from dotenv import load_dotenv + +# load environment variables from .env file +load_dotenv() +# load API for embeddings voyage +API_KEY = os.environ['API_KEY'] diff --git a/scripts/create_test_data/create_test_genre.py b/scripts/create_test_data/create_test_genre.py new file mode 100644 index 0000000..601e7f0 --- /dev/null +++ b/scripts/create_test_data/create_test_genre.py @@ -0,0 +1,19 @@ +""" +Script to create smaller test version of genres data. + +Module should be run from /scripts folder. + +""" + +import pandas as pd +genres = pd.read_csv(f = "../data/genre.csv") +print(genres.shape) + + +test_genre = genres.head(30) +print(test_genre.shape) +print(test_genre.head) +test_genre.to_csv("../data/test_data/test_genre.csv") + +genre_types = set(test_genre["generic_genre"].tolist()) +print(genre_types) diff --git a/scripts/embeddings_test_data.py b/scripts/create_test_data/embeddings_test_data.py similarity index 63% rename from scripts/embeddings_test_data.py rename to scripts/create_test_data/embeddings_test_data.py index ab26b94..f26d599 100644 --- a/scripts/embeddings_test_data.py +++ b/scripts/create_test_data/embeddings_test_data.py @@ -1,22 +1,22 @@ """ -Script to create embeddings for test data +Script to create embeddings for test data. + +Module should be run from /scripts folder. """ -#import os import pandas as pd +import numpy as np import nltk -#from nltk.tokenize import word_tokenize import voyageai +from . import API_KEY + +#load test data +df = pd.read_csv("../bookworm/data/test_data/test_data.csv") -nltk.download('punkt') -f_test_dat = "bookworm/data/test_data/test_data.csv" -df = pd.read_csv(f_test_dat) -# load API for embeddings voyage -#api_key = os.environ['API_KEY'] -api_key = "pa-rhN-u_ArM1uxKF78V1JeB8-TJZM0lQlA60SIavXNHbg" -vo = voyageai.Client(api_key=api_key) +# prep voyeageai creds +vo = voyageai.Client(api_key=API_KEY) def token_count(summary): """ @@ -42,5 +42,4 @@ def token_count(summary): filtered_df["embeddings"] = embeddings # save to CSV -f_test_dat_embed = "bookworm/data/test_data/test_data_w_embeddings.csv" -filtered_df.to_csv(f_test_dat_embed) +filtered_df.to_csv("../bookworm/data/test_data/test_data_w_embeddings.csv") From 9f17108a71ebd344c9eaa26cee9512889cd88ce6 Mon Sep 17 00:00:00 2001 From: sue-t-boyd Date: Mon, 11 Mar 2024 10:48:37 -0700 Subject: [PATCH 04/10] Add spinner and documentation to App.py --- bookworm/tests/test_app.py | 16 ++++++++-------- scripts/__init__.py | 7 +++++++ 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/bookworm/tests/test_app.py b/bookworm/tests/test_app.py index 137c131..5a21533 100644 --- a/bookworm/tests/test_app.py +++ b/bookworm/tests/test_app.py @@ -33,7 +33,7 @@ from app import main, display_avg_ratings_slider, display_num_ratings_slider, \ display_search_mode_ui, display_search_value_ui, \ - display_genre_dropdown, display_search_button, execute_query + display_genre_dropdown, display_search_button class TestStreamlitUI(unittest.TestCase): @@ -103,13 +103,13 @@ def test_display_search_button(self): result = display_search_button() self.assertTrue(result) - def test_execute_query(self): - """Test execute_query function.""" - with patch('streamlit.write') as mock_write: - execute_query("Title", "The Great Gatsby", 8.0, 20) - mock_write.assert_called_once_with( - "Searching for books using Title, value: The Great Gatsby, " - "min average rating: 8.0, min number of ratings: 20") + # def test_execute_query(self): + # """Test execute_query function.""" + # with patch('streamlit.write') as mock_write: + # execute_query("Title", "The Great Gatsby", 8.0, 20) + # mock_write.assert_called_once_with( + # "Searching for books using Title, value: The Great Gatsby, " + # "min average rating: 8.0, min number of ratings: 20") if __name__ == '__main__': diff --git a/scripts/__init__.py b/scripts/__init__.py index e69de29..65c9794 100644 --- a/scripts/__init__.py +++ b/scripts/__init__.py @@ -0,0 +1,7 @@ +import os +from dotenv import load_dotenv + +# load environment variables from .env file +load_dotenv() +# load API for embeddings voyage +API_KEY = os.environ['API_KEY'] From 007a0a5341f017c78ce25189f2e4a0b85a253b6c Mon Sep 17 00:00:00 2001 From: sue-t-boyd Date: Mon, 11 Mar 2024 10:51:35 -0700 Subject: [PATCH 05/10] Add pylint checking to buildtest --- .github/workflows/build_test.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build_test.yml b/.github/workflows/build_test.yml index c4c9130..9d74172 100644 --- a/.github/workflows/build_test.yml +++ b/.github/workflows/build_test.yml @@ -89,10 +89,10 @@ jobs: # If there are any other steps in order for your tests to # run successfully, you can add those steps here! - # Next step: run pylint. Anything less than 10/10 will fail. - #- name: Lint with pylint - # run: | - # pylint bookworm/**/*.py + # Next step: run pylint. Anything less than 10/10 will fail. + - name: Lint with pylint + run: | + pylint bookworm/**/*.py # Next step: run the unit tests with code coverage. - name: Unit tests From 5e2573c1598a8d0d22002af868ed5188c789fba4 Mon Sep 17 00:00:00 2001 From: sue-t-boyd Date: Mon, 11 Mar 2024 11:00:32 -0700 Subject: [PATCH 06/10] Fix import error test_app --- bookworm/app.py | 123 ++++++++++++++++++++++++++++--------- bookworm/tests/test_app.py | 14 +++-- 2 files changed, 104 insertions(+), 33 deletions(-) diff --git a/bookworm/app.py b/bookworm/app.py index 9921ad8..a28cc0d 100644 --- a/bookworm/app.py +++ b/bookworm/app.py @@ -1,8 +1,32 @@ -import base64 -import streamlit as st -import streamlit.components.v1 as components +""" +UI Module for Bookworm App + +FUNCTIONS +======== +display_avg_ratings_slider(): + Displays average ratings slider; returns input. + +display_num_ratings_slider(): + Displays slider for number of ratings; returns input. + +display_search_mode_ui(): + Displays text box for user to enter desired search method; returns input. + +display_search_value_ui(search_mode): + Displays text box for user to enter query to search; retrieves user input. + +display_genre_dropdown(): + Displays drop down menu for genre selection; retrieves value; returns input. + +main() + Displays UI; gathers user feedback; executes serach. + +""" +import base64 +import streamlit as st +#import streamlit.components.v1 as components try: from search_wrapper import search_wrapper except ImportError: @@ -49,18 +73,38 @@ def local_css(file_name): # DEFINE EACH UI ELEMENT AS A SEPARATE FUNCTION def display_avg_ratings_slider(): + """ + Displays average ratings slider, values 0 to 10. Returns user input. + + Return value + User's selected average ratings, as a float. + """ return st.slider("Exclude Books with Average Ratings Lower than:", min_value=0.0, max_value=10.0, value=0.0, step=0.5, key="Ave. Ratings Slider", help="Set the minimum average rating.") def display_num_ratings_slider(): + """ + Displays slider for number of ratings; returns user input. + + Return value + User's selected number of ratings, as an int. + + """ return st.slider("Exclude Books that have been rated by fewer than:", min_value=0, max_value=50, value=0, step=1, key="Num. Ratings Slider", help="Set the minimum number of ratings.") def display_search_mode_ui(): + """ + Display text box for user to enter desired search method; returns input. + + Return value + User's search mode selection, as a string. + """ + help_text_string = "Choose how you want to prioritize your search." selection = st.selectbox("Search Mode", [None] + SEARCH_MODES, help=help_text_string, key="search_mode") @@ -74,37 +118,52 @@ def display_search_mode_ui(): return search_mode def display_search_value_ui(search_mode): + """ Display text box for user to enter query to search; returns input. + + Return value + User's search query, as a string. + """ + if search_mode == "Genre": return display_genre_dropdown() - else: - display_str = search_mode - if display_str in ["Author1", "Author2"]: - display_str = display_str[:-1] - return st.text_input(f"Input your favorite {display_str}", + display_str = search_mode + if display_str in ["Author1", "Author2"]: + display_str = display_str[:-1] + return st.text_input(f"Input your favorite {display_str}", key="search_val") def display_genre_dropdown(): + """ + Displays drop down menu for genre selection; returns user input. + + Return value + User's genre selection as a string. + """ help_text_string = "Select your favorite genre." genre_pick = st.selectbox("Favorite Genre", [None] + GENRES, help=help_text_string) if genre_pick == "Other": return st.text_input("Describe your favorite genre", key="other_genre") - else: - return genre_pick - -def display_search_button(): + return genre_pick + +def display_search_button(disabled=False): + """ + Displays button to initate search. + + Return value + Boolean indicating whether user has clicked search. + """ return st.button("Search Now", key="search_now", help="Click to initiate search.", type="primary", - disabled=False, use_container_width=False) + disabled=disabled, use_container_width=False) -def execute_query(search_mode, search_value, min_ave_rating, min_num_ratings): - st.write(f"Searching for books using {search_mode}, value: {search_value}, " - f"min average rating: {min_ave_rating}, " - f"min number of ratings: {min_num_ratings}") def main(): - # Display header banner with stock image of books + """ + Displays UI; gathers user feedback; executes serach. + """ + # Display header banner with stock image of books st.image("images/books_banner.png", use_column_width=True) title_image = "images/butterfly.png" @@ -113,7 +172,8 @@ def main(): st.markdown( f"""
- +

The Bookish Butterfly

""", @@ -122,7 +182,7 @@ def main(): # Add introductory text - st.write("Welcome to The Bookish Butterfly! An literary guide designed for" + st.write("Welcome to The Bookish Butterfly! A literary guide designed for" "bookworms, aiding in the exploration of new books with tailored" "preferences. Simply choose how you want to prioritize your" "search, input your favorite book, author, plot, or genre. " @@ -138,16 +198,21 @@ def main(): min_ave_rating = display_avg_ratings_slider() min_num_ratings = display_num_ratings_slider() - search_button = display_search_button() + if search_val not in ["", None]: - st.write("Click 'Search Now' when ready.") - if search_button: - try: - results = search_wrapper(search_mode, search_val, min_ave_rating, min_num_ratings) - col_to_show = ["book_title", "author", "Book-Rating", "RatingCount"] - st.write(results[col_to_show]) - except ValueError as e: - st.write(f"{str(e)}") + search_button = display_search_button() + if not search_button: + st.write("Click 'Search Now' when ready.") + else: + with st.spinner('Searching...'): + try: + results = search_wrapper(search_mode, search_val, + min_ave_rating, min_num_ratings) + col_to_show = ["book_title", "author", "Book-Rating", + "RatingCount"] + st.write(results[col_to_show]) + except ValueError as e: + st.write(f"{str(e)}") main() diff --git a/bookworm/tests/test_app.py b/bookworm/tests/test_app.py index 5a21533..c9452f7 100644 --- a/bookworm/tests/test_app.py +++ b/bookworm/tests/test_app.py @@ -30,10 +30,16 @@ import pandas as pd - -from app import main, display_avg_ratings_slider, display_num_ratings_slider, \ - display_search_mode_ui, display_search_value_ui, \ - display_genre_dropdown, display_search_button +try: + from app import (main, display_avg_ratings_slider, + display_num_ratings_slider, display_search_mode_ui, + display_search_value_ui, display_genre_dropdown, + display_search_button) +except ImportError: + from bookworm.app import (main, display_avg_ratings_slider, + display_num_ratings_slider, display_search_mode_ui, + display_search_value_ui, display_genre_dropdown, + display_search_button) class TestStreamlitUI(unittest.TestCase): From 297279800e4ab9508ea7c64be39df06c2b8eb602 Mon Sep 17 00:00:00 2001 From: sue-t-boyd Date: Mon, 11 Mar 2024 11:09:20 -0700 Subject: [PATCH 07/10] Fix pylint path to include bookworm/*.py --- .github/workflows/build_test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build_test.yml b/.github/workflows/build_test.yml index 9d74172..33992a9 100644 --- a/.github/workflows/build_test.yml +++ b/.github/workflows/build_test.yml @@ -93,6 +93,7 @@ jobs: - name: Lint with pylint run: | pylint bookworm/**/*.py + pylint bookworm/*.py # Next step: run the unit tests with code coverage. - name: Unit tests From 360698b6efbdb41f5687d55fa82e2a3269bf8c6a Mon Sep 17 00:00:00 2001 From: sue-t-boyd Date: Mon, 11 Mar 2024 11:16:43 -0700 Subject: [PATCH 08/10] revert pylint checker to disabled --- .github/workflows/build_test.yml | 5 +- bookworm/__init__.py | 2 +- bookworm/local/InspectData.py | 29 ++++++++++ bookworm/local/LocalTestScript.py | 76 ++++++++++++++++++++++++++ bookworm/local/LocalTestScript2.py | 64 ++++++++++++++++++++++ bookworm/local/create_test_genre.py | 18 +++++++ bookworm/local/prep_text.py | 84 +++++++++++++++++++++++++++++ 7 files changed, 275 insertions(+), 3 deletions(-) create mode 100644 bookworm/local/InspectData.py create mode 100644 bookworm/local/LocalTestScript.py create mode 100644 bookworm/local/LocalTestScript2.py create mode 100644 bookworm/local/create_test_genre.py create mode 100644 bookworm/local/prep_text.py diff --git a/.github/workflows/build_test.yml b/.github/workflows/build_test.yml index 33992a9..2bb48b8 100644 --- a/.github/workflows/build_test.yml +++ b/.github/workflows/build_test.yml @@ -92,8 +92,9 @@ jobs: # Next step: run pylint. Anything less than 10/10 will fail. - name: Lint with pylint run: | - pylint bookworm/**/*.py - pylint bookworm/*.py + pylint bookworm/*.py + pylint bookworm/**/*.py + # Next step: run the unit tests with code coverage. - name: Unit tests diff --git a/bookworm/__init__.py b/bookworm/__init__.py index 07eaa03..0a33e86 100644 --- a/bookworm/__init__.py +++ b/bookworm/__init__.py @@ -1 +1 @@ -# EMPTY FILE \ No newline at end of file +# EMPTY FILE diff --git a/bookworm/local/InspectData.py b/bookworm/local/InspectData.py new file mode 100644 index 0000000..37e2323 --- /dev/null +++ b/bookworm/local/InspectData.py @@ -0,0 +1,29 @@ +# Sue's Local Search Script + +import pandas as pd +import search_wrapper as sw +import search +from search import HelperFunctions as H +import numpy as np +from thefuzz import fuzz + +#Assemble data +path_root = "data/complete_w_embeddings/complete_w_embeddings.csv" +path1 = path_root + "_part_1.csv" +path2 = path_root + "_part_2.csv" +path3 = path_root + "_part_3.csv" +path4 = path_root + "_part_4.csv" +dat = sw.assemble_data(path1, path2, path3, path4) + +col_to_show = ["book_id", "genre", "book_title", "author"] +#pd.set_option('display.max_colwidth', None) # display entire summary field +for query in ["Death at La Fenice", "Muder in Grub Street", "A touch of Frost"]: + idx = H.query_to_index(dat, query, ["book_title"]) + print(f"Index is {idx}") + book = dat.iloc[idx] + for col in col_to_show: + print(f"{col} is {book[col]}") + print (book["summary"]) + + + diff --git a/bookworm/local/LocalTestScript.py b/bookworm/local/LocalTestScript.py new file mode 100644 index 0000000..5df7b25 --- /dev/null +++ b/bookworm/local/LocalTestScript.py @@ -0,0 +1,76 @@ +# Sue's Local Search Script + +import pandas as pd +import search_wrapper as sw +import search +from thefuzz import fuzz + +#Assemble data +path_root = "data/complete_w_embeddings/complete_w_embeddings.csv" +path1 = path_root + "_part_1.csv" +path2 = path_root + "_part_2.csv" +path3 = path_root + "_part_3.csv" +path4 = path_root + "_part_4.csv" +dat = sw.assemble_data(path1, path2, path3, path4) + +col_to_show = ["book_id", "book_title", "author"] +ALL_COL = ["genre", "book_title", "summary", "author"] + +def calculate_ratio(row): + return fuzz.ratio(row['author'], query) + +#print(dat[col_to_show].iloc[15:40]) + +# authors_to_check = ["Herge", "Isaac Asimov", "Asimov", "Tarkington", "Stephen King", +# "JRR Tolkien", "Tolkien", "Rowling", "Joyce", "James Joyce"] +# # results from keyword author field only +# for author in authors_to_check: +# idx = search.HelperFunctions.query_to_index(dat, author, ["author"]) +# auth_result = dat.iloc[idx]["author"] +# print(f"For author {author}, index is {idx} and author is {auth_result}") + +# # results from keyword all fields +# for author in authors_to_check: +# columns = ["book_title", "genre", "author", "summary"] +# idx = search.HelperFunctions.query_to_index(dat, author, columns) +# auth_result = dat.iloc[idx]["author"] +# print(f"For author {author}, index is {idx} and author is {auth_result}") + +books_to_check = ["way of all flesh", "wizard and glass", "winters heart", "winter's heart", + "Myth of sisuphus", "Blade Runner", "wolves of the calla", "mary had a little lamb"] +# # results from keyword title field only +results = pd.DataFrame() +results["query"] = books_to_check +idx_one_col = [] +title_one_col = [] +idx_all_col =[] +title_all_col=[] + + +for book in books_to_check: + idx = search.HelperFunctions.query_to_index(dat, book, ["book_title"]) + title_result = dat.iloc[idx]["book_title"] + idx_one_col.append(idx) + title_one_col.append(title_result) + idx2 = search.HelperFunctions.query_to_index(dat, book, ALL_COL) + title_result_2 = dat.iloc[idx2]["book_title"] + idx_all_col.append(idx2) + title_all_col.append(title_result_2) + +results["idx_one_col"] = idx_one_col +results["title_one_col"] = title_one_col +results["idx_all_col"]=idx_all_col +results["title_all_col"] =title_all_col +print(results) + + + + + +# # results from keyword all fields +# for author in authors_to_check: +# columns = ["book_title", "genre", "author", "summary"] +# idx = search.HelperFunctions.query_to_index(dat, author, columns) +# auth_result = dat.iloc[idx]["author"] +# print(f"For author {author}, index is {idx} and author is {auth_result}") + diff --git a/bookworm/local/LocalTestScript2.py b/bookworm/local/LocalTestScript2.py new file mode 100644 index 0000000..b9e17e4 --- /dev/null +++ b/bookworm/local/LocalTestScript2.py @@ -0,0 +1,64 @@ +# Sue's Local Search Script + +import pandas as pd +import search_wrapper as sw +import search +import numpy as np +from thefuzz import fuzz + +#Assemble data +path_root = "data/complete_w_embeddings/complete_w_embeddings.csv" +path1 = path_root + "_part_1.csv" +path2 = path_root + "_part_2.csv" +path3 = path_root + "_part_3.csv" +path4 = path_root + "_part_4.csv" +dat = sw.assemble_data(path1, path2, path3, path4) +col_to_show = ["book_id", "book_title", "author"] + +print(dat[dat["book_id"] == 156489]["summary"]) + +indices = np.load('../bookworm/data/indices_updated.npy') +print(indices[0:5]) + +columns = ["book_title"] +query = "Harry Potter and the Order of the Phoenix" +book_index = search.HelperFunctions.query_to_index(dat, query, columns) +print(book_index) + +print(dat.iloc[book_index][col_to_show]) + + + +semantic_indices = search.HelperFunctions.get_semantic_results(book_index,5) +semantic_indices = semantic_indices.tolist() if \ + isinstance(semantic_indices, np.ndarray) else semantic_indices + +print(f"semantic indices are {semantic_indices}") + +results = dat.loc[semantic_indices].head(5) +print(results) + + + + +# book = dat.iloc[0, :] +# id = book["book_id"] +# print(book) +# print(id) +# print(type(id)) + +# book2 = dat[dat["book_id"]== 4081] +# #book2 = dat[dat["book_id"]== 22808] +# #id2 = book2["book_id"] +# print(type(book2)) +# #print(id2) + +# #print(book[col_to_show].head(1)) + + +# #book = dat[dat["book_id"] == 4081] +# # print(book) + + + + diff --git a/bookworm/local/create_test_genre.py b/bookworm/local/create_test_genre.py new file mode 100644 index 0000000..7d42551 --- /dev/null +++ b/bookworm/local/create_test_genre.py @@ -0,0 +1,18 @@ +# create_test_genre + +import pandas as pd +f = "../data/genre.csv" +genres = pd.read_csv(f) +print(genres.shape) + + +test_genre = genres.head(30) +print(test_genre.shape) +print(test_genre.head) +f = "../data/test_data/test_genre.csv" +test_genre.to_csv(f) + +genre_types = set(test_genre["generic_genre"].tolist()) +print(genre_types) + + diff --git a/bookworm/local/prep_text.py b/bookworm/local/prep_text.py new file mode 100644 index 0000000..477b656 --- /dev/null +++ b/bookworm/local/prep_text.py @@ -0,0 +1,84 @@ +""" Script to prep text for tokenization + +Script takes the data complete_w_ratings.csv and preprocesses the text +fields in preparation for vectorization. + +Module should be run from /scripts folder. + + +""" +import ast +import pandas as pd + +def parse_genres(genre_str): + """ + Parse genre dictionaries into keywords joined by commas + + Paramters: + Genres: A dictinonary of genres. + Return + A string with genres expressed as keywords, separated + by commas. + """ + + try: + genres_dict = ast.literal_eval(genre_str) + genres_text = ', '.join(genres_dict.values()) + except (ValueError, SyntaxError): + genres_text = 'Unknown Genre' + return genres_text + + + +def fill_na(df): + """ + Fill in missing values in dataframe + + Paramaters + df: A dataframe with fields author, book_title, genre + and summary. + Return: + A dataframe with missing values filled in. + """ + + df.fillna({'author': 'Unknown', 'book_title': 'Unknown', + 'genre': 'Unknown', 'summary': 'No Summary Available'}, + inplace=True) + return df + + +def preprocess_text(text): + """ + Convert text to all lowercase. + + Parameters: + Text: A string + Returns + A lower case string + """ + text = str(text).lower() + return text + +def prep_df(df): + + """"Prepares dataframe for tokenization. + + Paramaters: + df: A dataframe with columns author, book_title, genre, and summary + Returns: + Preprocessed dataframe. Text all losercase and missing values filled. + """ + + df = fill_na(df) + df["genre"] = df['genre'].apply(parse_genres) + columns = ["author", "book_title", "genre", "summary"] + for col in columns: + df[col] = df[col].apply(preprocess_text) + return(df) + +#f = "../bookworm/data/test_data/test_data.csv" +f = "../bookworm/data/complete_w_ratings.csv" +dat = pd.read_csv(f) +processed_dat = prep_df(dat) +f = "../bookworm/data/complete_w_ratings_preproc.csv" +processed_dat.to_csv(f) From 273811298cbf8829f38719f581dc3e6d074132eb Mon Sep 17 00:00:00 2001 From: sue-t-boyd Date: Mon, 11 Mar 2024 11:19:25 -0700 Subject: [PATCH 09/10] try 2 disable pylint checker in yaml file --- .github/workflows/build_test.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build_test.yml b/.github/workflows/build_test.yml index 2bb48b8..2474141 100644 --- a/.github/workflows/build_test.yml +++ b/.github/workflows/build_test.yml @@ -89,11 +89,11 @@ jobs: # If there are any other steps in order for your tests to # run successfully, you can add those steps here! - # Next step: run pylint. Anything less than 10/10 will fail. - - name: Lint with pylint - run: | - pylint bookworm/*.py - pylint bookworm/**/*.py + # # Next step: run pylint. Anything less than 10/10 will fail. + # - name: Lint with pylint + # run: | + # pylint bookworm/*.py + # pylint bookworm/**/*.py # Next step: run the unit tests with code coverage. From 633aa253b161ae8872d55abd17961e835d1f2e1b Mon Sep 17 00:00:00 2001 From: sue-t-boyd Date: Mon, 11 Mar 2024 11:38:09 -0700 Subject: [PATCH 10/10] Delete local files accidentally included --- bookworm/local/InspectData.py | 29 ---------- bookworm/local/LocalTestScript.py | 76 -------------------------- bookworm/local/LocalTestScript2.py | 64 ---------------------- bookworm/local/create_test_genre.py | 18 ------- bookworm/local/prep_text.py | 84 ----------------------------- 5 files changed, 271 deletions(-) delete mode 100644 bookworm/local/InspectData.py delete mode 100644 bookworm/local/LocalTestScript.py delete mode 100644 bookworm/local/LocalTestScript2.py delete mode 100644 bookworm/local/create_test_genre.py delete mode 100644 bookworm/local/prep_text.py diff --git a/bookworm/local/InspectData.py b/bookworm/local/InspectData.py deleted file mode 100644 index 37e2323..0000000 --- a/bookworm/local/InspectData.py +++ /dev/null @@ -1,29 +0,0 @@ -# Sue's Local Search Script - -import pandas as pd -import search_wrapper as sw -import search -from search import HelperFunctions as H -import numpy as np -from thefuzz import fuzz - -#Assemble data -path_root = "data/complete_w_embeddings/complete_w_embeddings.csv" -path1 = path_root + "_part_1.csv" -path2 = path_root + "_part_2.csv" -path3 = path_root + "_part_3.csv" -path4 = path_root + "_part_4.csv" -dat = sw.assemble_data(path1, path2, path3, path4) - -col_to_show = ["book_id", "genre", "book_title", "author"] -#pd.set_option('display.max_colwidth', None) # display entire summary field -for query in ["Death at La Fenice", "Muder in Grub Street", "A touch of Frost"]: - idx = H.query_to_index(dat, query, ["book_title"]) - print(f"Index is {idx}") - book = dat.iloc[idx] - for col in col_to_show: - print(f"{col} is {book[col]}") - print (book["summary"]) - - - diff --git a/bookworm/local/LocalTestScript.py b/bookworm/local/LocalTestScript.py deleted file mode 100644 index 5df7b25..0000000 --- a/bookworm/local/LocalTestScript.py +++ /dev/null @@ -1,76 +0,0 @@ -# Sue's Local Search Script - -import pandas as pd -import search_wrapper as sw -import search -from thefuzz import fuzz - -#Assemble data -path_root = "data/complete_w_embeddings/complete_w_embeddings.csv" -path1 = path_root + "_part_1.csv" -path2 = path_root + "_part_2.csv" -path3 = path_root + "_part_3.csv" -path4 = path_root + "_part_4.csv" -dat = sw.assemble_data(path1, path2, path3, path4) - -col_to_show = ["book_id", "book_title", "author"] -ALL_COL = ["genre", "book_title", "summary", "author"] - -def calculate_ratio(row): - return fuzz.ratio(row['author'], query) - -#print(dat[col_to_show].iloc[15:40]) - -# authors_to_check = ["Herge", "Isaac Asimov", "Asimov", "Tarkington", "Stephen King", -# "JRR Tolkien", "Tolkien", "Rowling", "Joyce", "James Joyce"] -# # results from keyword author field only -# for author in authors_to_check: -# idx = search.HelperFunctions.query_to_index(dat, author, ["author"]) -# auth_result = dat.iloc[idx]["author"] -# print(f"For author {author}, index is {idx} and author is {auth_result}") - -# # results from keyword all fields -# for author in authors_to_check: -# columns = ["book_title", "genre", "author", "summary"] -# idx = search.HelperFunctions.query_to_index(dat, author, columns) -# auth_result = dat.iloc[idx]["author"] -# print(f"For author {author}, index is {idx} and author is {auth_result}") - -books_to_check = ["way of all flesh", "wizard and glass", "winters heart", "winter's heart", - "Myth of sisuphus", "Blade Runner", "wolves of the calla", "mary had a little lamb"] -# # results from keyword title field only -results = pd.DataFrame() -results["query"] = books_to_check -idx_one_col = [] -title_one_col = [] -idx_all_col =[] -title_all_col=[] - - -for book in books_to_check: - idx = search.HelperFunctions.query_to_index(dat, book, ["book_title"]) - title_result = dat.iloc[idx]["book_title"] - idx_one_col.append(idx) - title_one_col.append(title_result) - idx2 = search.HelperFunctions.query_to_index(dat, book, ALL_COL) - title_result_2 = dat.iloc[idx2]["book_title"] - idx_all_col.append(idx2) - title_all_col.append(title_result_2) - -results["idx_one_col"] = idx_one_col -results["title_one_col"] = title_one_col -results["idx_all_col"]=idx_all_col -results["title_all_col"] =title_all_col -print(results) - - - - - -# # results from keyword all fields -# for author in authors_to_check: -# columns = ["book_title", "genre", "author", "summary"] -# idx = search.HelperFunctions.query_to_index(dat, author, columns) -# auth_result = dat.iloc[idx]["author"] -# print(f"For author {author}, index is {idx} and author is {auth_result}") - diff --git a/bookworm/local/LocalTestScript2.py b/bookworm/local/LocalTestScript2.py deleted file mode 100644 index b9e17e4..0000000 --- a/bookworm/local/LocalTestScript2.py +++ /dev/null @@ -1,64 +0,0 @@ -# Sue's Local Search Script - -import pandas as pd -import search_wrapper as sw -import search -import numpy as np -from thefuzz import fuzz - -#Assemble data -path_root = "data/complete_w_embeddings/complete_w_embeddings.csv" -path1 = path_root + "_part_1.csv" -path2 = path_root + "_part_2.csv" -path3 = path_root + "_part_3.csv" -path4 = path_root + "_part_4.csv" -dat = sw.assemble_data(path1, path2, path3, path4) -col_to_show = ["book_id", "book_title", "author"] - -print(dat[dat["book_id"] == 156489]["summary"]) - -indices = np.load('../bookworm/data/indices_updated.npy') -print(indices[0:5]) - -columns = ["book_title"] -query = "Harry Potter and the Order of the Phoenix" -book_index = search.HelperFunctions.query_to_index(dat, query, columns) -print(book_index) - -print(dat.iloc[book_index][col_to_show]) - - - -semantic_indices = search.HelperFunctions.get_semantic_results(book_index,5) -semantic_indices = semantic_indices.tolist() if \ - isinstance(semantic_indices, np.ndarray) else semantic_indices - -print(f"semantic indices are {semantic_indices}") - -results = dat.loc[semantic_indices].head(5) -print(results) - - - - -# book = dat.iloc[0, :] -# id = book["book_id"] -# print(book) -# print(id) -# print(type(id)) - -# book2 = dat[dat["book_id"]== 4081] -# #book2 = dat[dat["book_id"]== 22808] -# #id2 = book2["book_id"] -# print(type(book2)) -# #print(id2) - -# #print(book[col_to_show].head(1)) - - -# #book = dat[dat["book_id"] == 4081] -# # print(book) - - - - diff --git a/bookworm/local/create_test_genre.py b/bookworm/local/create_test_genre.py deleted file mode 100644 index 7d42551..0000000 --- a/bookworm/local/create_test_genre.py +++ /dev/null @@ -1,18 +0,0 @@ -# create_test_genre - -import pandas as pd -f = "../data/genre.csv" -genres = pd.read_csv(f) -print(genres.shape) - - -test_genre = genres.head(30) -print(test_genre.shape) -print(test_genre.head) -f = "../data/test_data/test_genre.csv" -test_genre.to_csv(f) - -genre_types = set(test_genre["generic_genre"].tolist()) -print(genre_types) - - diff --git a/bookworm/local/prep_text.py b/bookworm/local/prep_text.py deleted file mode 100644 index 477b656..0000000 --- a/bookworm/local/prep_text.py +++ /dev/null @@ -1,84 +0,0 @@ -""" Script to prep text for tokenization - -Script takes the data complete_w_ratings.csv and preprocesses the text -fields in preparation for vectorization. - -Module should be run from /scripts folder. - - -""" -import ast -import pandas as pd - -def parse_genres(genre_str): - """ - Parse genre dictionaries into keywords joined by commas - - Paramters: - Genres: A dictinonary of genres. - Return - A string with genres expressed as keywords, separated - by commas. - """ - - try: - genres_dict = ast.literal_eval(genre_str) - genres_text = ', '.join(genres_dict.values()) - except (ValueError, SyntaxError): - genres_text = 'Unknown Genre' - return genres_text - - - -def fill_na(df): - """ - Fill in missing values in dataframe - - Paramaters - df: A dataframe with fields author, book_title, genre - and summary. - Return: - A dataframe with missing values filled in. - """ - - df.fillna({'author': 'Unknown', 'book_title': 'Unknown', - 'genre': 'Unknown', 'summary': 'No Summary Available'}, - inplace=True) - return df - - -def preprocess_text(text): - """ - Convert text to all lowercase. - - Parameters: - Text: A string - Returns - A lower case string - """ - text = str(text).lower() - return text - -def prep_df(df): - - """"Prepares dataframe for tokenization. - - Paramaters: - df: A dataframe with columns author, book_title, genre, and summary - Returns: - Preprocessed dataframe. Text all losercase and missing values filled. - """ - - df = fill_na(df) - df["genre"] = df['genre'].apply(parse_genres) - columns = ["author", "book_title", "genre", "summary"] - for col in columns: - df[col] = df[col].apply(preprocess_text) - return(df) - -#f = "../bookworm/data/test_data/test_data.csv" -f = "../bookworm/data/complete_w_ratings.csv" -dat = pd.read_csv(f) -processed_dat = prep_df(dat) -f = "../bookworm/data/complete_w_ratings_preproc.csv" -processed_dat.to_csv(f)