hoverbird-ny-times-congress 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.mkdn +30 -11
- data/Rakefile +9 -6
- data/TODO +2 -0
- data/VERSION.yml +2 -2
- data/bin/setup.rb +2 -2
- data/lib/ny-times/congress/attribute_transformation.rb +3 -4
- data/lib/ny-times/congress/base.rb +6 -6
- data/lib/ny-times/congress/congress.rb +5 -5
- data/lib/ny-times/congress/legislator.rb +7 -4
- data/lib/ny-times/congress/position.rb +2 -5
- data/lib/ny-times/congress/roll_call_vote.rb +2 -1
- data/spec/base_spec.rb +3 -3
- data/spec/congress_spec.rb +6 -6
- data/spec/example_data/example_data.rb +59 -33
- data/spec/example_data/member.json +37 -12
- data/spec/example_data/members.json +1011 -2231
- data/spec/example_data/roll_call_votes.json +1 -1
- data/spec/legislator_spec.rb +55 -52
- data/spec/role_spec.rb +3 -3
- data/spec/roll_call_vote_spec.rb +1 -1
- data/spec/spec_helper.rb +2 -1
- metadata +4 -2
data/README.mkdn
CHANGED
@@ -3,12 +3,11 @@ NY Times Congress
|
|
3
3
|
|
4
4
|
A Ruby wrapper for the New York Times Congress API.
|
5
5
|
---------------------
|
6
|
-
The NY Times has
|
6
|
+
The NY Times has been quietly scraping the web for data related to the United States Congress, and making the data freely available through a public [API](http://open.blogs.nytimes.com/2009/01/08/introducing-the-congress-api/). [ny-times-congress](http://github.com/hoverbird/ny-times-congress/) aims to make it even easier to write Ruby applications using this data, and also provides a command shell for interacting with the API directly.
|
7
7
|
|
8
8
|
Introdushing Congresh
|
9
9
|
---------------------
|
10
|
-
The Congress Shell (congresh for short/cute) is a simple interactive prompt
|
11
|
-
|
10
|
+
The Congress Shell (congresh for short/cute) is a simple interactive prompt that wraps IRB. It includes your API key (see setup below) and provides a few conveniences for test-driving the API.
|
12
11
|
|
13
12
|
Congress.new
|
14
13
|
---------------------
|
@@ -16,7 +15,7 @@ You get a Congress object either by calling Congress.new with the session and ch
|
|
16
15
|
|
17
16
|
current_senate = Senate
|
18
17
|
current_house = House
|
19
|
-
2007_senate =
|
18
|
+
2007_senate = Congress.new(109, 'senate')
|
20
19
|
2008_house = Congress.new(110, 'house')
|
21
20
|
|
22
21
|
Through a Congress object, you can get a list of its representatives as a hash, keyed by congressional Bio ID.
|
@@ -26,15 +25,17 @@ Through a Congress object, you can get a list of its representatives as a hash,
|
|
26
25
|
Legislator
|
27
26
|
---------------------
|
28
27
|
|
29
|
-
|
28
|
+
$ senators.values.find {|legislator| legislator.name == "Hillary Clinton"}
|
30
29
|
|
31
30
|
or
|
32
31
|
|
33
|
-
|
32
|
+
$ senators['C001041']
|
34
33
|
|
35
|
-
|
34
|
+
You can also grav a Legislator directly by their Bio ID. This call includes full details on the congressperson's roles, biographical info and more:
|
36
35
|
|
37
|
-
Legislator.find('C001041')
|
36
|
+
$ Legislator.find('C001041')
|
37
|
+
|
38
|
+
When accessing a Legislator from a collection of congress members, they include only a limited set of attributes. However, the library will make a second API call and lazy-load full attributes if you ask for them specifically. So even though a Legislator object returned through Congress.members don't have the #gender attribute, if you call for a specific Legislators gender, that data will be fetched and populated just in time.
|
38
39
|
|
39
40
|
|
40
41
|
Roll Call Votes
|
@@ -42,11 +43,29 @@ Roll Call Votes
|
|
42
43
|
|
43
44
|
To find a vote in any congress, you need to know the session (usually 1 or 2, although rarely congress will go into a 3rd session) and then the ID of the vote:
|
44
45
|
|
45
|
-
Senate.roll_call_vote(session_number, vote_number)
|
46
|
+
$ Senate.roll_call_vote(session_number, vote_number)
|
46
47
|
|
47
48
|
You can also find recent votes for any given senator:
|
48
|
-
|
49
|
-
hillary.
|
49
|
+
|
50
|
+
$ hillary = Legislator.find('C001041')
|
51
|
+
$ hillary.votes
|
52
|
+
|
53
|
+
|
54
|
+
Setup
|
55
|
+
_____________________
|
56
|
+
|
57
|
+
Add Github to your rubygems sources (if you haven't already) and then install the gem:
|
58
|
+
$ gem sources -a http://gems.github.com
|
59
|
+
$ sudo gem install hoverbird-ny-times-congress
|
60
|
+
|
61
|
+
You'll also need to [get an API key]:http://developer.nytimes.com/apps/register from the [NY Times Developer Network]: http://developer.nytimes.com/. If you set the key returned to an environment variable as shown below, Congresh will pick it up and include it in all your requests. You can keep this in your bash profile, but I also recommend putting all your developer keys in a separate .api_keys file in your path
|
62
|
+
|
63
|
+
export NYTIMES_CONGRESS_API_KEY="123456789ETC"
|
64
|
+
|
65
|
+
Within your app, you can also set this directly like so:
|
66
|
+
|
67
|
+
NYTimes::Congress::Base.api_key = "123456789ETC"
|
68
|
+
|
50
69
|
|
51
70
|
Acknowledgements
|
52
71
|
---------------------
|
data/Rakefile
CHANGED
@@ -25,11 +25,14 @@ Rake::RDocTask.new do |rdoc|
|
|
25
25
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
26
26
|
end
|
27
27
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
28
|
+
begin
|
29
|
+
require 'spec/rake/spectask'
|
30
|
+
desc "Run all examples"
|
31
|
+
Spec::Rake::SpecTask.new('spec') do |t|
|
32
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
33
|
+
end
|
34
|
+
rescue LoadError
|
35
|
+
puts "RSpec is not available. You'll need it to test ny-times-congress."
|
33
36
|
end
|
34
37
|
|
35
38
|
begin
|
@@ -50,4 +53,4 @@ rescue LoadError
|
|
50
53
|
puts "Cucumber is not available. In order to run features, you must: sudo gem install cucumber"
|
51
54
|
end
|
52
55
|
|
53
|
-
task :default => :
|
56
|
+
task :default => :spec
|
data/TODO
ADDED
data/VERSION.yml
CHANGED
data/bin/setup.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
include NYTimes::Congress
|
3
3
|
|
4
|
-
if ENV['
|
5
|
-
NYTimes::Congress::Base.api_key = ENV['
|
4
|
+
if ENV['NY_TIMES_CONGRESS_API_KEY']
|
5
|
+
NYTimes::Congress::Base.api_key = ENV['NY_TIMES_CONGRESS_API_KEY']
|
6
6
|
|
7
7
|
Senate = Congress.new(111, :senate)
|
8
8
|
House = Congress.new(111, :house)
|
@@ -39,17 +39,16 @@ module NYTimes
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def roles_for(roles_array)
|
42
|
-
roles_array.collect {|e| Role.new
|
42
|
+
roles_array.collect {|e| Role.new(e)}
|
43
43
|
end
|
44
44
|
|
45
45
|
def votes_for(votes_array)
|
46
|
-
votes_array.collect {|vote_hash| RollCallVote.new
|
46
|
+
votes_array.collect {|vote_hash| RollCallVote.new(vote_hash['vote'])}
|
47
47
|
end
|
48
48
|
|
49
49
|
def positions_for(votes_array)
|
50
50
|
votes_array.collect do |vote_hash|
|
51
|
-
|
52
|
-
Position.new vote['member_id'], vote['vote_position'], vote
|
51
|
+
Position.new(vote_hash['member_id'], vote_hash['vote_position'])
|
53
52
|
end
|
54
53
|
end
|
55
54
|
|
@@ -1,10 +1,10 @@
|
|
1
1
|
module NYTimes
|
2
2
|
module Congress
|
3
3
|
class Base
|
4
|
-
API_NAME
|
5
|
-
API_SERVER
|
6
|
-
API_VERSION
|
7
|
-
API_BASE
|
4
|
+
API_NAME = 'congress'
|
5
|
+
API_SERVER = 'api.nytimes.com'
|
6
|
+
API_VERSION = 2
|
7
|
+
API_BASE = "/svc/politics/v#{API_VERSION}/us/legislative/#{API_NAME}"
|
8
8
|
|
9
9
|
@@api_key = nil
|
10
10
|
@@copyright = nil
|
@@ -40,7 +40,7 @@ module NYTimes
|
|
40
40
|
|
41
41
|
full_params = params.merge 'api-key' => @@api_key
|
42
42
|
uri = build_request_url(path, full_params)
|
43
|
-
|
43
|
+
|
44
44
|
reply = uri.read
|
45
45
|
reply = JSON.parse(reply)
|
46
46
|
|
@@ -64,7 +64,7 @@ module NYTimes
|
|
64
64
|
EVAL
|
65
65
|
end
|
66
66
|
end
|
67
|
+
|
67
68
|
end
|
68
|
-
|
69
69
|
end
|
70
70
|
end
|
@@ -5,12 +5,12 @@ module NYTimes
|
|
5
5
|
include AttributeTransformation
|
6
6
|
|
7
7
|
def initialize(number, chamber)
|
8
|
-
@number
|
9
|
-
@chamber = symbol_for
|
8
|
+
@number = integer_for(number)
|
9
|
+
@chamber = symbol_for(chamber)
|
10
10
|
raise AttributeError unless number && chamber
|
11
11
|
end
|
12
12
|
|
13
|
-
def members(params = {})
|
13
|
+
def members(params = {})
|
14
14
|
@members ||= fetch_members
|
15
15
|
end
|
16
16
|
|
@@ -36,8 +36,8 @@ module NYTimes
|
|
36
36
|
|
37
37
|
def api_path
|
38
38
|
"#{number}/#{chamber}"
|
39
|
-
end
|
40
|
-
|
39
|
+
end
|
41
40
|
end
|
41
|
+
|
42
42
|
end
|
43
43
|
end
|
@@ -5,14 +5,17 @@ module NYTimes
|
|
5
5
|
ATTRIBUTE_MAP = { :date_for => [:date_of_birth],
|
6
6
|
:roles_for => [:roles],
|
7
7
|
:integer_for => [:govtrack_id, :district],
|
8
|
-
:string_for => [:url, :state, :gender, :name, :party
|
8
|
+
:string_for => [:url, :state, :gender, :name, :party,
|
9
|
+
:missed_votes_pct, :votes_with_party_pct] }
|
9
10
|
|
10
11
|
ATTRIBUTES = ATTRIBUTE_MAP.values.flatten
|
11
12
|
ATTRIBUTES.each {|attribute| define_lazy_reader_for_attribute_named attribute }
|
12
13
|
|
13
14
|
def self.find(id)
|
14
|
-
response = invoke("members/#{id}.json")
|
15
|
-
|
15
|
+
response = invoke("members/#{id}.json")
|
16
|
+
require 'ruby-debug'
|
17
|
+
debugger if response.inspect unless response.has_key?('results')
|
18
|
+
new(response['results'].first)
|
16
19
|
end
|
17
20
|
attr_reader :attributes, :id
|
18
21
|
|
@@ -46,7 +49,7 @@ module NYTimes
|
|
46
49
|
end
|
47
50
|
|
48
51
|
def load_fully
|
49
|
-
full_legislator =
|
52
|
+
full_legislator = Legislator.find(id)
|
50
53
|
attributes.merge!(full_legislator.attributes)
|
51
54
|
@fully_loaded = true
|
52
55
|
end
|
@@ -6,11 +6,10 @@ module NYTimes
|
|
6
6
|
|
7
7
|
VALUES = ['Yes', 'No', 'Not Voting', 'Present', 'Speaker']
|
8
8
|
|
9
|
-
def initialize(member_id, vote_position, vote)
|
10
|
-
raise "Member ID required" unless member_id
|
9
|
+
def initialize(member_id, vote_position, vote = nil)
|
11
10
|
@member_id = member_id
|
12
11
|
@vote_position = vote_position
|
13
|
-
|
12
|
+
@vote = vote
|
14
13
|
end
|
15
14
|
|
16
15
|
def legislator
|
@@ -36,5 +35,3 @@ module NYTimes
|
|
36
35
|
end
|
37
36
|
end
|
38
37
|
end
|
39
|
-
|
40
|
-
# {"votes"=>[{"vote"=>{"chamber"=>"Senate", "time"=>"11:57:00", "date"=>"2008-06-10", "roll_call"=>"147", "session"=>"2", "member_id"=>"B001210", "congress"=>"110", "position"=>"Not Voting"}}], "total_votes"=>"100", "member_id"=>"B001210", "offset"=>"0"}
|
@@ -6,7 +6,8 @@ module NYTimes
|
|
6
6
|
ATTRIBUTE_MAP = {
|
7
7
|
:date_for => [:date],
|
8
8
|
:integer_for => [:session_number, :congress, :roll_call],
|
9
|
-
:
|
9
|
+
:symbol_for => [:chamber],
|
10
|
+
:string_for => [:bill_number, :question, :vote_type, :time, :result, :description],
|
10
11
|
:positions_for => [:positions]
|
11
12
|
}
|
12
13
|
attr_reader *ATTRIBUTE_MAP.values.flatten
|
data/spec/base_spec.rb
CHANGED
@@ -10,7 +10,7 @@ describe Base do
|
|
10
10
|
end
|
11
11
|
|
12
12
|
it "returns a string matching the expected URL" do
|
13
|
-
url.should eql
|
13
|
+
url.should eql(expected_url)
|
14
14
|
end
|
15
15
|
|
16
16
|
end
|
@@ -22,8 +22,8 @@ describe Base do
|
|
22
22
|
end
|
23
23
|
|
24
24
|
it "makes a call to a given url and parses the returned JSON into a response hash" do
|
25
|
-
FakeWeb.register_uri(api_url_for('
|
26
|
-
@response = NYTimes::Congress::Base.invoke("
|
25
|
+
FakeWeb.register_uri(api_url_for('111/senate/members.json'), :string => example_data)
|
26
|
+
@response = NYTimes::Congress::Base.invoke("111/senate/members.json")
|
27
27
|
response.should == JSON.parse(example_data)
|
28
28
|
end
|
29
29
|
|
data/spec/congress_spec.rb
CHANGED
@@ -9,11 +9,11 @@ describe Congress do
|
|
9
9
|
|
10
10
|
describe "initializing with a congress number and chamber symbol", :shared => true do
|
11
11
|
it "is numbered with an Integer" do
|
12
|
-
congress.number.should be_kind_of
|
12
|
+
congress.number.should be_kind_of(Integer)
|
13
13
|
end
|
14
14
|
|
15
15
|
it "has a symbol representing the chamber" do
|
16
|
-
congress.chamber.should be_kind_of
|
16
|
+
congress.chamber.should be_kind_of(Symbol)
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
@@ -29,7 +29,7 @@ describe Congress do
|
|
29
29
|
attr_accessor :members
|
30
30
|
|
31
31
|
def example_data
|
32
|
-
|
32
|
+
members_response
|
33
33
|
end
|
34
34
|
|
35
35
|
before do
|
@@ -38,13 +38,13 @@ describe Congress do
|
|
38
38
|
end
|
39
39
|
|
40
40
|
it "should return an hash of Legislators keyed by ID" do
|
41
|
-
members.should be_kind_of
|
41
|
+
members.should be_kind_of(Hash)
|
42
42
|
members.values.all? {|e| e.class.should == Legislator}
|
43
|
-
members['
|
43
|
+
members['M000303'].name.should == "John McCain"
|
44
44
|
end
|
45
45
|
|
46
46
|
it "should return all members" do
|
47
|
-
members.size.should ==
|
47
|
+
members.size.should == 102
|
48
48
|
end
|
49
49
|
|
50
50
|
end
|
@@ -1,49 +1,75 @@
|
|
1
1
|
def member_response
|
2
|
-
File.read('
|
2
|
+
File.read(File.dirname(__FILE__) + '/member.json')
|
3
|
+
end
|
4
|
+
|
5
|
+
def members_response
|
6
|
+
File.read(File.dirname(__FILE__) + '/members.json')
|
7
|
+
end
|
8
|
+
|
9
|
+
def roll_call_votes_response
|
10
|
+
File.read(File.dirname(__FILE__) + '/roll_call_votes.json')
|
3
11
|
end
|
4
12
|
|
5
13
|
def limited_legislator_attributes
|
6
14
|
<<-JSON
|
7
|
-
|
8
|
-
"
|
9
|
-
"
|
10
|
-
"
|
11
|
-
"
|
15
|
+
{
|
16
|
+
"id": "L000304",
|
17
|
+
"name": "Joseph I. Lieberman",
|
18
|
+
"first_name": "Joseph I.",
|
19
|
+
"middle_name": "I.",
|
20
|
+
"last_name": "Lieberman",
|
21
|
+
"party": "ID",
|
22
|
+
"state": "CT",
|
23
|
+
"missed_votes_pct": "0.00",
|
24
|
+
"votes_with_party_pct": "93.44"
|
25
|
+
}
|
12
26
|
JSON
|
13
27
|
end
|
14
28
|
|
15
29
|
def full_legislator_attributes
|
16
30
|
<<-JSON
|
17
31
|
{
|
18
|
-
"
|
19
|
-
"
|
20
|
-
"
|
21
|
-
"gender":"M",
|
22
|
-
"url":"http://biden.senate.gov",
|
23
|
-
"govtrack_id":"300008",
|
24
|
-
"roles":[
|
25
|
-
{
|
26
|
-
"congress":"111",
|
27
|
-
"chamber":"Senate",
|
28
|
-
"title":"Senator, 2nd Class",
|
29
|
-
"state":"DE",
|
30
|
-
"party":"D",
|
31
|
-
"district":"N/A",
|
32
|
-
"start_date":"2009-01-06",
|
33
|
-
"end_date":"2009-01-20"
|
34
|
-
},
|
32
|
+
"status":"OK",
|
33
|
+
"copyright":"Copyright (c) 2009 The New York Times Company. All Rights Reserved.",
|
34
|
+
"results":[
|
35
35
|
{
|
36
|
-
"
|
37
|
-
"
|
38
|
-
"
|
39
|
-
"
|
40
|
-
"
|
41
|
-
"
|
42
|
-
"
|
43
|
-
"
|
36
|
+
"member_id": "L000304",
|
37
|
+
"name": "Joseph I. Lieberman",
|
38
|
+
"first_name": "Joseph I.",
|
39
|
+
"middle_name": "I.",
|
40
|
+
"last_name": "Lieberman",
|
41
|
+
"date_of_birth": "1942-02-24",
|
42
|
+
"gender": "M",
|
43
|
+
"url": "http://lieberman.senate.gov/",
|
44
|
+
"govtrack_id": "300067",
|
45
|
+
"roles": [
|
46
|
+
{
|
47
|
+
"congress": "111",
|
48
|
+
"chamber": "Senate",
|
49
|
+
"title": "Senator, 1st Class",
|
50
|
+
"state": "CT",
|
51
|
+
"party": "ID",
|
52
|
+
"district": "N/A",
|
53
|
+
"start_date": "2009-01-06",
|
54
|
+
"end_date": "2011-01-04",
|
55
|
+
"missed_votes_pct": "0.00",
|
56
|
+
"votes_with_party_pct": "93.44"
|
57
|
+
}, {
|
58
|
+
"congress": "110",
|
59
|
+
"chamber": "Senate",
|
60
|
+
"title": "Senator, 1st Class",
|
61
|
+
"state": "CT",
|
62
|
+
"party": "ID",
|
63
|
+
"district": "N/A",
|
64
|
+
"start_date": "2007-01-04",
|
65
|
+
"end_date": "2009-01-03",
|
66
|
+
"missed_votes_pct": "3.20",
|
67
|
+
"votes_with_party_pct": "86.79"
|
68
|
+
}
|
69
|
+
]
|
44
70
|
}
|
45
|
-
|
46
|
-
|
71
|
+
]
|
72
|
+
}
|
47
73
|
JSON
|
48
74
|
end
|
49
75
|
|
@@ -5,6 +5,9 @@
|
|
5
5
|
{
|
6
6
|
"member_id": "L000304",
|
7
7
|
"name": "Joseph I. Lieberman",
|
8
|
+
"first_name": "Joseph I.",
|
9
|
+
"middle_name": "I.",
|
10
|
+
"last_name": "Lieberman",
|
8
11
|
"date_of_birth": "1942-02-24",
|
9
12
|
"gender": "M",
|
10
13
|
"url": "http://lieberman.senate.gov/",
|
@@ -18,7 +21,9 @@
|
|
18
21
|
"party": "ID",
|
19
22
|
"district": "N/A",
|
20
23
|
"start_date": "2009-01-06",
|
21
|
-
"end_date": "2011-01-04"
|
24
|
+
"end_date": "2011-01-04",
|
25
|
+
"missed_votes_pct": "0.00",
|
26
|
+
"votes_with_party_pct": "93.44"
|
22
27
|
}, {
|
23
28
|
"congress": "110",
|
24
29
|
"chamber": "Senate",
|
@@ -27,7 +32,9 @@
|
|
27
32
|
"party": "ID",
|
28
33
|
"district": "N/A",
|
29
34
|
"start_date": "2007-01-04",
|
30
|
-
"end_date": "2009-01-03"
|
35
|
+
"end_date": "2009-01-03",
|
36
|
+
"missed_votes_pct": "3.20",
|
37
|
+
"votes_with_party_pct": "86.79"
|
31
38
|
}, {
|
32
39
|
"congress": "109",
|
33
40
|
"chamber": "Senate",
|
@@ -36,7 +43,9 @@
|
|
36
43
|
"party": "D",
|
37
44
|
"district": "N/A",
|
38
45
|
"start_date": "2005-01-04",
|
39
|
-
"end_date": "2006-12-09"
|
46
|
+
"end_date": "2006-12-09",
|
47
|
+
"missed_votes_pct": "7.44",
|
48
|
+
"votes_with_party_pct": "88.78"
|
40
49
|
}, {
|
41
50
|
"congress": "108",
|
42
51
|
"chamber": "Senate",
|
@@ -45,7 +54,9 @@
|
|
45
54
|
"party": "D",
|
46
55
|
"district": "N/A",
|
47
56
|
"start_date": "2003-01-07",
|
48
|
-
"end_date": "2004-12-08"
|
57
|
+
"end_date": "2004-12-08",
|
58
|
+
"missed_votes_pct": "39.11",
|
59
|
+
"votes_with_party_pct": "92.21"
|
49
60
|
}, {
|
50
61
|
"congress": "107",
|
51
62
|
"chamber": "Senate",
|
@@ -54,7 +65,9 @@
|
|
54
65
|
"party": "D",
|
55
66
|
"district": "N/A",
|
56
67
|
"start_date": "2001-01-03",
|
57
|
-
"end_date": "2002-11-22"
|
68
|
+
"end_date": "2002-11-22",
|
69
|
+
"missed_votes_pct": "1.90",
|
70
|
+
"votes_with_party_pct": "92.11"
|
58
71
|
}, {
|
59
72
|
"congress": "106",
|
60
73
|
"chamber": "Senate",
|
@@ -63,7 +76,9 @@
|
|
63
76
|
"party": "D",
|
64
77
|
"district": "N/A",
|
65
78
|
"start_date": "1999-01-06",
|
66
|
-
"end_date": "2000-12-15"
|
79
|
+
"end_date": "2000-12-15",
|
80
|
+
"missed_votes_pct": "10.12",
|
81
|
+
"votes_with_party_pct": "90.56"
|
67
82
|
}, {
|
68
83
|
"congress": "105",
|
69
84
|
"chamber": "Senate",
|
@@ -72,7 +87,9 @@
|
|
72
87
|
"party": "D",
|
73
88
|
"district": "N/A",
|
74
89
|
"start_date": "1997-01-07",
|
75
|
-
"end_date": "1998-12-19"
|
90
|
+
"end_date": "1998-12-19",
|
91
|
+
"missed_votes_pct": "0.65",
|
92
|
+
"votes_with_party_pct": "85.03"
|
76
93
|
}, {
|
77
94
|
"congress": "104",
|
78
95
|
"chamber": "Senate",
|
@@ -81,7 +98,9 @@
|
|
81
98
|
"party": "D",
|
82
99
|
"district": "N/A",
|
83
100
|
"start_date": "1995-01-04",
|
84
|
-
"end_date": "1996-10-04"
|
101
|
+
"end_date": "1996-10-04",
|
102
|
+
"missed_votes_pct": "1.21",
|
103
|
+
"votes_with_party_pct": "61.50"
|
85
104
|
}, {
|
86
105
|
"congress": "103",
|
87
106
|
"chamber": "Senate",
|
@@ -90,7 +109,9 @@
|
|
90
109
|
"party": "D",
|
91
110
|
"district": "N/A",
|
92
111
|
"start_date": "1993-01-05",
|
93
|
-
"end_date": "1994-12-01"
|
112
|
+
"end_date": "1994-12-01",
|
113
|
+
"missed_votes_pct": "1.38",
|
114
|
+
"votes_with_party_pct": "83.94"
|
94
115
|
}, {
|
95
116
|
"congress": "102",
|
96
117
|
"chamber": "Senate",
|
@@ -99,7 +120,9 @@
|
|
99
120
|
"party": "D",
|
100
121
|
"district": "N/A",
|
101
122
|
"start_date": "1991-01-03",
|
102
|
-
"end_date": "1993-01-03"
|
123
|
+
"end_date": "1993-01-03",
|
124
|
+
"missed_votes_pct": "1.09",
|
125
|
+
"votes_with_party_pct": "84.19"
|
103
126
|
}, {
|
104
127
|
"congress": "101",
|
105
128
|
"chamber": "Senate",
|
@@ -108,8 +131,10 @@
|
|
108
131
|
"party": "D",
|
109
132
|
"district": "N/A",
|
110
133
|
"start_date": "1989-01-03",
|
111
|
-
"end_date": "1991-01-03"
|
134
|
+
"end_date": "1991-01-03",
|
135
|
+
"missed_votes_pct": "0.63",
|
136
|
+
"votes_with_party_pct": "84.86"
|
112
137
|
} ]
|
113
138
|
}
|
114
139
|
]
|
115
|
-
}
|
140
|
+
}
|