From 873d3bce39fbd1a3093a298cb8e866363fff00d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Floure?= Date: Wed, 2 Oct 2019 13:48:19 +0200 Subject: [PATCH] Import objsets handout --- .vscode/settings.json | 8 + build.sbt | 12 + grading-tests.jar | Bin 0 -> 18114 bytes project/MOOCSettings.scala | 23 + project/StudentTasks.scala | 323 ++++++++ project/build.properties | 1 + project/buildSettings.sbt | 8 + project/plugins.sbt | 2 + src/main/scala/objsets/TweetData.scala | 719 ++++++++++++++++++ src/main/scala/objsets/TweetReader.scala | 73 ++ src/main/scala/objsets/TweetSet.scala | 201 +++++ .../scala/objsets/TweetSetInterface.scala | 15 + src/test/scala/objsets/TweetSetSuite.scala | 64 ++ student.sbt | 9 + 14 files changed, 1458 insertions(+) create mode 100644 .vscode/settings.json create mode 100644 build.sbt create mode 100644 grading-tests.jar create mode 100644 project/MOOCSettings.scala create mode 100644 project/StudentTasks.scala create mode 100644 project/build.properties create mode 100644 project/buildSettings.sbt create mode 100644 project/plugins.sbt create mode 100644 src/main/scala/objsets/TweetData.scala create mode 100644 src/main/scala/objsets/TweetReader.scala create mode 100644 src/main/scala/objsets/TweetSet.scala create mode 100644 src/main/scala/objsets/TweetSetInterface.scala create mode 100644 src/test/scala/objsets/TweetSetSuite.scala create mode 100644 student.sbt diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..a35362b --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,8 @@ +{ + "dotty": { + "trace": { + "remoteTracingUrl": "wss://lamppc36.epfl.ch/dotty-remote-tracer/upload/lsp.log", + "server": { "format": "JSON", "verbosity": "verbose" } + } + } +} diff --git a/build.sbt b/build.sbt new file mode 100644 index 0000000..74f0536 --- /dev/null +++ b/build.sbt @@ -0,0 +1,12 @@ +course := "progfun1" +assignment := "objsets" +name := course.value + "-" + assignment.value +testSuite := "objsets.TweetSetSuite" + +scalaVersion := "0.19.0-bin-20190918-dd68eb8-NIGHTLY" + +scalacOptions ++= Seq("-language:implicitConversions", "-deprecation") + +libraryDependencies += "com.novocode" % "junit-interface" % "0.11" % Test + +testOptions in Test += Tests.Argument(TestFrameworks.JUnit, "-a", "-v", "-s") diff --git a/grading-tests.jar b/grading-tests.jar new file mode 100644 index 0000000000000000000000000000000000000000..7f133a2d33a5ed495b49b7925dd5dd3c50eec4d2 GIT binary patch literal 18114 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 literal 0 HcmV?d00001 diff --git a/project/MOOCSettings.scala b/project/MOOCSettings.scala new file mode 100644 index 0000000..80e34b8 --- /dev/null +++ b/project/MOOCSettings.scala @@ -0,0 +1,23 @@ +package ch.epfl.lamp + +import sbt._ +import sbt.Keys._ + +/** + * Settings shared by all assignments, reused in various tasks. + */ +object MOOCSettings extends AutoPlugin { + + object autoImport { + val course = SettingKey[String]("course") + val assignment = SettingKey[String]("assignment") + val testSuite = SettingKey[String]("testSuite") + val options = SettingKey[Map[String, Map[String, String]]]("options") + } + + override def trigger = allRequirements + + override val projectSettings: Seq[Def.Setting[_]] = Seq( + parallelExecution in Test := false + ) +} diff --git a/project/StudentTasks.scala b/project/StudentTasks.scala new file mode 100644 index 0000000..587ba85 --- /dev/null +++ b/project/StudentTasks.scala @@ -0,0 +1,323 @@ +package ch.epfl.lamp + +import sbt._ +import Keys._ + +// import scalaj.http._ +import java.io.{File, FileInputStream, IOException} +import java.nio.file.FileSystems +import org.apache.commons.codec.binary.Base64 +// import play.api.libs.json.{Json, JsObject, JsPath} +import scala.util.{Failure, Success, Try} + +import MOOCSettings.autoImport._ + +case class AssignmentInfo( + key: String, + itemId: String, + premiumItemId: Option[String], + partId: String +) + +/** + * Provides tasks for submitting the assignment + */ +object StudentTasks extends AutoPlugin { + + object autoImport { + val assignmentInfo = SettingKey[AssignmentInfo]("assignmentInfo") + + val packageSourcesOnly = TaskKey[File]("packageSourcesOnly", "Package the sources of the project") + val packageBinWithoutResources = TaskKey[File]("packageBinWithoutResources", "Like packageBin, but without the resources") + val packageSubmissionZip = TaskKey[File]("packageSubmissionZip") + val packageSubmission = inputKey[Unit]("package solution as an archive file") + val runGradingTests = taskKey[Unit]("run black-box tests used for final grading") + } + + + import autoImport._ + + override lazy val projectSettings = Seq( + packageSubmissionSetting, + // submitSetting, // FIXME: restore assignmentInfo setting on assignments + runGradingTestsSettings, + + fork := true, + connectInput in run := true, + outputStrategy := Some(StdoutOutput) + ) ++ packageSubmissionZipSettings + + lazy val runGradingTestsSettings = runGradingTests := { + val testSuiteJar = "grading-tests.jar" + if (!new File(testSuiteJar).exists) { + throw new MessageOnlyException(s"Could not find tests JarFile: $testSuiteJar") + } + + val classPath = s"${(Test / dependencyClasspath).value.map(_.data).mkString(File.pathSeparator)}${File.pathSeparator}$testSuiteJar" + val junitProcess = + Fork.java.fork( + ForkOptions(), + "-cp" :: classPath :: + "org.junit.runner.JUnitCore" :: + (Test / testSuite).value :: + Nil + ) + + // Wait for tests to complete. + junitProcess.exitValue() + } + + + /** ********************************************************** + * SUBMITTING A SOLUTION TO COURSERA + */ + + val packageSubmissionZipSettings = Seq( + packageSubmissionZip := { + val submission = crossTarget.value / "submission.zip" + val sources = (packageSourcesOnly in Compile).value + val binaries = (packageBinWithoutResources in Compile).value + IO.zip(Seq(sources -> "sources.zip", binaries -> "binaries.jar"), submission) + submission + }, + artifactClassifier in packageSourcesOnly := Some("sources"), + artifact in (Compile, packageBinWithoutResources) ~= (art => art.withName(art.name + "-without-resources")) + ) ++ + inConfig(Compile)( + Defaults.packageTaskSettings(packageSourcesOnly, Defaults.sourceMappings) ++ + Defaults.packageTaskSettings(packageBinWithoutResources, Def.task { + val relativePaths = + (unmanagedResources in Compile).value.flatMap(Path.relativeTo((unmanagedResourceDirectories in Compile).value)(_)) + (mappings in (Compile, packageBin)).value.filterNot { case (_, path) => relativePaths.contains(path) } + }) + ) + + val maxSubmitFileSize = { + val mb = 1024 * 1024 + 10 * mb + } + + /** Check that the jar exists, isn't empty, isn't crazy big, and can be read + * If so, encode jar as base64 so we can send it to Coursera + */ + def prepareJar(jar: File, s: TaskStreams): String = { + val errPrefix = "Error submitting assignment jar: " + val fileLength = jar.length() + if (!jar.exists()) { + s.log.error(errPrefix + "jar archive does not exist\n" + jar.getAbsolutePath) + failSubmit() + } else if (fileLength == 0L) { + s.log.error(errPrefix + "jar archive is empty\n" + jar.getAbsolutePath) + failSubmit() + } else if (fileLength > maxSubmitFileSize) { + s.log.error(errPrefix + "jar archive is too big. Allowed size: " + + maxSubmitFileSize + " bytes, found " + fileLength + " bytes.\n" + + jar.getAbsolutePath) + failSubmit() + } else { + val bytes = new Array[Byte](fileLength.toInt) + val sizeRead = try { + val is = new FileInputStream(jar) + val read = is.read(bytes) + is.close() + read + } catch { + case ex: IOException => + s.log.error(errPrefix + "failed to read sources jar archive\n" + ex.toString) + failSubmit() + } + if (sizeRead != bytes.length) { + s.log.error(errPrefix + "failed to read the sources jar archive, size read: " + sizeRead) + failSubmit() + } else encodeBase64(bytes) + } + } + + /** Task to package solution to a given file path */ + lazy val packageSubmissionSetting = packageSubmission := { + val args: Seq[String] = Def.spaceDelimited("[path]").parsed + val s: TaskStreams = streams.value // for logging + val jar = (packageSubmissionZip in Compile).value + + val base64Jar = prepareJar(jar, s) + + val path = args.headOption.getOrElse((baseDirectory.value / "submission.jar").absolutePath) + scala.tools.nsc.io.File(path).writeAll(base64Jar) + } + +/* + /** Task to submit a solution to coursera */ + val submit = inputKey[Unit]("submit solution to Coursera") + lazy val submitSetting = submit := { + val args: Seq[String] = Def.spaceDelimited("").parsed + val s: TaskStreams = streams.value // for logging + val jar = (packageSubmissionZip in Compile).value + + val assignmentDetails = assignmentInfo.value + val assignmentKey = assignmentDetails.key + val courseName = + course.value match { + case "capstone" => "scala-capstone" + case "bigdata" => "scala-spark-big-data" + case other => other + } + + val partId = assignmentDetails.partId + val itemId = assignmentDetails.itemId + val premiumItemId = assignmentDetails.premiumItemId + + val (email, secret) = args match { + case email :: secret :: Nil => + (email, secret) + case _ => + val inputErr = + s"""|Invalid input to `submit`. The required syntax for `submit` is: + |submit + | + |The submit token is NOT YOUR LOGIN PASSWORD. + |It can be obtained from the assignment page: + |https://www.coursera.org/learn/$courseName/programming/$itemId + |${ + premiumItemId.fold("") { id => + s"""or (for premium learners): + |https://www.coursera.org/learn/$courseName/programming/$id + """.stripMargin + } + } + """.stripMargin + s.log.error(inputErr) + failSubmit() + } + + val base64Jar = prepareJar(jar, s) + val json = + s"""|{ + | "assignmentKey":"$assignmentKey", + | "submitterEmail":"$email", + | "secret":"$secret", + | "parts":{ + | "$partId":{ + | "output":"$base64Jar" + | } + | } + |}""".stripMargin + + def postSubmission[T](data: String): Try[HttpResponse[String]] = { + val http = Http("https://www.coursera.org/api/onDemandProgrammingScriptSubmissions.v1") + val hs = List( + ("Cache-Control", "no-cache"), + ("Content-Type", "application/json") + ) + s.log.info("Connecting to Coursera...") + val response = Try(http.postData(data) + .headers(hs) + .option(HttpOptions.connTimeout(10000)) // scalaj default timeout is only 100ms, changing that to 10s + .asString) // kick off HTTP POST + response + } + + val connectMsg = + s"""|Attempting to submit "${assignment.value}" assignment in "$courseName" course + |Using: + |- email: $email + |- submit token: $secret""".stripMargin + s.log.info(connectMsg) + + def reportCourseraResponse(response: HttpResponse[String]): Unit = { + val code = response.code + val respBody = response.body + + /* Sample JSON response from Coursera + { + "message": "Invalid email or token.", + "details": { + "learnerMessage": "Invalid email or token." + } + } + */ + + // Success, Coursera responds with 2xx HTTP status code + if (response.is2xx) { + val successfulSubmitMsg = + s"""|Successfully connected to Coursera. (Status $code) + | + |Assignment submitted successfully! + | + |You can see how you scored by going to: + |https://www.coursera.org/learn/$courseName/programming/$itemId/ + |${ + premiumItemId.fold("") { id => + s"""or (for premium learners): + |https://www.coursera.org/learn/$courseName/programming/$id + """.stripMargin + } + } + |and clicking on "My Submission".""".stripMargin + s.log.info(successfulSubmitMsg) + } + + // Failure, Coursera responds with 4xx HTTP status code (client-side failure) + else if (response.is4xx) { + val result = Try(Json.parse(respBody)).toOption + val learnerMsg = result match { + case Some(resp: JsObject) => + (JsPath \ "details" \ "learnerMessage").read[String].reads(resp).get + case Some(x) => // shouldn't happen + "Could not parse Coursera's response:\n" + x + case None => + "Could not parse Coursera's response:\n" + respBody + } + val failedSubmitMsg = + s"""|Submission failed. + |There was something wrong while attempting to submit. + |Coursera says: + |$learnerMsg (Status $code)""".stripMargin + s.log.error(failedSubmitMsg) + } + + // Failure, Coursera responds with 5xx HTTP status code (server-side failure) + else if (response.is5xx) { + val failedSubmitMsg = + s"""|Submission failed. + |Coursera seems to be unavailable at the moment (Status $code) + |Check https://status.coursera.org/ and try again in a few minutes. + """.stripMargin + s.log.error(failedSubmitMsg) + } + + // Failure, Coursera repsonds with an unexpected status code + else { + val failedSubmitMsg = + s"""|Submission failed. + |Coursera replied with an unexpected code (Status $code) + """.stripMargin + s.log.error(failedSubmitMsg) + } + } + + // kick it all off, actually make request + postSubmission(json) match { + case Success(resp) => reportCourseraResponse(resp) + case Failure(e) => + val failedConnectMsg = + s"""|Connection to Coursera failed. + |There was something wrong while attempting to connect to Coursera. + |Check your internet connection. + |${e.toString}""".stripMargin + s.log.error(failedConnectMsg) + } + + } +*/ + + def failSubmit(): Nothing = { + sys.error("Submission failed") + } + + /** + * ***************** + * DEALING WITH JARS + */ + def encodeBase64(bytes: Array[Byte]): String = + new String(Base64.encodeBase64(bytes)) +} diff --git a/project/build.properties b/project/build.properties new file mode 100644 index 0000000..c0bab04 --- /dev/null +++ b/project/build.properties @@ -0,0 +1 @@ +sbt.version=1.2.8 diff --git a/project/buildSettings.sbt b/project/buildSettings.sbt new file mode 100644 index 0000000..a309025 --- /dev/null +++ b/project/buildSettings.sbt @@ -0,0 +1,8 @@ +libraryDependencies += "com.novocode" % "junit-interface" % "0.11" % Test +// Used for base64 encoding +libraryDependencies += "commons-codec" % "commons-codec" % "1.10" + +// Used for Coursera submussion +// libraryDependencies += "org.scalaj" %% "scalaj-http" % "2.3.0" +// libraryDependencies += "com.typesafe.play" %% "play-json" % "2.6.9" + diff --git a/project/plugins.sbt b/project/plugins.sbt new file mode 100644 index 0000000..64a2492 --- /dev/null +++ b/project/plugins.sbt @@ -0,0 +1,2 @@ +addSbtPlugin("io.get-coursier" % "sbt-coursier" % "2.0.0-RC3-5") +addSbtPlugin("ch.epfl.lamp" % "sbt-dotty" % "0.3.4") diff --git a/src/main/scala/objsets/TweetData.scala b/src/main/scala/objsets/TweetData.scala new file mode 100644 index 0000000..0e9ab9a --- /dev/null +++ b/src/main/scala/objsets/TweetData.scala @@ -0,0 +1,719 @@ +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&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 & 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 & 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&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&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&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&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&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&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 & 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 & 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 & 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 & 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 & 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 & 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 & iOS makes an excellent companion http://t.co/buVYA8E7", "retweets": 15.0 }, +{ "user": "CNET", "text": "MacFixIt Q&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&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 & $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 & 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 & 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 & 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 & 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 & #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 & 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 ---> 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 & 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 & 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 & 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 } +]""" +} diff --git a/src/main/scala/objsets/TweetReader.scala b/src/main/scala/objsets/TweetReader.scala new file mode 100644 index 0000000..630b9c3 --- /dev/null +++ b/src/main/scala/objsets/TweetReader.scala @@ -0,0 +1,73 @@ +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) +} diff --git a/src/main/scala/objsets/TweetSet.scala b/src/main/scala/objsets/TweetSet.scala new file mode 100644 index 0000000..ac88c95 --- /dev/null +++ b/src/main/scala/objsets/TweetSet.scala @@ -0,0 +1,201 @@ +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 = ??? + + /** + * 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 = ??? + + /** + * 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 = ??? + + /** + * 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 = ??? + + + /** + * 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 = ??? + lazy val appleTweets: TweetSet = ??? + + /** + * A list of all tweets mentioning a keyword from either apple or google, + * sorted by the number of retweets. + */ + lazy val trending: TweetList = ??? +} + +object Main extends App { + // Print the trending tweets + GoogleVsApple.trending foreach println +} diff --git a/src/main/scala/objsets/TweetSetInterface.scala b/src/main/scala/objsets/TweetSetInterface.scala new file mode 100644 index 0000000..0608d11 --- /dev/null +++ b/src/main/scala/objsets/TweetSetInterface.scala @@ -0,0 +1,15 @@ +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 +} diff --git a/src/test/scala/objsets/TweetSetSuite.scala b/src/test/scala/objsets/TweetSetSuite.scala new file mode 100644 index 0000000..21af555 --- /dev/null +++ b/src/test/scala/objsets/TweetSetSuite.scala @@ -0,0 +1,64 @@ +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) +} diff --git a/student.sbt b/student.sbt new file mode 100644 index 0000000..855fa0c --- /dev/null +++ b/student.sbt @@ -0,0 +1,9 @@ +// Used for base64 encoding +libraryDependencies += "commons-codec" % "commons-codec" % "1.10" + +// Used for Coursera submussion +// libraryDependencies += "org.scalaj" %% "scalaj-http" % "2.4.2" +// libraryDependencies += "com.typesafe.play" %% "play-json" % "2.7.4" + +// Student tasks (i.e. packageSubmission) +enablePlugins(StudentTasks)