Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
coverage
.bundle
11 changes: 11 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Encoding:
Enabled: false

AccessModifierIndentation:
EnforcedStyle: outdent

Documentation:
Enabled: false

ModuleFunction:
Enabled: false
4 changes: 4 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
source "https://rubygems.org"

gem "nokogiri"
gem "values"
17 changes: 17 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
GEM
remote: https://rubygems.org/
specs:
mini_portile (0.5.3)
nokogiri (1.6.1)
mini_portile (~> 0.5.0)
values (1.5.0)

PLATFORMS
ruby

DEPENDENCIES
nokogiri
values

BUNDLED WITH
1.10.5
65 changes: 44 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,33 +1,56 @@
***An exercise for Prime subscribers. Visit http://learn.thoughtbot.com/prime to learn more.***
# Upcase Analyzing Shakespeare

### Difficulty level: intermediate.
One of the many excersizes I take my students through at [Devschool's Online Developer School](https://devschool.rocks)

## Your Task
## Directions

As a Shakespeare buff, statistics junkie, and unix lover, Ben finds himself wanting a command-line tool for analyzing Macbeth.
Take the following XML file: [Macbeth XML](http://www.ibiblio.org/xml/examples/shakespeare/macbeth.xml)

Write a command-line program that prints the number of lines spoken by each character in the play.
Write Ruby code to parse the xml and extract the speakers and their line counts.

Sample usage/output (using made-up numbers):
The main entry-point is the lib/shakespeare_analyzer.rb and it is a stand-alone module, which means it holds no state and it is _not_ meant to be *mixed in*.

$ ruby macbeth_analyzer.rb
543 Macbeth
345 Banquo
220 Duncan
(etc.)
## Running the tests

You can find an XML-encoded version of Macbeth here: http://www.ibiblio.org/xml/examples/shakespeare/macbeth.xml. Your program should download and parse this file at runtime.
```bash
rake
```

Your solution must be tested, preferably via TDD.
Nothing more. You might need to `bundle install` frst.

## Working/Submitting
The tests that are here are very basic top level tests. They are meant to be acceptance tests, meaning when the code 'works' these tests will pass without you changing them at'tall, as my English friend says.

1. To work on this exercise, fork the repo and begin implementing your solution.
2. When you are done, copy the output of your program into a file in this repository.
3. Create a pull request so your code can be reviewed.
4. Perform a code review on at least one other person's solution. Your comments should follow our code review guidelines: https://github.com/thoughtbot/guides/tree/master/code-review. Most important: be friendly. Make suggestions, not demands.
5. Improve your solution based on the comments you've received and approaches you've learned from reviewing others' attempts.
## How about some help asshole?

## Bounty
Well, sure. That is only fair. If I gave you no further help I wouldn't be much of a RubyMentor, and that is exactly what I have become and am happy to be. So.......

## TDDing the Shakespeare Analyzer

I do this kind of thing much better in video than I do in text. Maybe it is because I curse less in video... Probably not, I think it may just be because I am really too lazy for my own good. Bullshit. I am a good programmer because I am just lazy enough!

Watch the [RubyLIVE.tv episode here](https://www.youtube.com/watch?v=lBkau5T1KnA)

And the code is in [this branch](https://github.com/therubymentor/shakespeare_analyzer/tree/420-live)

## My solution

Located [in this branch](https://github.com/therubymentor/shakespeare_analyzer/tree/jimokelly-solution)

In the ./bin folder you will find 2 executable files that implement my solution. One prints out to a screen, the other saves the file to the hard disk as output.txt You could, for instance, write one that saves to a database or whatever floats your boat, all without editing the original software in lib. Al la, the Open/Closed principle bitches.

## Running my solution

to print the output to screen:

```bash
bundle
./bin/print
```

or to save the output:

```bash
bundle
./bin/save
```

While knowledge and skill improvement are their own rewards, the author with the best solution (as judged by thoughtbot) will receive a cool thoughtbot t-shirt.
10 changes: 10 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
require "rake/testtask"

task default: [:test]

Rake::TestTask.new(:test) do |t|
t.libs << "lib"
t.libs << "test"
t.pattern = "test/**/*_test.rb"
t.verbose = false
end
14 changes: 14 additions & 0 deletions bin/print
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#! /usr/bin/env ruby

$LOAD_PATH.unshift "lib"

require 'rubygems'
require 'bundler/setup'
require 'nokogiri'
require 'open-uri'
require 'shakespeare_analyzer'

printer = ->(s) { puts s }

uri = "http://www.ibiblio.org/xml/examples/shakespeare/macbeth.xml"
ShakespeareAnalyzer.(printer, open(uri))
14 changes: 14 additions & 0 deletions bin/save
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#! /usr/bin/env ruby

$LOAD_PATH.unshift "lib"

require 'rubygems'
require 'bundler/setup'
require 'nokogiri'
require 'open-uri'
require 'shakespeare_analyzer'

printer = ->(s) { File.write "output.txt", s.map(&:to_s).join("\n") }

uri = "http://www.ibiblio.org/xml/examples/shakespeare/macbeth.xml"
ShakespeareAnalyzer.(printer, open(uri))
6 changes: 6 additions & 0 deletions lib/shakespeare_analyzer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module ShakespeareAnalyzer
extend self

def call(xml)
end
end
23 changes: 23 additions & 0 deletions test/fixtures/story.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0"?>
<SCENE>
<SPEECH>
<SPEAKER>DUNCAN</SPEAKER>
<LINE>What bloody man is that? He can report,</LINE>
<LINE>As seemeth by his plight, of the revolt</LINE>
<LINE>The newest state.</LINE>
</SPEECH>
<SPEECH>
<SPEAKER>MALCOLM</SPEAKER>
<LINE>This is the sergeant</LINE>
<LINE>Who like a good and hardy soldier fought</LINE>
<LINE>'Gainst my captivity. Hail, brave friend!</LINE>
<LINE>Say to the king the knowledge of the broil</LINE>
<LINE>As thou didst leave it.</LINE>
</SPEECH>
<SPEECH>
<SPEAKER>DUNCAN</SPEAKER>
<LINE>What bloody man is that? He can report,</LINE>
<LINE>As seemeth by his plight, of the revolt</LINE>
<LINE>The newest state.</LINE>
</SPEECH>
</SCENE>
14 changes: 14 additions & 0 deletions test/integration/line_counts_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
require 'minitest_helper'
require 'shakespeare_analyzer'

describe ShakespeareAnalyzer do
describe 'call' do
subject { ShakespeareAnalyzer }
let(:fixture) { File.expand_path('../../fixtures/story.xml', __FILE__) }
let(:xml) { File.read(fixture) }

it 'must print a list of speakers and line counts' do
subject.call(xml).must_equal "6 Duncan\n5 Malcolm\n"
end
end
end
3 changes: 3 additions & 0 deletions test/minitest_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
require 'minitest/autorun'
require 'minitest/pride'
Dir[File.join('./test/support/**/*.rb')].sort.each { |f| require f }