reality 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.dokaz +1 -0
  3. data/LICENSE.txt +22 -0
  4. data/README.md +538 -66
  5. data/bin/reality +9 -0
  6. data/config/demo.yml +3 -0
  7. data/data/wikidata-predicates.json +1 -0
  8. data/data/wikidata-predicates.yaml +2089 -0
  9. data/lib/reality.rb +26 -7
  10. data/lib/reality/config.rb +46 -0
  11. data/lib/reality/definitions/dictionaries.rb +67 -0
  12. data/lib/reality/definitions/helpers.rb +34 -0
  13. data/lib/reality/definitions/wikidata.rb +105 -0
  14. data/lib/reality/definitions/wikipedia_character.rb +17 -0
  15. data/lib/reality/definitions/wikipedia_city.rb +19 -0
  16. data/lib/reality/definitions/wikipedia_continent.rb +21 -0
  17. data/lib/reality/definitions/wikipedia_country.rb +23 -0
  18. data/lib/reality/definitions/wikipedia_musical_artist.rb +15 -0
  19. data/lib/reality/definitions/wikipedia_person.rb +17 -0
  20. data/lib/reality/entity.rb +152 -0
  21. data/lib/reality/entity/coercion.rb +76 -0
  22. data/lib/reality/entity/wikidata_predicates.rb +31 -0
  23. data/lib/reality/entity/wikipedia_type.rb +73 -0
  24. data/lib/reality/extras/geonames.rb +29 -0
  25. data/lib/reality/extras/open_weather_map.rb +63 -0
  26. data/lib/reality/geo.rb +122 -0
  27. data/lib/reality/infoboxer_templates.rb +8 -0
  28. data/lib/reality/list.rb +95 -0
  29. data/lib/reality/measure.rb +18 -12
  30. data/lib/reality/measure/unit.rb +5 -1
  31. data/lib/reality/methods.rb +16 -0
  32. data/lib/reality/pretty_inspect.rb +11 -0
  33. data/lib/reality/refinements.rb +26 -0
  34. data/lib/reality/shortcuts.rb +11 -0
  35. data/lib/reality/tz_offset.rb +64 -0
  36. data/lib/reality/util/formatters.rb +35 -0
  37. data/lib/reality/util/parsers.rb +53 -0
  38. data/lib/reality/version.rb +6 -0
  39. data/lib/reality/wikidata.rb +310 -0
  40. data/reality.gemspec +12 -3
  41. data/script/extract_wikidata_properties.rb +23 -0
  42. data/script/lib/nokogiri_more.rb +175 -0
  43. metadata +137 -7
  44. data/examples/all_countries.rb +0 -16
  45. data/lib/reality/country.rb +0 -283
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6667ae3ec798575298a1434c024d08a411c91a2a
4
- data.tar.gz: 19eac6b250907987efae5a7dca7f8b86a2740000
3
+ metadata.gz: 81bd37c8f48b943d3f21927ba08a6632c3646e29
4
+ data.tar.gz: 60515a620873fe07de08f2de446148003f95152b
5
5
  SHA512:
6
- metadata.gz: 8edafe08ba68cb0407d67ae09759d87cf5cc63e04502578e364668850892e8c4515a2e40926a30853ceb54c1a3d10ce468e6cda289e6f0b0c00e1fa7ae514ab0
7
- data.tar.gz: 4c8881c8747b0459e7db2d8edafb36352416acade0b8dbf5d683d7c7cccf6546265ee971148e016d069bca7e910c4cbd49354b660007d143725ab73d931c4cd2
6
+ metadata.gz: c8ec19350cc2616ce97065ea6651c739936def8b4e3e9014e4afed52fe3dec35f265bc5c6fc03746fbb7c31c8c8f6134ff30ce4501593c73a375ce9f3d9fcbf2
7
+ data.tar.gz: 06b7ab6e795fd71ffdc7983a279b2c3bb3e7caf2829593eda917820bba32ec6d125e9b0c4b844aa545f9d86cb550c81d8b189389c6606c79fa49dd89b53c1124
data/.dokaz ADDED
@@ -0,0 +1 @@
1
+ --require ./spec/dokaz_helpers.rb
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Victor 'Zverok' Shepelev and contributors.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -1,69 +1,542 @@
1
1
  Reality
2
2
  =======
3
3
 
