Skip to content

Commit df20680

Browse files
committed
Added dataflow example to the doc folder.
1 parent 7ff3b9a commit df20680

File tree

3 files changed

+120
-0
lines changed

3 files changed

+120
-0
lines changed

doc/top-stock-scala/.gitignore

Whitespace-only changes.

doc/top-stock-scala/README.md

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
# Top Stock - Scala
2+
3+
This program determines which stock had the highest price in a given year.
4+
It as an example from chapter 1 "Introduction", section 1.2 "What's Scala?" of the book
5+
[Programming Scala: Tackle Multi-Core Complexity on the Java Virtual Machine](http://pragprog.com/book/vsscala/programming-scala).
6+
7+
## What It Does
8+
9+
This program takes a list of one or more stock symbols and a year. It then concurrently
10+
obtains the relevant stock data from Yahoo's iChart service for each symbol. Once all
11+
the data has been retrieved the program determines which stock had the highest year-end
12+
closing price.
13+
14+
http://ichart.finance.yahoo.com/table.csv?s=AAPL&a=11&b=01&c=2008&d=11&e=31&f=2008&g=m
15+
16+
### Run It
17+
18+
This example can be run from the console. From the root of the repo run:
19+
20+
> $ bundle exec ruby top-stock-scala/top-stock.rb
21+
22+
The output should be:
23+
24+
> Top stock of 2008 is GOOG closing at price $307.65
25+
26+
#### The Ruby Code
27+
28+
```ruby
29+
require 'concurrent'
30+
require 'open-uri'
31+
32+
def get_year_end_closing(symbol, year)
33+
uri = "http://ichart.finance.yahoo.com/table.csv?s=#{symbol}&a=11&b=01&c=#{year}&d=11&e=31&f=#{year}&g=m"
34+
data = open(uri) {|f| f.collect{|line| line.strip } }
35+
price = data[1].split(',')[4]
36+
price.to_f
37+
[symbol, price.to_f]
38+
end
39+
40+
def get_top_stock(symbols, year, timeout = 5)
41+
stock_prices = symbols.collect{|symbol| Concurrent::dataflow{ get_year_end_closing(symbol, year) }}
42+
Concurrent::dataflow(*stock_prices) { |*prices|
43+
prices.reduce(['', 0.0]){|highest, price| price.last > highest.last ? price : highest}
44+
}.value(timeout)
45+
end
46+
47+
symbols = ['AAPL', 'GOOG', 'IBM', 'ORCL', 'MSFT']
48+
year = 2008
49+
50+
top_stock, highest_price = get_top_stock(symbols, year)
51+
52+
puts "Top stock of #{year} is #{top_stock} closing at price $#{highest_price}"
53+
```
54+
55+
#### The Scala Code
56+
57+
```scala
58+
//START:PART1
59+
import scala.actors._
60+
import Actor._
61+
62+
val symbols = List( "AAPL", "GOOG", "IBM", "JAVA", "MSFT")
63+
val receiver = self
64+
val year = 2008
65+
66+
symbols.foreach { symbol =>
67+
actor { receiver ! getYearEndClosing(symbol, year) }
68+
}
69+
70+
val (topStock, highestPrice) = getTopStock(symbols.length)
71+
72+
printf("Top stock of %d is %s closing at price %f\n", year, topStock, highestPrice)
73+
//END:PART1
74+
75+
//START:PART2
76+
def getYearEndClosing(symbol : String, year : Int) = {
77+
val url = "http://ichart.finance.yahoo.com/table.csv?s=" +
78+
symbol + "&a=11&b=01&c=" + year + "&d=11&e=31&f=" + year + "&g=m"
79+
80+
val data = io.Source.fromURL(url).mkString
81+
val price = data.split("\n")(1).split(",")(4).toDouble
82+
(symbol, price)
83+
}
84+
//END:PART2
85+
86+
//START:PART3
87+
def getTopStock(count : Int) : (String, Double) = {
88+
(1 to count).foldLeft("", 0.0) { (previousHigh, index) =>
89+
receiveWithin(10000) {
90+
case (symbol : String, price : Double) =>
91+
if (price > previousHigh._2) (symbol, price) else previousHigh
92+
}
93+
}
94+
}
95+
//END:PART3
96+
```

doc/top-stock-scala/top-stock.rb

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
require 'concurrent'
2+
require 'open-uri'
3+
4+
def get_year_end_closing(symbol, year)
5+
uri = "http://ichart.finance.yahoo.com/table.csv?s=#{symbol}&a=11&b=01&c=#{year}&d=11&e=31&f=#{year}&g=m"
6+
data = open(uri) {|f| f.collect{|line| line.strip } }
7+
price = data[1].split(',')[4]
8+
price.to_f
9+
[symbol, price.to_f]
10+
end
11+
12+
def get_top_stock(symbols, year, timeout = 5)
13+
stock_prices = symbols.collect{|symbol| Concurrent::dataflow{ get_year_end_closing(symbol, year) }}
14+
Concurrent::dataflow(*stock_prices) { |*prices|
15+
prices.reduce(['', 0.0]){|highest, price| price.last > highest.last ? price : highest}
16+
}.value(timeout)
17+
end
18+
19+
symbols = ['AAPL', 'GOOG', 'IBM', 'ORCL', 'MSFT']
20+
year = 2008
21+
22+
top_stock, highest_price = get_top_stock(symbols, year)
23+
24+
puts "Top stock of #{year} is #{top_stock} closing at price $#{highest_price}"

0 commit comments

Comments
 (0)