Compare commits

...

No commits in common. "submission-objsets" and "codecs" have entirely different histories.

14 changed files with 495 additions and 1106 deletions

View File

@ -7,7 +7,9 @@ stages:
compile:
stage: build
image: lampepfl/moocs-dotty:2019-09-17-2
image: lampepfl/moocs-dotty:2019-10-16
except:
- tags
tags:
- cs210
script:
@ -19,10 +21,12 @@ compile:
grade:
stage: grade
except:
- tags
tags:
- cs210
image:
name: registry.gitlab.com/fnux/cs210-grading-images/progfun1-objsets:20191002-626d0012efc94653bff8736b2570386000f65ea2
name: registry.gitlab.com/fnux/cs210-grading-images/progfun2-codecs:20191027-dfbea8aed96096ed3af1cf1958549b97328d4c25
entrypoint: [""]
allow_failure: true
before_script:

View File

@ -1,7 +1,6 @@
# CS-210: Object-Oriented Sets
# CS-210: Codecs
Please follow the [instructions from the main course
respository](https://gitlab.epfl.ch/lamp/cs-210-functional-programming-2019/blob/master/week3/00-homework3.md).
respository](https://gitlab.epfl.ch/lamp/cs-210-functional-programming-2019/blob/master/week11/00-homework8.md).
Grading and submission details can be found [here](https://gitlab.epfl.ch/lamp/cs-210-functional-programming-2019/blob/master/week1/02-grading-and-submission.md).

View File

@ -1,12 +1,16 @@
course := "progfun1"
assignment := "objsets"
course := "progfun2"
assignment := "codecs"
name := course.value + "-" + assignment.value
testSuite := "objsets.TweetSetSuite"
testSuite := "codecs.CodecsSuite"
scalaVersion := "0.19.0-bin-20190918-dd68eb8-NIGHTLY"
scalacOptions ++= Seq("-language:implicitConversions", "-deprecation")
libraryDependencies += "com.novocode" % "junit-interface" % "0.11" % Test
scalaVersion := "0.19.0-RC1"
scalacOptions ++= Seq("-deprecation")
libraryDependencies ++= Seq(
("org.scalacheck" %% "scalacheck" % "1.14.2" % Test).withDottyCompat(scalaVersion.value),
("org.typelevel" %% "jawn-parser" % "0.14.2").withDottyCompat(scalaVersion.value),
"com.novocode" % "junit-interface" % "0.11" % Test
)
testOptions in Test += Tests.Argument(TestFrameworks.JUnit, "-a", "-v", "-s")
initialCommands in console := """import codecs.{_, given}"""

Binary file not shown.

View File

@ -18,6 +18,8 @@ object MOOCSettings extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings: Seq[Def.Setting[_]] = Seq(
parallelExecution in Test := false
parallelExecution in Test := false,
// Report test result after each test instead of waiting for every test to finish
logBuffered in Test := false
)
}

View File

@ -1,4 +1,3 @@
libraryDependencies += "com.novocode" % "junit-interface" % "0.11" % Test
// Used for base64 encoding
libraryDependencies += "commons-codec" % "commons-codec" % "1.10"

View File

@ -0,0 +1,283 @@
package codecs
/**
* A data type modeling JSON values.
*
* For example, the `42` integer JSON value can be modeled as `Json.Num(42)`
*/
sealed trait Json {
/**
* Try to decode this JSON value into a value of type `A` by using
* the given decoder.
*
* Note that you have to explicitly fix `A` type parameter when you call the method:
*
* {{{
* someJsonValue.decodeAs[User] // OK
* someJsonValue.decodeAs // Wrong!
* }}}
*/
def decodeAs[A](given decoder: Decoder[A]): Option[A] = decoder.decode(this)
}
object Json {
/** The JSON `null` value */
case object Null extends Json
/** JSON boolean values */
case class Bool(value: Boolean) extends Json
/** JSON numeric values */
case class Num(value: BigDecimal) extends Json
/** JSON string values */
case class Str(value: String) extends Json
/** JSON objects */
case class Obj(fields: Map[String, Json]) extends Json
/** JSON arrays */
case class Arr(items: List[Json]) extends Json
}
/**
* A type class that turns a value of type `A` into its JSON representation.
*/
trait Encoder[-A] {
def encode(value: A): Json
/**
* Transforms this `Encoder[A]` into an `Encoder[B]`, given a transformation function
* from `B` to `A`.
*
* For instance, given a `Encoder[String]`, we can get an `Encoder[UUID]`:
*
* {{{
* def uuidEncoder(given stringEncoder: Encoder[String]): Encoder[UUID] =
* stringEncoder.transform[UUID](uuid => uuid.toString)
* }}}
*
* This operation is also known as ?contramap?.
*/
def transform[B](f: B => A): Encoder[B] =
Encoder.fromFunction[B](value => this.encode(f(value)))
}
object Encoder extends GivenEncoders {
/**
* Convenient method for creating an instance of encoder from a function `f`
*/
def fromFunction[A](f: A => Json) = new Encoder[A] {
def encode(value: A): Json = f(value)
}
}
trait GivenEncoders {
/** An encoder for the `Unit` value */
given Encoder[Unit] = Encoder.fromFunction(_ => Json.Null)
/** An encoder for `Int` values */
given Encoder[Int] = Encoder.fromFunction(n => Json.Num(BigDecimal(n)))
/** An encoder for `String` values */
given Encoder[String] =
Encoder.fromFunction(str => Json.Str(str))
/** An encoder for `Boolean` values */
given Encoder[Boolean] =
Encoder.fromFunction(v => Json.Bool(v))
/**
* Encodes a list of values of type `A` into a JSON array containing
* the list elements encoded with the given `encoder`
*/
given [A](given encoder: Encoder[A]): Encoder[List[A]] =
Encoder.fromFunction(as => Json.Arr(as.map(encoder.encode)))
}
/**
* A specialization of `Encoder` that returns JSON objects only
*/
trait ObjectEncoder[-A] extends Encoder[A] {
// Refines the encoding result to `Json.Obj`
def encode(value: A): Json.Obj
/**
* Combines `this` encoder with `that` encoder.
* Returns an encoder producing a JSON object containing both
* fields of `this` encoder and fields of `that` encoder.
*/
def zip[B](that: ObjectEncoder[B]): ObjectEncoder[(A, B)] =
ObjectEncoder.fromFunction { (a, b) =>
Json.Obj(this.encode(a).fields ++ that.encode(b).fields)
}
}
object ObjectEncoder {
/**
* Convenient method for creating an instance of object encoder from a function `f`
*/
def fromFunction[A](f: A => Json.Obj): ObjectEncoder[A] = new ObjectEncoder[A] {
def encode(value: A): Json.Obj = f(value)
}
/**
* An encoder for values of type `A` that produces a JSON object with one field
* named according to the supplied `name` and containing the encoded value.
*/
def field[A](name: String)(given encoder: Encoder[A]): ObjectEncoder[A] =
ObjectEncoder.fromFunction(a => Json.Obj(Map(name -> encoder.encode(a))))
}
/**
* The dual of an encoder. Decodes a serialized value into its initial type `A`.
*/
trait Decoder[+A] {
/**
* @param data The data to de-serialize
* @return The decoded value wrapped in `Some`, or `None` if decoding failed
*/
def decode(data: Json): Option[A]
/**
* Combines `this` decoder with `that` decoder.
* Returns a decoder that invokes both `this` decoder and `that`
* decoder and returns a pair of decoded value in case both succeed,
* or `None` if at least one failed.
*/
def zip[B](that: Decoder[B]): Decoder[(A, B)] =
Decoder.fromFunction { json =>
this.decode(json).zip(that.decode(json))
}
/**
* Transforms this `Decoder[A]` into a `Decoder[B]`, given a transformation function
* from `A` to `B`.
*
* This operation is also known as ?map?.
*/
def transform[B](f: A => B): Decoder[B] =
Decoder.fromFunction(json => this.decode(json).map(f))
}
object Decoder extends GivenDecoders {
/**
* Convenient method to build a decoder instance from a function `f`
*/
def fromFunction[A](f: Json => Option[A]): Decoder[A] = new Decoder[A] {
def decode(data: Json): Option[A] = f(data)
}
/**
* Alternative method for creating decoder instances
*/
def fromPartialFunction[A](pf: PartialFunction[Json, A]): Decoder[A] =
fromFunction(pf.lift)
}
trait GivenDecoders {
/** A decoder for the `Unit` value */
given Decoder[Unit] =
Decoder.fromPartialFunction { case Json.Null => () }
/** A decoder for `Int` values. Hint: use the `isValidInt` method of `BigDecimal`. */
// TODO Define a given `Decoder[Int]` instance
given Decoder[Int] =
Decoder.fromFunction{ case Json.Num(v) => if v.isValidInt then Some(v.intValue) else None
case _ => None}
/** A decoder for `String` values */
// TODO Define a given `Decoder[String]` instance
given Decoder[String] =
Decoder.fromPartialFunction{ case Json.Str(str) => str}
/** A decoder for `Boolean` values */
// TODO Define a given `Decoder[Boolean]` instance
given Decoder[Boolean] =
Decoder.fromPartialFunction{ case Json.Bool(v) => v}
/**
* A decoder for JSON arrays. It decodes each item of the array
* using the given `decoder`. The resulting decoder succeeds only
* if all the JSON array items are successfully decoded.
*/
given [A](given decoder: Decoder[A]): Decoder[List[A]] =
Decoder.fromFunction {
case Json.Arr(items: List[Json]) => Some(items.map(v => decoder.decode(v).get))
case _ => None
}
/**
* A decoder for JSON objects. It decodes the value of a field of
* the supplied `name` using the given `decoder`.
*/
def field[A](name: String)(given decoder: Decoder[A]): Decoder[A] =
Decoder.fromFunction{
case Json.Obj(field: Map[String, Json]) => decoder.decode(field.get(name).get)
case _ => None
}
}
case class Person(name: String, age: Int)
object Person extends PersonCodecs
trait PersonCodecs {
/** The encoder for `Person` */
given Encoder[Person] =
ObjectEncoder.field[String]("name")
.zip(ObjectEncoder.field[Int]("age"))
.transform[Person](user => (user.name, user.age))
/** The corresponding decoder for `Person` */
given Decoder[Person] ={
Decoder.field[String]("name").zip(Decoder.field[Int]("age")).transform[Person](user => Person(user._1, user._2))
}
}
case class Contacts(people: List[Person])
object Contacts extends ContactsCodecs
trait ContactsCodecs {
// TODO Define the encoder and the decoder for `Contacts`
// The JSON representation of a value of type `Contacts` should be
// a JSON object with a single field named ?people? containing an
// array of values of type `Person` (reuse the `Person` codecs)
given Encoder[Contacts] =
ObjectEncoder.field[List[Person]]("people").transform[Contacts](c => c.people)
given Decoder[Contacts] =
Decoder.field[List[Person]]("people").transform[Contacts](p => Contacts(p))
}
// In case you want to try your code, here is a simple `Main`
// that can be used as a starting point. Otherwise, you can use
// the REPL (use the `console` sbt task).
object Main {
def main(args: Array[String]): Unit = {
println(renderJson(42))
println(renderJson("foo"))
val maybeJsonString = parseJson(""" "foo" """)
val maybeJsonObj = parseJson(""" { "name": "Alice", "age": 42 } """)
val maybeJsonObj2 = parseJson(""" { "name": "Alice", "age": "42" } """)
// Uncomment the following lines as you progress in the assignment
println(maybeJsonString.flatMap(_.decodeAs[Int]))
println(maybeJsonString.flatMap(_.decodeAs[String]))
println(maybeJsonObj.flatMap(_.decodeAs[Person]))
println(maybeJsonObj2.flatMap(_.decodeAs[Person]))
println(renderJson(Person("Bob", 66)))
}
}

View File

@ -0,0 +1,74 @@
package codecs
import org.typelevel.jawn.{ Parser, SimpleFacade }
import scala.collection.mutable
import scala.util.Try
// Utility methods that decode values from `String` JSON blobs, and
// render values to `String` JSON blobs
/**
* Parse a JSON document contained in a `String` value into a `Json` value, returns
* `None` in case the supplied `s` value is not a valid JSON document.
*/
def parseJson(s: String): Option[Json] = Parser.parseFromString[Json](s).toOption
/**
* Parse the JSON value from the supplied `s` parameter, and then try to decode
* it as a value of type `A` using the given `decoder`.
*
* Returns `None` if JSON parsing failed, or if decoding failed.
*/
def parseAndDecode[A](s: String)(given decoder: Decoder[A]): Option[A] =
for {
json <- parseJson(s)
a <- decoder.decode(json)
} yield a
/**
* Render the supplied `value` into JSON using the given `encoder`.
*/
def renderJson[A](value: A)(given encoder: Encoder[A]): String =
render(encoder.encode(value))
private def render(json: Json): String = json match {
case Json.Null => "null"
case Json.Bool(b) => b.toString
case Json.Num(n) => n.toString
case Json.Str(s) => renderString(s)
case Json.Arr(vs) => vs.map(render).mkString("[", ",", "]")
case Json.Obj(vs) => vs.map { case (k, v) => s"${renderString(k)}:${render(v)}" }.mkString("{", ",", "}")
}
private def renderString(s: String): String = {
val sb = new StringBuilder
sb.append('"')
var i = 0
val len = s.length
while (i < len) {
s.charAt(i) match {
case '"' => sb.append("\\\"")
case '\\' => sb.append("\\\\")
case '\b' => sb.append("\\b")
case '\f' => sb.append("\\f")
case '\n' => sb.append("\\n")
case '\r' => sb.append("\\r")
case '\t' => sb.append("\\t")
case c =>
if (c < ' ') sb.append("\\u%04x" format c.toInt)
else sb.append(c)
}
i += 1
}
sb.append('"').toString
}
given SimpleFacade[Json] {
def jnull() = Json.Null
def jtrue() = Json.Bool(true)
def jfalse() = Json.Bool(false)
def jnum(s: CharSequence, decIndex: Int, expIndex: Int) = Json.Num(BigDecimal(s.toString))
def jstring(s: CharSequence) = Json.Str(s.toString)
def jarray(vs: List[Json]) = Json.Arr(vs)
def jobject(vs: Map[String, Json]) = Json.Obj(vs)
}

View File

@ -1,719 +0,0 @@
package objsets
// real tweet data, collected on Oct 1 2012
object TweetData {
val gizmodo = """[
{ "user": "gizmodo", "text": "Kindle Paperwhite Review: Forget Everything Else, This Is the E-Reader You Want http://t.co/737W6aNC", "retweets": 51.0 },
{ "user": "gizmodo", "text": "These new Apple patents give a sneak peek at what future iPhone cameras might have in store. http://t.co/0YT9rjxp", "retweets": 49.0 },
{ "user": "gizmodo", "text": "Ever wonder why the sky is dark at night? Here's your answer. http://t.co/eTKxkcaE", "retweets": 86.0 },
{ "user": "gizmodo", "text": "The head of Homeland Security stays secure by just not using email, at all. http://t.co/W6KAFEUu", "retweets": 37.0 },
{ "user": "gizmodo", "text": "This is how graphene will grow the flexible semiconductors of the future: http://t.co/IoEvuxp4", "retweets": 43.0 },
{ "user": "gizmodo", "text": "It's the tech-based reality TV show you never knew you didn't want: http://t.co/j9J8gAo8", "retweets": 19.0 },
{ "user": "gizmodo", "text": "How do you make your Steve Jobs sculpture stand out? Easy, mix in some trash you stole from him. http://t.co/mvHBj3CH", "retweets": 15.0 },
{ "user": "gizmodo", "text": "This awesome baggage roller coaster will make you wish you were a suitcase. http://t.co/ECaE2hgd", "retweets": 17.0 },
{ "user": "gizmodo", "text": "This price cut is putting the Kindle Paperwhite and the Nook with GlowLight head to head. Fight! http://t.co/1x6nOJGY", "retweets": 15.0 },
{ "user": "gizmodo", "text": "18 unlucky people who already broke the iPhone 5: http://t.co/9RpvX4te", "retweets": 79.0 },
{ "user": "gizmodo", "text": "Here's how to ditch cash and start paying for everything electronically. http://t.co/tgrZ50XM", "retweets": 30.0 },
{ "user": "gizmodo", "text": "If you're going to get a Nexus 7, you should just go out and buy it right now. http://t.co/tACY1YYG", "retweets": 33.0 },
{ "user": "gizmodo", "text": "The one thing you can buy that will make your smartphone better: http://t.co/rlA32n4r", "retweets": 74.0 },
{ "user": "gizmodo", "text": "Cold brew Irish coffee! It's the best part of waking up (drunk) http://t.co/cr3oCPKf", "retweets": 23.0 },
{ "user": "gizmodo", "text": "Maybe the best reminder yet that the coffee shop is not your office: http://t.co/T8aNd3SX", "retweets": 47.0 },
{ "user": "gizmodo", "text": "Why a brand new, billion-dollar battleship still needs old-timey wooden ladders: http://t.co/75yOeche", "retweets": 13.0 },
{ "user": "gizmodo", "text": "Time for another story bundle! Seven crime novels, pay what you want, support indie authors! http://t.co/kI7tFMvM", "retweets": 14.0 },
{ "user": "gizmodo", "text": "Apple's added a Maps section to its App Store to help you find an Apple Maps replacement: http://t.co/rpP0tCMI", "retweets": 114.0 },
{ "user": "gizmodo", "text": "Man jailed for accidentally sexting his whole address book (including some tweens) http://t.co/5IxaTHkz #WTFriday", "retweets": 65.0 },
{ "user": "gizmodo", "text": "An Iranian news agency thought an Onion article was real--and plagiarized it: http://t.co/C4lWe1Ij", "retweets": 112.0 },
{ "user": "gizmodo", "text": "Yep, the TSA is definitely stealing iPads: http://t.co/THYd8MKe", "retweets": 79.0 },
{ "user": "gizmodo", "text": "A week with the iPhone 5: http://t.co/ReuK1aJs", "retweets": 111.0 },
{ "user": "gizmodo", "text": "Tim Cook apologizes for Apple Maps and suggests you download... Bing: http://t.co/imQFFOyW", "retweets": 280.0 },
{ "user": "gizmodo", "text": "Neil Young unveils his new Pono music player: http://t.co/EEMznUio", "retweets": 27.0 },
{ "user": "gizmodo", "text": "This $50 stick turns any HDTV into an Android-powered smart TV: http://t.co/8FpZUnIE", "retweets": 101.0 },
{ "user": "gizmodo", "text": "NASA has found proof of a river on Mars: http://t.co/QPPUSQXp", "retweets": 242.0 },
{ "user": "gizmodo", "text": "14 people who should be ashamed of their @foursquare mayorship http://t.co/7AEHQJLT", "retweets": 50.0 },
{ "user": "gizmodo", "text": "This team of quadrocopter drones can throw and catch better than you http://t.co/GYdhzZMq", "retweets": 32.0 },
{ "user": "gizmodo", "text": "Steve Jobs' reality distortion field lives on http://t.co/CDnZi4z8", "retweets": 56.0 },
{ "user": "gizmodo", "text": "What's the worst children's toy you've ever seen? Let's bask in the awful http://t.co/fk41tJj0", "retweets": 18.0 },
{ "user": "gizmodo", "text": "Spies like us: why we're all Big Brother now http://t.co/MB3gXB0b", "retweets": 8.0 },
{ "user": "gizmodo", "text": "18 places carbon fiber just doesn't belong: http://t.co/vJo1Yhlj", "retweets": 21.0 },
{ "user": "gizmodo", "text": "A woman had a new ear grown on her arm and attached to her head and it is PRETTY GROSS: http://t.co/NyuikEmP", "retweets": 88.0 },
{ "user": "gizmodo", "text": "That iron man found by Nazis? It's of extraterrestrial origin. Yes, really. http://t.co/hRR7oufa", "retweets": 92.0 },
{ "user": "gizmodo", "text": "The new best desk toy since... maybe ever? http://t.co/IwuHYYgI", "retweets": 64.0 },
{ "user": "gizmodo", "text": "Poop snow on ancient burial ground. This can't end well. http://t.co/DAmSgIiu", "retweets": 30.0 },
{ "user": "gizmodo", "text": "Giant electronic circuits make wonderfully geeky art: http://t.co/um99UW4Y", "retweets": 20.0 },
{ "user": "gizmodo", "text": "This little robot will help make all that wine you drink: http://t.co/a6W5wY0p", "retweets": 16.0 },
{ "user": "gizmodo", "text": "Facebook's finally deleting thousands of face accounts: http://t.co/3quTouWv", "retweets": 51.0 },
{ "user": "gizmodo", "text": "These people actually really, really love Apple Maps: http://t.co/VvWsa5V7", "retweets": 29.0 },
{ "user": "gizmodo", "text": "Is your iPhone 5 camera seeing purple? Like, where it shouldn't be? http://t.co/EBnaMfFR", "retweets": 37.0 },
{ "user": "gizmodo", "text": "Ooh, a galaxy-shooting camera you might actually afford http://t.co/VLXkarGV", "retweets": 22.0 },
{ "user": "gizmodo", "text": "Is this the most stunning shuttle flyover ever? http://t.co/IYKbjmnx", "retweets": 59.0 },
{ "user": "gizmodo", "text": "Why Apple really ditched Google Maps http://t.co/evVBDYCu", "retweets": 104.0 },
{ "user": "gizmodo", "text": "Why is this part of Facebook broken? http://t.co/Y9Ur2U5T", "retweets": 12.0 },
{ "user": "gizmodo", "text": "Don't buy cheap iPhone 5 cables because they don't actually exist yet http://t.co/3LHLeCdO", "retweets": 56.0 },
{ "user": "gizmodo", "text": "How vicious spyware contaminated hundreds of thousands of rental PCs: http://t.co/MlrUDWZe", "retweets": 12.0 },
{ "user": "gizmodo", "text": "How Jack Daniels hand crafts every barrel for aging http://t.co/QeYKZDNv", "retweets": 54.0 },
{ "user": "gizmodo", "text": "Is putting pictures of missing children on 404 pages effective? http://t.co/WFh9tiZU", "retweets": 26.0 },
{ "user": "gizmodo", "text": "The gigantic crane that builds even more gigantic aircraft carriers http://t.co/KraKD1sE", "retweets": 17.0 },
{ "user": "gizmodo", "text": "The 20 most obvious PINs are painfully obvious http://t.co/Du9BYjeR", "retweets": 38.0 },
{ "user": "gizmodo", "text": "This is the closest, clearest view of Mars yet http://t.co/VrbZRVgR", "retweets": 45.0 },
{ "user": "gizmodo", "text": "Meet the new Apple, where things don't just work http://t.co/XS36kHWi", "retweets": 146.0 },
{ "user": "gizmodo", "text": "Cheap goodies on Google Play for the next five days: http://t.co/dT3bRBzZ", "retweets": 52.0 },
{ "user": "gizmodo", "text": "Do phones need to come with chargers these days? http://t.co/AZMsPUeD", "retweets": 21.0 },
{ "user": "gizmodo", "text": "The font on your car's dash might increase your risk of crashing: http://t.co/R6e6QiWp", "retweets": 27.0 },
{ "user": "gizmodo", "text": "Holy crap, self-driving cars are now legal in California! http://t.co/nSOwBSZ1", "retweets": 277.0 },
{ "user": "gizmodo", "text": "Judging by this photo, joining the USAF makes you a superhero http://t.co/XlCb7nK8", "retweets": 16.0 },
{ "user": "gizmodo", "text": "Warning: Security bug can wipe out your Android phone just by visiting a web page-not only limited to Samsung http://t.co/0y6vnOKw", "retweets": 290.0 },
{ "user": "gizmodo", "text": "Nikon D600 review: Images this spectacular have never been so cheap http://t.co/PK4LCOwX", "retweets": 33.0 },
{ "user": "gizmodo", "text": "Oh good, Iran's homemade war drone is in the air http://t.co/ySXchFfv", "retweets": 40.0 },
{ "user": "gizmodo", "text": "BTW, this is @brentrose tweeting for Gizmodo this week. Follow for witticisms and euphemisms.", "retweets": 0.0 },
{ "user": "gizmodo", "text": "Major Samsung security bug can wipe your Galaxy phone (updating) http://t.co/n5yDZ3dh", "retweets": 120.0 },
{ "user": "gizmodo", "text": "Aboard the ligher, smarter, deadlier aircraft carrier of tomorrow http://t.co/xVjQAr6J", "retweets": 22.0 },
{ "user": "gizmodo", "text": "NASA publishes the most detailed photo of the universe ever captured, and it's stunning http://t.co/68pDKByp", "retweets": 192.0 },
{ "user": "gizmodo", "text": "How NASA prevents a space plague outbreak http://t.co/jIeI7hPX", "retweets": 20.0 },
{ "user": "gizmodo", "text": "iPhone 5's brain dissected. Guess what, it's made by Samsung. http://t.co/wSyjvpDc", "retweets": 321.0 },
{ "user": "gizmodo", "text": "BlackBerry 10 adds so many features that so few people want http://t.co/eaQM0vlS", "retweets": 58.0 },
{ "user": "gizmodo", "text": "The supercomputer that houses the entire universe http://t.co/KQciouL2", "retweets": 47.0 },
{ "user": "gizmodo", "text": "Gambling website refunds everyone's Packers bets because of horrible refs http://t.co/bwmgYBDq", "retweets": 121.0 },
{ "user": "gizmodo", "text": "12 deadly inventions that killed their creators (not for the faint of heart) http://t.co/BCwRAzhe", "retweets": 82.0 },
{ "user": "gizmodo", "text": "You won't believe this amazing this wildlife photography contest winner http://t.co/nHIRgFVG", "retweets": 20.0 },
{ "user": "gizmodo", "text": "How to build an iPhone 5 dock for $1.27 http://t.co/kqsQ1GIV", "retweets": 65.0 },
{ "user": "gizmodo", "text": "Would you eat this disgusting stuff? (Spoiler: yes, you would) http://t.co/mRAmDRpk", "retweets": 25.0 },
{ "user": "gizmodo", "text": "The iPhone 5 'shortage' is apparently a result of its new ultra-thin display: http://t.co/RqUSuYif", "retweets": 48.0 },
{ "user": "gizmodo", "text": "How much do you care about how Twitter measures your influence? http://t.co/0fitjfCD", "retweets": 19.0 },
{ "user": "gizmodo", "text": "Eric Schmidt confirms a Google Maps app on iOS 6 is still some way off: http://t.co/bobRuY06", "retweets": 76.0 },
{ "user": "gizmodo", "text": "Breville YouBrew coffee maker review: excellent, expensive, safe for idiots (like @harrysawyers) http://t.co/67wKNuLM", "retweets": 11.0 },
{ "user": "gizmodo", "text": "Can this flashy redesign make Myspace cool again? http://t.co/OfHVPHz6", "retweets": 94.0 },
{ "user": "gizmodo", "text": "No, your private Facebook messages have not gone public. Filthy secrets, still safe. http://t.co/RAJsAyK0", "retweets": 67.0 },
{ "user": "gizmodo", "text": "iOS 5.1 for Apple TV brings new AirPlay goodness http://t.co/1Yj55T52", "retweets": 48.0 },
{ "user": "gizmodo", "text": "The Facebook for poor people you didn't know existed http://t.co/9zmMTZci", "retweets": 29.0 },
{ "user": "gizmodo", "text": "(In case you're wondering who the awesome speller is, that's @brentrose. He has an MFA.)", "retweets": 2.0 },
{ "user": "gizmodo", "text": "iPhone 5 vs Galaxy S III: Who's screen is prettier? http://t.co/n6CbaspY", "retweets": 108.0 },
{ "user": "gizmodo", "text": "Yeah, we live in the future, but there's all this awesome 50-year-old Jetsons tech we still don't have http://t.co/lXsqu49Z", "retweets": 46.0 },
{ "user": "gizmodo", "text": "This tiny telescope implant gives eyesight to the blind http://t.co/W50RHP4L", "retweets": 40.0 },
{ "user": "gizmodo", "text": "Iran shuts down Google, will completely cut citizens fff the internet http://t.co/60ZucBic", "retweets": 146.0 },
{ "user": "gizmodo", "text": "10 stupid, crazy, wonderful gadget fails http://t.co/p3Al28G5", "retweets": 32.0 },
{ "user": "gizmodo", "text": "Watch an NBA player dunk the iPhone 5. Boomshakalaka! http://t.co/UQAX0awf", "retweets": 47.0 },
{ "user": "gizmodo", "text": "Is your iPhone 5... rattling? http://t.co/mn0r2dhb", "retweets": 67.0 },
{ "user": "gizmodo", "text": "The definitive comparison of iOS 5 Google Maps vs iOS 6 Apple Maps in one single image: http://t.co/fTwTfVMy", "retweets": 191.0 },
{ "user": "gizmodo", "text": "Study splits breast cancer into four treatable types: http://t.co/myTn3LHu", "retweets": 23.0 },
{ "user": "gizmodo", "text": "IBM's supercomputer genius Watson is headed for the cloud: http://t.co/Z1psttXB", "retweets": 59.0 },
{ "user": "gizmodo", "text": "Nuance is planning to develop voice recognition which works while your phone sleeps. Good idea? http://t.co/WEXD9bQa", "retweets": 25.0 },
{ "user": "gizmodo", "text": "Is your new iPhone picking up more scratches than you'd like? http://t.co/DGEiawOi", "retweets": 35.0 },
{ "user": "gizmodo", "text": "Foxconn has shut down a factory after 2,000 of its employees started a massive brawl. http://t.co/d7TXo3K9", "retweets": 90.0 },
{ "user": "gizmodo", "text": "If you thought the NES Zapper was cool before, watch it set things on fire with a laser. http://t.co/t3f0oE8O", "retweets": 37.0 },
{ "user": "gizmodo", "text": "Want to hack NFC to get free train rides? There's an app for that. http://t.co/eAp6yTbE", "retweets": 82.0 },
{ "user": "gizmodo", "text": "The weirdest thing people hate about the iPhone 5: http://t.co/GMwuRp8D", "retweets": 202.0 },
{ "user": "gizmodo", "text": "Data centers waste a completely absurd amount of energy. http://t.co/NcO9pXqb", "retweets": 58.0 }
]"""
val TechCrunch = """[
{ "user": "TechCrunch", "text": "Resignation Media Hires CEO John Ellis To Run Tapiture, Its Fast-Growing Pinterest For Men http://t.co/ctn7oWJc by @anthonyha", "retweets": 18.0 },
{ "user": "TechCrunch", "text": "FreedomPop Opens Its Freemium Internet Service To The Masses With New Public Beta http://t.co/35mA9Adp by @chrisvelazco", "retweets": 27.0 },
{ "user": "TechCrunch", "text": "Dish And The Dream Of Internet TV http://t.co/y8KcSl8G by @ryanlawler", "retweets": 25.0 },
{ "user": "TechCrunch", "text": "Adobe's Acrobat XI Boasts New PDF Editor And Touch-Friendly Interface ? Upgrades Start At $139 http://t.co/1YDWvlVI by @anthonyha", "retweets": 26.0 },
{ "user": "TechCrunch", "text": "Testing Out Bodymetrics, The Startup That Wants To Be A Denim Shopper's Best Friend [TCTV] http://t.co/sPe6wA02 by @loyalelectron", "retweets": 22.0 },
{ "user": "TechCrunch", "text": "Up Close With The Next Big Home Commodity: LED Lighting http://t.co/nGPSMnMH", "retweets": 17.0 },
{ "user": "TechCrunch", "text": "Cloning Instagram For Video Will Not Revolutionize Mobile Video http://t.co/B5DMkSnQ by @sandeepcasi", "retweets": 43.0 },
{ "user": "TechCrunch", "text": "(R)evolution http://t.co/dzQFqjBh by @sarahintampa", "retweets": 20.0 },
{ "user": "TechCrunch", "text": "An Analysis Of Market Demand For Web Programming Languages http://t.co/gdYrXz7i by @marcgayle", "retweets": 91.0 },
{ "user": "TechCrunch", "text": "The Kindle Paperwhite Is A Reader's Dream http://t.co/jGslGazO by @johnbiggs", "retweets": 61.0 },
{ "user": "TechCrunch", "text": "Soon-To-Be-Acquired BlueSprig's AirCover Family Locator Is An iOS/Android App That Lets You Track ... http://t.co/qSQquuLS by @ingridlunden", "retweets": 24.0 },
{ "user": "TechCrunch", "text": "Data Markets: The Emerging Data Economy http://t.co/lnTekycH by @gilelbaz", "retweets": 63.0 },
{ "user": "TechCrunch", "text": "CoCoon, The Newest Home For Startups In Hong Kong http://t.co/IN164KNl by @mulligan", "retweets": 35.0 },
{ "user": "TechCrunch", "text": "Imagine No Ads On Facebook. It's Easy If You Try http://t.co/kWSYY2v8 by @joshconstine", "retweets": 70.0 },
{ "user": "TechCrunch", "text": "Microsoft Needs Windows Phone 7 - Not WP8 - To Win Significant Mobile Market Share http://t.co/X71YJ0MD by @riptari", "retweets": 36.0 },
{ "user": "TechCrunch", "text": "Open Source Fear Mongering Is Ridiculous With The Advent Of Open APIs http://t.co/evVLkzCu by @alexwilliams", "retweets": 41.0 },
{ "user": "TechCrunch", "text": "Logitech UE Boombox And Mobile Boombox Review: Bluetooth Speakers With A Rich Sound http://t.co/ZpewcBEX by @romaindillet", "retweets": 17.0 },
{ "user": "TechCrunch", "text": "You Don't Need A Prototype To Raise A Seed Round http://t.co/vkPaK3sM by @VCMike", "retweets": 59.0 },
{ "user": "TechCrunch", "text": "Jason Calacanis' Next Act, And Another Pivot For http://t.co/XBhz5HpF, As A 'Knowledge Community' http://t.co/7ZLTckm6 by @ingridlunden", "retweets": 12.0 },
{ "user": "TechCrunch", "text": "Mass Persuasion, One User at a Time http://t.co/0Cv9fd4V by @nireyal", "retweets": 24.0 },
{ "user": "TechCrunch", "text": "The Zooka Wireless Speaker Bar Turns Bad Audio Into Loud Noises! http://t.co/VNljouTp by @jordanrcrook", "retweets": 34.0 },
{ "user": "TechCrunch", "text": "Iterations: We Know About B2B And B2C, But Don't Overlook B2D http://t.co/i0FIyDbX by @semil", "retweets": 55.0 },
{ "user": "TechCrunch", "text": "5 Big Map App Issues Apple Must Solve http://t.co/XGV7PuXk", "retweets": 82.0 },
{ "user": "TechCrunch", "text": "B&amp;N Drops Price Of Its Nook GlowLight In Advance Of Amazon's New Reader http://t.co/TkhEJpoz by @johnbiggs", "retweets": 26.0 },
{ "user": "TechCrunch", "text": "Why Angel Investors Don?t Make Money ? And Advice For People Who Are Going To Become Angels Anyway http://t.co/u2ApCrw7", "retweets": 138.0 },
{ "user": "TechCrunch", "text": "Barnes &amp; Noble Cuts GlowLight Nook Price To $129 As Amazon Prepares To Ship Its Own Backlit Kindles http://t.co/kiDTncdF by @chrisvelazco", "retweets": 40.0 },
{ "user": "TechCrunch", "text": "Games Are A Difficult Investment Proposition, But Crowdfunding Could Change That http://t.co/EvpdbrsS", "retweets": 43.0 },
{ "user": "TechCrunch", "text": "Simon Cowell And http://t.co/7lk1PBvp Are Creating An X Factor To Find The Next Mark Zuckerberg http://t.co/ZesTDWMs by @leenarao", "retweets": 192.0 },
{ "user": "TechCrunch", "text": "How Technology Is Empowering Teachers, Minting Millionaires, And Improving Education http://t.co/EgFaGI6w by @ripemp", "retweets": 154.0 },
{ "user": "TechCrunch", "text": "Italians Take Up The Torch To Ignite Their Own Tech Startup Scene http://t.co/zAuoFO4t by @mikebutcher", "retweets": 89.0 },
{ "user": "TechCrunch", "text": "A Tech Way Around Creative Block http://t.co/H6eOyiay by @alexcornell", "retweets": 50.0 },
{ "user": "TechCrunch", "text": "Klout Would Like Potential Employers To Consider Your Score Before Hiring You. And That's Stupid. http://t.co/YmnMj271 by @thatdrew", "retweets": 204.0 },
{ "user": "TechCrunch", "text": "A Venture Capitalist's E-Commerce Shopping List http://t.co/tA7VbXBT by @VCSerge", "retweets": 55.0 },
{ "user": "TechCrunch", "text": "Five Big Changes In The iOS 6 App Store (And What Developers Should Do) http://t.co/pkMSN96G by @sarahintampa", "retweets": 76.0 },
{ "user": "TechCrunch", "text": "Canadian Internet Provider Rogers Experiencing Major, Prolonged Outage http://t.co/xIKbMsou by @drizzled", "retweets": 134.0 },
{ "user": "TechCrunch", "text": "Hate http://t.co/y6Udo2nZ", "retweets": 38.0 },
{ "user": "TechCrunch", "text": "The Search For Minority Entrepreneurs Is Over -- Now They Need To Be Ready For Investors http://t.co/8PE4Jjp3 by @waynesutton", "retweets": 59.0 },
{ "user": "TechCrunch", "text": "Kickstarter: Helios, An iPhone Telepresence Rig On A Budget http://t.co/EgEKtsvt by @johnbiggs", "retweets": 33.0 },
{ "user": "TechCrunch", "text": "Facebook Updates Messenger For iOS With New Chat UI, iOS 6 And iPhone 5 Support http://t.co/Ffc2a6Ib by @fredericl", "retweets": 66.0 },
{ "user": "TechCrunch", "text": "The Next Big E-Commerce Wave: Vertically Integrated Commerce http://t.co/MEND0OQk by @bwertz", "retweets": 132.0 },
{ "user": "TechCrunch", "text": "Bootstrap's Maintainers Leave Twitter For GitHub And Obvious Corp., Will Move It Into Its Own Organiz... http://t.co/jznaaxc1 by @fredericl", "retweets": 76.0 },
{ "user": "TechCrunch", "text": "Should You Trust Your Gut? The Answer Is Yes. http://t.co/8TlMTip1", "retweets": 74.0 },
{ "user": "TechCrunch", "text": "PSA For Win8 Devs: The Only Way To Distribute Your Metro Apps Is Through The Windows Store http://t.co/v26GTcsO by @fredericl", "retweets": 22.0 },
{ "user": "TechCrunch", "text": "Gillmor Gang: Platformicide http://t.co/Sk9zwRw4 by @stevegillmor", "retweets": 17.0 },
{ "user": "TechCrunch", "text": "Apple's Maps Is A Black Eye, Nothing More http://t.co/XK9H5B5h by @jdalrymple", "retweets": 71.0 },
{ "user": "TechCrunch", "text": "Lessons From The Dramatic Slow-Motion Death Of Wikitravel http://t.co/u7BUYnwc by @rezendi", "retweets": 43.0 },
{ "user": "TechCrunch", "text": "Startup Success Requires The Drive For Data http://t.co/Yl2JpFCI by @jeffma", "retweets": 78.0 },
{ "user": "TechCrunch", "text": "Here Are The Singers Competing In Next Week's 'American Idol For The Geek Set' http://t.co/OcBvSOLl by @anthonyha", "retweets": 20.0 },
{ "user": "TechCrunch", "text": "Ford CTO Paul Mascarenas On Bridging The Worlds Of Silicon Valley And Motor City [TCTV] http://t.co/oeD4AD5n by @loyalelectron", "retweets": 21.0 },
{ "user": "TechCrunch", "text": "Apple Adds A Clarifying Description To Its Apps For Passbook Page In The App Store http://t.co/fkj4P0EP by @drizzled", "retweets": 42.0 },
{ "user": "TechCrunch", "text": "Post-SingTel Acquisition, Photo Aggregation App Pixable Gets An Image-Centric Redesign http://t.co/pNS4tFke by @anthonyha", "retweets": 12.0 },
{ "user": "TechCrunch", "text": "Rest In Peace, Charles Alfred Eldon: A Pioneer Of Silicon Valley, A Role Model For This New Generation http://t.co/3p1mt486 by @eldon", "retweets": 89.0 },
{ "user": "TechCrunch", "text": "TechCrunch Giveaway: Free Tickets To Box's 2012 #BoxWorks Event http://t.co/t4l8IIrK by @elinblesener", "retweets": 35.0 },
{ "user": "TechCrunch", "text": "Cloud Security Firm Qualys' IPO Opens At $12/Share, Raising $71.8M http://t.co/n2WNQkuH by @ingridlunden", "retweets": 18.0 },
{ "user": "TechCrunch", "text": "The FeedBurner Deathwatch Continues: Google Kills AdSense For Feeds http://t.co/CztoKUFP by @fredericl", "retweets": 31.0 },
{ "user": "TechCrunch", "text": "Google's Spring Cleaning In Fall: AdSense For Feeds, Classic Plus, Spreadsheet Gadgets Get The Axe http://t.co/pSeE3fCS by @thatdrew", "retweets": 26.0 },
{ "user": "TechCrunch", "text": "Gillmor Gang Live 09.28.12 (TCTV) http://t.co/eUf0Df0q by @stevegillmor", "retweets": 6.0 },
{ "user": "TechCrunch", "text": "Facebook Shares Jump More Than 6% After Gifts Launch. (Hooray For New Revenue Streams.) http://t.co/8fEXj2kG by @kimmaicutler", "retweets": 99.0 },
{ "user": "TechCrunch", "text": "Evernote Listens To Unhappy Skitch 2.0 Users: Brings Back Some Old Features And Version 1.0 http://t.co/y2YRxxyJ by @fredericl", "retweets": 29.0 },
{ "user": "TechCrunch", "text": "Groupon's Leadership Shuffle Continues: New North American Sales Head Named http://t.co/V4USZ7XU by @ingridlunden", "retweets": 19.0 },
{ "user": "TechCrunch", "text": "Ptch Partners With Paramount, Letting Users Remix Their Own Paranormal Activity Found Footage http://t.co/28vTlzvu by @ryanlawler", "retweets": 17.0 },
{ "user": "TechCrunch", "text": "Foursquare Partners With OpenTable To Make Reservations Simple http://t.co/EUz36s6i by @thatdrew", "retweets": 82.0 },
{ "user": "TechCrunch", "text": "Treasure Data Launches Cloud-Based Data Warehouse With Investment From Ruby Creator Yukihiro ?Ma... http://t.co/Ds9mYFAX by @alexwilliams", "retweets": 15.0 },
{ "user": "TechCrunch", "text": "Meet Apple's New CEO, Tom Brooks http://t.co/fdyX3Oox by @drizzled", "retweets": 54.0 },
{ "user": "TechCrunch", "text": "Music-Sharing Startup MyStream Preps Android Launch, Looks Beyond Music http://t.co/CusbX5mh by @anthonyha", "retweets": 18.0 },
{ "user": "TechCrunch", "text": "HP's Open webOS Goes 1.0, Can Now Be Ported To New Devices http://t.co/xljTC0L7 by @drizzled", "retweets": 60.0 },
{ "user": "TechCrunch", "text": "Another Day, Another Eyeful Of HTC's Mildly-Updated One X+ http://t.co/LLU27dkp by @chrisvelazco", "retweets": 16.0 },
{ "user": "TechCrunch", "text": "Color CEO Bill Nguyen Checks Out Of Day-To-Day Operations, While A New Leadership... http://t.co/vePSKt9x by @loyalelectron and @ryanlawler", "retweets": 19.0 },
{ "user": "TechCrunch", "text": "Professor Facebook: Social Network Co-Designs New Course At General Assembly http://t.co/3UvQ3Mts by @ferenstein", "retweets": 19.0 },
{ "user": "TechCrunch", "text": "Windows Phone Dev Center Now Provides User Review Translations For App Developers http://t.co/shAUIS64 by @drizzled", "retweets": 15.0 },
{ "user": "TechCrunch", "text": "Sprint And Motorola Party Like It's 2010: Motorola XPRT Finally Gets A Taste Of Gingerbread http://t.co/vOJRwng8 by @romaindillet", "retweets": 7.0 },
{ "user": "TechCrunch", "text": "U.S. Appeals Court: Samsung Free To Seek Lifting Of Galaxy Tab 10.1 Sales Injunction http://t.co/HTvIDlQU by @drizzled", "retweets": 24.0 },
{ "user": "TechCrunch", "text": "Google Launches A New Tablet-Optimized User Interface For Flight Search http://t.co/xQOdAA60 by @fredericl", "retweets": 36.0 },
{ "user": "TechCrunch", "text": "Twitter Announces New Improvements For Discover Tab, Adds Continuous Tweet Stream http://t.co/DpMRuDvO by @thatdrew", "retweets": 69.0 },
{ "user": "TechCrunch", "text": "Apple Is Heavily Promoting Alternative Map Apps On The App Store http://t.co/LNf6lKQH by @thatdrew", "retweets": 77.0 },
{ "user": "TechCrunch", "text": "PadPivot NST Review: The Best Available iPad Stand Just Got Better http://t.co/YJWkwkDd by @drizzled", "retweets": 11.0 },
{ "user": "TechCrunch", "text": "AngelList Wings Is A Handy App For Searching AngelList On Your iPhone http://t.co/tJwqOMdi by @sarahintampa", "retweets": 7.0 },
{ "user": "TechCrunch", "text": "Google Updates Gmail For iOS With Support For The iPhone 5's Larger Screen http://t.co/4fQ7YqYn by @fredericl", "retweets": 41.0 },
{ "user": "TechCrunch", "text": "Well Played On Maps, Apple. Your Move, Google. http://t.co/kJvuAfw9 by @thatdrew", "retweets": 70.0 },
{ "user": "TechCrunch", "text": "Flat-Fee, Dongle-free Card Payments Startup Emu Opens For Business In U.K., Registrations In Europe http://t.co/cILxZAVn by @riptari", "retweets": 27.0 },
{ "user": "TechCrunch", "text": "Report: Apple's Pandora-Killer Hits Licensing Trouble With Sony/ATV http://t.co/7sV1BMb8 by @drizzled", "retweets": 55.0 },
{ "user": "TechCrunch", "text": "LinkedIn Shuts Off API Access To Fellow Professional Social Network Viadeo For TOS Violations http://t.co/nAFHWLQ4 by @leenarao", "retweets": 31.0 },
{ "user": "TechCrunch", "text": "iOS 6 Adoption At Just Over One Week: 60% For iPhone And 41% For iPad http://t.co/Q0HAgCz8 by @drizzled", "retweets": 125.0 },
{ "user": "TechCrunch", "text": "Business Dashboards Get Instant Widgets, And Geckoboard Gets $1.5M From A Group Of Top Investors http://t.co/lDMDJUMQ by @ingridlunden", "retweets": 29.0 },
{ "user": "TechCrunch", "text": "BlackBerry 10 Touch, Qwerty Devices Leak In Video; RIM Wants Lady Gaga To Help Sell BB10 http://t.co/7rFGECgA by @riptari", "retweets": 36.0 },
{ "user": "TechCrunch", "text": "Neil Young Begins His Long Quest Towards True Audio Fidelity With Pono, A New Music Service And Device http://t.co/t1Ez2d26 by @johnbiggs", "retweets": 34.0 },
{ "user": "TechCrunch", "text": "Socialize's New Ad Platform Turns Passbook Passes Into Mobile Ads http://t.co/I2aku6yx by @sarahintampa", "retweets": 21.0 },
{ "user": "TechCrunch", "text": "Pay-By-Keyword Startup Seconds Refocuses As A Way To Make Anyone A Merchant http://t.co/id0jy9i4 by @drizzled", "retweets": 19.0 },
{ "user": "TechCrunch", "text": "Google Maps, Now With More High-Res Satellite And 45? Aerial Imagery http://t.co/FRIe230w by @mjburnsy", "retweets": 83.0 },
{ "user": "TechCrunch", "text": "Tim Cook Apologizes For Apple Maps, Points To Competitive Alternatives http://t.co/aOONqQLt by @jordanrcrook", "retweets": 265.0 },
{ "user": "TechCrunch", "text": "Apple's iPhone 5 Availability Expands: What It Means To Regional Carriers http://t.co/eNU1Mzfq by @drizzled", "retweets": 31.0 },
{ "user": "TechCrunch", "text": "Survey: Younger Shoppers Increasingly Using Mobiles To Buy And Compare http://t.co/TzI9dyeM by @riptari", "retweets": 87.0 },
{ "user": "TechCrunch", "text": "MyVR Raises $1.4M From SV Angel, Chris Dixon To Attack The $85B Vacation Rental Industry http://t.co/h65xm9mV by @ripemp", "retweets": 29.0 },
{ "user": "TechCrunch", "text": "New Pricing For Amazon RDS Running Oracle Database http://t.co/nwXG81fu by @alexwilliams", "retweets": 33.0 },
{ "user": "TechCrunch", "text": "Which Founders Use FoundersCard? Craig Newmark, Kevin Rose, Leah Busque &amp; 8K Others http://t.co/krGynNsV by @ripemp", "retweets": 21.0 },
{ "user": "TechCrunch", "text": "If You Had Remote Access To Your Neighbor's Printer, What Would You Print? http://t.co/2iXhjjNY by @alexia", "retweets": 94.0 },
{ "user": "TechCrunch", "text": "Pluralis Takes A Crowdsourced Approach To Improving Your Landing Pages http://t.co/YcqHJuC7 by @anthonyha", "retweets": 27.0 },
{ "user": "TechCrunch", "text": "Best photobomb of the day. http://t.co/Xa2EYTyd", "retweets": 326.0 },
{ "user": "TechCrunch", "text": "An Afternoon With Bad Piggies, Rovio's Next Hit http://t.co/KpYlmFSQ by @jordanrcrook", "retweets": 18.0 },
{ "user": "TechCrunch", "text": "Most Docks Should Work With The Lightning Adapter And iPhone 5 http://t.co/oGlTupcK by @johnbiggs", "retweets": 13.0 }
]"""
val engadget = """[
{ "user": "engadget", "text": "Sony reveals Japan prices for Windows 8 VAIO machines - http://t.co/FRCu2XVb", "retweets": 18.0 },
{ "user": "engadget", "text": "FreedomPop's pay-as-you-go data service launches in beta, offering 500MB of free WiMAX per month - http://t.co/Ny48yXUl", "retweets": 10.0 },
{ "user": "engadget", "text": "Lenovo intros ThinkCentre M78 with AMD A-Series APU and a starting price of $449 - http://t.co/OEDe1EwW", "retweets": 22.0 },
{ "user": "engadget", "text": "HP announces the ElitePad 900, a business-friendly Windows 8 tablet arriving in January - http://t.co/RjSj2cms", "retweets": 33.0 },
{ "user": "engadget", "text": "How would you change Nokia's Lumia 900? - http://t.co/kW4MqiCv", "retweets": 8.0 },
{ "user": "engadget", "text": "Amazon Kindle Paperwhite review - http://t.co/A1ytikHz", "retweets": 34.0 },
{ "user": "engadget", "text": "Refresh Roundup: week of September 24th, 2012 - http://t.co/7BZkgDcN", "retweets": 5.0 },
{ "user": "engadget", "text": "Slackware 14.0 now available, freshens and simplifies a Linux vanguard - http://t.co/Lq2s5RL6", "retweets": 33.0 },
{ "user": "engadget", "text": "Slingbox 350 and 500 show up unannounced in Best Buy, flaunt 1080p and built-in WiFi - http://t.co/BCBmTq8i", "retweets": 32.0 },
{ "user": "engadget", "text": "Switched On: iOS 6 gets back from the app - http://t.co/8j4YL4Yn", "retweets": 16.0 },
{ "user": "engadget", "text": "IRL: Dyson DC44, NUU ClickMate PowerPlus and the Galaxy S III - http://t.co/5Duf2aa5", "retweets": 8.0 },
{ "user": "engadget", "text": "B&amp;N makes the Nook Simple Touch with GlowLight's $20 price drop official - http://t.co/qDOwJHFT", "retweets": 9.0 },
{ "user": "engadget", "text": "New process for nanotube semiconductors could be graphene's ticket to primetime (video) - http://t.co/6hiwBora", "retweets": 30.0 },
{ "user": "engadget", "text": "Inhabitat's Week in Green: ECOLAR house, transparent solar panel and Star Wars terrariums - http://t.co/oeINUocC", "retweets": 8.0 },
{ "user": "engadget", "text": "Sony shuts down PSP Comic Store after October 30th, leaves most of us in the lurch for now - http://t.co/sYpIQLtO", "retweets": 30.0 },
{ "user": "engadget", "text": "Google retires more services, consolidates others in continued efficiency bid - http://t.co/UUdCFYPD", "retweets": 53.0 },
{ "user": "engadget", "text": "LightSquared pitches new plans to FCC in attempt to end GPS interference hex - http://t.co/MubfRh7q", "retweets": 10.0 },
{ "user": "engadget", "text": "Razer Blade review (late 2012) - http://t.co/QJpAz1nu", "retweets": 31.0 },
{ "user": "engadget", "text": "Maingear announces Nomad 17 gaming laptop, comes with custom paint job - http://t.co/mj9dT843", "retweets": 9.0 },
{ "user": "engadget", "text": "Ask Engadget: should companies include a cable with a new product? - http://t.co/NpXV1CdY", "retweets": 6.0 },
{ "user": "engadget", "text": "RT @engadgethd: Looking for more pictures of the new Logitech Harmony Touch universal remote? We've got 'em http://t.co/GL7D8DCO", "retweets": 34.0 },
{ "user": "engadget", "text": "Target, Walmart list price drop for B&amp;N's Nook Simple Touch with GlowLight to $119 - http://t.co/zLtZGjrK", "retweets": 13.0 },
{ "user": "engadget", "text": "Mobile Miscellany: week of September 24th, 2012 - http://t.co/e4LWzDgb", "retweets": 9.0 },
{ "user": "engadget", "text": "Logitech Harmony Touch remote pops up unannounced at Best Buy - http://t.co/PHOgiyAj", "retweets": 16.0 },
{ "user": "engadget", "text": "Alt-week 9.29.12: 3D pictures of the moon, 4D clocks and laser-controlled worms - http://t.co/IuEKU297", "retweets": 10.0 },
{ "user": "engadget", "text": "Hard drive shipments recover from floods in Thailand, expected to reach record high - http://t.co/JnKct0aV", "retweets": 65.0 },
{ "user": "engadget", "text": "Cubify lets you skin, 3D print your own personal Android - http://t.co/S6nimh5R", "retweets": 23.0 },
{ "user": "engadget", "text": "Facebook Messenger 2.0 for iPhone brings new design to conversations, swipe left for friends list - http://t.co/fDQO7eJN", "retweets": 55.0 },
{ "user": "engadget", "text": "US Cellular expands its Windows Phone catalog with the ZTE Render for $80 - http://t.co/uPZzQyy8", "retweets": 13.0 },
{ "user": "engadget", "text": "Modbook Pro to launch with SSD storage, up for pre-order October 3rd - http://t.co/w87nj1W4", "retweets": 61.0 },
{ "user": "engadget", "text": "BlackBerry 10 L-series tutorial videos surface online, give a literal peek at the future (video) - http://t.co/fLLDSRvA", "retweets": 47.0 },
{ "user": "engadget", "text": "Logitech promises continued support for Squeezebox, says it won't force a switch to UE Smart Radio - http://t.co/xGFz7aLE", "retweets": 17.0 },
{ "user": "engadget", "text": "Scape, Brian Eno's new ambient music creation app is now available on the iPad (video) - http://t.co/pRgrXoHA", "retweets": 33.0 },
{ "user": "engadget", "text": "Touch Bionics releases new prosthetic fingers, flip the old ones the bird - http://t.co/xJNFmahn", "retweets": 48.0 },
{ "user": "engadget", "text": "Sony starts delivering Ice Cream Sandwich update to Xperia go, Xperia U and Xperia sola - http://t.co/ao0Y6Iur", "retweets": 38.0 },
{ "user": "engadget", "text": "Xi3 goes the crowdfunding route for future X3A, X7A modular PCs (video) - http://t.co/aPvAO10A", "retweets": 14.0 },
{ "user": "engadget", "text": "FCC votes in favor of rethinking spectrum holding rules, goading broadcasters into wireless selloffs - http://t.co/x50qKCNB", "retweets": 14.0 },
{ "user": "engadget", "text": "Prometheus Blu-ray specs unveiled, arrives with seven hours of extras October 9th (video) - http://t.co/xGnog3Kr", "retweets": 60.0 },
{ "user": "engadget", "text": "Samsung Galaxy Note II variants for AT&amp;T, T-Mobile, Verizon possibly caught at the FCC - http://t.co/YLvixd9D", "retweets": 21.0 },
{ "user": "engadget", "text": "Nokia Parking helps you find and pay for a spot, we go hands-on (video) - http://t.co/NnAvzIlG", "retweets": 43.0 },
{ "user": "engadget", "text": "PSA: $25 Google Play credit for Nexus 7 ends this weekend - http://t.co/3iyUo8iK", "retweets": 32.0 },
{ "user": "engadget", "text": "US Appeals court rules Motorola can't enforce injunction against Microsoft in Germany... again - http://t.co/K2efo4cU", "retweets": 9.0 },
{ "user": "engadget", "text": "This is the carbon fiber core of Ferrari's first hybrid - http://t.co/y2HP1rjX", "retweets": 43.0 },
{ "user": "engadget", "text": "For Nokia, helping the competition find its way is good business - http://t.co/1sSiTbn7", "retweets": 22.0 },
{ "user": "engadget", "text": "Google optimizes Flight Search for tablets, makes booking trips easier - http://t.co/HufiiXw2", "retweets": 29.0 },
{ "user": "engadget", "text": "Microsoft details its own Windows 8 rollout, lessons learned from 'dogfooding' - http://t.co/bg5swwsm", "retweets": 33.0 },
{ "user": "engadget", "text": "PBS draws link between digital music ethics and magic spells, somehow makes it look simple (video) - http://t.co/Fx7sPphG", "retweets": 7.0 },
{ "user": "engadget", "text": "PSA: iPhone 5 available in 22 more countries, on Cricket and US regional carriers galore - http://t.co/lE4dLNQC", "retweets": 18.0 },
{ "user": "engadget", "text": "It's now a surprise to hear of a company listening to its users, issuing an apology and vowing to make it better. (http://t.co/R5bu5Wp1)", "retweets": 49.0 },
{ "user": "engadget", "text": "Wikipad CEO James Bower defends his gaming tablet's $500 pricing, why one device beats two - http://t.co/eUiFdD8g", "retweets": 11.0 },
{ "user": "engadget", "text": "Parallella project: designed to bring mouth-watering power to a board similar in size to the Raspberry Pi for $99. http://t.co/lOz8cmX8", "retweets": 12.0 },
{ "user": "engadget", "text": "Kodak dropping out of the consumer inkjet printer business in 2013 - http://t.co/bpE6f6Za", "retweets": 20.0 },
{ "user": "engadget", "text": ".@EngadgetDistro's Issue 59 is ready for your eyes and fingers. We've got bicycles, new Sony products and much more. (http://t.co/Xk2F1et0)", "retweets": 2.0 },
{ "user": "engadget", "text": "Court of Appeals for the Federal Circuit tells Judge Koh to revisit Galaxy Tab 10.1 injunction - http://t.co/iIOCcwDW", "retweets": 13.0 },
{ "user": "engadget", "text": "Indian government tells carriers to end 3G roaming pacts, doesn't stop to explain why - http://t.co/Wwkk4qXY", "retweets": 12.0 },
{ "user": "engadget", "text": "HP takes Open webOS 1.0 live, shows it supersized on a TouchSmart (video) - http://t.co/VWd1tmd7", "retweets": 17.0 },
{ "user": "engadget", "text": "How to set up your Raspberry Pi to play Atari 2600 games - http://t.co/U7qMnHvb", "retweets": 29.0 },
{ "user": "engadget", "text": "Amazon breaks down its Kindle Paperwhite light technology (video) - http://t.co/ThAUTZNt", "retweets": 18.0 },
{ "user": "engadget", "text": "NPD: Android users chew an average 870MB of cellular data per month, youngest gobble the most - http://t.co/tUHgRYn8", "retweets": 25.0 },
{ "user": "engadget", "text": "T-Mobile leases 7,200 mobile towers to Crown Castle in a 28-year, $2.4 billion deal http://t.co/jrlV0qrE", "retweets": 7.0 },
{ "user": "engadget", "text": "Insert Coin: The Parallella project dreams of $99 supercomputers - http://t.co/nb0vKSKM", "retweets": 14.0 },
{ "user": "engadget", "text": "Don't mind the zero-emissions Mercedes fuel-cell car behind the invisible curtain (eyes-on video) - http://t.co/3EYNK9d8", "retweets": 14.0 },
{ "user": "engadget", "text": "Editorial: Apple apologies actually aren't that infrequent, and that's okay - http://t.co/oQn1MnEz", "retweets": 39.0 },
{ "user": "engadget", "text": "AT&amp;T 4G LTE adds Galaxy Note 2, Galay Tab 2 10.1, Galaxy Express and Galaxy Rugby Pro to lineup - http://t.co/uvBFFMQO", "retweets": 12.0 },
{ "user": "engadget", "text": "Engadget Podcast 311 - 09.28.2012 - http://t.co/rirxdjgi", "retweets": 1.0 },
{ "user": "engadget", "text": "GreenGT H2 eyes-on: the first fuel cell-powered racer to tackle Le Mans - http://t.co/zYBo1SnD", "retweets": 9.0 },
{ "user": "engadget", "text": "Google offers up more high-res places in Maps / Earth, intros additional 45-degree imagery - http://t.co/MV8SSHxb", "retweets": 29.0 },
{ "user": "engadget", "text": "Distro Issue 59: Boston's DBC City Bike is putting a new spin on an old design - http://t.co/1KOqTPVy", "retweets": 2.0 },
{ "user": "engadget", "text": "Tim Cook apologizes for Maps mess - http://t.co/8QaU630q", "retweets": 210.0 },
{ "user": "engadget", "text": "Smart Forstars concept EV brings drive-in theater to a wall near you (video) - http://t.co/u9Hxmlf3", "retweets": 20.0 },
{ "user": "engadget", "text": "John Rogers returns with a silicon-silk circuit that dissolves inside your body - http://t.co/5qUQnKnP", "retweets": 9.0 },
{ "user": "engadget", "text": "Neil Young's Pono music service wants to democratize high-quality audio (video) - http://t.co/gncQNRiS", "retweets": 20.0 },
{ "user": "engadget", "text": "Build-a-bear's new store concept wants you to choose, love, stuff and fluff with high-tech (video) - http://t.co/3YwQ6tPS", "retweets": 11.0 },
{ "user": "engadget", "text": "Sony Xperia Tablet S gets chunky update: better multi-tasking and IR, guest mode, new media apps - http://t.co/6H2fl92W", "retweets": 18.0 },
{ "user": "engadget", "text": "Sony makes Olympus rescue pact official with $645 million investment - http://t.co/kTZdhyLK", "retweets": 17.0 },
{ "user": "engadget", "text": "Ibis hotels to have robots paint art while they track your sleep: no, that's not creepy at all (video) - http://t.co/jzRbMwms", "retweets": 19.0 },
{ "user": "engadget", "text": "FAVI's $50 Streaming Stick adds apps, streaming services to any HDTV with Android 4.1 Jelly Bean - http://t.co/dL9geyBU", "retweets": 20.0 },
{ "user": "engadget", "text": "Google gives users an easy out, adds YouTube to Takeout data transfer tool - http://t.co/nPpUgW4Q", "retweets": 14.0 },
{ "user": "engadget", "text": "NASA's Curiosity rover finds ancient streambed on Mars, evidence of 'vigorous' water flow - http://t.co/NEFjCaVj", "retweets": 67.0 },
{ "user": "engadget", "text": "Google adds CardDAV support to contacts for easier syncing with iOS and other third-party devices - http://t.co/Sx5oXOvQ", "retweets": 34.0 },
{ "user": "engadget", "text": "Sharp takes out $4.6 billion loan while it continues restructuring - http://t.co/O9t9mROq", "retweets": 15.0 },
{ "user": "engadget", "text": "The Dark Knight Rises Blu-ray officially set for December 4th, limited edition Bat cowl revealed - http://t.co/7S0LD6Gx", "retweets": 210.0 },
{ "user": "engadget", "text": "iPhone 5 vs. Lumia 920 Image Stabilization. Check out the test - http://t.co/TAMu9eYV", "retweets": 131.0 },
{ "user": "engadget", "text": "ADATA's got an 8.9mm thick portable USB 3.0 drive, limbos under the competition by a millimeter - http://t.co/uNHhcDWN", "retweets": 10.0 },
{ "user": "engadget", "text": "ZTE Engage cleared to land at Cricket on October 2nd for $250 - http://t.co/G72tUGEc", "retweets": 7.0 },
{ "user": "engadget", "text": "NFL Network's Thursday Night Football Xtra app comes to Android - http://t.co/cPvJKgdR", "retweets": 12.0 },
{ "user": "engadget", "text": "Exagon Motors Furtive-eGT electric supercar eyes-on - http://t.co/lkh6ANAW", "retweets": 9.0 },
{ "user": "engadget", "text": "ZTE shows off the V98 Windows 8 slate, we go hands-on - http://t.co/FYrccrr8", "retweets": 13.0 },
{ "user": "engadget", "text": "Kingston Digital SDXC cards arrive with lower price, larger capacities - http://t.co/yYfPHQOX", "retweets": 13.0 },
{ "user": "engadget", "text": "http://t.co/WT4zylJj working on NFC-equipped business cards, kicks off limited beta program today - http://t.co/MtAea0jh", "retweets": 35.0 },
{ "user": "engadget", "text": "Simple.TV clarifies shipping dates, tells backers units will start arriving October 10th - http://t.co/eod6khQJ", "retweets": 3.0 },
{ "user": "engadget", "text": "Samsung Galaxy Camera swings past the FCC with AT&amp;T-capable 3G - http://t.co/4lRRnTr3", "retweets": 9.0 },
{ "user": "engadget", "text": "Mozilla Persona sign-in launches in beta, skips the social networking ball and chain (video) - http://t.co/GpVDM7Vz", "retweets": 8.0 },
{ "user": "engadget", "text": "Cellcom to offer iPhone 5 for $149 and up starting Friday - http://t.co/4zCHVb0f", "retweets": 19.0 },
{ "user": "engadget", "text": "Facebook Messenger for BlackBerry reaches App World, sates compulsive chatters - http://t.co/ZmuNQLjs", "retweets": 20.0 },
{ "user": "engadget", "text": "RIM: first BlackBerry 10 devices to focus on mid-range and up, entry-level may be ready in 2013 - http://t.co/OMQMLJvs", "retweets": 34.0 },
{ "user": "engadget", "text": "RT @EngadgetDistro: Since iOS 6's launch, how happy are you with Apple's Maps app?", "retweets": 25.0 },
{ "user": "engadget", "text": "Harman shows off its upcomming JBL docks and speakers, we go eyes-on - http://t.co/5bz8UCBo", "retweets": 7.0 },
{ "user": "engadget", "text": "From the lab: Lumia 920 image stabilization and 808 drop test at Nokia R&amp;D (video) - http://t.co/s9zFp7hU", "retweets": 13.0 },
{ "user": "engadget", "text": "Sony's Xperia T is now available on O2 and ThreeUK, Walther PPK/S not included - http://t.co/LlZsSzqQ", "retweets": 7.0 }
]"""
val amazondeals = """[
{ "user": "amazondeals", "text": "Deal of the Day: 50% Off Select BEARPAW Boots &amp; Slippers http://t.co/ZBvpSN33", "retweets": 0.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $38.69 - Honeywell Portable Wireless Door Chime and Push Button http://t.co/yYBV4ebr", "retweets": 0.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $124.99 - Ritmo Mundo Unisex White Sport Quartz Watch http://t.co/RfungjJC", "retweets": 0.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $129.99 - Giulio Romano Piemonte Black Silicone Watch http://t.co/7v1ovQCQ", "retweets": 1.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $59.99 - Stuhrling Original Men's Roulette Swiss Quartz Watch http://t.co/vreVCFvJ", "retweets": 0.0 },
{ "user": "amazondeals", "text": "Lightning Deal! Marware Microshell for Fire (not for HD) http://t.co/Mtb1Uoea", "retweets": 0.0 },
{ "user": "amazondeals", "text": "Lightning Deal! Belkin Quilted Case for Fire HD 7 http://t.co/gxpUszgw", "retweets": 0.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $17.99 - iHome Rechargeable Speaker for Kindle Fire http://t.co/JCIBkwS1", "retweets": 2.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $119.95 - Shun Premier 7-Inch Santoku Knife http://t.co/Lpsyh0gY", "retweets": 3.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $39.99 - Crock-Pot Cook Travel Serve 6-Quart Programmable Slow Cooker http://t.co/8HlHPMh3", "retweets": 2.0 },
{ "user": "amazondeals", "text": "Deal of the Day: $37.49 - Tron: Legacy/Tron Original Classic (Five-Disc Combo: Blu-ray 3D / Blu-ray / DVD / Digital Co http://t.co/RqqRAwxO", "retweets": 8.0 },
{ "user": "amazondeals", "text": "Lightning Deal! Dove Body Wash, 24 ounce (Pack of 4) http://t.co/PFmNhvsQ", "retweets": 3.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $249.99 - DwellStudio Crib Set, Owls http://t.co/f2C4ab6j", "retweets": 0.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $89.99 - Canon imageCLASS Laser Multifunction Printer http://t.co/RAiMddij", "retweets": 2.0 },
{ "user": "amazondeals", "text": "Lightning Deal! Marware Jurni for Kindle + Kindle Paperwhite http://t.co/TzliFyFm", "retweets": 2.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $19.99 - Amazon Kindle DX Leather Cover http://t.co/BRDBNBsz", "retweets": 4.0 },
{ "user": "amazondeals", "text": "Lightning Deal! Verso Duct Tape Case for Fire HD 7 http://t.co/UID1EZfo", "retweets": 1.0 },
{ "user": "amazondeals", "text": "Lightning Deal! Lightwedge Reading Light for Kindle E-readers http://t.co/8WvOPwib", "retweets": 1.0 },
{ "user": "amazondeals", "text": "Deal of the Day: $1.99 Kindle Mysteries &amp; Thrillers http://t.co/ApOcFD5g", "retweets": 7.0 },
{ "user": "amazondeals", "text": "Lightning Deal! Lewis N. Clark Sport Pack http://t.co/ax9n0p4I", "retweets": 0.0 },
{ "user": "amazondeals", "text": "Lightning Deal! Sherpani Latitude LE Wheeled Suitcase http://t.co/oor6wzfr", "retweets": 0.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $79.99 - Hunter 3.5-Gallon CareFree Plus Humidifier with PermaWick Filter http://t.co/TXnzAtGi", "retweets": 0.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $89.95 - Chicago Cutlery 12-Piece Knife Set with Block http://t.co/MFtohB5H", "retweets": 1.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $189.99 - 3M Mobile Projector http://t.co/pjwDE8s3", "retweets": 1.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $9.99 - Scotch Adhesive Dot Roller Value 4-Pack http://t.co/m7FdEzXr", "retweets": 1.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $89.99 - Swingline Stack-and-Shred Red 60-Sheet Shredder, Cross-Cut, 60 Sheets http://t.co/kIB7eczO", "retweets": 0.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $249.00 - Sony Cyber-shot 18.2 MP Digital Camera http://t.co/uy6V6XfB", "retweets": 2.0 },
{ "user": "amazondeals", "text": "Deal of the Day: $59.99 - Jamie Oliver by T-fal Nonstick Hard Anodized 10-Piece Cookware Set http://t.co/C3Kqkhwi", "retweets": 4.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $199.95 - Cutlery Saber F-11 Chef Knives with Knife Bag http://t.co/EjdYR668", "retweets": 1.0 },
{ "user": "amazondeals", "text": "Lightning Deal! Tommy Hilfiger Pebble Leather Easy Tote http://t.co/AAKERLrs", "retweets": 1.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $39.00 - AudioSource Indoor/Outdoor Two-Way Speakers http://t.co/4AMrXZYG", "retweets": 1.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $159.00 - AudioSource S3D60 Soundbar with Sonic Emotion 3D Sound http://t.co/2MpkXteo", "retweets": 1.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $99.99 - Jamo S-602 Bookshelf Speaker Pair http://t.co/qsK9vPee", "retweets": 1.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $41.35 - Keeper Waterproof Roof Top Cargo Bag http://t.co/gPJ6HEqs", "retweets": 0.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $81.35 - Masterbuilt Hitch-Haul Cargo Carrier http://t.co/CmBPGfnb", "retweets": 1.0 },
{ "user": "amazondeals", "text": "Deal of the Day: $59.99 - T3 Mane Tamer Ionic Ceramic Tourmaline Flat Iron http://t.co/Nd7myReH", "retweets": 3.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $160.99 - Sarah Peyton 10-Inch Twin-Size Memory Foam Mattress http://t.co/3PHWkPcG", "retweets": 2.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $24.99 - PG Tips tea http://t.co/zwwzDoaV", "retweets": 2.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $17.99 - Mr. Beams Motion-Sensing Wireless LED Ceiling Light http://t.co/H67DlkoE", "retweets": 3.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $49.72 - Maytag Pur Refrigerator Cyst Water Filter 2-Pack http://t.co/Y3QuaVmb", "retweets": 3.0 },
{ "user": "amazondeals", "text": "Lightning Deal! Jabra CLIPPER Bluetooth Stereo Headset http://t.co/XkvVrWJ0", "retweets": 5.0 },
{ "user": "amazondeals", "text": "Deal of the Day: $219.99 - Dallas: The Complete Collection (Seasons 1-14 + Movies) http://t.co/bEIlKv37", "retweets": 5.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $89.99 - Ear Force DPX21 Headset http://t.co/lmrl7A47", "retweets": 3.0 },
{ "user": "amazondeals", "text": "Lightning Deal! LEGO Batman 2: DC Super Heroes http://t.co/Khqr9vao", "retweets": 1.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $19.99 - Plantronics Gamecom P90 http://t.co/Dd1SUbTy", "retweets": 1.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $34.99 - PS3 Black DualShock 3 Wireless Controller http://t.co/fG0zuhW4", "retweets": 6.0 },
{ "user": "amazondeals", "text": "Lightning Deal! Sleeping Dogs http://t.co/4Hp1acZA", "retweets": 4.0 },
{ "user": "amazondeals", "text": "Lightning Deal! Ghost Recon Future Soldier http://t.co/EP6t5M7F", "retweets": 10.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $9.99 - Black Eyed Peas Experience http://t.co/7uIfrnlp", "retweets": 5.0 },
{ "user": "amazondeals", "text": "Deal of the Day: $39.99 - Madden NFL 13 http://t.co/YVUYk52D", "retweets": 18.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $14.99 - Death &amp; Taxes (1 Page Book) http://t.co/QFepRypH", "retweets": 1.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $17.99 - Hello Kitty Sterling Silver Red Enamel Stud Earrings http://t.co/XG8ACVni", "retweets": 2.0 },
{ "user": "amazondeals", "text": "Lightning Deal! Sterling Silver Created Gemstone and Diamond Jewelry Set http://t.co/swzagwJB", "retweets": 1.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $199.99 - Sterling Silver 1/2 cttw Black Diamond Bamboo Hoop Earrings http://t.co/ZF1r622t", "retweets": 0.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $24.99 - Sterling Silver Diamond Accent Dragonfly Pendant Necklace http://t.co/v8lzl73r", "retweets": 2.0 },
{ "user": "amazondeals", "text": "Lightning Deal! Alex Stevens Men's Hoodie http://t.co/U00M1xj4", "retweets": 5.0 },
{ "user": "amazondeals", "text": "Lightning Deal! Dickies Men's Short Sleeve Ring-Spun Work Shirt http://t.co/iTwRTTBL", "retweets": 1.0 },
{ "user": "amazondeals", "text": "Get Ready for Fall: Save on Your Choice of Comforters http://t.co/lFFGKbuA", "retweets": 3.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $39.99 - Baggallini Luggage Run Away Satchel Bag http://t.co/543etCwD", "retweets": 0.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $129.99 - Sennheiser OMX 980 In-Ear Headphones http://t.co/JgRjVQAU", "retweets": 0.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $17.99 - JLab TV Wall Mount http://t.co/ISYTXU5d", "retweets": 3.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $25.99 - Monster GreenPower Digital PowerCenter MDP 900 http://t.co/pKTK3bB7", "retweets": 3.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $12.99 - Atlantic Movie Bin http://t.co/0VMfGZUF", "retweets": 0.0 },
{ "user": "amazondeals", "text": "Deal of the Day: $94.99 - Up to 66% off Schlage Camelot Keypad Lever Door Locks http://t.co/yBGB1JgW", "retweets": 2.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $23.55 - Christian Audigier Ed Hardy Deluxe Collection 4 Set Perfume http://t.co/hh6glIGv", "retweets": 4.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $59.99 - Panasonic DECT 6.0 Corded/Cordless Phone http://t.co/P1w5SlDz", "retweets": 2.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $99.99 - Polar SD Heart Rate Monitor Watch with S1 Foot Pod http://t.co/ckSeWPP8", "retweets": 3.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $84.99 - Cuisinart Petit Gourmet Portable Tabletop Gas Grill http://t.co/lRj6ZdPb", "retweets": 1.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $41.20 - Terrazzo Patio Table &amp; Chair Set Cover http://t.co/J6qBBl9O", "retweets": 2.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $23.50 - Classic Accessories Veranda Patio Chair Cover http://t.co/zH75UlBK", "retweets": 1.0 },
{ "user": "amazondeals", "text": "Deal of the Day: Up to 54% off Select Exercise Bikes from Schwinn http://t.co/nx0MyVxf", "retweets": 3.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $39.99 - Business Plan Pro Complete v 12 http://t.co/HpasTV4k", "retweets": 3.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $54.99 - Home Designer Suite 2012 by Chief Architect http://t.co/SWEoEFPL", "retweets": 1.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $24.99 - Uniden PRO505XL 40-Channel CB Radio http://t.co/K1skXu8V", "retweets": 3.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $19.99 - Garmin Carry All Case for Garmin nuvi Models http://t.co/qa8Sr9gL", "retweets": 0.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $154.99 - Garmin Forerunner 405CX GPS Watch with Heart Rate Monitor http://t.co/wV3vwncz", "retweets": 2.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $12.99 - Pyrex Storage 10-Piece Set http://t.co/NfJms2Dz", "retweets": 3.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $99.99 - 10-Piece KitchenAid Stainless Steel Cookware Set http://t.co/Dtl5zK5N", "retweets": 1.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $21.95 - Da Vinci Catapult Kit, Wood http://t.co/LUvEnJgo", "retweets": 2.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $117.02 - Norton Waterstone Starter Kit: 220/1000 grit stone, 4000/8000 grit stone, SiC flattening sto http://t.co/gMhOyN5z", "retweets": 2.0 },
{ "user": "amazondeals", "text": "Deal of the Day: $294.99 - Panasonic 3D Blu-Ray Disc 5.1 Surround Sound Home Theater System http://t.co/vkAUPbOW", "retweets": 2.0 },
{ "user": "amazondeals", "text": "Lightning Deal! Skechers Men's Rival Running Shoe http://t.co/leAWLm5F", "retweets": 2.0 },
{ "user": "amazondeals", "text": "Lightning Deal! Bear Grylls Men's Mountain Jacket by Craghoppers http://t.co/TLQ1hg45", "retweets": 0.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $39.99 - iHome Alarm Clock Dock for Kindle Fire (Not for HD) http://t.co/oDP4ZtSl", "retweets": 1.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $34.99 - SINGER Perfect Finish 1700 Watt Steam Iron http://t.co/wiri14KB", "retweets": 0.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $39.99 - Armitron Men's Black/Rosegold Multi-Function Watch http://t.co/b1TXRG94", "retweets": 2.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $54.99 - Marc Ecko Men's The Encore OZ Classic Analog Watch http://t.co/ACe4nUE8", "retweets": 1.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $109.99 - Stuhrling Men's Raptor Mechanical Skeleton Watch http://t.co/S7YTLGYW", "retweets": 1.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $39.99 - Stuhrling Original Men's Regatta Swiss Quartz Black Watch http://t.co/R050xFJK", "retweets": 2.0 },
{ "user": "amazondeals", "text": "Deal of the Day: $64.99 - Irwin Vise-Grip GrooveLock 8-Piece Plier Set http://t.co/noygxOJi", "retweets": 2.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $31.99 - Spynet Ultravision http://t.co/ThDnpqlC", "retweets": 0.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $19.99 - Lucky Brand Gold-Tone Turquoise-Color Howlite Link Bracelet http://t.co/w9jbDbZq", "retweets": 0.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $14.99 - Sterling Silver Plated Heart Cable Bangle Bracelet http://t.co/oRPIiEae", "retweets": 0.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $79.99 - Duragold 14k Yellow Gold Diamond-Cut Hoop Earrings http://t.co/yKlvrs2O", "retweets": 1.0 },
{ "user": "amazondeals", "text": "Lightning Deal! Sterling Silver Diamond Stud Earrings http://t.co/8dzWkf2r", "retweets": 1.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $9.99 - Brother PT90 Personal Labeler http://t.co/pJuiSxZn", "retweets": 0.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $39.99 - TRENDnet 200 Mbps Powerline Ethernet AV Adapter Kit http://t.co/AhwHHIUD", "retweets": 2.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $299.99 - Neato XV-11 All-Floor Robotic Vacuum System http://t.co/jQTTi3Im", "retweets": 2.0 },
{ "user": "amazondeals", "text": "Lightning Deal! $101.15 - BISSELL Lift-Off Steam Mop http://t.co/kE5YhYZZ", "retweets": 2.0 },
{ "user": "amazondeals", "text": "Deal of the Day: Starting from $3.99 Each: Essential MP3 Albums for Your Collection http://t.co/wotNjjir", "retweets": 5.0 }
]"""
val CNET = """[
{ "user": "CNET", "text": "HP aims for business users with ElitePad 900 Windows 8 tablet http://t.co/XyOipAdL", "retweets": 10.0 },
{ "user": "CNET", "text": "RT @CNETNews: Apple rolls out fix for iPhone 5 Wi-Fi network data bug http://t.co/Gz13JfDD", "retweets": 93.0 },
{ "user": "CNET", "text": "Ever wonder how your iPhone screen got its color? (Video) http://t.co/Fq9FFbnc", "retweets": 29.0 },
{ "user": "CNET", "text": "The Kindle Paperwhite rises to the top of the e-reader pack http://t.co/QVXp6P0H", "retweets": 19.0 },
{ "user": "CNET", "text": "How to switch from iPhone to Android http://t.co/M8I9lwua", "retweets": 131.0 },
{ "user": "CNET", "text": "Let's crack open the iPhone 5! (video) http://t.co/4tiuroNg", "retweets": 30.0 },
{ "user": "CNET", "text": "RT @CNETNews: Oracle taps Nokia for location-based services, The Wall Street journal reports. http://t.co/ecxuXHD3", "retweets": 54.0 },
{ "user": "CNET", "text": "How to simplify your messy photo collection http://t.co/nFwJ8jSi", "retweets": 24.0 },
{ "user": "CNET", "text": "Everything you need to know about using iOS 6 http://t.co/10jWoN7I #ICYMI #Ios6", "retweets": 47.0 },
{ "user": "CNET", "text": "Where iPhones go to die (video) http://t.co/86fBpfvh", "retweets": 33.0 },
{ "user": "CNET", "text": "How RIM could get you to buy into BlackBerry 10 http://t.co/AUo08CkG", "retweets": 28.0 },
{ "user": "CNET", "text": "Camera contest: Apple iPhone 5 vs. Samsung Galaxy S3 vs. HTC One X http://t.co/PmbhNgrd", "retweets": 49.0 },
{ "user": "CNET", "text": "RT @CNETNews: Apple backtracks on 'most powerful' map app claim http://t.co/mB39ilOg", "retweets": 50.0 },
{ "user": "CNET", "text": "Digging for rare earths: The mines where iPhones are born http://t.co/TKHx8hYK", "retweets": 29.0 },
{ "user": "CNET", "text": "The new Twitter for iOS adds headline photos and revamps iPad interface. Check out our review: http://t.co/234thJkl", "retweets": 17.0 },
{ "user": "CNET", "text": "Yes, a search engine just for porn http://t.co/AhFCUf8I", "retweets": 60.0 },
{ "user": "CNET", "text": "How to reduce annoying microphonics from your in-ear headphones http://t.co/dmwHA4LY", "retweets": 22.0 },
{ "user": "CNET", "text": "Is this what an iPad Mini might look like? http://t.co/MmfrLItm", "retweets": 50.0 },
{ "user": "CNET", "text": "The mad world of Foxconn, your iPhone's birthplace: @iamjaygreene reports from China http://t.co/WsUssqj7 #ICYMI", "retweets": 45.0 },
{ "user": "CNET", "text": "Sony's new portable external battery is gorgeous http://t.co/upKqXII7", "retweets": 42.0 },
{ "user": "CNET", "text": "FIFA Soccer 13 is not only the best soccer game, but the best sports game on an iOS device. Check out our review: http://t.co/pZv7DKF1", "retweets": 63.0 },
{ "user": "CNET", "text": "The wireless router is arguably the most important piece of computer equipment in your home. You deserve a good one http://t.co/LQCO1VBz", "retweets": 88.0 },
{ "user": "CNET", "text": "The periodic table of iPhones (infographic) http://t.co/ShUvE27y", "retweets": 54.0 },
{ "user": "CNET", "text": "The environmental pitfalls at the end of an iPhone's life http://t.co/jLfiPCVA", "retweets": 43.0 },
{ "user": "CNET", "text": "Transit directions field test: Apple Maps vs. Google Maps http://t.co/M9kDqLGX", "retweets": 36.0 },
{ "user": "CNET", "text": "Will the Nook HD+ put out the Kindle Fire? Check out our hands on with Barnes &amp; Noble's latest tablet http://t.co/t6A2EV1D", "retweets": 10.0 },
{ "user": "CNET", "text": "How to wake up to any song in your iTunes library in iOS 6 http://t.co/hTnUiyjt", "retweets": 68.0 },
{ "user": "CNET", "text": "How to lock down and find Android and Windows phones http://t.co/mRw8P80z", "retweets": 25.0 },
{ "user": "CNET", "text": "Four most-useful new settings in iOS 6 http://t.co/LHFOCLnA", "retweets": 63.0 },
{ "user": "CNET", "text": "Looper review: Bruce Willis does the time warp, kicks ass http://t.co/ttIk26r8", "retweets": 19.0 },
{ "user": "CNET", "text": "In need of a new app? Here are our favourites from this week http://t.co/9D3kEhWf", "retweets": 17.0 },
{ "user": "CNET", "text": "How rocks power your iPhone (video) http://t.co/hufxUMok", "retweets": 11.0 },
{ "user": "CNET", "text": "View Einstein's brain under a microscope, piece by piece http://t.co/b7O8YDDN", "retweets": 31.0 },
{ "user": "CNET", "text": "If you're really, really, really paranoid about Facebook privacy issues, then maybe just leave Facebook http://t.co/fDPLjXHM", "retweets": 72.0 },
{ "user": "CNET", "text": "How to prevent phone and tablet theft http://t.co/LbhmJT7t", "retweets": 62.0 },
{ "user": "CNET", "text": "Whether you're a casual shopper or an avid buyer &amp; seller, eBay for Android is worth a download. Check out our review http://t.co/dNWIjcxx", "retweets": 10.0 },
{ "user": "CNET", "text": "Twitter's revamped Android app is wonderful, but is it enough to satisfy power users? Check out our full review: http://t.co/234thJkl", "retweets": 25.0 },
{ "user": "CNET", "text": "Google cofounder Sergey Brin: Robotic cars will be available to the general public within 5 years http://t.co/al2PyAP5", "retweets": 134.0 },
{ "user": "CNET", "text": "The original Kindle Fire goes through the battery of Torture Tests. Will it survive? http://t.co/O0gEUklc", "retweets": 10.0 },
{ "user": "CNET", "text": "iPhone 5 to iPhone 4S: I vibrate so much harder than you http://t.co/1XMZVvVE", "retweets": 57.0 },
{ "user": "CNET", "text": "Take a look at how Lenovo stress-tests laptops http://t.co/MQCMeVBz", "retweets": 32.0 },
{ "user": "CNET", "text": "FIFA Soccer 13 is not only the best soccer game, but the best sports game on an iOS device. Check out our review: http://t.co/pZv7DKF1", "retweets": 59.0 },
{ "user": "CNET", "text": "The Sonos Connect brings effortless wireless media streaming to existing hi-fi owners. Check out our review: http://t.co/xyHxFLXi", "retweets": 9.0 },
{ "user": "CNET", "text": "The cheap, smart Vizio 32-inch TV is a great buy. Check out our review: http://t.co/AjH2yFgQ", "retweets": 11.0 },
{ "user": "CNET", "text": "The Super Slim PlayStation 3 shrinks a powerful gaming machine into an even tinier package. Check out our review: http://t.co/1LUyyuEj", "retweets": 35.0 },
{ "user": "CNET", "text": "RT @benjaminphotos: @CNETNews Yes we are... http://t.co/NxGMjVWq", "retweets": 74.0 },
{ "user": "CNET", "text": "Inside Scoop: @Josh discusses the ins and outs of Apple's recent map flub (video) http://t.co/4wLrkvFG #mapology", "retweets": 2.0 },
{ "user": "CNET", "text": "Is the computer mouse dead? @DanAckerman on the ascendance of the touch pad: http://t.co/vjwps44j", "retweets": 43.0 },
{ "user": "CNET", "text": "If you watch television regularly, second-screen app Zeebox for Android &amp; iOS makes an excellent companion http://t.co/buVYA8E7", "retweets": 15.0 },
{ "user": "CNET", "text": "MacFixIt Q&amp;A: Is your iTunes not reading burned disks? http://t.co/GnPo0lLv", "retweets": 6.0 },
{ "user": "CNET", "text": "Business cards go wireless as Moo folds in NFC technology. Bump goes the contact info http://t.co/N6zGZUdF", "retweets": 27.0 },
{ "user": "CNET", "text": "The awesome size of Foxconn (infographic) http://t.co/drvvmsVb", "retweets": 19.0 },
{ "user": "CNET", "text": "The day the Earth stood still... while Tim Cook apologized to it. Get the full recap on @CNETUpdate http://t.co/rqJjKXph", "retweets": 23.0 },
{ "user": "CNET", "text": "How to download your YouTube videos in their original format (video) http://t.co/J7QOQiul", "retweets": 42.0 },
{ "user": "CNET", "text": "Are you ready for Facebook updates to invade your caller ID? http://t.co/uG8lG9J6", "retweets": 28.0 },
{ "user": "CNET", "text": "The cost of charging your iPhone 5 for one year: $0.41 http://t.co/DTOV8D3M", "retweets": 93.0 },
{ "user": "CNET", "text": "The iPhone map of China (infographic) http://t.co/ioazYk6y", "retweets": 13.0 },
{ "user": "CNET", "text": "Finally, you can play as the pigs from Angry Birds! But is 'Bad Piggies' as addictive as the original game? (review) http://t.co/7W6vflLf", "retweets": 15.0 },
{ "user": "CNET", "text": "When an iPhone is recycled (infographic) http://t.co/YixSaMOi", "retweets": 18.0 },
{ "user": "CNET", "text": "A mathematician accurately predicted when Android's app store would hit 25 billion downloads http://t.co/VFLBJ0z3", "retweets": 36.0 },
{ "user": "CNET", "text": "Tech tip: Manage your iPhone address book with CopyTrans Contacts http://t.co/C3Je5FJo", "retweets": 14.0 },
{ "user": "CNET", "text": "Man jailed for mistakenly sexting young girls, freed because he also inadvertently sexted his own family http://t.co/Mp11ELmH", "retweets": 33.0 },
{ "user": "CNET", "text": "A TSA security guard was caught red-handed stealing an iPad in a TV sting operation http://t.co/HipBLbgs", "retweets": 43.0 },
{ "user": "CNET", "text": "The periodic table of iPhones (infographic) http://t.co/ShUvE27y", "retweets": 21.0 },
{ "user": "CNET", "text": "How to opt out of Facebook's online and offline tracking http://t.co/VCJnZdM7", "retweets": 70.0 },
{ "user": "CNET", "text": "How to make your Android phone look like an iPhone 5 http://t.co/tZZYb8Ti", "retweets": 39.0 },
{ "user": "CNET", "text": "RT @CNETNews: Judge Lucy Koh now has the authority to lift the sales ban on Samsung's Galaxy Tab 10.1 tablet. Will she? http://t.co/2SwBiOAE", "retweets": 19.0 },
{ "user": "CNET", "text": "Getting started with Passbook on iOS 6 http://t.co/3ATZW25o", "retweets": 33.0 },
{ "user": "CNET", "text": "Researchers are building a real life RoboCop! No word yet on if they'll follow it up with two inferior sequels http://t.co/a3lunSCQ", "retweets": 23.0 },
{ "user": "CNET", "text": "Scenes from the 2012 Paris Motor Show http://t.co/z1MhqngC", "retweets": 15.0 },
{ "user": "CNET", "text": "Minecraft creator says he won't certify the game for Windows 8 http://t.co/xqo84j2B", "retweets": 25.0 },
{ "user": "CNET", "text": "How to change your Twitter header photo http://t.co/FCs8hpTs", "retweets": 27.0 },
{ "user": "CNET", "text": "The tweets in the Discovery tab just got a lot more relevant http://t.co/v6IWlTdQ", "retweets": 5.0 },
{ "user": "CNET", "text": "RT @CNETNews: Tim Cook's Mapology: What's missing is any explanation why Apple would issue a beta app it knew would frustrate you http ...", "retweets": 32.0 },
{ "user": "CNET", "text": "How to set up an Android tablet as a second display for your PC or Mac http://t.co/YynJll9N", "retweets": 48.0 },
{ "user": "CNET", "text": "A Texas company is joining the patent wars by suing Apple over spreadsheet technology http://t.co/sntXqimH", "retweets": 16.0 },
{ "user": "CNET", "text": "Eying the iPad's turf, Intel and the Windows 8 gang is set to make a play for business users http://t.co/7OEr4hqc", "retweets": 7.0 },
{ "user": "CNET", "text": "Friday Poll: Would you use a self-driving car? http://t.co/qRAvKCpc", "retweets": 7.0 },
{ "user": "CNET", "text": "The mad world of Foxconn, your iPhone's birthplace: @iamjaygreene reports from China http://t.co/WsUssqj7 #ICYMI", "retweets": 19.0 },
{ "user": "CNET", "text": "RT @CNETNews: As Apple says sorry, Google Maps gets a little better, depending on where you are http://t.co/6k2WPgc3", "retweets": 42.0 },
{ "user": "CNET", "text": "Sure, tablets and smartphones are risky, but HP doesn't really have any choice but to plunge into the post-PC era http://t.co/vnTBjSMo", "retweets": 6.0 },
{ "user": "CNET", "text": "RT @jetscott: The good news: New York's getting the world's tallest Ferris wheel. The bad news: it's on Staten Island. http://t.co/5VciVVue", "retweets": 19.0 },
{ "user": "CNET", "text": "11 essential tips for mastering iOS 6 http://t.co/10jWoN7I", "retweets": 37.0 },
{ "user": "CNET", "text": "RT @CNETNews: Here's what AT&amp;T's got coming up, a la Samsung: Galaxy Note 2, Rugby Pro, Express, Tab 10.1 2 http://t.co/iOwZxoRR", "retweets": 12.0 },
{ "user": "CNET", "text": "Observers of a humans vs. bots death match decided that the bots were more human than the actual humans http://t.co/BXNwyH8a", "retweets": 11.0 },
{ "user": "CNET", "text": "RT @jeskillings: Apple's iOS 6 maps apology today: gracious http://t.co/F25NOxr6 Apple's iPhone 4 antenna apology in 2010: grudging http ...", "retweets": 37.0 },
{ "user": "CNET", "text": "Getting started with the YouTube app in iOS 6 http://t.co/HhACyxfp", "retweets": 12.0 },
{ "user": "CNET", "text": "Distressed camera maker Olympus is getting a $645 million boost care of Sony http://t.co/VzKufK5z", "retweets": 8.0 },
{ "user": "CNET", "text": "Deal alert: Get a free year of SiriusXM Internet radio! http://t.co/LXUrqZ1R", "retweets": 42.0 },
{ "user": "CNET", "text": "Kindle Fire 2012: Even hotter than last year. Check out our full review of Amazon's updated media tablet http://t.co/lUxnqomZ", "retweets": 15.0 },
{ "user": "CNET", "text": "Music publisher Sony/ATV killed Apple's iPhone 5 music service, report says http://t.co/whx2JbAO", "retweets": 22.0 },
{ "user": "CNET", "text": "5 great, cheap plasma TVs http://t.co/4QYARxB8", "retweets": 10.0 },
{ "user": "CNET", "text": "How RIM could get you to buy into BlackBerry 10 http://t.co/AUo08CkG", "retweets": 15.0 },
{ "user": "CNET", "text": "RT @CNETNews: Apple fell short with iOS 6 maps, and we are extremely sorry, CEO Tim Cook says in open letter http://t.co/t1U4497r", "retweets": 139.0 },
{ "user": "CNET", "text": "iPhone 5 to iPhone 4S: I vibrate so much harder than you http://t.co/1XMZVvVE", "retweets": 43.0 },
{ "user": "CNET", "text": "Leak: Photos of RIM's BlackBerry 10 phones hit the web http://t.co/X0OvqMwL", "retweets": 46.0 },
{ "user": "CNET", "text": "RT @CNETNews: Apple's Tim Cook: We are extremely sorry about those problems with iOS 6 Maps http://t.co/rlcCUgQO", "retweets": 114.0 },
{ "user": "CNET", "text": "Samsung Galaxy Music leak shows budget music phone http://t.co/aTAjDKk2", "retweets": 14.0 },
{ "user": "CNET", "text": "Bad Piggies review: Angry Birds follow-up bolts on complexity http://t.co/lmfK0Yjd", "retweets": 16.0 },
{ "user": "CNET", "text": "HTC One X+ turns up in O2 brochure, Jelly Bean in tow http://t.co/MGvjw24E", "retweets": 26.0 }
]"""
val gadgetlab = """[
{ "user": "gadgetlab", "text": "A Clean, Well-Lighted Face: The Kindle Paperwhite http://t.co/WlUPzZbS by @strngwys", "retweets": 11.0 },
{ "user": "gadgetlab", "text": "Maps? Purple halos in photos? Screen glitches? What? iPhone 5 'problems' explained http://t.co/xVGBVhGE by @redgirlsays", "retweets": 22.0 },
{ "user": "gadgetlab", "text": "Tim Cook apologizes for Mapocalypse debacle, offers interim fixes http://t.co/ahPbLcU5 by @redgirlsays", "retweets": 18.0 },
{ "user": "gadgetlab", "text": "Pretty Cities: Google Maps Improves Aerial Images http://t.co/nEopgNpY by @alexandra_chang", "retweets": 7.0 },
{ "user": "gadgetlab", "text": "Nokia Lumia Premium Pricing Won?t Help Windows Phone Adoption: http://t.co/mbc7fu1a by @alexandra_chang", "retweets": 15.0 },
{ "user": "gadgetlab", "text": "BlueStacks and AMD Bring 500,000 Android Apps to Windows 8: http://t.co/GskuXhRo by @alexandra_chang", "retweets": 22.0 },
{ "user": "gadgetlab", "text": "BlackBerry 10 Could Be Too Little, Too Late http://t.co/ViQWBSYY By @Strngwys", "retweets": 28.0 },
{ "user": "gadgetlab", "text": "And, in case you haven't seen it yet, @GadgetLab's review of iOS 6: http://t.co/PUf9Yisb by @redgirlsays", "retweets": 10.0 },
{ "user": "gadgetlab", "text": "Our review of the iPhone 5: http://t.co/gkrfr1Bt by @redgirlsays", "retweets": 27.0 },
{ "user": "gadgetlab", "text": "Ballmer Pitches Window 8 to Developers, But Keeps Tight Reign On Surface: http://t.co/TdkBZbXR by @alexandra_chang", "retweets": 15.0 },
{ "user": "gadgetlab", "text": "Gadget Lab Show: Apple?s iPhone 5 Wins, Maps App Fails http://t.co/9gLGvagS with @redgirlsays + @strngwys", "retweets": 13.0 },
{ "user": "gadgetlab", "text": "BlackBerry 10 features all-in-one approach to the inbox http://t.co/UzTPt3Dh by @strngwys", "retweets": 14.0 },
{ "user": "gadgetlab", "text": "Update on @redgirlsays' #walletless adventures -- Living Walletless, Week One: My Kingdom for a Bagel http://t.co/3zEIPqdl", "retweets": 8.0 },
{ "user": "gadgetlab", "text": "Foxconn rioting leaves factory closed, dozens injured http://t.co/VSgFcak5 by @redgirlsays", "retweets": 29.0 },
{ "user": "gadgetlab", "text": "Who's Waiting in Line for the #iPhone5? These People Are: http://t.co/qeYJaGu2 by @redgirlsays", "retweets": 21.0 },
{ "user": "gadgetlab", "text": "Operation iPhone Drop: From Cargo Plane to Door Stoop http://t.co/TEuxL13p By @strngwys", "retweets": 11.0 },
{ "user": "gadgetlab", "text": "Know anyone around age 60 (parents, grandparents, yourself) looking to buy their first smartphone? Give @redgirlsays a ping!", "retweets": 4.0 },
{ "user": "gadgetlab", "text": "iPhone 5 Exposed: iFixit Tears Down Apple's Latest http://t.co/4HbErQRw by @redgirlsays", "retweets": 35.0 },
{ "user": "gadgetlab", "text": "Facebook?s New Plug-in Gives You Better Protection From Embarrassing Overshares: http://t.co/AbiHJWwJ by @alexandra_chang", "retweets": 10.0 },
{ "user": "gadgetlab", "text": "Apple Mapocalypse Sends iOS 6 Users Into a Tizzy, Riverbank http://t.co/amGwTFUu by @redgirlsays", "retweets": 19.0 },
{ "user": "gadgetlab", "text": "Don?t Miss the Bus, Gus: 7 Public Transit Apps (And One Workaround) for iOS 6 http://t.co/1mgyGbFC by @alexandra_chang", "retweets": 6.0 },
{ "user": "gadgetlab", "text": "In case you missed it... Samsung continues Apple potshots with latest ad: http://t.co/IiNzQW7p by @redgirlsays", "retweets": 24.0 },
{ "user": "gadgetlab", "text": "Multiple Wi-Fi Issues Plague iOS 6 Upgrade http://t.co/fI3LGTeY by @strngwys", "retweets": 42.0 },
{ "user": "gadgetlab", "text": "Any Blackberry users (in the SF area) that are planning to switch to another smartphone platform? @alexandra_chang wants to talk.", "retweets": 11.0 },
{ "user": "gadgetlab", "text": "Downloaded iOS 6 yet? Here are 13 tips, tricks and hidden features: http://t.co/IXWOHkXB by @strngwys and @redgirlsays", "retweets": 95.0 },
{ "user": "gadgetlab", "text": "The details and specs on HTC's Windows Phone 8X and 8S: http://t.co/k8b0kQCZ by @alexandra_chang", "retweets": 14.0 },
{ "user": "gadgetlab", "text": "HTC's 8X and 8S are Windows Phone's Best Shot: http://t.co/2egTC11C by @alexandra_chang", "retweets": 10.0 },
{ "user": "gadgetlab", "text": "Motorola?s Razr i: A Razr M With Intel Inside http://t.co/eLtTIxan by @nateog", "retweets": 19.0 },
{ "user": "gadgetlab", "text": "Hi-Call Phone Gloves Bring Inspector Gadget Functionality to Life http://t.co/IbsRzeew by @nateog", "retweets": 33.0 },
{ "user": "gadgetlab", "text": "Amazon Kindle Fire HD Teardown http://t.co/IR9rx6h3 by @nateog", "retweets": 35.0 },
{ "user": "gadgetlab", "text": "Apple?s Jony Ive Designing One-Off Leica Camera http://t.co/s3PeVcUM by @karissabe", "retweets": 11.0 },
{ "user": "gadgetlab", "text": "iFixit EarPod Teardown: Better Buds, But Don't Try Repairing Them http://t.co/IDtX4MBz by @redgirlsays", "retweets": 12.0 },
{ "user": "gadgetlab", "text": "Galaxy Tab 10.1 Injunction Still Stands in Apple v. Samsung http://t.co/JwOCDnw1 by @redgirlsays", "retweets": 11.0 },
{ "user": "gadgetlab", "text": "Hands-on with the redesigned Twitter for iPad http://t.co/JKLIVV4g by @redgirlsays", "retweets": 15.0 },
{ "user": "gadgetlab", "text": "First iPhone 5 Benchmarks: Screaming Fast, Yes, But Just Shy of Galaxy S III http://t.co/QIAhda3L by @redgirlsays", "retweets": 79.0 },
{ "user": "gadgetlab", "text": "Fitbit adds two new Bluetooth-compatible fitness trackers: The Fitbit Zip and Fitbit One http://t.co/38m1fUSR by @redgirlsays", "retweets": 4.0 },
{ "user": "gadgetlab", "text": "This week on the Gadget Lab Show, iPhone 5 chat and hands on with Apple's EarPods: http://t.co/0DPubUFz", "retweets": 13.0 },
{ "user": "gadgetlab", "text": "Microsoft News: Windows 8 Event and Hints on Surface Pricing: http://t.co/kswqw4gj by @alexandra_chang", "retweets": 15.0 },
{ "user": "gadgetlab", "text": "Yowza: iPhone 5 tops two million in pre-orders in first 24 hours on sale. http://t.co/Nx2d9CBN by @redgirlsays", "retweets": 47.0 },
{ "user": "gadgetlab", "text": "From earlier today: iPhone 5 pre-orders come flooding in despite numerous website hiccups http://t.co/tbyirA59 by @redgirlsays", "retweets": 18.0 },
{ "user": "gadgetlab", "text": "The iPhone 5 Lightning adapter could be bad news for high-end docks. @strngwys reports: http://t.co/90eAf68y", "retweets": 16.0 },
{ "user": "gadgetlab", "text": "Apple iPhone 5 Specs vs. the Competition?s: Which Will You Buy?: http://t.co/r6xALNpe by @alexandra_chang", "retweets": 33.0 },
{ "user": "gadgetlab", "text": "Think the new iPhone is great, but kinda boring? Here are 5 things that would make us fall in love all over again: http://t.co/sKm9P78B", "retweets": 32.0 },
{ "user": "gadgetlab", "text": "So long, Ping: Apple's shuttering its failed social network Sept. 30 http://t.co/wO75kCfd by @redgirlsays", "retweets": 21.0 },
{ "user": "gadgetlab", "text": "Why Apple Made Three iPhone 5 Models and What That Means For You: http://t.co/ll39koPx by @alexandra_chang", "retweets": 25.0 },
{ "user": "gadgetlab", "text": "Pricing and Availability: Why It's a Tough Spec for Everyone But Apple http://t.co/bYd27fYD by @redgirlsays", "retweets": 6.0 },
{ "user": "gadgetlab", "text": "Apple Confirms iPhone 5 Pre-Orders Start at 12:01AM September 14 http://t.co/Cwenf7Zu By @strngwys", "retweets": 45.0 },
{ "user": "gadgetlab", "text": "Hands on with the faster, lighter, longer iPhone 5: http://t.co/D5z6yu45 by @redgirlsays", "retweets": 31.0 },
{ "user": "gadgetlab", "text": "RT @strngwys: Why the iPod classic will never go away. http://t.co/zhCQRfu3", "retweets": 8.0 },
{ "user": "gadgetlab", "text": "What You Need to Know About Apple?s New iPhone 5 http://t.co/ArTQrO6b by @alexandra_chang", "retweets": 41.0 },
{ "user": "gadgetlab", "text": "RT @redgirlsays: So, what do you think was the most exciting part of today's event? iPhone 5? iPod touch? nano? iTunes? Foo Fighters?", "retweets": 9.0 },
{ "user": "gadgetlab", "text": "Apple's #iPhone5 event is now over. New iPods, new iTunes, new EarPods. All sorts of newness. See our LIVEBLOG here... http://t.co/5AtpHCfY", "retweets": 32.0 },
{ "user": "gadgetlab", "text": "http://t.co/z7Dsi93S has been updated with all the new product details... http://t.co/8sH8jdas #iPhone5", "retweets": 42.0 },
{ "user": "gadgetlab", "text": "RT @wired: Apple in-ear headphones now EarPods - Look like little aliens speaking in your ears. On sale today. http://t.co/PewWjvwX", "retweets": 88.0 },
{ "user": "gadgetlab", "text": "RT @redgirlsays: Yes, that's the foo fighters. http://t.co/qgUpreGb", "retweets": 29.0 },
{ "user": "gadgetlab", "text": "RT @redgirlsays: Wait, we're getting a Foo Fighters concert? I guess that's almost as good as Hot Chip that I missed last night?", "retweets": 6.0 },
{ "user": "gadgetlab", "text": "Say goodbye to the iconic Apple Earbuds. A new headphone set is introduced...the Earpods http://t.co/op5vlGq4 #Apple #iPhone5 LIVEBLOG", "retweets": 31.0 },
{ "user": "gadgetlab", "text": "New iPod Touch will be $299 for 32 GB &amp; $399 for 64 GB, shipping sometime October http://t.co/DwtKQkSu #Apple #iPhone5 LIVEBLOG", "retweets": 52.0 },
{ "user": "gadgetlab", "text": "New iPod Touch is available in 5 colors: white, black, cyan, yellow &amp; red http://t.co/DwtKQkSu #Apple #iPhone5 LIVEBLOG", "retweets": 21.0 },
{ "user": "gadgetlab", "text": "Siri will be on the new iPod Touch. Cool! http://t.co/DwtKQkSu #Apple #iPhone5 LIVEBLOG", "retweets": 16.0 },
{ "user": "gadgetlab", "text": "New iPod Touch has same 4-inch Retina display as #iPhone5 + A5 CPU making it the 1st dual-core Touch http://t.co/DwtKQkSu #Apple LIVEBLOG", "retweets": 25.0 },
{ "user": "gadgetlab", "text": "New iPod Touch announced. It's just 6.1-mm thin. http://t.co/DwtKQkSu #Apple #iPhone5 LIVEBLOG", "retweets": 15.0 },
{ "user": "gadgetlab", "text": "New iPod Nano has 2.5-in multitouch display. Available in white, black, pink, green, blue, yellow &amp; red http://t.co/DwtKQkSu #Apple #iPhone5", "retweets": 26.0 },
{ "user": "gadgetlab", "text": "7th-gen iPod nano is rectangular, 5 mm thin, about 40% than iPod nano it replaces http://t.co/DwtKQkSu #Apple #iPhone5 LIVEBLOG", "retweets": 12.0 },
{ "user": "gadgetlab", "text": "New iTunes for desktops will launch late October http://t.co/DwtKQkSu #Apple #iPhone5 LIVEBLOG", "retweets": 10.0 },
{ "user": "gadgetlab", "text": "#iOS6 will feature new iTunes stores and a new desktop iTunes (w iCloud built in) will launch too http://t.co/DwtKQkSu #Apple #iPhone5", "retweets": 12.0 },
{ "user": "gadgetlab", "text": "#iOS6 hits the iPhone 4S, 4, 3GS, 3rd-gen iPad, iPad 2 &amp; 4th-gen iPod Touch on Sept. 19 http://t.co/DwtKQkSu #Apple #iPhone5 LIVEBLOG", "retweets": 42.0 },
{ "user": "gadgetlab", "text": "iPhone 4 (8 GB) is now free &amp; 4S (16GB) is now $99 on 2-year carrier contracts http://t.co/DwtKQkSu #Apple #iPhone5 LIVEBLOG", "retweets": 32.0 },
{ "user": "gadgetlab", "text": "#iPhone5 pre-orders start Sept. 14. Hits stores Sept. 21. http://t.co/DwtKQkSu #Apple LIVEBLOG", "retweets": 79.0 },
{ "user": "gadgetlab", "text": "#iPhone5 costs the same as the iPhone 4S: $199 for 16 Gb, $200 for 32 GB, $399 for 64 GB http://t.co/DwtKQkSu #Apple LIVEBLOG", "retweets": 66.0 },
{ "user": "gadgetlab", "text": "?iPhone 5 is the best phone we?ve ever made,? @PSchiller says http://t.co/DwtKQkSu #Apple LIVEBLOG", "retweets": 27.0 },
{ "user": "gadgetlab", "text": "#Apple says #iPhone5 has a 4-inch screen you can still comfortably use with one hand http://t.co/DwtKQkSu LIVEBLOG", "retweets": 23.0 },
{ "user": "gadgetlab", "text": "#Apple #iPhone5 comes in either Slate (aka black) or White http://t.co/DwtKQkSu LIVEBLOG", "retweets": 17.0 },
{ "user": "gadgetlab", "text": "#Apple: Shared Photo Streams in #iOS6 is easiest way to share photos with your friends? http://t.co/DwtKQkSu #iPhone5 LIVEBLOG #iPhone5", "retweets": 11.0 },
{ "user": "gadgetlab", "text": "#Apple now talking iOS 6 updates for the #iPhone5 http://t.co/DwtKQkSu LIVEBLOG", "retweets": 25.0 },
{ "user": "gadgetlab", "text": "#iPhone5 Lightning connector is 80% smaller than old 30-pin connectors http://t.co/DwtKQkSu LIVEBLOG #Apple", "retweets": 15.0 },
{ "user": "gadgetlab", "text": "#iPhone5 has smaller, new connecter called Lightning in a nod to Thunderbolt ports on Macs http://t.co/DwtKQkSu LIVEBLOG #Apple", "retweets": 32.0 },
{ "user": "gadgetlab", "text": "#iPhone5 front camera shoots 720p, has Face detection &amp; #Apple announces FaceTime over cellular networks http://t.co/DwtKQkSu LIVEBLOG", "retweets": 94.0 },
{ "user": "gadgetlab", "text": "#Apple #iPhone5 has 40% faster photo capture thanks iPhone 4S http://t.co/DwtKQkSu LIVEBLOG", "retweets": 17.0 },
{ "user": "gadgetlab", "text": "#iPhone5 has camera has new image sensor for better low light photos &amp; is 25% smaller http://t.co/DwtKQkSu LIVEBLOG #Apple", "retweets": 21.0 },
{ "user": "gadgetlab", "text": "#Apple #iPhone5 camera is 8megapixels...same as iPhone 4S. But it's not the same camera http://t.co/DwtKQkSu #LIVEBLOG", "retweets": 30.0 },
{ "user": "gadgetlab", "text": "#Apple #iPhone5 battery: 8hrs of 3G talk time, 8hrs of LTE or 3G browsing, 10hrs of WiFi browsing, 225hrs of standby http://t.co/DwtKQkSu", "retweets": 121.0 },
{ "user": "gadgetlab", "text": "We've updated every aspect of iPhone 5,? @PSchiller says. #Apple #iPhone5 LIVEBLOG http://t.co/DwtKQkSu", "retweets": 16.0 },
{ "user": "gadgetlab", "text": "#iPhone5 display has 44% more color saturation. #Apple says its most accurate in industry http://t.co/DwtKQkSu LIVEBLOG by @redgirlsays", "retweets": 21.0 },
{ "user": "gadgetlab", "text": "#iPhone5 new A6 chip has 2x faster graphics and processing power http://t.co/DwtKQkSu LIVEBLOG by @redgirlsays", "retweets": 31.0 },
{ "user": "gadgetlab", "text": "Yes, the #iPhone5 does have LTE. #Apple liveblog http://t.co/DwtKQkSu", "retweets": 19.0 },
{ "user": "gadgetlab", "text": "#Apple #iPhone5 photos up on our liveblog ---&gt; http://t.co/DwtKQkSu", "retweets": 35.0 },
{ "user": "gadgetlab", "text": "#iPhone5 has has a 326 PPI Retina display. The new screen is 4 inches, 1136x640 pixels w/ 16x9 aspect ratio http://t.co/DwtKQkSu #Apple", "retweets": 76.0 },
{ "user": "gadgetlab", "text": "#iPhone5 is the thinnest &amp; lightest phone Apple ever http://t.co/DwtKQkSu #Apple LIVEBLOG by @redgirlsays", "retweets": 46.0 },
{ "user": "gadgetlab", "text": "Last month, Apple sold its 400 millionth iOS device. #iPhone5 LIVEBLOG http://t.co/DwtKQkSu by @redgirlsays", "retweets": 15.0 },
{ "user": "gadgetlab", "text": "#Apple: More than 700,000 apps in App Store &amp; 250,000 specifically for iPad http://t.co/DwtKQkSu #iPhone5 LIVEBLOG by @redgirlsays", "retweets": 6.0 },
{ "user": "gadgetlab", "text": "#Apple CEO Tim Cook: 7million copies of Mountain Lion downloaded so far. Fastest selling version of OS X ever http://t.co/DwtKQkSu LIVEBLOG", "retweets": 10.0 },
{ "user": "gadgetlab", "text": "Apple has 380 stores in 12 countries. On Friday it will open a store in its 13th, Sweden. http://t.co/5AtpHCfY #Apple #iPhone5 LIVEBLOG", "retweets": 11.0 },
{ "user": "gadgetlab", "text": "#Apple CEO Tim Cook takes the stage at #iPhone5 event, has really cool stuff to show you.? http://t.co/DwtKQkSu liveblog by @redgirlsays", "retweets": 25.0 },
{ "user": "gadgetlab", "text": "RT @wired: FYI, @wired's liveblog photos are Creative Commons - repost, if you like, with link and license http://t.co/PewWjvwX", "retweets": 26.0 },
{ "user": "gadgetlab", "text": "Soon, photos from the inside of Apple's iPhone 5 event. @redgirlsays + @johnwbradley are on the scene... http://t.co/2mqmIhVB", "retweets": 14.0 },
{ "user": "gadgetlab", "text": "Apple iPhone 5 event LIVEBLOG: the event starts in 30 mins but we've got some photos of reporters standing in line! http://t.co/2mqmIhVB", "retweets": 26.0 },
{ "user": "gadgetlab", "text": "http://t.co/z7Dsi93S Search Confirms iPhone 5 with LTE Support, Plus New iPods http://t.co/a7mZnloy by @alexandra_chang", "retweets": 30.0 },
{ "user": "gadgetlab", "text": "@redgirlsays on the scene at Apple's iPhone 5 unveiling &amp; she has photos...of the outside of the event. Inside soon! http://t.co/5AtpHCfY", "retweets": 0.0 },
{ "user": "gadgetlab", "text": "Demoing at an Apple Event: Secretive, Stressful, and (Probably) Worth It http://t.co/7NOIDSJw by @strngwys", "retweets": 11.0 }
]"""
val mashable = """[
{ "user": "mashable", "text": "Which is sorriest, #Apple Maps or #Siri? @Charlie_White has the comic - http://t.co/YRXXJXGY", "retweets": 55.0 },
{ "user": "mashable", "text": "Watch These Quadrotor #Robots Learn to Play Catch [VIDEO] http://t.co/CHZ5BPfL", "retweets": 21.0 },
{ "user": "mashable", "text": "10 Funny @YouTube Clips of Sleeping Dogs http://t.co/ukPgWZjH", "retweets": 34.0 },
{ "user": "mashable", "text": "65 Digital Media Resources You May Have Missed http://t.co/u1LJWc22", "retweets": 64.0 },
{ "user": "mashable", "text": ".@HP Shows What @Windows 8 #Tablets for Business Will Look Like [PICS] http://t.co/Md6ua8Xc", "retweets": 32.0 },
{ "user": "mashable", "text": "Twice as Many #Mobile News Readers Prefer Browsers to #Apps [STUDY] http://t.co/lEXhVLLJ", "retweets": 40.0 },
{ "user": "mashable", "text": "7 Free #Android Apps for Killing Time in Lines http://t.co/eKu5hhsh", "retweets": 42.0 },
{ "user": "mashable", "text": "Here's what you can expect at the Mashable #MediaSummit - http://t.co/S5Hxw3Iz Get your tickets today!", "retweets": 27.0 },
{ "user": "mashable", "text": "'Dexter' Season 7 Premiere Available in Full on @YouTube [VIDEO] http://t.co/Cc5HeiZZ", "retweets": 345.0 },
{ "user": "mashable", "text": ".@Amazon #Kindle Paperwhite is the Best E-Ink Screen You Can Buy [REVIEW] http://t.co/JDenefqi", "retweets": 55.0 },
{ "user": "mashable", "text": "Watch These Epic #iPhone 5 Vs. #Android Music Videos http://t.co/Sf0De6de", "retweets": 49.0 },
{ "user": "mashable", "text": "One Proposal to Cool a Warming Planet: An Umbrella Made of Asteroids http://t.co/ote1Dw3Z via @theatlantic", "retweets": 33.0 },
{ "user": "mashable", "text": "Viral Video Recap: Bad Actors, #Apple Trolling and Slow-Motion Fireballs http://t.co/62XWSdWx", "retweets": 28.0 },
{ "user": "mashable", "text": "#DidYouKnow 81% of mobile phone subscribers use text messaging? http://t.co/ABJMZpNZ", "retweets": 55.0 },
{ "user": "mashable", "text": "Smartphone Camera Shootout: iPhone 5 vs. Galaxy SIII vs. iPhone 4S http://t.co/Qp0PM0fh", "retweets": 85.0 },
{ "user": "mashable", "text": "Simon Cowell and http://t.co/sLfE3y62 Planning Show to Find the Next Steve Jobs http://t.co/zvIk0dwc", "retweets": 145.0 },
{ "user": "mashable", "text": "Xi3 Packs a Fully Functional Desktop PC Into a Tiny Cube [VIDEO] http://t.co/OcOqZkU6", "retweets": 21.0 },
{ "user": "mashable", "text": "How ?Mad Men? Could Turn You Into The Worst Employee Ever [INFOGRAPHIC] http://t.co/NngQ3qDT via @TheJaneDough", "retweets": 95.0 },
{ "user": "mashable", "text": "Tumblr Will Be Down Next Weekend. Here's Why: http://t.co/xN8yFINP", "retweets": 129.0 },
{ "user": "mashable", "text": "Top 10 Tech This Week http://t.co/N4emMtmD", "retweets": 50.0 },
{ "user": "mashable", "text": "Which is Sorriest, Apple Maps or Siri? [SUNDAY COMICS] http://t.co/eka8gts0", "retweets": 89.0 },
{ "user": "mashable", "text": "Book About Kickstarter Fails to Raise Enough Money on Kickstarter http://t.co/SpKYdnOx", "retweets": 59.0 },
{ "user": "mashable", "text": "Top 10 #GIFs of the Week http://t.co/YVYDncNc", "retweets": 32.0 },
{ "user": "mashable", "text": "Spookiest Smartphone Malware Yet? http://t.co/5Kk1DyPg via @TheAtlantic", "retweets": 57.0 },
{ "user": "mashable", "text": "5 Mobile Photographers Capturing the World With #Android http://t.co/786NneBt", "retweets": 78.0 },
{ "user": "mashable", "text": "Does This Video Show the iPad Mini? http://t.co/0Sbdpiu1", "retweets": 27.0 },
{ "user": "mashable", "text": "Subscribe to Mashable on Kindle for the latest tech and social news on the go - http://t.co/HWWj3Xii", "retweets": 10.0 },
{ "user": "mashable", "text": "Facebook to FTC: Let Us Advertise to Children http://t.co/mipwVjbp", "retweets": 28.0 },
{ "user": "mashable", "text": "4 Tips to Avoid Work-From-Home Email Scams http://t.co/j4qxnmrj", "retweets": 43.0 },
{ "user": "mashable", "text": "10 Amazing Google Earth and Maps Discoveries http://t.co/UyDMs135", "retweets": 144.0 },
{ "user": "mashable", "text": "Top 5 Apps Your Kids Will Love This Week http://t.co/7YeW58Af", "retweets": 39.0 },
{ "user": "mashable", "text": "#DidYouKnow T9 is short for Text on 9 keys? http://t.co/9rAFobkz", "retweets": 145.0 },
{ "user": "mashable", "text": "Is your university better at social networking than you are? See how it ranks here: http://t.co/6aM1zpFa", "retweets": 57.0 },
{ "user": "mashable", "text": "Facebook's upgraded its Messenger app for iPhone, and @ToddWasserman took it for a spin: http://t.co/MMgCEsJ2", "retweets": 47.0 },
{ "user": "mashable", "text": "Imagine how it would feel to get fired from @Facebook. One man describes his experience. @joannellepan has the story -...", "retweets": 21.0 },
{ "user": "mashable", "text": "Looking for a stand for your #iPad that doubles as a speaker? @Charlie_White found a great one: http://t.co/ImpCsgkd", "retweets": 49.0 },
{ "user": "mashable", "text": "What would Psy's 'Gangnam Style' video be like without music? Even quirkier. @neeeda has the video - http://t.co/z6xrmclV", "retweets": 80.0 },
{ "user": "mashable", "text": "Who knew there were such great games available for less than $15? @ChelseaBot, that's who: http://t.co/j5yqMbYd", "retweets": 24.0 },
{ "user": "mashable", "text": "The 'Ostrich Pillow' claims to give you the ideal power-napping experience. @neeeda has more - http://t.co/YCzvanHH", "retweets": 77.0 },
{ "user": "mashable", "text": "#DidYouKnow the Dvorak is a more efficient keyboard layout than QWERTY? http://t.co/IlHnfSsz", "retweets": 162.0 },
{ "user": "mashable", "text": "Find out which fashion brands dominate social media - @ToddWasserman brings you this handy chart: http://t.co/hArNJOkE", "retweets": 49.0 },
{ "user": "mashable", "text": "This iPad keyboard reveals what's wrong with Kickstarter. @PetePachal reviews it: http://t.co/2yjhGnY9", "retweets": 18.0 },
{ "user": "mashable", "text": "Apple's given up on calling its Maps app the most powerful ever. @ToddWasserman explains why: http://t.co/3YatPmWf", "retweets": 98.0 },
{ "user": "mashable", "text": "Week's worth of TV boiled down to the best 12 GIFs, thanks to the keen eye of @ChristErickson http://t.co/BAUiteqd", "retweets": 22.0 },
{ "user": "mashable", "text": "Power Nap With This Head-Consuming Ostrich Pillow http://t.co/d34dzlPT", "retweets": 107.0 },
{ "user": "mashable", "text": "#Bots Drive 16% of U.S. Web Traffic [INFOGRAPHIC] http://t.co/lfFAjUy6", "retweets": 84.0 },
{ "user": "mashable", "text": "#Apple Cites Improved Working Conditions in Foreign Factories [REPORT] http://t.co/PKmkIYYK", "retweets": 22.0 },
{ "user": "mashable", "text": "Bizarre @YouTube Video Removes Music From 'Gangnam Style' http://t.co/AzSLo2cq", "retweets": 47.0 },
{ "user": "mashable", "text": "These #Robots Can Help Disabled Officers, Veterans Get Back to Work [VIDEO] http://t.co/wg29VIx7", "retweets": 28.0 },
{ "user": "mashable", "text": "Like viral videos and gadget demos? Subscribe to the Mashable YouTube channel - http://t.co/Sp0NWvgo", "retweets": 23.0 },
{ "user": "mashable", "text": "Biodegradable Medical Implants Dissolve in Water [VIDEO] http://t.co/XVseXUaa", "retweets": 36.0 },
{ "user": "mashable", "text": "5 Easy Steps To Make Your Job Descriptions Go Viral http://t.co/a5ArxrL5", "retweets": 56.0 },
{ "user": "mashable", "text": "Why Social Media Makes Customer Service Better http://t.co/JkdkzqnV", "retweets": 167.0 },
{ "user": "mashable", "text": "10 Essential Resources for Bootstrapping #Businesses http://t.co/1e3hqvZA", "retweets": 39.0 },
{ "user": "mashable", "text": "The Digerati: 7 Profiles of Successful #Entrepreneurs http://t.co/M5l5CmNF", "retweets": 25.0 },
{ "user": "mashable", "text": "10 Amazing @Google Earth and Maps Discoveries http://t.co/gDrlBXJ8", "retweets": 115.0 },
{ "user": "mashable", "text": "Former Employee Explains Why He Was Fired From @Facebook http://t.co/3n1wb5fJ", "retweets": 56.0 },
{ "user": "mashable", "text": "6 #Apps You Don't Want to Miss http://t.co/cQxIq9VU", "retweets": 78.0 },
{ "user": "mashable", "text": "#DidYouKnow the QWERTY keyboard layout was invented in 1868 -- and it's proven to be inefficient? http://t.co/5q3kKrQy", "retweets": 152.0 },
{ "user": "mashable", "text": "Which Are the Most Social Colleges? [INFOGRAPHIC] http://t.co/8eztys5v", "retweets": 60.0 },
{ "user": "mashable", "text": "Facebook Embraces Bubbles in Messenger iPhone Upgrade http://t.co/NaFHao22", "retweets": 61.0 },
{ "user": "mashable", "text": "Zooka Speaker Bar Makes Any Bluetooth Device Sound Better [REVIEW] http://t.co/LN6jWldu", "retweets": 23.0 },
{ "user": "mashable", "text": "Top Comments From Mashable Readers This Week http://t.co/E0ANQg3q", "retweets": 18.0 },
{ "user": "mashable", "text": "FinderCodes Uses QR Codes to Find Lost Phones http://t.co/kn3euvFy", "retweets": 28.0 },
{ "user": "mashable", "text": "5 Games You Should Play This Weekend http://t.co/t0kxXONY", "retweets": 42.0 },
{ "user": "mashable", "text": "How Much Bandwidth Will the Vice Presidential Debate Need? http://t.co/ysANGsVP", "retweets": 33.0 },
{ "user": "mashable", "text": "#DidYouKnow the JPG is a compression technique, not a file size? http://t.co/bVJjxUFJ", "retweets": 117.0 },
{ "user": "mashable", "text": "Something Is Missing, Batman [COMIC] http://t.co/TBlNdfBg", "retweets": 20.0 },
{ "user": "mashable", "text": "Burberry Tops Fashion Brands In Social Media This Week [CHART] http://t.co/8GZl4U5t", "retweets": 64.0 },
{ "user": "mashable", "text": "Video Callers Know No Bounds ? Not Even Bathrooms http://t.co/JmNNbAkZ via @BNDarticles", "retweets": 14.0 },
{ "user": "mashable", "text": "CruxSkunk iPad Keyboard Exposes the Mirage of Kickstarter [REVIEW] http://t.co/R7jjva6V", "retweets": 13.0 },
{ "user": "mashable", "text": "Apple No Longer Saying Maps Are 'Most Powerful Ever' http://t.co/MhofMrC7", "retweets": 100.0 },
{ "user": "mashable", "text": "Doing some weekend reading? Check out the new and improved Mashable iPad app for our latest news - http://t.co/G1S46WJe", "retweets": 11.0 },
{ "user": "mashable", "text": "Parking Panda App Finds and Guarantees Parking Spots http://t.co/D9kl2Hsc", "retweets": 41.0 },
{ "user": "mashable", "text": "This Week's Top TV Moments in GIF Form http://t.co/V2asPRBp", "retweets": 26.0 },
{ "user": "mashable", "text": "Small Business Advertisers Like Facebook's Immediacy, But Not Its Metrics http://t.co/KPYD1UlC", "retweets": 50.0 },
{ "user": "mashable", "text": "iOS 6 Users Complain About Wi-Fi, Connectivity Issues - http://t.co/iogRstNn", "retweets": 180.0 },
{ "user": "mashable", "text": "#DidYouKnow the 1962 'Sensorama Stimulator' was a precursor to augmented reality?http://t.co/0t4Eqjuq", "retweets": 59.0 },
{ "user": "mashable", "text": "Our iPhones Are Depleting the Earth's Resources [INFOGRAPHIC] http://t.co/XnTLqe0p", "retweets": 205.0 },
{ "user": "mashable", "text": "iPad 4 Has Carbon Fiber Body, Flexible Display [REPORT] http://t.co/Dft5VoXD via @tabtimes", "retweets": 198.0 },
{ "user": "mashable", "text": "Disagreement over Voice Guided Turn-by-Turn Convinced Apple to Develop own Map App http://t.co/tMwL9IVN", "retweets": 49.0 },
{ "user": "mashable", "text": "Derrick Rose's Brilliant Digital-Only Marketing Campaign #TheReturn http://t.co/S2lfS9Sw", "retweets": 73.0 },
{ "user": "mashable", "text": "New Rolling Stone Cover Features YouTube-Grown duo Garmin http://t.co/gxug1n8F", "retweets": 18.0 },
{ "user": "mashable", "text": "Facebook and the Gates Foundation Organize Hackathon to Develop Apps for Future College Students http://t.co/7tvGDMCe", "retweets": 80.0 },
{ "user": "mashable", "text": "#DidYouKnow Sennheiser made a $40,000 pair of headphones? http://t.co/JbOWGElL", "retweets": 71.0 },
{ "user": "mashable", "text": "Only 10% of Tweets About Apple Maps Are Positive [REPORT] http://t.co/wmGh8pGx", "retweets": 116.0 },
{ "user": "mashable", "text": "Justin Bieber's Fan Tribute Gets 200,000 Retweets http://t.co/gWtxdPHa", "retweets": 14.0 },
{ "user": "mashable", "text": "These Are the New Tech Job Hot Spots [INFOGRAPHIC] http://t.co/w1e2AHMp", "retweets": 79.0 },
{ "user": "mashable", "text": "82 tech gadgets and products that are worth the splurge - http://t.co/HaNdfLRW #TheHotList", "retweets": 98.0 },
{ "user": "mashable", "text": "Startup Marketplace Connects Fashion Brands With Boutiques http://t.co/IQ0rA7HI", "retweets": 27.0 },
{ "user": "mashable", "text": "Time Inc. CEO Promises Less Free Content http://t.co/Ftb2w4me", "retweets": 20.0 },
{ "user": "mashable", "text": "You can now read the latest from Mashable on @pulsepad - http://t.co/h3d6lULz", "retweets": 15.0 },
{ "user": "mashable", "text": "Many Windows 8 Tablets Will Sport a Keyboard http://t.co/5OpFx5VR via: @techreview", "retweets": 33.0 },
{ "user": "mashable", "text": "The Bluth Family Gets Political in New Tumblr Page http://t.co/t4OzctO0", "retweets": 16.0 },
{ "user": "mashable", "text": "China's Internet Is Getting Faster [INFOGRAPHIC] http://t.co/4dqj8Ln0", "retweets": 63.0 },
{ "user": "mashable", "text": "Camera+ Arrives on the iPad http://t.co/EG4nDhsQ", "retweets": 25.0 },
{ "user": "mashable", "text": "Cute Images Make Us 44% Sharper [STUDY] http://t.co/I4IiIbHX", "retweets": 42.0 },
{ "user": "mashable", "text": "Take 100 NASA Photos, Stir, Make Van Gogh's 'Starry Night' http://t.co/dQv6mvwI", "retweets": 73.0 },
{ "user": "mashable", "text": "Why Being Unfriended on Facebook Hurts [STUDY] http://t.co/0eHHUrTo", "retweets": 51.0 },
{ "user": "mashable", "text": "Think Apple Maps Is Bad? Remember the Tale of MobileMe http://t.co/Koeew9eU", "retweets": 41.0 }
]"""
}

View File

@ -1,73 +0,0 @@
package objsets
object TweetReader {
object ParseTweets {
def regexParser(s: String): List[Map[String, Any]] =
// In real life. you would use an actual JSON library...
val tweetRegex = """^\{ .*"user": "([^"]+)", "text": "([^"]+)", "retweets": ([\\.0-9]+) \},?$""".r
s.split("\r?\n").toList.tail.init.map {
case tweetRegex(user, text, retweets) => Map("user" -> user, "text" -> text, "retweets" -> retweets.toDouble)
}
def getTweets(user: String, json: String): List[Tweet] =
for map <- regexParser(json) yield
val text = map("text")
val retweets = map("retweet_count")
new Tweet(user, text.toString, retweets.toString.toDouble.toInt)
def getTweetData(user: String, json: String): List[Tweet] =
// is list
val l = regexParser(json)
for map <- l yield
val text = map("text")
val retweets = map("retweets")
new Tweet(user, text.toString, retweets.toString.toDouble.toInt)
}
def toTweetSet(l: List[Tweet]): TweetSet =
l.foldLeft(new Empty: TweetSet)(_.incl(_))
def unparseToData(tws: List[Tweet]): String =
val buf = new StringBuffer
for tw <- tws do
val json = "{ \"user\": \"" + tw.user + "\", \"text\": \"" +
tw.text.replaceAll(""""""", "\\\\\\\"") + "\", \"retweets\": " +
tw.retweets + ".0 }"
buf.append(json + ",\n")
buf.toString
val sites = List("gizmodo", "TechCrunch", "engadget", "amazondeals", "CNET", "gadgetlab", "mashable")
private val gizmodoTweets = TweetReader.ParseTweets.getTweetData("gizmodo", TweetData.gizmodo)
private val techCrunchTweets = TweetReader.ParseTweets.getTweetData("TechCrunch", TweetData.TechCrunch)
private val engadgetTweets = TweetReader.ParseTweets.getTweetData("engadget", TweetData.engadget)
private val amazondealsTweets = TweetReader.ParseTweets.getTweetData("amazondeals", TweetData.amazondeals)
private val cnetTweets = TweetReader.ParseTweets.getTweetData("CNET", TweetData.CNET)
private val gadgetlabTweets = TweetReader.ParseTweets.getTweetData("gadgetlab", TweetData.gadgetlab)
private val mashableTweets = TweetReader.ParseTweets.getTweetData("mashable", TweetData.mashable)
private val sources = List(gizmodoTweets, techCrunchTweets, engadgetTweets, amazondealsTweets, cnetTweets, gadgetlabTweets, mashableTweets)
val tweetMap: Map[String, List[Tweet]] =
Map() ++ Seq((sites(0) -> gizmodoTweets),
(sites(1) -> techCrunchTweets),
(sites(2) -> engadgetTweets),
(sites(3) -> amazondealsTweets),
(sites(4) -> cnetTweets),
(sites(5) -> gadgetlabTweets),
(sites(6) -> mashableTweets))
val tweetSets: List[TweetSet] = sources.map(tweets => toTweetSet(tweets))
private val siteTweetSetMap: Map[String, TweetSet] =
Map() ++ (sites zip tweetSets)
private def unionOfAllTweetSets(curSets: List[TweetSet], acc: TweetSet): TweetSet =
if curSets.isEmpty then
acc
else
unionOfAllTweetSets(curSets.tail, acc.union(curSets.head))
val allTweets: TweetSet = unionOfAllTweetSets(tweetSets, new Empty)
}

View File

@ -1,220 +0,0 @@
package objsets
import TweetReader._
/**
* A class to represent tweets.
*/
class Tweet(val user: String, val text: String, val retweets: Int) {
override def toString: String =
"User: " + user + "\n" +
"Text: " + text + " [" + retweets + "]"
}
/**
* This represents a set of objects of type `Tweet` in the form of a binary search
* tree. Every branch in the tree has two children (two `TweetSet`s). There is an
* invariant which always holds: for every branch `b`, all elements in the left
* subtree are smaller than the tweet at `b`. The elements in the right subtree are
* larger.
*
* Note that the above structure requires us to be able to compare two tweets (we
* need to be able to say which of two tweets is larger, or if they are equal). In
* this implementation, the equality / order of tweets is based on the tweet's text
* (see `def incl`). Hence, a `TweetSet` could not contain two tweets with the same
* text from different users.
*
*
* The advantage of representing sets as binary search trees is that the elements
* of the set can be found quickly. If you want to learn more you can take a look
* at the Wikipedia page [1], but this is not necessary in order to solve this
* assignment.
*
* [1] http://en.wikipedia.org/wiki/Binary_search_tree
*/
abstract class TweetSet extends TweetSetInterface {
/**
* This method takes a predicate and returns a subset of all the elements
* in the original set for which the predicate is true.
*
* Question: Can we implment this method here, or should it remain abstract
* and be implemented in the subclasses?
*/
def filter(p: Tweet => Boolean): TweetSet = filterAcc(p, new Empty)
/**
* This is a helper method for `filter` that propagetes the accumulated tweets.
*/
def filterAcc(p: Tweet => Boolean, acc: TweetSet): TweetSet
/**
* Returns a new `TweetSet` that is the union of `TweetSet`s `this` and `that`.
*
* Question: Should we implment this method here, or should it remain abstract
* and be implemented in the subclasses?
*/
def union(that: TweetSet): TweetSet = that.filterAcc(elem => true, this)
/**
* Returns the tweet from this set which has the greatest retweet count.
*
* Calling `mostRetweeted` on an empty set should throw an exception of
* type `java.util.NoSuchElementException`.
*
* Question: Should we implment this method here, or should it remain abstract
* and be implemented in the subclasses?
*/
def mostRetweeted: Tweet
/**
* Returns a list containing all tweets of this set, sorted by retweet count
* in descending order. In other words, the head of the resulting list should
* have the highest retweet count.
*
* Hint: the method `remove` on TweetSet will be very useful.
* Question: Should we implment this method here, or should it remain abstract
* and be implemented in the subclasses?
*/
def descendingByRetweet: TweetList
/**
* The following methods are already implemented
*/
/**
* Returns a new `TweetSet` which contains all elements of this set, and the
* the new element `tweet` in case it does not already exist in this set.
*
* If `this.contains(tweet)`, the current set is returned.
*/
def incl(tweet: Tweet): TweetSet
/**
* Returns a new `TweetSet` which excludes `tweet`.
*/
def remove(tweet: Tweet): TweetSet
/**
* Tests if `tweet` exists in this `TweetSet`.
*/
def contains(tweet: Tweet): Boolean
/**
* This method takes a function and applies it to every element in the set.
*/
def foreach(f: Tweet => Unit): Unit
}
class Empty extends TweetSet {
def filterAcc(p: Tweet => Boolean, acc: TweetSet): TweetSet = acc
def mostRetweeted: Tweet = throw new java.util.NoSuchElementException
def descendingByRetweet: TweetList = Nil
/**
* The following methods are already implemented
*/
def contains(tweet: Tweet): Boolean = false
def incl(tweet: Tweet): TweetSet = new NonEmpty(tweet, new Empty, new Empty)
def remove(tweet: Tweet): TweetSet = this
def foreach(f: Tweet => Unit): Unit = ()
}
class NonEmpty(elem: Tweet, left: TweetSet, right: TweetSet) extends TweetSet {
def filterAcc(p: Tweet => Boolean, acc: TweetSet): TweetSet =
if (p(elem)) then
left.filterAcc(p, right.filterAcc(p, acc.incl(elem)))
else
left.filterAcc(p, right.filterAcc(p, acc))
def mostRetweeted: Tweet = {
var mostRet: Tweet = elem
(left union right).foreach(t => if (t.retweets > mostRet.retweets) then mostRet = t)
mostRet
}
def descendingByRetweet: TweetList = {
val mostRet: Tweet = mostRetweeted
new Cons(mostRet,remove(mostRet).descendingByRetweet)
}
/**
* The following methods are already implemented
*/
def contains(x: Tweet): Boolean =
if x.text < elem.text then
left.contains(x)
else if elem.text < x.text then
right.contains(x)
else true
def incl(x: Tweet): TweetSet =
if x.text < elem.text then
new NonEmpty(elem, left.incl(x), right)
else if elem.text < x.text then
new NonEmpty(elem, left, right.incl(x))
else
this
def remove(tw: Tweet): TweetSet =
if tw.text < elem.text then
new NonEmpty(elem, left.remove(tw), right)
else if elem.text < tw.text then
new NonEmpty(elem, left, right.remove(tw))
else
left.union(right)
def foreach(f: Tweet => Unit): Unit =
f(elem)
left.foreach(f)
right.foreach(f)
}
trait TweetList {
def head: Tweet
def tail: TweetList
def isEmpty: Boolean
def foreach(f: Tweet => Unit): Unit =
if !isEmpty then
f(head)
tail.foreach(f)
}
object Nil extends TweetList {
def head = throw new java.util.NoSuchElementException("head of EmptyList")
def tail = throw new java.util.NoSuchElementException("tail of EmptyList")
def isEmpty = true
}
class Cons(val head: Tweet, val tail: TweetList) extends TweetList {
def isEmpty = false
}
object GoogleVsApple {
val google = List("android", "Android", "galaxy", "Galaxy", "nexus", "Nexus")
val apple = List("ios", "iOS", "iphone", "iPhone", "ipad", "iPad")
lazy val googleTweets: TweetSet = TweetReader.allTweets.filter(tweet => google.exists(elem => tweet.text.contains(elem)))
lazy val appleTweets: TweetSet = TweetReader.allTweets.filter(tweet => apple.exists(elem => tweet.text.contains(elem)))
/**
* A list of all tweets mentioning a keyword from either apple or google,
* sorted by the number of retweets.
*/
lazy val trending: TweetList = googleTweets.union(appleTweets).descendingByRetweet
}
object Main extends App {
// Print the trending tweets
GoogleVsApple.trending foreach println
}

View File

@ -1,15 +0,0 @@
package objsets
/**
* The interface used by the grading infrastructure. Do not change signatures
* or your submission will fail with a NoSuchMethodError.
*/
trait TweetSetInterface {
def incl(tweet: Tweet): TweetSet
def remove(tweet: Tweet): TweetSet
def contains(tweet: Tweet): Boolean
def foreach(f: Tweet => Unit): Unit
def union(that: TweetSet): TweetSet
def mostRetweeted: Tweet
def descendingByRetweet: TweetList
}

View File

@ -0,0 +1,115 @@
package codecs
import org.scalacheck
import org.scalacheck.{ Gen, Prop }
import org.scalacheck.Prop.propBoolean
import org.junit.{ Assert, Test }
import scala.reflect.ClassTag
class CodecsSuite extends GivenEncoders, GivenDecoders, PersonCodecs, ContactsCodecs, TestEncoders, TestDecoders {
def checkProperty(prop: Prop): Unit = {
val result = scalacheck.Test.check(scalacheck.Test.Parameters.default, prop)
def fail(labels: Set[String], fallback: String): Nothing =
if labels.isEmpty then throw new AssertionError(fallback)
else throw new AssertionError(labels.mkString(". "))
result.status match {
case scalacheck.Test.Passed | _: scalacheck.Test.Proved => ()
case scalacheck.Test.Failed(_, labels) => fail(labels, "A property failed.")
case scalacheck.Test.PropException(_, e, labels) => fail(labels, s"An exception was thrown during property evaluation: $e.")
case scalacheck.Test.Exhausted => fail(Set.empty, "Unable to generate data.")
}
}
/**
* Check that a value of an arbitrary type `A` can be encoded and then successfully
* decoded with the given pair of encoder and decoder.
*/
def encodeAndThenDecodeProp[A](a: A)(given encA: Encoder[A], decA: Decoder[A]): Prop = {
val maybeDecoded = decA.decode(encA.encode(a))
maybeDecoded.contains(a) :| s"Encoded value '$a' was not successfully decoded. Got '$maybeDecoded'."
}
@Test def `it is possible to encode and decode the 'Unit' value (0pts)`(): Unit = {
checkProperty(Prop.forAll((unit: Unit) => encodeAndThenDecodeProp(unit)))
}
@Test def `it is possible to encode and decode 'Int' values (1pt)`(): Unit = {
checkProperty(Prop.forAll((x: Int) => encodeAndThenDecodeProp(x)))
}
@Test def `the 'Int' decoder should reject invalid 'Int' values (2pts)`(): Unit = {
val decoded = summon[Decoder[Int]].decode(Json.Num(4.2))
assert(decoded.isEmpty, "decoding 4.2 as an integer value should fail")
}
@Test def `a 'String' value should be encoded as a JSON string (1pt)`(): Unit = {
assert(summon[Encoder[String]].encode("foo") == Json.Str("foo"))
}
@Test def `it is possible to encode and decode 'String' values (1pt)`(): Unit = {
checkProperty(Prop.forAll((s: String) => encodeAndThenDecodeProp(s)))
}
@Test def `a 'Boolean' value should be encoded as a JSON boolean (1pt)`(): Unit = {
val encoder = summon[Encoder[Boolean]]
assert(encoder.encode(true) == Json.Bool(true))
assert(encoder.encode(false) == Json.Bool(false))
}
@Test def `it is possible to encode and decode 'Boolean' values (1pt)`(): Unit = {
checkProperty(Prop.forAll((b: Boolean) => encodeAndThenDecodeProp(b)))
}
@Test def `a 'List[A]' value should be encoded as a JSON array (0pts)`(): Unit = {
val xs = 1 :: 2 :: Nil
val encoder = summon[Encoder[List[Int]]]
assert(encoder.encode(xs) == Json.Arr(List(Json.Num(1), Json.Num(2))))
}
@Test def `it is possible to encode and decode lists (5pts)`(): Unit = {
checkProperty(Prop.forAll((xs: List[Int]) => encodeAndThenDecodeProp(xs)))
}
@Test def `a 'Person' value should be encoded as a JSON object (1pt)`(): Unit = {
val person = Person("Alice", 42)
val json = Json.Obj(Map("name" -> Json.Str("Alice"), "age" -> Json.Num(42)))
val encoder = summon[Encoder[Person]]
assert(encoder.encode(person) == json)
}
@Test def `it is possible to encode and decode people (4pts)`(): Unit = {
checkProperty(Prop.forAll((s: String, x: Int) => encodeAndThenDecodeProp(Person(s, x))))
}
@Test def `a 'Contacts' value should be encoded as a JSON object (1pt)`(): Unit = {
val contacts = Contacts(List(Person("Alice", 42)))
val json = Json.Obj(Map("people" ->
Json.Arr(List(Json.Obj(Map("name" -> Json.Str("Alice"), "age" -> Json.Num(42)))))
))
val encoder = summon[Encoder[Contacts]]
assert(encoder.encode(contacts) == json)
}
@Test def `it is possible to encode and decode contacts (4pts)`(): Unit = {
val peopleGenerator = Gen.listOf(Gen.resultOf((s: String, x: Int) => Person(s, x)))
checkProperty(Prop.forAll(peopleGenerator)(people => encodeAndThenDecodeProp(Contacts(people))))
}
}
trait TestEncoders extends EncoderFallbackInstance
trait EncoderFallbackInstance {
given [A](given ct: ClassTag[A]): Encoder[A] = throw new AssertionError(s"No given instance of `Encoder[${ct.runtimeClass.getSimpleName}]`")
}
trait TestDecoders extends DecoderFallbackInstance
trait DecoderFallbackInstance {
given [A](given ct: ClassTag[A]): Decoder[A] = throw new AssertionError(s"No given instance of `Decoder[${ct.runtimeClass.getSimpleName}]")
}

View File

@ -1,64 +0,0 @@
package objsets
import org.junit._
import org.junit.Assert.assertEquals
class TweetSetSuite {
trait TestSets {
val set1 = new Empty
val set2 = set1.incl(new Tweet("a", "a body", 20))
val set3 = set2.incl(new Tweet("b", "b body", 20))
val c = new Tweet("c", "c body", 7)
val d = new Tweet("d", "d body", 9)
val set4c = set3.incl(c)
val set4d = set3.incl(d)
val set5 = set4c.incl(d)
}
def asSet(tweets: TweetSet): Set[Tweet] =
var res = Set[Tweet]()
tweets.foreach(res += _)
res
def size(set: TweetSet): Int = asSet(set).size
@Test def `filter: on empty set`: Unit =
new TestSets {
assertEquals(0, size(set1.filter(tw => tw.user == "a")))
}
@Test def `filter: a on set5`: Unit =
new TestSets {
assertEquals(1, size(set5.filter(tw => tw.user == "a")))
}
@Test def `filter: twenty on set5`: Unit =
new TestSets {
assertEquals(2, size(set5.filter(tw => tw.retweets == 20)))
}
@Test def `union: set4c and set4d`: Unit =
new TestSets {
assertEquals(4, size(set4c.union(set4d)))
}
@Test def `union: with empty set1`: Unit =
new TestSets {
assertEquals(4, size(set5.union(set1)))
}
@Test def `union: with empty set2`: Unit =
new TestSets {
assertEquals(4, size(set1.union(set5)))
}
@Test def `descending: set5`: Unit =
new TestSets {
val trends = set5.descendingByRetweet
assert(!trends.isEmpty)
assert(trends.head.user == "a" || trends.head.user == "b")
}
@Rule def individualTestTimeout = new org.junit.rules.Timeout(10 * 1000)
}