reality 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.dokaz +1 -0
- data/LICENSE.txt +22 -0
- data/README.md +538 -66
- data/bin/reality +9 -0
- data/config/demo.yml +3 -0
- data/data/wikidata-predicates.json +1 -0
- data/data/wikidata-predicates.yaml +2089 -0
- data/lib/reality.rb +26 -7
- data/lib/reality/config.rb +46 -0
- data/lib/reality/definitions/dictionaries.rb +67 -0
- data/lib/reality/definitions/helpers.rb +34 -0
- data/lib/reality/definitions/wikidata.rb +105 -0
- data/lib/reality/definitions/wikipedia_character.rb +17 -0
- data/lib/reality/definitions/wikipedia_city.rb +19 -0
- data/lib/reality/definitions/wikipedia_continent.rb +21 -0
- data/lib/reality/definitions/wikipedia_country.rb +23 -0
- data/lib/reality/definitions/wikipedia_musical_artist.rb +15 -0
- data/lib/reality/definitions/wikipedia_person.rb +17 -0
- data/lib/reality/entity.rb +152 -0
- data/lib/reality/entity/coercion.rb +76 -0
- data/lib/reality/entity/wikidata_predicates.rb +31 -0
- data/lib/reality/entity/wikipedia_type.rb +73 -0
- data/lib/reality/extras/geonames.rb +29 -0
- data/lib/reality/extras/open_weather_map.rb +63 -0
- data/lib/reality/geo.rb +122 -0
- data/lib/reality/infoboxer_templates.rb +8 -0
- data/lib/reality/list.rb +95 -0
- data/lib/reality/measure.rb +18 -12
- data/lib/reality/measure/unit.rb +5 -1
- data/lib/reality/methods.rb +16 -0
- data/lib/reality/pretty_inspect.rb +11 -0
- data/lib/reality/refinements.rb +26 -0
- data/lib/reality/shortcuts.rb +11 -0
- data/lib/reality/tz_offset.rb +64 -0
- data/lib/reality/util/formatters.rb +35 -0
- data/lib/reality/util/parsers.rb +53 -0
- data/lib/reality/version.rb +6 -0
- data/lib/reality/wikidata.rb +310 -0
- data/reality.gemspec +12 -3
- data/script/extract_wikidata_properties.rb +23 -0
- data/script/lib/nokogiri_more.rb +175 -0
- metadata +137 -7
- data/examples/all_countries.rb +0 -16
- data/lib/reality/country.rb +0 -283
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 81bd37c8f48b943d3f21927ba08a6632c3646e29
|
4
|
+
data.tar.gz: 60515a620873fe07de08f2de446148003f95152b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c8ec19350cc2616ce97065ea6651c739936def8b4e3e9014e4afed52fe3dec35f265bc5c6fc03746fbb7c31c8c8f6134ff30ce4501593c73a375ce9f3d9fcbf2
|
7
|
+
data.tar.gz: 06b7ab6e795fd71ffdc7983a279b2c3bb3e7caf2829593eda917820bba32ec6d125e9b0c4b844aa545f9d86cb550c81d8b189389c6606c79fa49dd89b53c1124
|
data/.dokaz
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--require ./spec/dokaz_helpers.rb
|
data/LICENSE.txt
ADDED
@@ -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
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
and
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
ar
|
17
|
-
ar.
|
18
|
-
|
19
|
-
|
20
|
-
#
|
21
|
-
|
22
|
-
#
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
#
|
29
|
-
|
30
|
-
#
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
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)
|