Flash_Cards_Sturdy_Cards_App 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
File without changes
File without changes
File without changes
@@ -0,0 +1,102 @@
1
+ # STURDY CARDS
2
+
3
+ - [STURDY CARDS](#sturdy-cards)
4
+ - [About](#about)
5
+ - [Research and Problem statement](#research-and-problem-statement)
6
+ - [Features](#features)
7
+ - [Next Steps](#next-steps)
8
+ - [Tutorial](#tutorial)
9
+ - [UML Diagram](#uml-diagram)
10
+ - [Project Timeline](#project-timeline)
11
+ - [Github](#github)
12
+
13
+
14
+ ## About
15
+
16
+
17
+ Sturdy cards is flash cards with spaced repetition learning feature. It is created for anyone who wants to reinforce their learning through spaced repetition.
18
+
19
+ The concept is simple.
20
+
21
+ 1. You will be given a few default decks to get a feel of how the application works.
22
+ 2. You can create custom decks and cards within the decks.
23
+ 3. You can export decks as csv files to share information with friends/families, or create new decks by importing csv files
24
+ 4. Once you are all set up, you can start learning. There are a few different modes available for you so you will never get bored of being tested by the same method throughout the process.
25
+ 5. Lastly, sit back and be sturdy. Your knowledge will only ever going to get sturdier.
26
+
27
+
28
+
29
+ * There is a [tutorial](##Tutorial) section below if you need further instructions on how to use the application.
30
+ * Feel free to read through the [feature section](##Features) to understand how our feature works.
31
+
32
+
33
+
34
+ #### Research and Problem statement
35
+
36
+ From my learning experience and my observation with how humans learn, we humans learn and retain better through continuous repetition. As quoted from Tony Robbins,
37
+
38
+ > Repetitions is a mother of skill
39
+ > - Tony Robbins
40
+
41
+ **"Many students find it difficult to memorise information even though the information has been processed and understood. More often than not, subject contents delivered in a traditional method, do not provide students with the time and reinforcement tool to excel in mastering those content."**
42
+
43
+ With Sturdy Cards, you can be rest assured your learning will be taken care of. By using spaced repetition and several distinctive modes available to choose from, we can help you learn and retain information more effectively. For those who are already at an advanced level in a subject, your subject expertise can be further reinforced.
44
+
45
+ ## Features
46
+
47
+ | Features | Functions | Released Date |
48
+ |:----------------- | :--------------------------------------------------------: | :---------------------------------: |
49
+ |1. Decks | Allows deck viewing, creation, updating and deletion | 14-March-2020 |
50
+ |2. Cards | Allows card viewing, creation, updating and deletion | 14-March-2020 |
51
+ |3. Learning Mode | Users are given a few different modes to learn | 14-March-2020 - Present |
52
+
53
+ ## Next Steps
54
+
55
+ 1. More learning modes - TBA
56
+ 2. Learning Progress - implement a tracking feature every time the users attempt the learning mode
57
+ 3. Export/Import of csv files as decks and cards
58
+ 4. Notifications - daily question auto-prompt
59
+ 5. Community and Friends - allow information to be published publicly in the app and follow friends
60
+ 6. Ranking system
61
+ 7. Competitions
62
+
63
+ ## Tutorial
64
+
65
+ The app runs on terminal command-line.
66
+
67
+ CSV files are used to keep the data created/altered from the command-line.
68
+
69
+ Notes:
70
+ * Most deck search functionality uses id unless stated otherwise by the program.
71
+ * Card search functionality uses card_name
72
+ * Errors like duplicates, names and non-existent data are captured
73
+
74
+ The first menu you will encounter is the *Main Menu*
75
+ * Select one of the options (select 1 as Learning Mode is in progress)
76
+ * The next stop is *Deck Menu*.
77
+ * Select one of the options (View, Create, Update and etc)
78
+ * In View Deck, you will be asked to select a deck id. (The program will catch the error if id does not exist and asks for your input again)
79
+ * In Create Deck, you will be asked *name* and *topic* of the deck you want to create (If name already exists, you will need to enter another name)
80
+ * In Update Deck, the information presented is the same as View Deck. Once a deck is selected for update, it will update the csv file.
81
+ * In Delete Deck, select a deck to be removed (csv will update). If deck does not exist, it will prompt you to enter a valid id.
82
+
83
+
84
+ ## UML Diagram
85
+
86
+ ![UML Diagram](./Desktop/../../../resources/UML Sturdy Cards.png)
87
+
88
+
89
+ ## Project Timeline
90
+
91
+ [Sturdy Cards - Trello](https://trello.com/b/crD1QQab/sturdycards-terminal-app)
92
+
93
+ ## Github
94
+
95
+ [codebender16-git-hub](https://github.com/codebender16/noname)
96
+
97
+ How to install
98
+
99
+ You must include:
100
+ - steps to install the application
101
+ - any dependencies required by the application to operate
102
+ - any system/hardware requirements
@@ -0,0 +1,6 @@
1
+ module Noname
2
+ VERSION = "0.1.2"
3
+ end
4
+
5
+
6
+ # need this file for gem to work correctly
@@ -0,0 +1,490 @@
1
+ require_relative "noname/version"
2
+ require_relative "classes/Deck"
3
+ require_relative "classes/Card"
4
+ require "csv"
5
+ require "colorize"
6
+ require "colorized_string"
7
+ require "tty-font"
8
+
9
+ # first menu
10
+ def start(decks_array, cards_array)
11
+ sleep(1)
12
+ puts
13
+ puts ColorizedString["WELCOME TO STURDY CARDS"].colorize(:green)
14
+ puts
15
+ puts "📚" + (" " * 11) + "📚"
16
+ puts "¯\\_( ͡♥ ͜ʖ ͡♥)_/¯"
17
+ puts
18
+ puts "1. Decks"
19
+ puts "2. Learning Mode >> Current Progress"
20
+ puts "3. Exit"
21
+ print "> "
22
+ selection = gets.chomp.to_i
23
+ puts
24
+ case selection
25
+ when 1
26
+ deck_menu(decks_array, cards_array)
27
+ when 2
28
+ # In progress
29
+ when 3
30
+ exit
31
+ else
32
+ sleep(2)
33
+ puts "Taking you back to the main menu :)"
34
+ start
35
+ end
36
+ end
37
+
38
+ # second menu / deck menu
39
+ def deck_menu(decks_array, cards_array)
40
+ sleep(1)
41
+ puts "Please select one of the following:"
42
+ puts
43
+ puts "1. View Deck" # done
44
+ puts "2. Create Deck" # done - last step is to push to csv
45
+ puts "3. Update Deck"
46
+ puts "4. Delete Deck"
47
+ puts "5. Main Menu"
48
+ puts "6. Exit"
49
+ print "> "
50
+ # p decks_array
51
+ selection = gets.chomp.to_i
52
+ puts
53
+ case selection
54
+ when 1
55
+ deck = view_deck(decks_array, cards_array)
56
+ when 2
57
+ create_deck(decks_array)
58
+ when 3
59
+ update_deck(decks_array)
60
+ when 4
61
+ del_deck(decks_array) # this will have cards array too
62
+ when 5
63
+ sleep(2)
64
+ puts "Taking you back to the main menu :)"
65
+ start
66
+ when 6
67
+ exit
68
+ else
69
+ sleep(2)
70
+ puts "Taking you back to the main menu :)"
71
+ start
72
+ end
73
+ end
74
+
75
+ # view deck
76
+
77
+ def view_deck(decks_array, cards_array)
78
+ viewing = true
79
+ valid_deck_id = false
80
+ while viewing
81
+ sleep(1)
82
+ # p decks_array
83
+ puts "-" * 30
84
+ puts "ID Deck Name"
85
+ puts "-" * 30
86
+ sleep(1)
87
+ decks_array.each do |deck| # data in deck is in string format
88
+ puts "#{deck.id}. #{deck.deck_name}"
89
+ end
90
+ puts "Which deck would you like to view? Select a deck using the id: "
91
+ print "> "
92
+ which_deck = gets.chomp# input = deck id
93
+ sleep(1)
94
+ if decks_array.include? decks_array[which_deck.to_i - 1]
95
+ viewing = false # breaks the loop a deck is found
96
+ deck_name = nil
97
+ decks_array.each do |deck| # deck = object in decks_array
98
+ if deck.id.to_i == which_deck.to_i
99
+ puts
100
+ puts "#{deck.deck_name.upcase}"
101
+ puts "-" * 40
102
+ puts "1. ID: | #{deck.id}"
103
+ puts "2. Deck Name: | #{deck.deck_name.capitalize}"
104
+ puts "3. Topic Name: | #{deck.topic.capitalize}"
105
+ puts "4. Date Created: | #{deck.date_created}"
106
+ puts "5. Date Modified: | #{deck.date_modified}"
107
+ puts "6. No. of Cards: | #{deck.card_counts}"
108
+ puts "7. No. of Tests Taken: | #{deck.test_counts}"
109
+ puts "8. Familiarity: | #{deck.familiarity_rate}"
110
+ puts "-" * 40
111
+
112
+ deck_name = deck.deck_name
113
+
114
+ end
115
+ end
116
+ else
117
+ sleep(1)
118
+ puts ColorizedString["Deck id #{which_deck} does not exist! Please enter the correct id: "].red
119
+ end
120
+ # view cards from deck
121
+
122
+ card_menu(cards_array, deck_name)
123
+ end
124
+ end
125
+
126
+ # card section - view card
127
+
128
+ def card_menu(cards_array, deck_name)
129
+ sleep(1)
130
+ puts "You are in Deck #{deck_name}"
131
+ puts "Please select one of the following:"
132
+ puts ""
133
+ puts "1. View Cards" # done
134
+ puts "2. Create Cards" # done - last step is to push to csv
135
+ puts "3. Update Cards"
136
+ puts "4. Delete Cards"
137
+ puts "5. Go back to Deck Menu"
138
+ puts "6. Exit"
139
+ print "> "
140
+ # p decks_array
141
+ selection = gets.chomp.to_i
142
+ puts
143
+ case selection
144
+ when 1
145
+ card = view_cards(cards_array, deck_name)
146
+ when 2
147
+ create_cards(cards_array, deck_name)
148
+ when 3
149
+ update_cards(cards_array, deck_name)
150
+ when 4
151
+ del_cards(cards_array, deck_name)
152
+ when 5
153
+ sleep(2)
154
+ puts "Taking you back to deck menu :)"
155
+ deck_menu
156
+ when 6
157
+ exit
158
+ else
159
+ sleep(2)
160
+ puts "Taking you back to the main menu :)"
161
+ start
162
+ end
163
+ end
164
+
165
+ # view cards
166
+
167
+ def view_cards(cards_array, deck_name)
168
+ viewing_card = true
169
+ while viewing_card
170
+ sleep(1)
171
+ # p cards_array
172
+ puts "-" * 30 * 2
173
+ puts "Card Name Description"
174
+ puts "-" * 30 * 2
175
+ sleep(1)
176
+ cards_array.each do |card| # data in card is in string format
177
+ if card.deck == deck_name.downcase
178
+ puts "#{card.card_name} #{card.description}"
179
+ end
180
+ end
181
+ puts "-" * 30 * 2
182
+ puts "Which card would you like to view? Select a card using the id: "
183
+ print "> "
184
+ card_id = gets.chomp# input = card id
185
+ sleep(1)
186
+ if cards_array.include? cards_array[card_id.to_i - 1]
187
+ viewing_card = false # breaks the loop a deck is found
188
+ card_name = nil
189
+ cards_array.each do |card| # card = object in cards_array
190
+ if card.card_id.to_i == card_id.to_i
191
+ puts
192
+ puts "#{card.deck}"
193
+ puts "#{card.card_name.upcase}"
194
+ puts "-" * 40
195
+ # puts "1. Card ID: | #{card.card_id}"
196
+ puts "1. Card Name: | #{card.card_name.capitalize}"
197
+ puts "2. Description Name: | #{card.description.capitalize}"
198
+ # puts "4. Date Created: | #{deck.date_created}"
199
+ # puts "5. Date Modified: | #{deck.date_modified}"
200
+ # puts "6. No. of Cards: | #{deck.card_counts}"
201
+ # puts "7. No. of Tests Taken: | #{deck.test_counts}"
202
+ # puts "8. Familiarity: | #{deck.familiarity_rate}"
203
+ puts "-" * 40
204
+ end
205
+ end
206
+ else
207
+ puts ColorizedString["Card id #{card_id.to_s} does not exist. Please enter a valid card id: "].red
208
+ end
209
+ end
210
+ end
211
+
212
+ # create cards
213
+
214
+ def create_cards(cards_array, deck_name)
215
+ sleep(1)
216
+ creating_card_name = true
217
+ card_name = nil
218
+ description = nil
219
+ puts "What's the name of the card that you want to create?"
220
+ print "> "
221
+ while creating_card_name
222
+ card_input = gets.chomp.downcase
223
+ if valid_card_name?(cards_array, card_input) # need include deck name comparison as well. because duplicates can exist as long as cards are in different decks.
224
+ # Create a new card
225
+ sleep(1)
226
+ puts "#{card_input.upcase} is available! Now, enter a description: "
227
+ card_name = card_input
228
+ description = gets.chomp.downcase
229
+ card_id = (cards_array[-1].card_id.to_i + 1).to_s
230
+ cards_array << Card.new(card_id,deck_name, card_name, description)
231
+ write_to_csv_card(cards_array[-1])
232
+ puts
233
+ sleep(1)
234
+ puts ColorizedString["\"#{card_name.capitalize}\" card has been successfully created!"].green
235
+ creating_card_name = false
236
+ else
237
+ sleep(1)
238
+ puts "Card name #{card_input.upcase} already exists. Please enter another name: "
239
+ print "> "
240
+ end
241
+ end
242
+ end
243
+
244
+ #
245
+
246
+ def valid_name?(decks_array, name)
247
+ decks_array.each do |deck|
248
+ if deck.deck_name == name
249
+ return false
250
+ end
251
+ end
252
+ return true
253
+ end
254
+
255
+ def valid_topic_name?(decks_array, topic)
256
+ decks_array.each do |deck|
257
+ if deck.topic == topic
258
+ return false
259
+ end
260
+ end
261
+ return true
262
+ end
263
+
264
+ def valid_card_name?(cards_array, card_input)
265
+ cards_array.each do |card|
266
+ if card.card_name == card_input
267
+ return false
268
+ end
269
+ end
270
+ return true
271
+ end
272
+
273
+ # create deck
274
+ def create_deck(decks_array)
275
+ sleep(1)
276
+ creating_name = true
277
+ name = nil
278
+ topic = nil
279
+ puts "What's the name of the deck that you want to create?"
280
+ print "> "
281
+ while creating_name
282
+ name_input = gets.chomp.downcase
283
+ if valid_name?(decks_array, name_input)
284
+ # Create a new deck
285
+ sleep(1)
286
+ puts "#{name_input.upcase} is available! Now, name a topic: "
287
+ name = name_input
288
+ topic = gets.chomp.downcase
289
+ id = (decks_array[-1].id.to_i + 1).to_s
290
+ decks_array << Deck.new(id, name, topic)
291
+ write_to_csv(decks_array[-1])
292
+ puts
293
+ sleep(1)
294
+ puts "\"#{name.capitalize}\" deck has been successfully created!"
295
+ creating_name = false
296
+ else
297
+ sleep(1)
298
+ puts "Deck name #{name_input.upcase} already exists. Please enter another name: "
299
+ print "> "
300
+ end
301
+ end
302
+ # while creating_topic
303
+ # topic_input = gets.chomp.downcase
304
+ # if valid_topic_name?(decks_array, topic_input)
305
+ # puts "#{topic_input.upcase} is available!"
306
+ # creating_topic = false
307
+ # topic = topic_input
308
+ # else
309
+ # puts "Topic name #{topic_input.upcase} already exists. Please enter another topic: "
310
+ # print "> "
311
+ # end
312
+ end
313
+
314
+ def write_to_csv(deck)
315
+ CSV.open("database/decks.csv", "ab") do |csv|
316
+ csv << [deck.id, deck.deck_name, deck.topic]
317
+ # p csv
318
+ end
319
+ end
320
+
321
+ def write_to_csv_card(card)
322
+ CSV.open("database/cards.csv", "ab") do |csv|
323
+ csv << [card.card_id, card.deck, card.card_name, card.description]
324
+ end
325
+ end
326
+
327
+ def update_csv(decks_array)
328
+ CSV.open("database/decks.csv", "w+") do |csv|
329
+ csv << ['id','deck name','topic']
330
+ decks_array.each do |deck|
331
+ csv << deck.to_a
332
+ end
333
+ end
334
+ end
335
+
336
+ # update deck
337
+
338
+ def update_deck(decks_array)
339
+ sleep(1)
340
+ updating = true
341
+ puts "-" * 30
342
+ puts "ID Deck Name"
343
+ puts "-" * 30
344
+ sleep(1)
345
+ decks_array.each do |deck|
346
+ puts "#{deck.id}. #{deck.deck_name}"
347
+ end
348
+
349
+ while updating
350
+ puts "Which deck would you like to update? Select the id: "
351
+ print "> "
352
+ which_deck = gets.chomp
353
+
354
+ if decks_array.include? decks_array[which_deck.to_i - 1]
355
+ sleep(1)
356
+ updating = false
357
+ selected_deck = nil
358
+ selected_deck_id = nil
359
+ decks_array.each do |deck| # deck = object in decks_array
360
+ if which_deck.to_i == deck.id.to_i
361
+ puts
362
+ puts "#{deck.deck_name.upcase}"
363
+ puts "-" * 40
364
+ puts "## " + "ID: | #{deck.id}"
365
+ puts "1. " + "Deck Name: | #{deck.deck_name.capitalize}"
366
+ puts "2. " + "Topic: | #{deck.topic.capitalize}"
367
+ # puts "3. " + "Date Created: | #{deck.date_created}"
368
+ # puts "4. " + "Date Modified: | #{deck.date_modified}"
369
+ # puts "5. " + "No. of Cards: | #{deck.card_counts}"
370
+ # puts "6. " + "No. of Tests Taken: | #{deck.test_counts}"
371
+ # puts "7. " + "Familiarity: | #{deck.familiarity_rate}"
372
+ puts "-" * 40
373
+ selected_deck = deck
374
+ # selected_deck_id = deck.id.to_i + 1
375
+ end
376
+ end
377
+ else
378
+ sleep(1)
379
+ puts "Deck id #{which_deck} does not exist! Please enter the correct id: "
380
+ sleep(1)
381
+ end
382
+ end
383
+
384
+ select_field_to_update(decks_array, selected_deck)
385
+ update_csv(decks_array)
386
+ sleep(1)
387
+ puts
388
+ puts "\"#{selected_deck.deck_name.capitalize}\" deck has been successfully updated!"
389
+ # p selected_deck
390
+ # p decks_array --> does not update in View Deck because has not been pushed to csv
391
+ end
392
+
393
+
394
+ def select_field_to_update(decks_array, selected_deck)
395
+
396
+ puts "What would you like to update (note that id is not editable)?"
397
+ sleep(1)
398
+ puts "Select one of the numbers: "
399
+ print "> "
400
+ selected_field = gets.chomp.to_i
401
+ case selected_field
402
+ when 1
403
+ sleep(1)
404
+ puts "Enter new name: "
405
+ print "> "
406
+ new_deck_name = gets.chomp
407
+ selected_deck.deck_name = new_deck_name
408
+ when 2
409
+ sleep(1)
410
+ puts "Enter new topic name: "
411
+ print "> "
412
+ new_topic_name = gets.chomp
413
+ selected_deck.topic = new_topic_name
414
+ else
415
+ exit
416
+ end
417
+
418
+ end
419
+
420
+ def del_deck(decks_array)
421
+ deleting = true
422
+ deck_name_to_del = nil
423
+ selected_deck = nil
424
+ while deleting == true
425
+ puts "-" * 30
426
+ puts "ID Deck Name"
427
+ puts "-" * 30
428
+ sleep(1)
429
+ decks_array.each do |deck|
430
+ puts "#{deck.id}. #{deck.deck_name}"
431
+ end
432
+ puts "Which deck would you like to delete? Please enter deck id: "
433
+ print "> "
434
+ sleep(1)
435
+ deck_to_del = gets.chomp # deck id
436
+
437
+ if decks_array.include? decks_array[deck_to_del.to_i - 1]
438
+ deleting = false
439
+ while true
440
+ puts "Are you sure you want to delete #{deck_name_to_del}? Y/N"
441
+ user_confirmation = gets.chomp.downcase
442
+ if user_confirmation == "y" || user_confirmation == "n"
443
+ break
444
+ end
445
+ end
446
+
447
+ decks_array.each do |deck|
448
+ if deck.id.to_i == deck_to_del.to_i
449
+ deck_name_to_del = deck.deck_name # deck name
450
+ selected_deck = deck.id.to_i - 1
451
+ p selected_deck
452
+ end
453
+ end
454
+ end
455
+ end
456
+
457
+ decks_array.delete_at(selected_deck)
458
+ update_csv(decks_array)
459
+ sleep(1)
460
+ puts
461
+ puts "\"#{deck_name_to_del.capitalize}\" deck has been successfully deleted!"
462
+ end
463
+
464
+ # starts up the app
465
+ decks_array = []
466
+ # read in the decks from the csv
467
+ decks = File.read("database/decks.csv") # decks is the csv file
468
+ csv = CSV.parse(decks, headers: true)
469
+ csv.each do |row|
470
+ decks_array << Deck.new(row["id"], row["deck name"], row["topic"]) # pushing data from csv into var decks_array
471
+ end
472
+
473
+ cards_array = []
474
+ cards = File.read("database/cards.csv")
475
+ csv = CSV.parse(cards, headers: true)
476
+ csv.each do |row|
477
+ cards_array << Card.new(row["card id"], row["deck"], row["card name"], row["description"])
478
+ end
479
+
480
+ # p decks_array
481
+
482
+ while true
483
+ start(decks_array, cards_array)
484
+ puts "LOADING...."
485
+ sleep(2)
486
+ puts "Taking you back to the main menu :)"
487
+ sleep(1)
488
+ end
489
+
490
+