4
- **Reality** is a gem (in its early development stage) for easy and
5
- convenient recieving data on various real-life knowledge entities. It
6
- uses open data sources (only Wikipedia and DBPedia currently, but more
7
- of them planned) and makes data accessible to novices, experimentators
8
- and hobbyists.
9
-
10
- Now, at earliest version possible, Reality provides access only to
11
- world countries data:
12
-
13
- ```ruby
14
- # One country
15
- ar = Reality.country('Argentina')
16
- ar.area # => #<Reality::Measure(2,780,400 km²)>
17
- ar.capital # => Buenos Aires
18
- ar.leaders['President'] # => Mauricio Macri
19
-
20
- # List of countries:
21
- countries = Reality.countries.to_a
22
- # CAUTION tooks like ~2 min to load on modern Internet & CPU.
23
-
24
- countries.
25
- select{|c| c.continent == 'Africa'}.
26
- reject{|c| !c.gdp || (c.gdp / c.population).amount > 5_000}.
27
- map(:area).inject(:+)
28
- # => #<Reality::Measure(22,412,893 km²)>
29
-
30
- # or, with loading from wikipedia only relevant countries:
31
- Reality.countries.where(continent: 'Africa').
32
- reject{|c| !c.gdp || (c.gdp / c.population).amount > 5_000}.
33
- map(:area).inject(:+)
34
- ```
35
-
36
- Rough examples of what the library is supposed to do eventually, can be
37
- seen at [showcase draft](https://github.com/molybdenum-99/reality/wiki).
38
-
39
- Roadmap
40
- -------
41
-
42
- * [x] World countries: first example of Wikipedia -> easy data
43
- translation;
44
- * [x] Generic named measure concept and arithmetics;
45
- * [ ] Usage of Wikipedia as a query engine like "countries with
46
- population larger than", proxied via "List of countries by population");
47
- * [ ] More of related entities, starting from `city`, and interaction
48
- with countries (like "cities of this country" and more);
49
- * [ ] Generic entity concept;
50
- * [ ] Evaluation of usage of DBPedia as a query engine;
51
- * [ ] Wrappers for most common and most interesting data types (like
52
- people, famous places, music bands, movies, and so on) from Wikipedia;
53
- * [ ] Extending Reality sources to other open data sources, like
54
- OpenStreetMap, OpenWeatherMap, OpenExchange and so on;
55
- * [ ] Extending Reality calculations to real world time and space, like
56
- "calculate sunset at concrete date for concrete city and convert it
57
- to my timezone", or "calculate distance between those two places" and
58
- so on;
59
- * [ ] Integration with means of pretty output (like RMagick and IRuby
60
- Notebooks);
61
- * ....
62
-
63
- Authors
64
- -------
65
-
66
- * [Victor Shepelev](https://zverok.github.io)
4
+ [![Gem Version](https://badge.fury.io/rb/reality.svg)](http://badge.fury.io/rb/reality)
5
+ [![Join the chat at https://gitter.im/molybdenum-99/reality](https://badges.gitter.im/molybdenum-99/reality.svg)](https://gitter.im/molybdenum-99/reality?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
6
+
7
+ **Reality** is your quick access point to almost any entity existing in
8
+ real world (and described in Wikipedia). Its goal is to make the world
9
+ inspectable and computable.
10
+
11
+ ```ruby
12
+ # Like this
13
+ require 'reality'
14
+ include Reality
15
+
16
+ ar = Entity('Argentina')
17
+ ar.cities.load!
18
+ # => #<Reality::List[Buenos Aires, "Córdoba, Argentina", "Rosario, Santa Fe", "Mendoza, Argentina", La Plata, San Miguel de Tucumán, Mar del Plata, Salta, "Santa Fe, Argentina", "San Juan, Argentina", "Resistencia, Chaco", Neuquén, Santiago del Estero, Corrientes, Avellaneda, Bahía Blanca, San Salvador de Jujuy, Quilmes, Lanús, Comodoro Rivadavia, "Concordia, Entre Ríos"]>
19
+ ar.cities.map{|city| city.coord.distance_to(ar.capital)}
20
+ # => [#<Reality::Measure(0.0 km)>, #<Reality::Measure(646 km)>, #<Reality::Measure(278 km)>, #<Reality::Measure(985 km)>, #<Reality::Measure(54 km)>, #<Reality::Measure(1,084 km)>, #<Reality::Measure(385 km)>, #<Reality::Measure(1,285 km)>, #<Reality::Measure(394 km)>, #<Reality::Measure(1,005 km)>, #<Reality::Measure(797 km)>, #<Reality::Measure(987 km)>, #<Reality::Measure(942 km)>, #<Reality::Measure(793 km)>, #<Reality::Measure(7 km)>, #<Reality::Measure(574 km)>, #<Reality::Measure(1,338 km)>, #<Reality::Measure(16 km)>, #<Reality::Measure(11 km)>, #<Reality::Measure(1,471 km)>, #<Reality::Measure(358 km)>]
21
+
22
+ # or this
23
+ matz = Entity('Yukihiro Matsumoto')
24
+ # => #<Reality::Entity(Yukihiro Matsumoto):person>
25
+ matz.describe
26
+ # ---------------------------------------------
27
+ # #<Reality::Entity(Yukihiro Matsumoto):person>
28
+ # ---------------------------------------------
29
+ # awards: #<Reality::List[FSF Free Software Awards?]>
30
+ # birth_place: #<Reality::Entity?(Ōsaka Prefecture)>
31
+ # birthday: #<Date: 1965-04-14>
32
+ # citizenship: #<Reality::Entity?(Japan)>
33
+ # occupations: ["scientist", "engineer", "computer scientist", "programmer"]
34
+ # sex: "male"
35
+
36
+ matz.birth_place.population
37
+ # => #<Reality::Measure(8,847,838 person)>
38
+ matz.birth_place.neighbours.map(&:population)
39
+ # => [#<Reality::Measure(2,610,073 person)>, #<Reality::Measure(5,522,917 person)>, #<Reality::Measure(1,372,046 person)>, #<Reality::Measure(961,320 person)>, #<Reality::Measure(119,291 person)>]
40
+ matz.birth_place.coord.weather
41
+ # => #<Reality::Weather(-0.91°C, Clear)>
42
+
43
+ # or maybe this?
44
+ beatles = Entity('Beatles').parts
45
+ # => #<Reality::List[John Lennon?, Sir. Paul McCartney?, Ringo Starr?, George Harrison?, Stuart Sutcliffe?, Pete Best?]>
46
+ beatles.load!
47
+ beatles.select(&:alive?)
48
+ # => #<Reality::List[Paul McCartney, Ringo Starr, Pete Best]>
49
+ beatles.select(&:alive?).map{|beatle| beatle.albums && beatle.albums.last}
50
+ # => [#<Reality::Entity?(New (album))>, #<Reality::Entity?(Old Wave)>, nil]
51
+
52
+ # and stuff
53
+ titanic = Entity('Titanic (1997 film)')
54
+ titanic.actors.each do |actor|
55
+ puts "#{ actor.name }: #{ actor.age_at(titanic.published_at) }"
56
+ end
57
+ # Frances Fisher: 45
58
+ # Leonardo DiCaprio: 22
59
+ # Danny Nucci: 29
60
+ # Bill Paxton: 42
61
+ # Gloria Stuart: 87
62
+ # Kate Winslet: 22
63
+ # Billy Zane: 31
64
+ # ......
65
+ ```
66
+
67
+ ## Is it real? Is it really working?.. But how?
68
+
69
+ Yes. Every example you can see above is working. And many other things
70
+ are working. And almost _any_ thing which Wikipedia knows about, can be
71
+ loaded through **Reality**, and somehow inspected and used and navigated
72
+ to next entities and measured and ...
73
+
74
+ For any entity (or list of entities) you request, it will do:
75
+ * query English Wikipedia for this entity by name;
76
+ * gather data from Wikipedia **and** Wikidata, by several parsing rules
77
+ (the list of them is growing every day);
78
+ * present you with `Entity` object with ton of useful methods.
79
+
80
+ Above this core functionality, **Reality** also does:
81
+ * allow you to navigate through entity and linked entities and lists of
82
+ them;
83
+ * provide some (simple, but pretty looking) value classes like "amount
84
+ with units" (see distances and populations above), "geo coordinates",
85
+ "timezone offset" and so on;
86
+ * mix some other services (few for now, dozens in future) into those
87
+ value types, like `Geo::Coord#weather` through OpenWeatherMap and
88
+ so on.
89
+
90
+ Eventually, **Reality**, following its pretentious name, plans to interconnect
91
+ multiple open data sources (all of them!) into easily navigable and usable
92
+ graph of Ruby objects. Or something like that.
93
+
94
+ ## Why/when do I need this?..
95
+
96
+ Let's start from when you _don't_ need this.
97
+
98
+ Reality is not incredibly precise and realiable: for example, as you can
99
+ see in first example above, it lists only top cities of country, not all
100
+ of them (in fact, it is contents of Wikipedia page "List of cities in
101
+ %countryname%"). The data is only as good as data in Wikipedia/Wikidata
102
+ **and** our parsers/processors for this data. So, don't try to use
103
+ it for really precise scientific computations or really important business
104
+ tasks.
105
+
106
+ But! Data there is, and already a lot of it, and it will be a lot _moar_
107
+ in near future. So, feel free and happy to use Reality for:
108
+ * teaching Ruby and data processing on _real and actual_ data;
109
+ * use interesting data for experiments, quick scripts and insights about
110
+ errrm reality;
111
+ * demonstrating some tools for data processing and/or visualisation on
112
+ variative and intersting examples;
113
+ * initial seeding of development databases with countries, cities, genres,
114
+ dates, coordinates and so on;
115
+ * ...your option?..
116
+
117
+ ## Uhm, ok. How to use it?
118
+
119
+ First, install the gem as usual (it is on rubygems, and named "reality"),
120
+ using Gemfile/`bundle install` or `gem install reality`.
121
+
122
+ Second, `require "reality"` or use interactive console with the same name.
123
+
124
+ Now, to Reality concepts.
125
+
126
+ ### Entity
127
+
128
+ Now you can use `Reality::Entity`, which is core concept:
129
+
130
+ ```ruby
131
+ ar = Reality::Entity('Argentina')
132
+ # => #<Reality::Entity(Argentina):country>
133
+
134
+ ar.describe # shows all fields entity have
135
+ # -------------------------------------
136
+ # #<Reality::Entity(Argentina):country>
137
+ # -------------------------------------
138
+ # adm_divisions: #<Reality::List[Buenos Aires?, Buenos Aires Province?, Catamarca Province?, Chaco Province?, Corrientes?, Córdoba Province?, Formosa Province?, Entre Ríos Provinces?, Jujuy Province?, La Pampa Province?, La Rioja Province?, Mendoza Province?, Misiones Province?, Neuquén Province?, Río Negro Province?, Salta Province?, San Juan Province?, San Luis Province?, Santa Cruz Province?, Santa Fe Province?, Santiago del Estero Province?, Tucumán Province?, Tierra del Fuego Province?]>
139
+ # area: #<Reality::Measure(2,780,400 km²)>
140
+ # calling_code: "+54"
141
+ # capital: #<Reality::Entity?(Buenos Aires)>
142
+ # continent: #<Reality::Entity?(South America)>
143
+ # coord: #<Reality::Geo::Coord(34°0′0″S,64°0′0″W)>
144
+ # country: #<Reality::Entity?(Argentina)>
145
+ # created_at: #<Date: 1816-01-01>
146
+ # currency: #<Reality::Entity?(peso)>
147
+ # gdp_nominal: #<Reality::Measure(537,659,972,702 $)>
148
+ # gdp_ppp: #<Reality::Measure(964,279,000,000 $)>
149
+ # head_of_state: #<Reality::Entity?(Mauricio Macri)>
150
+ # highest_point: #<Reality::Entity?(Aconcagua)>
151
+ # iso2_code: "AR"
152
+ # iso3_code: "ARG"
153
+ # long_name: "Argentine Republic"
154
+ # neighbours: #<Reality::List[Uruguay?, Brazil?, Chile?, Paraguay?, Bolivia?]>
155
+ # organizations: #<Reality::List[United Nations?, Union of South American Nations?, Mercosur?, World Trade Organization?, G-20 major economies?, Central American Bank for Economic Integration?, International Bank for Reconstruction and Development?, African Development Bank?, Andean Community of Nations?, International Finance Corporation?, Australia Group?, International Development Association?, International Centre for Settlement of Investment Disputes?, Multilateral Investment Guarantee Agency?, Agency for the Prohibition of Nuclear Weapons in Latin America and the Caribbean?]>
156
+ # part_of: #<Reality::List[Latin America?]>
157
+ # population: #<Reality::Measure(43,417,000 person)>
158
+ # tld: ".ar"
159
+ # tz_offset: #<Reality::TZOffset(UTC-03:00)>
160
+
161
+ # all those fields are exposed as methods:
162
+ p ar.population
163
+ # => #<Reality::Measure(43,417,000 person)>
164
+
165
+ # those which are entities could be navigated further:
166
+ ar.capital.describe
167
+ # -------------------------------------
168
+ # #<Reality::Entity(Buenos Aires):city>
169
+ # -------------------------------------
170
+ # adm_divisions: #<Reality::List[Villa Devoto?, Agronomía?, "Retiro, Buenos Aires"?, "Caballito, Buenos Aires"?, "Chacarita, Buenos Aires"?, Parque Avellaneda?, "Villa Real, Buenos Aires"?, Flores?, Vélez Sársfield?, "Versalles, Buenos Aires"?, "Saavedra, Buenos Aires"?, "Barracas manda , Buenos Aires"?, La Boca?, Villa Lugano?, Villa del Parque?, Villa Luro?, Puerto Madero?, Balvanera?, Belgrano?, Boedo?, "Recoleta, Buenos Aires"?, Palermo?, Villa General Mitre?, Villa Riachuelo?, Villa Pueyrredón?, "San Telmo, Buenos Aires"?, Villa Urquiza?, Villa Santa Rita?, Villa Ortúzar?, "Monserrat, Buenos Aires"?, "Coghlan, Buenos Aires"?, Colegiales?, Parque Chacabuco?, Mataderos?, Constitución?, "Floresta, Buenos Aires"?, Villa Crespo?, Villa Soldati?, "La Paternal, Buenos Aires"?, Liniers?, Monte Castro?, Nueva Pompeya?, San Nicolás?, "Núñez, Buenos Aires"?, Parque Chas?, Parque Patricios?, San Cristóbal?, "Almagro, Buenos Aires"?]>
171
+ # area: #<Reality::Measure(203 km²)>
172
+ # coord: #<Reality::Geo::Coord(34°35′58″S,58°22′54″W)>
173
+ # country: #<Reality::Entity?(Argentina)>
174
+ # created_at: #<Date: 1580-06-21>
175
+ # elevation: #<Reality::Measure(25 m)>
176
+ # long_name: "Autonomous City of Buenos Aires"
177
+ # neighbours: #<Reality::List[Buenos Aires Province?]>
178
+ # population: #<Reality::Measure(2,890,151 person)>
179
+ # population_metro: #<Reality::Measure(12,741,364 person)>
180
+ # tz_offset: #<Reality::TZOffset(UTC-03:00)>
181
+ ```
182
+
183
+ #### Entity loading
184
+
185
+ When you see something like
186
+ `#<Reality::Entity?(Mauricio Macri)>` it means "not loaded entity" (like
187
+ link or reference). Entity can be loaded explicitly via `load!` method,
188
+ or implicitly on `method_missing` or `describe` call.
189
+
190
+ ```ruby
191
+ ar.head_of_state
192
+ # => #<Reality::Entity?(Mauricio Macri)>
193
+ ar.head_of_state.loaded?
194
+ # => false
195
+ ar.head_of_state.describe
196
+ # ----------------------------------
197
+ # #<Reality::Entity(Mauricio Macri)>
198
+ # ----------------------------------
199
+ # birth_place: #<Reality::Entity?(Tandil)>
200
+ # birthday: #<Date: 1959-02-08>
201
+ # citizenship: #<Reality::Entity?(Argentina)>
202
+ # father: #<Reality::Entity?(Francisco Macri)>
203
+ # given_name: "Mauricio"
204
+ # occupations: ["businessperson", "politician", "civil engineer"]
205
+ # position: "President of Argentina"
206
+ # sex: "male"
207
+ # spouse: #<Reality::Entity?(Juliana Awada)>
208
+ ar.head_of_state.loaded?
209
+ # => true
210
+ ```
211
+
212
+ #### Entity naming
213
+
214
+ Currently, reality loads entities just by _Wikipedia page name_ (and
215
+ respects redirects the same way Wikipedia does). So, for example:
216
+
217
+ ```ruby
218
+ # cool:
219
+ Reality::Entity('Einstein')
220
+ # => #<Reality::Entity(Albert Einstein)>
221
+
222
+ # but...
223
+ Reality::Entity('Ruby') # => about mineral
224
+ Reality::Entity('Ruby (programming language)') # => about programming language
225
+ ```
226
+
227
+ Further Reality versions would at least work smarter with disambiguation
228
+ pages and "other uses" link. But currently, that's just what you have.
229
+
230
+ #### Entity additional types
231
+
232
+ Let's look at this again:
233
+
234
+ ```ruby
235
+ ar = Reality::Entity('Argentina')
236
+ # => #<Reality::Entity(Argentina):country>
237
+ ```
238
+
239
+ Final `:country` part means Reality "guessed" desired object type (by
240
+ Wikipedia infobox name) and used this to parse additional properties from
241
+ Wikipedia, and also add some useful methods. For example (as seen above):
242
+
243
+ ```ruby
244
+ ar.cities
245
+ # => #<Reality::List[Buenos Aires?, "Córdoba, Argentina"?, "Rosario, Santa Fe"?, "Mendoza, Argentina"?, La Plata?, San Miguel de Tucumán?, Mar del Plata?, Salta?, "Santa Fe, Argentina"?, "San Juan, Argentina"?, "Resistencia, Chaco"?, Neuquén?, Santiago del Estero?, Corrientes?, Avellaneda?, Bahía Blanca?, San Salvador de Jujuy?, Quilmes?, Lanús?, Comodoro Rivadavia?, "Concordia, Entre Ríos"?]>
246
+ ```
247
+
248
+ It is not a property parsed on entry loading (so, it will not be seen
249
+ in `#describe`), but helpful method, which fetched additional data from
250
+ Wikipedia. (Unfortunately, there are no way to know which "helpful methods"
251
+ were added with current entity type, except for scanning `entity.methdods`
252
+ by eyes.)
253
+
254
+ Also, you should note there are some quirks about this "guess by infobox"
255
+ thing. For ex:
256
+
257
+ ```ruby
258
+ # ok
259
+ Reality::Entity('Buenos Aires')
260
+ # => #<Reality::Entity(Buenos Aires):city>
261
+
262
+ # not ok: note no "additional type" :city
263
+ l = Reality::Entity('Lyon')
264
+ # => #<Reality::Entity(Lyon)>
265
+ # thats because of:
266
+ l.wikipage.infobox.name
267
+ # => "Infobox French commune"
268
+ ```
269
+
270
+ This will become better in future.
271
+
272
+ #### Entity internals
273
+
274
+ Each entity has `wikipage` and `wikidata` methods, containing data loaded
275
+ from Wikipedia and Wikidata respectively. While `wikidata` is pretty ugly
276
+ internal object, `wikipage` CAN be useful on its own: it is an instance
277
+ of [Infoboxer::MediaWiki::Page](http://www.rubydoc.info/gems/infoboxer/Infoboxer/MediaWiki/Page)
278
+ and quite sophisticated and useful object:
279
+
280
+ ```ruby
281
+ ruby = Reality::Entity('Ruby (programming language)')
282
+ puts ruby.wikipage.intro
283
+ # Ruby is a dynamic, reflective, object-oriented, general-purpose programming language....
284
+ ruby.wikipage.sections
285
+ # => [#<Section(level: 2, heading: "History"): ...>, #<Section(level: 2, heading: "Table of versions"): ...>, #<Section(level: 2, heading: "Philosophy"): ...>, ...and so on
286
+ ```
287
+
288
+ ### Lists
289
+
290
+ Let's look closer at this part:
291
+
292
+ ```ruby
293
+ ar.neighbours
294
+ # => #<Reality::List[Uruguay?, Brazil?, Chile?, Paraguay?, Bolivia?]>
295
+ ```
296
+
297
+ `Reality::List` is just array of entities, with some useful differences.
298
+ For example, it provides more concise output (compare with
299
+ `ar.neighbours.to_a` on your own). It also provides ability to batch-load
300
+ all entities in list:
301
+
302
+ ```ruby
303
+ # instead of:
304
+ # ar.neighbours.each(&:load!)
305
+ # ...which will be 5 separate requests to Wikipedia and 5 to Wikidata
306
+ # ...you can write:
307
+ ar.neighbours.load!
308
+ # ...which is 1 request to Wikipedia API and 1 to Wikidata
309
+ ```
310
+
311
+ And last, for list of loaded entities, it provides pretty `#describe`
312
+ method to quickly look inside:
313
+
314
+ ```ruby
315
+ ar.neighbours.describe
316
+ # -------------------------
317
+ # #<Reality::List(5 items)>
318
+ # -------------------------
319
+ # keys: adm_divisions (5), area (5), calling_code (5), capital (5), continent (5), coord (5), country (5), created_at (5), currency (5), follows (1), gdp_nominal (5), gdp_ppp (5), head_of_state (5), highest_point (5), iso2_code (5), iso3_code (5), long_name (5), neighbours (5), organizations (5), part_of (5), population (5), tld (5), tz_offset (5)
320
+ # types: country (5)
321
+ ```
322
+
323
+ (OK, not incredibly useful for now, but provides you with some insights
324
+ on "what's inside".)
325
+
326
+ Finally, there are some (will be more in future) "default lists" in Reality:
327
+
328
+ ```ruby
329
+ Reality.countries
330
+ # => #<Reality::List[Algeria?, Angola?, Benin?, Botswana?, Burkina Faso?, Burundi?, Cameroon?, Cape Verde?, Central African Republic?, Chad?, Comoros?, Republic of the Congo?, Democratic Republic of the Congo?, Djibouti?, Egypt?, Equatorial Guinea?, Eritrea?, Ethiopia?, Gabon?, Gambia?, Ghana?, Guinea?, Guinea-Bissau?, Ivory Coast?, Kenya?, Lesotho?, Liberia?, Libya?, Madagascar?, Malawi?, Mali?, Mauritania?, Mauritius?, Morocco?, Mozambique?, Namibia?, Niger?, Nigeria?, Rwanda?, São Tomé and Príncipe?, Senegal?, Seychelles?, Sierra Leone?, Somalia?, South Africa?, South Sudan?, Sudan?, Swaziland?, Tanzania?, Togo?, Tunisia?, Uganda?, Zambia?, Zimbabwe?, Afghanistan?, Armenia?, Azerbaijan?, Bahrain?, Bangladesh?, Bhutan?, Brunei?, Cambodia?, China?, Cyprus?, East Timor?, Georgia (country)?, India?, Indonesia?, Iran?, Iraq?, Israel?, Japan?, Jordan?, Kazakhstan?, Kuwait?, Kyrgyzstan?, Laos?, Lebanon?, Malaysia?, Maldives?, Mongolia?, Myanmar?, Nepal?, North Korea?, Oman?, Pakistan?, State of Palestine?, Philippines?, Qatar?, Saudi Arabia?, Singapore?, South Korea?, Sri Lanka?, Syria?, Tajikistan?, Thailand?, Turkey?, Turkmenistan?, United Arab Emirates?, Uzbekistan?, Vietnam?, Yemen?, Albania?, Andorra?, Austria?, Belarus?, Belgium?, Bosnia and Herzegovina?, Bulgaria?, Croatia?, Czech Republic?, Denmark?, Estonia?, Finland?, France?, Germany?, Greece?, Hungary?, Iceland?, Republic of Ireland?, Italy?, Latvia?, Liechtenstein?, Lithuania?, Luxembourg?, Republic of Macedonia?, Malta?, Moldova?, Monaco?, Montenegro?, Kingdom of the Netherlands?, Norway?, Poland?, Portugal?, Romania?, Russia?, San Marino?, Serbia?, Slovakia?, Slovenia?, Spain?, Sweden?, Switzerland?, Ukraine?, United Kingdom?, Vatican City?, Antigua and Barbuda?, Bahamas?, Barbados?, Belize?, Canada?, Costa Rica?, Cuba?, Dominica?, Dominican Republic?, El Salvador?, Grenada?, Guatemala?, Haiti?, Honduras?, Jamaica?, Mexico?, Nicaragua?, Panama?, Saint Kitts and Nevis?, Saint Lucia?, Saint Vincent and the Grenadines?, Trinidad and Tobago?, United States?, Argentina?, Bolivia?, Brazil?, Chile?, Colombia?, Ecuador?, Guyana?, Paraguay?, Peru?, Suriname?, Uruguay?, Venezuela?, Australia?, Fiji?, Kiribati?, Marshall Islands?, Federated States of Micronesia?, Nauru?, New Zealand?, Palau?, Papua New Guinea?, Samoa?, Solomon Islands?, Tonga?, Tuvalu?, Vanuatu?]>
331
+ Reality.continents
332
+ # => #<Reality::List[Asia?, Africa?, North America?, South America?, Antarctica?, Europe?, Australia (continent)?]>
333
+ ```
334
+
335
+ Though, there is one funny quirk with latter (still thinking of it):
336
+
337
+ ```ruby
338
+ Reality.continents.last
339
+ # => #<Reality::Entity(Australia (continent)):continent>
340
+ Reality.continents.last.countries
341
+ # => #<Reality::List[]>
342
+ # ????
343
+ # Let's see...
344
+ a = Reality::Entity('Australia')
345
+ # => #<Reality::Entity(Australia):country>
346
+ a.continent
347
+ # => #<Reality::Entity?(Oceania)>
348
+ # Hmmmm....
349
+ a.continent.countries
350
+ # => #<Reality::List[Australia?, Fiji?, Kiribati?, Marshall Islands?, Federated States of Micronesia?, Nauru?, New Zealand?, Palau?, Papua New Guinea?, Samoa?, Solomon Islands?, Tonga?, Tuvalu?, Vanuatu?]>
351
+ ```
352
+
353
+ That's kinda weird thing of Wikipedia data ("Countries by continents" and
354
+ "List of continents" pages seems to be vague of "continent" and "part of
355
+ world" concepts).
356
+
357
+ ### Helper classes
358
+
359
+ Currently, there are several of them. All are just "handy wrappers"
360
+ around some values, that may be (or may be not) replaced with additional
361
+ gems in future versions.
362
+
363
+ #### Reality::Measure
364
+
365
+ ```ruby
366
+ ar.population
367
+ # => #<Reality::Measure(43,417,000 person)>
368
+ ar.population.amount
369
+ # => 43,417,000
370
+ ar.population.unit
371
+ # => #<Reality::Measure::Unit(person)>
372
+ ar.population ** 2
373
+ # => #<Reality::Measure(1,885,035,889,000,000 person²)>
374
+ ar.population / ar.area
375
+ # => #<Reality::Measure(15 person/km²)>
376
+
377
+ # using on its own:
378
+ m = Reality::Measure.new(10, 'm')
379
+ # => #<Reality::Measure(10 m)>
380
+ m ** 2
381
+ # => #<Reality::Measure(100 m²)>
382
+ ```
383
+
384
+ **NB**: No measure conversion provided for now. Attempt to sum metres with
385
+ kilometres will fail miserably. [unitwise](https://github.com/joshwlewis/unitwise)
386
+ may be utilised instead or inside `Measure` in future.
387
+
388
+ #### Reality::Geo::Coord
389
+
390
+ ```ruby
391
+ ar.capital.coord
392
+ # => #<Reality::Geo::Coord(34°35′58″S,58°22′54″W)>
393
+ ar.capital.coord.to_s
394
+ # => "-34.599722222222,-58.381944444444"
395
+ ar.capital.coord.distance_to(ar.highest_point.coord)
396
+ # => #<Reality::Measure(1,097 km)>
397
+ # ar.capital.coord.distance_to(ar.highest_point) also can be used, if highest_point has coord method
398
+ ar.capital.coord.direction_to(ar.highest_point.coord)
399
+ # => #<Reality::Measure(278 °)>
400
+ ```
401
+
402
+ **NB**: [geokit](https://github.com/geokit/geokit) already somehow
403
+ utilized inside.
404
+
405
+ #### Reality::TZOffset
406
+
407
+ ```ruby
408
+ ar.tz_offset
409
+ # => #<Reality::TZOffset(UTC-03:00)>
410
+ ar.tz_offset.now
411
+ # => 2016-03-01 16:03:52 -0300
412
+ ar.tz_offset.local(2016, 3, 2, 14, 30)
413
+ # => 2016-03-02 14:30:00 -0300
414
+ ar.tz_offset.convert(Time.now)
415
+ # => 2016-03-01 16:04:36 -0300
416
+
417
+ # using on its own:
418
+ Reality::TZOffset.parse('GMT+1').now
419
+ # => 2016-03-01 20:05:10 +0100
420
+ ```
421
+
422
+ ### Using external services
423
+
424
+ Currently, there are two external services (except of Wikipedia and
425
+ Wikidata) mashed into Reality:
426
+ * [OpenWeatherMap](http://openweathermap.org/) for "current weather"
427
+ feature;
428
+ * [GeoNames](http://www.geonames.org/) for "timezone at this coordinates"
429
+ feature.
430
+
431
+ Both of them, unlike Wikipedia/Wikidata API, require free access key
432
+ for usage. So, in your own code, you'll see something like this:
433
+
434
+ ```ruby
435
+ ar.capital.coord.weather
436
+ # KeyError: Expected keys.open_weather_map to exist in config. It is OpenWeatherMap APPID. Can be obtained here: http://openweathermap.org/appid
437
+ ar.capital.coord.timezone
438
+ # KeyError: Expected keys.geonames to exist in config. It is GeoNames username. Can be received from http://www.geonames.org/login
439
+ ```
440
+
441
+ For experiments you can use (but not abuse) Reality demo config, like this:
442
+
443
+ ```ruby
444
+ Reality.configure(:demo)
445
+ ar.capital.coord.weather
446
+ # => #<Reality::Weather(21°C, Clear)>
447
+ ar.capital.coord.timezone
448
+ # => #<TZInfo::DataTimezone: America/Argentina/Buenos_Aires>
449
+ ```
450
+
451
+ For more extensive data usage, you should use `Reality#configure` with
452
+ your own config (see `config/demo.yml` for sample of this).
453
+
454
+ Note, that reality binary is configured with `:demo` by default.
455
+
456
+ ### More
457
+
458
+ There are several things that are not required by `require "reality"` (but
459
+ are included in interactive console).
460
+
461
+ **Pretty inspect**: `require "reality/pretty_inspect"` redefines `#inspect`
462
+ method for some core classes, which are heavily utilized by reality, and
463
+ their default `#inspect` is not that pretty. For example:
464
+
465
+ ```ruby
466
+ # without pretty_inspect
467
+ Reality::Entity('Yukihiro Matsumoto').birthday
468
+ # => #<Date: 1965-04-14 ((2438865j,0s,0n),+0s,2299161j)>
469
+
470
+ # with pretty_inspect
471
+ Reality::Entity('Yukihiro Matsumoto').birthday
472
+ # => #<Date: 1965-04-14>
473
+
474
+ # without pretty_inspect
475
+ Reality::Entity('Buenos Aires').population / Reality::Entity('London').population
476
+ # => (2890151/8416535)
477
+ # ↑ it's Rational, pretty precise, but hard to read
478
+
479
+ # with pretty_inspect
480
+ Reality::Entity('Buenos Aires').population / Reality::Entity('London').population
481
+ # => 0.3
482
+ # ↑ it's still the same Rational, but with less precise/more readable output
483
+ ```
484
+
485
+ **Shortcuts**: `require "reality/shortcuts"` provides you with pretty
486
+ concise syntax:
487
+
488
+ ```ruby
489
+ include Reality
490
+
491
+ E('Yukihiro Matsumoto')
492
+
493
+ L('Argentine', 'Bolivia', 'Chile')
494
+ ```
495
+
496
+ Also, you could do `include Reality::Methods` (instead of `include Reality`)
497
+ in your code to not pollute your namespace with anything except `Entity`
498
+ and `List` methods (`E` and `L` is also in this namespace after you
499
+ have required "reality/shortcuts").
500
+
501
+ ## Good. What next?..
502
+
503
+ Reality currently in, let's say "working prototype" state. Many things
504
+ work and useful, many others are subject to change/improve. Near and
505
+ not-so-near plans looks like this (order is vague):
506
+
507
+ * more definitions of useful Wikidata/Wikipedia properties and types,
508
+ cleanup and re-checking of existing ones;
509
+ * more external datasources ([OpenStreetMap](http://www.openstreetmap.org/)
510
+ one of first candidates) and more info from already included ones;
511
+ * more maturity: cleaner code, more tests, docs, config policy....
512
+ * powerful and flexible data caching (if you run "study all world capitals"
513
+ script 10 times, or want to do a quick presentation of topic to students,
514
+ you'll be happy that previously quiried data are already on disk);
515
+ * large demo-scripts set, maybe in independent repository;
516
+ * separation of largely independent parts to another gems and libraries.
517
+
518
+ ## Want to help?
519
+
520
+ Great!
521
+
522
+ **Reality** will be glad to accept your issues and pull requests.
523
+ Currently, it would be great if somebody lay their hands on:
524
+
525
+ * thoroughly define more and more Wikidata predicates (and enchance system
526
+ for predicates definition: consider aliases, plural/singular properties
527
+ and so on);
528
+ * investigate and define more Wikipedia types (kinds of infoboxes) and
529
+ enchance existing ones;
530
+ * connect more external services and integrate them into Reality (for
531
+ example, geocoding: via OpenStreetMap guess city from coordinates
532
+ **and** make this city a `Reality::Entity`);
533
+ * play with Reality and share your experiences and examples and problems
534
+ and cool demos!
535
+
536
+ ## Credits
537
+
538
+ * [Victor Shepelev](https://zverok.github.io) [@zverok](https://github.com/zverok);
539
+ * Sergey Mostovoy [@smostovoy](https://github.com/smostovoy).
67
540
 
68
541
  Development sponsored by
69
542
  [2015 Ruby Association Grant](http://www.ruby.or.jp/en/news/20151116.html).
@@ -71,7 +544,6 @@ Development sponsored by
71
544
  Initial idea is inspired by "integrated data" of
72
545
  [Wolfram Language](http://reference.wolfram.com/language/).
73
546
 
74
- License
75
- -------
547
+ ## License
76
548
 
77
- MIT
549
+ [MIT](https://github.com/molybdenum-99/reality/blob/master/LICENSE.txt)