friends 0.18 → 0.19

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cafcf4ae0c7862e767cfa66d62f82358aa4427dd
4
- data.tar.gz: ce713e78e33183b58d1dfe8a0a4ee56434bef476
3
+ metadata.gz: 4ba2ca1e570ce12bae59bd92e45eed450b15859d
4
+ data.tar.gz: f29a32cae219ae83c7cbc925d1493894d76409cb
5
5
  SHA512:
6
- metadata.gz: abe895385b3b8fead89b0d05693b8c8ccce448a3a0af2af65bb0eb0441cc22e4b25d8de0d62b2318572053d5db977ec69dd33b90003017b89bd7349124baa0e1
7
- data.tar.gz: 26ccbf5fe8b0178a8473ed8c7b541bed990cc9d65644760cd21a642a00a4b840048c1a3cde58e87c619d3ee5554e660342b4fce81bc7a012ea29bdff3c631509
6
+ metadata.gz: 264af4e8b7d6956401c9a7e6babecb6a8e8b6dc154de383394aef7890c2262685ea90c24c1d525d03802ecb1a028ffbc445cd4306fa91c5badbf044389667d1e
7
+ data.tar.gz: 674aa75753fc7aedc6f50bbb54956ecd91f6df2d8930d886f5f018e08d9c89b0db2e4f5aa74c014b45b35c6d429809d6fbdb7982598b52b66b0636f377136d3a
@@ -1,5 +1,16 @@
1
1
  # Change Log
2
2
 
