worldbank_as_dataframe 0.2 → 0.2.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.
- checksums.yaml +4 -4
- data/Changelog +4 -0
- data/README.md +66 -0
- data/lib/worldbank_as_dataframe/client.rb +11 -11
- data/lib/worldbank_as_dataframe/commodities.rb +108 -0
- data/lib/worldbank_as_dataframe/version.rb +1 -1
- data/lib/worldbank_as_dataframe.rb +13 -14
- data/reqs/executed_plans.md +3 -0
- data/reqs/explicitly_stated_requirements.md +5 -0
- data/reqs/requirements/REQ-001.md +13 -0
- data/spec/fixtures/cmo_monthly_prices.xlsx +0 -0
- data/spec/worldbank_as_dataframe/commodities_spec.rb +29 -0
- data/test/test_commodities.rb +31 -0
- data/worldbank_as_dataframe.gemspec +1 -0
- metadata +27 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: dcb1ea76123deedc99ddce0e174ccd7930eba3a27ed76a617c7c8a7b28eb967a
|
|
4
|
+
data.tar.gz: daa92655da05f0df4014a67f4c3d35c14eff14c319c4da619747312c79a6b6d9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c08b5c1fda2faaef793185a0c8b3e1c56509d98ca38380faf892952476fb42a75da6b8c0d1be99cfeab4192c95f3803762cc048c4e5d040987672b9ce36e348c
|
|
7
|
+
data.tar.gz: f73a4ccd0590c351e8fde7e932b2744ec818034e7340eae868f3b79e8a89b1aae82bb746c9698c8ce542abfe6422607b3c9acd5f5755f8e4f16e267224a479a1
|
data/Changelog
CHANGED
data/README.md
CHANGED
|
@@ -96,6 +96,72 @@ include WorldbankAsDataframe
|
|
|
96
96
|
# modifiers (like #dates above) called as class methods or chained in a query.
|
|
97
97
|
#
|
|
98
98
|
|
|
99
|
+
# Commodities#fetch downloads the Pink Sheet xlsx and parses the Monthly Prices
|
|
100
|
+
# sheet with Roo (chart-only sheets such as AFOSHEET are skipped).
|
|
101
|
+
|
|
102
|
+
WorldbankAsDataframe::Commodities.new.fetch
|
|
103
|
+
# =>
|
|
104
|
+
# shape: (777, 72)
|
|
105
|
+
# ┌────────────┬────────────────────────────┬──────────────────────────┬──────────────────────────┬───┬─────────────┬──────────────────┬──────────────────────┬────────────────────┐
|
|
106
|
+
# │ Timestamps ┆ Crude oil, average ($/bbl) ┆ Crude oil, Brent ($/bbl) ┆ Crude oil, Dubai ($/bbl) ┆ … ┆ Zinc ($/mt) ┆ Gold ($/troy oz) ┆ Platinum ($/troy oz) ┆ Silver ($/troy oz) │
|
|
107
|
+
# │ --- ┆ --- ┆ --- ┆ --- ┆ ┆ --- ┆ --- ┆ --- ┆ --- │
|
|
108
|
+
# │ date ┆ f64 ┆ f64 ┆ f64 ┆ ┆ f64 ┆ f64 ┆ f64 ┆ f64 │
|
|
109
|
+
# ╞════════════╪════════════════════════════╪══════════════════════════╪══════════════════════════╪═══╪═════════════╪══════════════════╪══════════════════════╪════════════════════╡
|
|
110
|
+
# │ 1960-01-01 ┆ 1.63 ┆ 1.63 ┆ 1.63 ┆ … ┆ 260.8 ┆ 35.27 ┆ 83.5 ┆ 0.9137 │
|
|
111
|
+
# │ 1960-02-01 ┆ 1.63 ┆ 1.63 ┆ 1.63 ┆ … ┆ 244.9 ┆ 35.27 ┆ 83.5 ┆ 0.9137 │
|
|
112
|
+
# │ 1960-03-01 ┆ 1.63 ┆ 1.63 ┆ 1.63 ┆ … ┆ 248.7 ┆ 35.27 ┆ 83.5 ┆ 0.9137 │
|
|
113
|
+
# │ 1960-04-01 ┆ 1.63 ┆ 1.63 ┆ 1.63 ┆ … ┆ 254.6 ┆ 35.27 ┆ 83.5 ┆ 0.9137 │
|
|
114
|
+
# │ 1960-05-01 ┆ 1.63 ┆ 1.63 ┆ 1.63 ┆ … ┆ 253.8 ┆ 35.27 ┆ 83.5 ┆ 0.9137 │
|
|
115
|
+
# │ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … │
|
|
116
|
+
# │ 2024-05-01 ┆ 81.445 ┆ 81.995 ┆ 83.53 ┆ … ┆ 2959.13 ┆ 2351.13 ┆ 1014.68 ┆ 29.36 │
|
|
117
|
+
# │ 2024-06-01 ┆ 81.205 ┆ 82.555 ┆ 82.17 ┆ … ┆ 2809.19 ┆ 2326.44 ┆ 985.08 ┆ 29.577 │
|
|
118
|
+
# │ 2024-07-01 ┆ 83.258667 ┆ 85.296 ┆ 83.94 ┆ … ┆ 2777.27 ┆ 2398.2 ┆ 978.8 ┆ 29.773 │
|
|
119
|
+
# │ 2024-08-01 ┆ 78.121 ┆ 80.863 ┆ 77.95 ┆ … ┆ 2714.08 ┆ 2470.15 ┆ 945.36 ┆ 28.53 │
|
|
120
|
+
# │ 2024-09-01 ┆ 72.424333 ┆ 74.293 ┆ 73.43 ┆ … ┆ 2837.02 ┆ 2570.55 ┆ 966.7 ┆ 30.131 │
|
|
121
|
+
# └────────────┴────────────────────────────┴──────────────────────────┴──────────────────────────┴───┴─────────────┴──────────────────┴──────────────────────┴────────────────────┘
|
|
122
|
+
|
|
123
|
+
WorldbankAsDataframe::Commodities.new('crude').fetch
|
|
124
|
+
# =>
|
|
125
|
+
# shape: (777, 5)
|
|
126
|
+
# ┌────────────┬────────────────────────────┬──────────────────────────┬──────────────────────────┬────────────────────────┐
|
|
127
|
+
# │ Timestamps ┆ Crude oil, average ($/bbl) ┆ Crude oil, Brent ($/bbl) ┆ Crude oil, Dubai ($/bbl) ┆ Crude oil, WTI ($/bbl) │
|
|
128
|
+
# │ --- ┆ --- ┆ --- ┆ --- ┆ --- │
|
|
129
|
+
# │ date ┆ f64 ┆ f64 ┆ f64 ┆ f64 │
|
|
130
|
+
# ╞════════════╪════════════════════════════╪══════════════════════════╪══════════════════════════╪════════════════════════╡
|
|
131
|
+
# │ 1960-01-01 ┆ 1.63 ┆ 1.63 ┆ 1.63 ┆ null │
|
|
132
|
+
# │ 1960-02-01 ┆ 1.63 ┆ 1.63 ┆ 1.63 ┆ null │
|
|
133
|
+
# │ 1960-03-01 ┆ 1.63 ┆ 1.63 ┆ 1.63 ┆ null │
|
|
134
|
+
# │ 1960-04-01 ┆ 1.63 ┆ 1.63 ┆ 1.63 ┆ null │
|
|
135
|
+
# │ 1960-05-01 ┆ 1.63 ┆ 1.63 ┆ 1.63 ┆ null │
|
|
136
|
+
# │ … ┆ … ┆ … ┆ … ┆ … │
|
|
137
|
+
# │ 2024-05-01 ┆ 81.445 ┆ 81.995 ┆ 83.53 ┆ 78.81 │
|
|
138
|
+
# │ 2024-06-01 ┆ 81.205 ┆ 82.555 ┆ 82.17 ┆ 78.89 │
|
|
139
|
+
# │ 2024-07-01 ┆ 83.258667 ┆ 85.296 ┆ 83.94 ┆ 80.54 │
|
|
140
|
+
# │ 2024-08-01 ┆ 78.121 ┆ 80.863 ┆ 77.95 ┆ 75.55 │
|
|
141
|
+
# │ 2024-09-01 ┆ 72.424333 ┆ 74.293 ┆ 73.43 ┆ 69.55 │
|
|
142
|
+
# └────────────┴────────────────────────────┴──────────────────────────┴──────────────────────────┴────────────────────────┘
|
|
143
|
+
|
|
144
|
+
WorldbankAsDataframe::Commodities.new('gold').fetch(start: '1980-01-01', fin: '2000-12-31')
|
|
145
|
+
# =>
|
|
146
|
+
# shape: (252, 2)
|
|
147
|
+
# ┌────────────┬──────────────────┐
|
|
148
|
+
# │ Timestamps ┆ Gold ($/troy oz) │
|
|
149
|
+
# │ --- ┆ --- │
|
|
150
|
+
# │ date ┆ f64 │
|
|
151
|
+
# ╞════════════╪══════════════════╡
|
|
152
|
+
# │ 1980-01-01 ┆ 675.31 │
|
|
153
|
+
# │ 1980-02-01 ┆ 665.32 │
|
|
154
|
+
# │ 1980-03-01 ┆ 553.58 │
|
|
155
|
+
# │ 1980-04-01 ┆ 517.41 │
|
|
156
|
+
# │ 1980-05-01 ┆ 513.8 │
|
|
157
|
+
# │ … ┆ … │
|
|
158
|
+
# │ 2000-08-01 ┆ 274.47 │
|
|
159
|
+
# │ 2000-09-01 ┆ 273.68 │
|
|
160
|
+
# │ 2000-10-01 ┆ 270.0 │
|
|
161
|
+
# │ 2000-11-01 ┆ 266.01 │
|
|
162
|
+
# │ 2000-12-01 ┆ 271.45 │
|
|
163
|
+
# └────────────┴──────────────────┘
|
|
164
|
+
|
|
99
165
|
```
|
|
100
166
|
|
|
101
167
|
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '/source'))
|
|
2
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '/income_level'))
|
|
3
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '/lending_type'))
|
|
4
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '/country'))
|
|
5
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '/indicator'))
|
|
6
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '/topic'))
|
|
7
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '/region'))
|
|
8
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '/query'))
|
|
9
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '/data'))
|
|
10
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '/param_query'))
|
|
11
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '/data_query'))
|
|
1
12
|
require 'httparty'
|
|
2
|
-
require File.expand_path(File.join(File.dirname(__FILE__), 'source'))
|
|
3
|
-
require File.expand_path(File.join(File.dirname(__FILE__), 'income_level'))
|
|
4
|
-
require File.expand_path(File.join(File.dirname(__FILE__), 'lending_type'))
|
|
5
|
-
require File.expand_path(File.join(File.dirname(__FILE__), 'country'))
|
|
6
|
-
require File.expand_path(File.join(File.dirname(__FILE__), 'indicator'))
|
|
7
|
-
require File.expand_path(File.join(File.dirname(__FILE__), 'topic'))
|
|
8
|
-
require File.expand_path(File.join(File.dirname(__FILE__), 'region'))
|
|
9
|
-
require File.expand_path(File.join(File.dirname(__FILE__), 'query'))
|
|
10
|
-
require File.expand_path(File.join(File.dirname(__FILE__), 'data'))
|
|
11
|
-
require File.expand_path(File.join(File.dirname(__FILE__), 'param_query'))
|
|
12
|
-
require File.expand_path(File.join(File.dirname(__FILE__), 'data_query'))
|
|
13
13
|
|
|
14
14
|
module WorldbankAsDataframe
|
|
15
15
|
class Client
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
require 'open-uri'
|
|
2
|
+
require 'roo'
|
|
3
|
+
require 'polars-df'
|
|
4
|
+
require 'tempfile'
|
|
5
|
+
require 'date'
|
|
6
|
+
|
|
7
|
+
module WorldbankAsDataframe
|
|
8
|
+
class Commodities
|
|
9
|
+
CMO_URL = 'https://thedocs.worldbank.org/en/doc/5d903e848db1d1b83e0ec8f744e55570-0350012021/related/CMO-Historical-Data-Monthly.xlsx'
|
|
10
|
+
MONTHLY_PRICES_SHEET = 'Monthly Prices'
|
|
11
|
+
MISSING_MARKERS = ["…", "..."].freeze
|
|
12
|
+
|
|
13
|
+
attr_reader :tag
|
|
14
|
+
|
|
15
|
+
def initialize(series = nil, options={})
|
|
16
|
+
@tag = series
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def fetch(start: nil, fin: nil, path: nil)
|
|
20
|
+
if path
|
|
21
|
+
_frame_from_path(path, start: start, fin: fin)
|
|
22
|
+
else
|
|
23
|
+
Tempfile.open(['cmo', '.xlsx'], binmode: true) do |f|
|
|
24
|
+
f.write(URI.open(CMO_URL, 'User-Agent' => 'worldbank_as_dataframe').read)
|
|
25
|
+
f.flush
|
|
26
|
+
_frame_from_path(f.path, start: start, fin: fin)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def _frame_from_path(path, start: nil, fin: nil)
|
|
32
|
+
xlsx = Roo::Excelx.new(path)
|
|
33
|
+
rows = _monthly_price_rows(xlsx)
|
|
34
|
+
_build_frame(rows, start: start, fin: fin)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def _monthly_price_rows(xlsx)
|
|
38
|
+
name = xlsx.sheets.find { |sheet_name| _normalize_key(sheet_name) == _normalize_key(MONTHLY_PRICES_SHEET) }
|
|
39
|
+
raise 'CMO workbook contained no Monthly Prices sheet' if name.nil?
|
|
40
|
+
|
|
41
|
+
sheet = xlsx.sheet(name)
|
|
42
|
+
last_row = sheet.last_row
|
|
43
|
+
raise 'CMO Monthly Prices sheet is empty' if last_row.nil?
|
|
44
|
+
|
|
45
|
+
(1..last_row).map { |idx| sheet.row(idx) }
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def _build_frame(rows, start: nil, fin: nil)
|
|
49
|
+
ary = rows[4..].map { |row| row.dup }
|
|
50
|
+
raise 'CMO Monthly Prices sheet is missing header rows' if ary.nil? || ary.length < 3
|
|
51
|
+
|
|
52
|
+
ary[0][0] = 'Timestamps'
|
|
53
|
+
ary.map! { |a| a.reverse.drop_while(&:nil?).reverse }
|
|
54
|
+
ary[1].length.times { |i| ary[1][i] = [ary[0][i], ary[1][i]].compact.join(' ') }
|
|
55
|
+
ary = ary[1..]
|
|
56
|
+
|
|
57
|
+
cols = ary[0]
|
|
58
|
+
dat = ary[1..].map { |row| _coerce_row(row) }
|
|
59
|
+
dat.reject! { |row| row.compact.empty? }
|
|
60
|
+
|
|
61
|
+
frame_hsh = {}
|
|
62
|
+
cols.each_with_index { |col, i| frame_hsh[col] = dat.map { |row| row[i] } }
|
|
63
|
+
df = Polars::DataFrame.new(frame_hsh)
|
|
64
|
+
|
|
65
|
+
start_date = _to_date(start)
|
|
66
|
+
fin_date = _to_date(fin)
|
|
67
|
+
df = df.filter(Polars.col('Timestamps') >= start_date) unless start_date.nil?
|
|
68
|
+
df = df.filter(Polars.col('Timestamps') <= fin_date) unless fin_date.nil?
|
|
69
|
+
|
|
70
|
+
unless @tag.nil?
|
|
71
|
+
matched = cols.select { |c| c.to_s.downcase.include?(@tag.to_s.downcase) }
|
|
72
|
+
df = df.select(['Timestamps', *matched]) if matched.length > 0
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
df
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def _normalize_label(text)
|
|
79
|
+
return '' if text.nil?
|
|
80
|
+
|
|
81
|
+
text.to_s
|
|
82
|
+
.gsub(/<[^>]+>/, '')
|
|
83
|
+
.gsub(/[[:space:]]+/, ' ')
|
|
84
|
+
.delete('*')
|
|
85
|
+
.strip
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def _normalize_key(text)
|
|
89
|
+
_normalize_label(text).downcase
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def _coerce_row(row)
|
|
93
|
+
row = row.dup
|
|
94
|
+
if row[0].to_s =~ /\A(\d{4})M(\d{2})\z/
|
|
95
|
+
row[0] = Date.new($1.to_i, $2.to_i, 1)
|
|
96
|
+
end
|
|
97
|
+
row.map { |cell| MISSING_MARKERS.include?(cell) ? nil : cell }
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def _to_date(value)
|
|
101
|
+
return nil if value.nil?
|
|
102
|
+
return value if value.is_a?(Date)
|
|
103
|
+
return value.to_date if value.respond_to?(:to_date)
|
|
104
|
+
|
|
105
|
+
Date.parse(value.to_s)
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
@@ -1,21 +1,20 @@
|
|
|
1
1
|
require File.expand_path(File.join(File.dirname(__FILE__), '/worldbank_as_dataframe/client'))
|
|
2
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '/worldbank_as_dataframe/commodities'))
|
|
2
3
|
|
|
3
4
|
module WorldbankAsDataframe
|
|
4
|
-
|
|
5
5
|
def self.client(query={}, raw=false)
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
# Delegate to WorldbankAsDataframe::Client.new
|
|
12
|
-
def self.method_missing(method, *args, &block)
|
|
13
|
-
return super unless client.respond_to?(method)
|
|
14
|
-
client.send(method, *args, &block)
|
|
15
|
-
end
|
|
6
|
+
defaults = {:params => {:format => :json}, :dirs => []}
|
|
7
|
+
defaults.merge!(query)
|
|
8
|
+
WorldbankAsDataframe::Client.new(defaults, raw)
|
|
9
|
+
end
|
|
16
10
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
11
|
+
# Delegate to WorldbankAsDataframe::Client.new
|
|
12
|
+
def self.method_missing(method, *args, &block)
|
|
13
|
+
return super unless client.respond_to?(method)
|
|
14
|
+
client.send(method, *args, &block)
|
|
15
|
+
end
|
|
20
16
|
|
|
17
|
+
def self.respond_to?(method, include_private=false)
|
|
18
|
+
client.respond_to?(method, include_private) || super(method, include_private)
|
|
19
|
+
end
|
|
21
20
|
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# REQ-001 — Parse the current World Bank CMO workbook
|
|
2
|
+
|
|
3
|
+
**Source:** user directive to fix the same SimpleXlsxReader failures found in `ny_frb_as_dataframe` (2026-09-09).
|
|
4
|
+
|
|
5
|
+
## Statement
|
|
6
|
+
|
|
7
|
+
`WorldbankAsDataframe::Commodities#fetch` must load the current Pink Sheet `CMO-Historical-Data-Monthly.xlsx` and return a Polars frame.
|
|
8
|
+
|
|
9
|
+
## Required behavior
|
|
10
|
+
|
|
11
|
+
- Do not use SimpleXlsxReader. The published workbook includes a chart sheet (`AFOSHEET`) and `simple_xlsx_reader` 1.0.5 fails on sheets without a dimension node. Parse data sheets with Roo.
|
|
12
|
+
- Do not set `SimpleXlsxReader.configuration.auto_slurp`.
|
|
13
|
+
- Match the `Monthly Prices` sheet after normalizing whitespace and case.
|
|
Binary file
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
require 'helper'
|
|
2
|
+
|
|
3
|
+
describe WorldbankAsDataframe::Commodities do
|
|
4
|
+
let(:fixture) { File.expand_path('../../fixtures/cmo_monthly_prices.xlsx', __FILE__) }
|
|
5
|
+
|
|
6
|
+
it 'is instantiable' do
|
|
7
|
+
WorldbankAsDataframe::Commodities.new.should be_a WorldbankAsDataframe::Commodities
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it 'parses Monthly Prices from a chart-heavy workbook via Roo' do
|
|
11
|
+
df = WorldbankAsDataframe::Commodities.new.fetch(path: fixture)
|
|
12
|
+
df.columns.should include('Timestamps')
|
|
13
|
+
df.columns.should include('Crude oil, average ($/bbl)')
|
|
14
|
+
df['Timestamps'].to_a.should include(Date.new(1960, 1, 1))
|
|
15
|
+
df['Crude oil, average ($/bbl)'].to_a.first.should == 1.63
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it 'treats ellipsis cells as null and matches series tags case-insensitively' do
|
|
19
|
+
df = WorldbankAsDataframe::Commodities.new('crude oil').fetch(path: fixture)
|
|
20
|
+
df.columns.should == ['Timestamps', 'Crude oil, average ($/bbl)']
|
|
21
|
+
df.filter(Polars.col('Timestamps') == Date.new(1960, 2, 1))['Crude oil, average ($/bbl)'].to_a.first.should be_nil
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it 'filters by start and fin' do
|
|
25
|
+
df = WorldbankAsDataframe::Commodities.new.fetch(path: fixture, start: '2020-01-01', fin: '2020-12-31')
|
|
26
|
+
df.height.should == 1
|
|
27
|
+
df['Timestamps'].to_a.should == [Date.new(2020, 1, 1)]
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'bundler/setup'
|
|
4
|
+
require 'date'
|
|
5
|
+
require_relative '../lib/worldbank_as_dataframe'
|
|
6
|
+
|
|
7
|
+
FIXTURE = File.expand_path('../spec/fixtures/cmo_monthly_prices.xlsx', __dir__)
|
|
8
|
+
failures = []
|
|
9
|
+
|
|
10
|
+
failures << 'version' if WorldbankAsDataframe::VERSION.to_s.empty?
|
|
11
|
+
|
|
12
|
+
df = WorldbankAsDataframe::Commodities.new.fetch(path: FIXTURE)
|
|
13
|
+
failures << 'timestamps column' unless df.columns.include?('Timestamps')
|
|
14
|
+
failures << 'crude column' unless df.columns.include?('Crude oil, average ($/bbl)')
|
|
15
|
+
failures << '1960-01-01 row' unless df['Timestamps'].to_a.include?(Date.new(1960, 1, 1))
|
|
16
|
+
failures << 'crude value' unless df['Crude oil, average ($/bbl)'].to_a.first == 1.63
|
|
17
|
+
|
|
18
|
+
tagged = WorldbankAsDataframe::Commodities.new('CRUDE OIL').fetch(path: FIXTURE)
|
|
19
|
+
failures << 'tag columns' unless tagged.columns == ['Timestamps', 'Crude oil, average ($/bbl)']
|
|
20
|
+
|
|
21
|
+
windowed = WorldbankAsDataframe::Commodities.new.fetch(path: FIXTURE, start: '2020-01-01', fin: '2020-12-31')
|
|
22
|
+
failures << 'date window' unless windowed.height == 1 && windowed['Timestamps'].to_a == [Date.new(2020, 1, 1)]
|
|
23
|
+
|
|
24
|
+
c = WorldbankAsDataframe::Commodities.new
|
|
25
|
+
failures << 'normalize' unless c._normalize_key('<html>Monthly Prices*</html>') == 'monthly prices'
|
|
26
|
+
|
|
27
|
+
if failures.empty?
|
|
28
|
+
puts 'test_commodities: ok'
|
|
29
|
+
else
|
|
30
|
+
abort "test_commodities failed: #{failures.join(', ')}"
|
|
31
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: worldbank_as_dataframe
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 0.2.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Bill McKinnon
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2026-09-10 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: ZenTest
|
|
@@ -150,6 +150,20 @@ dependencies:
|
|
|
150
150
|
- - ">="
|
|
151
151
|
- !ruby/object:Gem::Version
|
|
152
152
|
version: '0'
|
|
153
|
+
- !ruby/object:Gem::Dependency
|
|
154
|
+
name: roo
|
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
|
156
|
+
requirements:
|
|
157
|
+
- - ">="
|
|
158
|
+
- !ruby/object:Gem::Version
|
|
159
|
+
version: '0'
|
|
160
|
+
type: :runtime
|
|
161
|
+
prerelease: false
|
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
163
|
+
requirements:
|
|
164
|
+
- - ">="
|
|
165
|
+
- !ruby/object:Gem::Version
|
|
166
|
+
version: '0'
|
|
153
167
|
description: A Ruby wrapper around the World Bank's Development Indicators API, with
|
|
154
168
|
credit to Code for America and Justin Stoller
|
|
155
169
|
email:
|
|
@@ -177,6 +191,7 @@ files:
|
|
|
177
191
|
- bin/setup
|
|
178
192
|
- lib/worldbank_as_dataframe.rb
|
|
179
193
|
- lib/worldbank_as_dataframe/client.rb
|
|
194
|
+
- lib/worldbank_as_dataframe/commodities.rb
|
|
180
195
|
- lib/worldbank_as_dataframe/country.rb
|
|
181
196
|
- lib/worldbank_as_dataframe/data.rb
|
|
182
197
|
- lib/worldbank_as_dataframe/data_query.rb
|
|
@@ -190,7 +205,11 @@ files:
|
|
|
190
205
|
- lib/worldbank_as_dataframe/source.rb
|
|
191
206
|
- lib/worldbank_as_dataframe/topic.rb
|
|
192
207
|
- lib/worldbank_as_dataframe/version.rb
|
|
208
|
+
- reqs/executed_plans.md
|
|
209
|
+
- reqs/explicitly_stated_requirements.md
|
|
210
|
+
- reqs/requirements/REQ-001.md
|
|
193
211
|
- spec/fixtures/brazil.json
|
|
212
|
+
- spec/fixtures/cmo_monthly_prices.xlsx
|
|
194
213
|
- spec/fixtures/countries.json
|
|
195
214
|
- spec/fixtures/countries_india.json
|
|
196
215
|
- spec/fixtures/income_level_lmc.json
|
|
@@ -207,6 +226,7 @@ files:
|
|
|
207
226
|
- spec/fixtures/topics.json
|
|
208
227
|
- spec/helper.rb
|
|
209
228
|
- spec/worldbank_as_dataframe/client_spec.rb
|
|
229
|
+
- spec/worldbank_as_dataframe/commodities_spec.rb
|
|
210
230
|
- spec/worldbank_as_dataframe/country_spec.rb
|
|
211
231
|
- spec/worldbank_as_dataframe/data_query_spec.rb
|
|
212
232
|
- spec/worldbank_as_dataframe/data_spec.rb
|
|
@@ -219,6 +239,7 @@ files:
|
|
|
219
239
|
- spec/worldbank_as_dataframe/source_spec.rb
|
|
220
240
|
- spec/worldbank_as_dataframe/topic_spec.rb
|
|
221
241
|
- spec/worldbank_as_dataframe_spec.rb
|
|
242
|
+
- test/test_commodities.rb
|
|
222
243
|
- worldbank_as_dataframe.gemspec
|
|
223
244
|
homepage: https://github.com/bmck/worldbank_as_dataframe
|
|
224
245
|
licenses: []
|
|
@@ -238,12 +259,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
238
259
|
- !ruby/object:Gem::Version
|
|
239
260
|
version: '0'
|
|
240
261
|
requirements: []
|
|
241
|
-
rubygems_version: 3.
|
|
262
|
+
rubygems_version: 3.3.7
|
|
242
263
|
signing_key:
|
|
243
264
|
specification_version: 4
|
|
244
265
|
summary: A Ruby wrapper around the World Bank's Development Indicators API
|
|
245
266
|
test_files:
|
|
246
267
|
- spec/fixtures/brazil.json
|
|
268
|
+
- spec/fixtures/cmo_monthly_prices.xlsx
|
|
247
269
|
- spec/fixtures/countries.json
|
|
248
270
|
- spec/fixtures/countries_india.json
|
|
249
271
|
- spec/fixtures/income_level_lmc.json
|
|
@@ -260,6 +282,7 @@ test_files:
|
|
|
260
282
|
- spec/fixtures/topics.json
|
|
261
283
|
- spec/helper.rb
|
|
262
284
|
- spec/worldbank_as_dataframe/client_spec.rb
|
|
285
|
+
- spec/worldbank_as_dataframe/commodities_spec.rb
|
|
263
286
|
- spec/worldbank_as_dataframe/country_spec.rb
|
|
264
287
|
- spec/worldbank_as_dataframe/data_query_spec.rb
|
|
265
288
|
- spec/worldbank_as_dataframe/data_spec.rb
|
|
@@ -272,3 +295,4 @@ test_files:
|
|
|
272
295
|
- spec/worldbank_as_dataframe/source_spec.rb
|
|
273
296
|
- spec/worldbank_as_dataframe/topic_spec.rb
|
|
274
297
|
- spec/worldbank_as_dataframe_spec.rb
|
|
298
|
+
- test/test_commodities.rb
|