3
+ ## [v0.19](https://github.com/JacobEvelyn/friends/tree/v0.19) (2016-05-02)
4
+ [Full Changelog](https://github.com/JacobEvelyn/friends/compare/v0.18...v0.19)
5
+
6
+ **Implemented enhancements:**
7
+
8
+ - Add command to list favorite locations [\#108](https://github.com/JacobEvelyn/friends/issues/108)
9
+
10
+ **Merged pull requests:**
11
+
12
+ - Add `list favorite locations` command [\#115](https://github.com/JacobEvelyn/friends/pull/115) ([JacobEvelyn](https://github.com/JacobEvelyn))
13
+
3
14
  ## [v0.18](https://github.com/JacobEvelyn/friends/tree/v0.18) (2016-05-02)
4
15
  [Full Changelog](https://github.com/JacobEvelyn/friends/compare/v0.17...v0.18)
5
16
 
data/README.md CHANGED
@@ -14,7 +14,7 @@ Extrovert-approved.
14
14
  - [Global flags](#global-flags)
15
15
  - [Syncing across multiple machines](#syncing-across-multiple-machines)
16
16
  - [Command reference](#command-reference)
17
- - [`add`](#add)
17
+ - `add`
18
18
  - [`add activity`](#add-activity)
19
19
  - [`add friend`](#add-friend)
20
20
  - [`add location`](#add-location)
@@ -22,13 +22,15 @@ Extrovert-approved.
22
22
  - [`clean`](#clean)
23
23
  - [`graph`](#graph)
24
24
  - [`help`](#help)
25
- - [`list`](#list)
25
+ - `list`
26
26
  - [`list activities`](#list-activities)
27
- - [`list favorites`](#list-favorites)
27
+ - `list favorite`
28
+ - [`list favorite friends`](#list-favorite-friends)
29
+ - [`list favorite locations`](#list-favorite-locations)
28
30
  - [`list friends`](#list-friends)
29
31
  - [`list locations`](#list-locations)
30
32
  - [`remove nickname`](#remove-nickname)
31
- - [`rename`](#rename)
33
+ - `rename`
32
34
  - [`rename friend`](#rename-friend)
33
35
  - [`rename location`](#rename-location)
34
36
  - [`set location`](#set)
@@ -177,9 +179,7 @@ alias friends="friends --filename '~/Dropbox/friends.md'"
177
179
 
178
180
  *Note that the command-line output is colored, which this README cannot show.
179
181
 
180
- #### `add`
181
-
182
- ##### `add activity`
182
+ #### `add activity`
183
183
 
184
184
  ```bash
185
185
  $ friends add activity "Got lunch with Grace and George."
@@ -240,21 +240,21 @@ $ friends add activity "2015-11-01: Grace and I went to \Marie's Diner. \George
240
240
  Activity added: "2015-11-01: Grace Hopper and I went to Marie's Diner. George had to cancel at the last minute."
241
241
  ```
242
242
 
243
- ##### `add friend`
243
+ #### `add friend`
244
244
 
245
245
  ```bash
246
246
  $ friends add friend "Grace Hopper"
247
247
  Friend added: "Grace Hopper"
248
248
  ```
249
249
 
250
- ##### `add location`
250
+ #### `add location`
251
251
 
252
252
  ```
253
253
  $ friends add location Atlantis
254
254
  Location added: "Atlantis"
255
255
  ```
256
256
 
257
- ##### `add nickname`
257
+ #### `add nickname`
258
258
 
259
259
  ```bash
260
260
  $ friends add nickname "Grace Hopper" "The Admiral"
@@ -344,9 +344,7 @@ $ friends help list
344
344
  $ friends help list activities
345
345
  ```
346
346
 
347
- #### `list`
348
-
349
- ##### `list activities`
347
+ #### `list activities`
350
348
 
351
349
  Lists recent activities:
352
350
 
@@ -380,12 +378,12 @@ $ friends list activities --in "New York"
380
378
  2014-12-31: Celebrated the new year with Marie Curie in New York City.
381
379
  ```
382
380
 
383
- ##### `list favorites`
381
+ #### `list favorite friends`
384
382
 
385
383
  Lists your "favorite" friends (by total number of activities):
386
384
 
387
385
  ```bash
388
- $ friends list favorites
386
+ $ friends list favorite friends
389
387
  Your favorite friends:
390
388
  1. George Washington Carver (2 activities)
391
389
  2. Grace Hopper (1)
@@ -395,13 +393,34 @@ Your favorite friends:
395
393
  You can specify a number of favorites to show:
396
394
 
397
395
  ```bash
398
- $ friends list favorites --limit 2
396
+ $ friends list favorite friends --limit 2
399
397
  Your favorite friends:
400
398
  1. George Washington Carver (2 activities)
401
399
  2. Grace Hopper (1)
402
400
  ```
403
401
 
404
- ##### `list friends`
402
+ #### `list favorite locations`
403
+
404
+ Lists your "favorite" locations (by total number of activities):
405
+
406
+ ```bash
407
+ $ friends list favorite locations
408
+ Your favorite locations:
409
+ 1. Atlantis (2 activities)
410
+ 2. Paris (1)
411
+ 3. London (1)
412
+ ```
413
+
414
+ You can specify a number of favorites to show:
415
+
416
+ ```bash
417
+ $ friends list favorite locations --limit 2
418
+ Your favorite locations:
419
+ 1. Atlantis (2 activities)
420
+ 2. Paris (1)
421
+ ```
422
+
423
+ #### `list friends`
405
424
 
406
425
  Lists all of your friends:
407
426
 
@@ -419,7 +438,7 @@ $ friends list friends --in Paris
419
438
  Marie Curie
420
439
  ```
421
440
 
422
- ##### `list locations`
441
+ #### `list locations`
423
442
 
424
443
  Lists all of the locations you've added:
425
444
 
@@ -439,16 +458,14 @@ $ friends remove nickname "Grace Hopper" "The Admiral"
439
458
  Nickname removed: "Grace Hopper (a.k.a. Amazing Grace)"
440
459
  ```
441
460
 
442
- #### `rename`
443
-
444
- ##### `rename friend`
461
+ #### `rename friend`
445
462
 
446
463
  ```bash
447
464
  $ friends rename friend "Grace Hopper" "Grace Brewster Murray Hopper"
448
465
  Name changed: "Grace Brewster Murray Hopper (a.k.a. Amazing Grace)"
449
466
  ```
450
467
 
451
- ##### `rename location`
468
+ #### `rename location`
452
469
 
453
470
  ```bash
454
471
  $ friends rename location Paris "Paris, France"
@@ -79,25 +79,52 @@ command :list do |list|
79
79
  end
80
80
  end
81
81
 
82
- list.desc "List favorite friends"
83
- list.command :favorites do |list_favorites|
84
- list_favorites.flag [:limit],
85
- arg_name: "NUMBER",
86
- default_value: 10,
87
- desc: "The number of friends to return"
88
-
89
- list_favorites.action do |_, options|
90
- limit = options[:limit].to_i
91
- favorites = @introvert.list_favorites(limit: limit)
82
+ list.desc "List favorite friends and locations"
83
+ list.command :favorite do |list_favorite|
84
+ list_favorite.desc "List favorite friends"
85
+ list_favorite.command :friends do |list_favorite_friends|
86
+ list_favorite_friends.flag [:limit],
87
+ arg_name: "NUMBER",
88
+ default_value: 10,
89
+ desc: "The number of friends to return"
90
+
91
+ list_favorite_friends.action do |_, options|
92
+ limit = options[:limit].to_i
93
+ favorites = @introvert.list_favorite_friends(limit: limit)
94
+
95
+ if limit == 1
96
+ puts "Your best friend is #{favorites.first}"
97
+ else
98
+ puts "Your favorite friends:"
92
99
 
93
- if limit == 1
94
- puts "Your best friend is #{favorites.first}"
95
- else
96
- puts "Your favorite friends:"
100
+ num_str_size = favorites.size.to_s.size + 1
101
+ favorites.each.with_index(1) do |name, rank|
102
+ puts "#{"#{rank}.".ljust(num_str_size)} #{name}"
103
+ end
104
+ end
105
+ end
106
+ end
107
+
108
+ list_favorite.desc "List favorite locations"
109
+ list_favorite.command :locations do |list_favorite_locations|
110
+ list_favorite_locations.flag [:limit],
111
+ arg_name: "NUMBER",
112
+ default_value: 10,
113
+ desc: "The number of locations to return"
114
+
115
+ list_favorite_locations.action do |_, options|
116
+ limit = options[:limit].to_i
117
+ favorites = @introvert.list_favorite_locations(limit: limit)
118
+
119
+ if limit == 1
120
+ puts "Your favorite location is #{favorites.first}"
121
+ else
122
+ puts "Your favorite locations:"
97
123
 
98
- num_str_size = favorites.size.to_s.size + 1
99
- favorites.each.with_index(1) do |name, rank|
100
- puts "#{"#{rank}.".ljust(num_str_size)} #{name}"
124
+ num_str_size = favorites.size.to_s.size + 1
125
+ favorites.each.with_index(1) do |name, rank|
126
+ puts "#{"#{rank}.".ljust(num_str_size)} #{name}"
127
+ end
101
128
  end
102
129
  end
103
130
  end
@@ -127,6 +127,13 @@ module Friends
127
127
  end
128
128
  memoize :friend_names
129
129
 
130
+ # Find the names of all locations in this description.
131
+ # @return [Array] list of all location names in the description
132
+ def location_names
133
+ @description.scan(/(?<=_)\w[^_]*(?=_)/).uniq
134
+ end
135
+ memoize :location_names
136
+
130
137
  private
131
138
 
132
139
  # Modify the description to turn inputted location names (e.g. "Atlantis")
@@ -184,7 +191,7 @@ module Friends
184
191
  end
185
192
 
186
193
  # Now, we compute the likelihood of each friend in the possible-match set.
187
- introvert.set_n_activities!
194
+ introvert.set_friend_n_activities!
188
195
  introvert.set_likelihood_score!(
189
196
  matches: matched_friends,
190
197
  possible_matches: possible_matched_friends
@@ -192,29 +192,19 @@ module Friends
192
192
  end
193
193
 
194
194
  # List your favorite friends.
195
- # @param limit [Integer] the number of favorite friends to return, or nil
196
- # for no limit
195
+ # @param limit [Integer] the number of favorite friends to return
197
196
  # @return [Array] a list of the favorite friends' names and activity
198
197
  # counts
199
- def list_favorites(limit:)
200
- if !limit.nil? && limit < 1
201
- raise FriendsError, "Favorites limit must be positive or unlimited"
202
- end
203
-
204
- set_n_activities! # Set n_activities for all friends.
205
-
206
- # Sort the results, with the most favorite friend first.
207
- results = @friends.sort_by { |friend| -friend.n_activities }
208
-
209
- # If we need to, trim the list.
210
- results = results.take(limit) unless limit.nil?
198
+ def list_favorite_friends(limit:)
199
+ list_favorite_things(:friend, limit: limit)
200
+ end
211
201
 
212
- max_str_size = results.map(&:name).map(&:size).max
213
- results.map.with_index(0) do |friend, index|
214
- name = friend.name.ljust(max_str_size)
215
- parenthetical = "(#{friend.n_activities}#{' activities' if index == 0})"
216
- "#{name} #{parenthetical}"
217
- end
202
+ # List your favorite friends.
203
+ # @param limit [Integer] the number of favorite locations to return
204
+ # @return [Array] a list of the favorite locations' names and activity
205
+ # counts
206
+ def list_favorite_locations(limit:)
207
+ list_favorite_things(:location, limit: limit)
218
208
  end
219
209
 
220
210
  # List all activity details.
@@ -306,7 +296,7 @@ module Friends
306
296
  # for unfiltered
307
297
  # @return [Hash{String => Array<String>}]
308
298
  def suggest(location_name:)
309
- set_n_activities! # Set n_activities for all friends.
299
+ set_friend_n_activities! # Set n_activities for all friends.
310
300
 
311
301
  # Filter our friends by location if necessary.
312
302
  fs = @friends
@@ -338,20 +328,8 @@ module Friends
338
328
  ###################################################################
339
329
 
340
330
  # Sets the n_activities field on each friend.
341
- def set_n_activities!
342
- # Construct a hash of friend name to frequency of appearance.
343
- freq_table = Hash.new { |h, k| h[k] = 0 }
344
- @activities.each do |activity|
345
- activity.friend_names.each do |friend_name|
346
- freq_table[friend_name] += 1
347
- end
348
- end
349
-
350
- # Remove names that are not in the friends list.
351
- freq_table.each do |name, count|
352
- friend = friend_with_exact_name(name)
353
- friend.n_activities = count if friend # Do nothing if name not valid.
354
- end
331
+ def set_friend_n_activities!
332
+ set_n_activities!(:friend)
355
333
  end
356
334
 
357
335
  # Get a regex friend map.
@@ -445,6 +423,59 @@ module Friends
445
423
 
446
424
  private
447
425
 
426
+ # @param type [Symbol] one of: [:friend, :location]
427
+ # @param limit [Integer] the number of favorite things to return
428
+ # @return [Array] a list of the favorite things' names and activity counts
429
+ def list_favorite_things(type, limit:)
430
+ unless [:friend, :location].include? type
431
+ raise FriendsError, "Type must be either :friend or :location"
432
+ end
433
+
434
+ if limit < 1
435
+ raise FriendsError, "Favorites limit must be positive"
436
+ end
437
+
438
+ send("set_n_activities!", type) # Set n_activities for all things.
439
+
440
+ # Sort the results, with the most favorite thing first.
441
+ results = instance_variable_get("@#{type}s").sort_by do |thing|
442
+ -thing.n_activities
443
+ end.take(limit) # Trim the list.
444
+
445
+ max_str_size = results.map(&:name).map(&:size).max
446
+ results.map.with_index(0) do |thing, index|
447
+ name = thing.name.ljust(max_str_size)
448
+ n = thing.n_activities
449
+ if index == 0
450
+ label = n == 1 ? " activity" : " activities"
451
+ end
452
+ parenthetical = "(#{n}#{label})"
453
+ "#{name} #{parenthetical}"
454
+ end
455
+ end
456
+
457
+ # Sets the n_activities field on each thing.
458
+ # @param type [Symbol] one of: [:friend, :location]
459
+ def set_n_activities!(type)
460
+ unless [:friend, :location].include? type
461
+ raise FriendsError, "Type must be either :friend or :location"
462
+ end
463
+
464
+ # Construct a hash of location name to frequency of appearance.
465
+ freq_table = Hash.new { |h, k| h[k] = 0 }
466
+ @activities.each do |activity|
467
+ activity.send("#{type}_names").each do |thing_name|
468
+ freq_table[thing_name] += 1
469
+ end
470
+ end
471
+
472
+ # Remove names that are not in the locations list.
473
+ freq_table.each do |name, count|
474
+ thing = send("#{type}_with_exact_name", name)
475
+ thing.n_activities = count if thing # Do nothing if name isn't valid.
476
+ end
477
+ end
478
+
448
479
  # Process the friends.md file and store its contents in internal data
449
480
  # structures.
450
481
  def read_file
@@ -541,6 +572,19 @@ module Friends
541
572
  end
542
573
  end
543
574
 
575
+ # @param name [String] the name of the location to search for
576
+ # @return [Location] the location whose name exactly matches the argument
577
+ # @raise [FriendsError] if more than one location has the given name
578
+ def location_with_exact_name(name)
579
+ results = @locations.select { |location| location.name == name }
580
+
581
+ case results.size
582
+ when 0 then nil
583
+ when 1 then results.first
584
+ else raise FriendsError, "More than one location named #{name}"
585
+ end
586
+ end
587
+
544
588
  # @param text [String] the name (or substring) of the location to search for
545
589
  # @return [Location] the location that matches
546
590
  # @raise [FriendsError] if 0 or 2+ location match the given text
@@ -39,6 +39,13 @@ module Friends
39
39
  Friends::RegexBuilder.regex(@name)
40
40
  end
41
41
 
42
+ # The number of activities this location is in. This is for internal use
43
+ # only and is set by the Introvert as needed.
44
+ attr_writer :n_activities
45
+ def n_activities
46
+ @n_activities || 0
47
+ end
48
+
42
49
  private
43
50
 
44
51
  # Default sorting for an array of locations is alphabetical.
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Friends
3
- VERSION = "0.18".freeze
3
+ VERSION = "0.19".freeze
4
4
  end
@@ -562,31 +562,34 @@ describe Friends::Introvert do
562
562
  end
563
563
  end
564
564
 
565
- describe "#list_favorites" do
566
- subject { introvert.list_favorites(limit: limit) }
565
+ describe "#list_favorite_friends" do
566
+ subject { introvert.list_favorite_friends(limit: limit) }
567
567
 
568
- describe "when limit is nil" do
569
- let(:limit) { nil }
568
+ describe "when there are more friends than favorites requested" do
569
+ let(:limit) { 1 }
570
570
 
571
- it "returns all friends in order of favoritism with activity counts" do
571
+ it "returns the number of favorites requested" do
572
572
  stub_friends(friends) do
573
573
  stub_activities(activities) do
574
- subject.must_equal [
575
- "Betsy Ross (2 activities)",
576
- "George Washington Carver (1)"
577
- ]
574
+ subject.must_equal ["Betsy Ross (2 activities)"]
578
575
  end
579
576
  end
580
577
  end
581
578
  end
579
+ end
582
580
 
583
- describe "when there are more friends than favorites requested" do
581
+ describe "#list_favorite_locations" do
582
+ subject { introvert.list_favorite_locations(limit: limit) }
583
+
584
+ describe "when there are more locations than favorites requested" do
584
585
  let(:limit) { 1 }
585
586
 
586
587
  it "returns the number of favorites requested" do
587
- stub_friends(friends) do
588
- stub_activities(activities) do
589
- subject.must_equal ["Betsy Ross (2 activities)"]
588
+ stub_locations(locations) do
589
+ stub_activities(
590
+ [Friends::Activity.new(str: "Swimming in _Atlantis_.")]
591
+ ) do
592
+ subject.must_equal ["Atlantis (1 activity)"]
590
593
  end
591
594
  end
592
595
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: friends
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.18'
4
+ version: '0.19'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jacob Evelyn