I was having problems trying to get all tweets from a specific user, and I didn't realize that the Twitter API only lets you retrieve the last 3200 tweets. So to get all of a users tweets, you have to scrape the website. Luckily, this person wrote some really great code that you can get here. https://github.com/Jefferson-Henrique/GetOldTweets-python
I also uploaded a zip of the code to my Google Drive:
When I’m at my desk during the week and have written new code, I always create a new unit test file, and it looks something like this:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Why do I create a new testcase class for every new class?
Why do all of the tests I have always contains four-steps?
History of XCTest and xUnit
XCTest is based off of OCUnit and falls under the family of xUnit testing frameworks. xUnit is the collective name for several unit testing frameworks that derive their structure and functionality from Smalltalk’s SUnit [1], notably JUnit, which was also authored by Kent Beck [2]. In March 1998, OCUnit was written by Sen:te using Kent Beck’s description of the Smalltalk testing framework [3]. Understanding the origins of XCTest and JUnit helped me discover that most of the testing habits I have today all derive from Kent Beck’s Simple Smalltalk Testing: With Patterns.
One Testcase Class
I recommend that developers write their own unit tests, one per class. The framework supports the writing of suites of tests, which can be attached to a class. I recommend that all classes respond to the message “testSuite”, returning a suite containing the unit tests.
It was Kent Beck’s philosophy that led to the practice of creating one testcase class per class. Beck believed that test logic should be encoded as a single test method on some class [4], and a testcase class gives you a place to group these similarly related test methods [5]. Making test methods instance methods of a testcase class and creating a testcase object for each test, allows us to manipulate the test methods at runtime, such as running a single test case, a group of test cases, or skipping a particular test case [6].
Source: xUnitPatterns
Four-Phase Test
Source: xUnitPatterns
The idea of having a setup method, a test method, then a tearDown method come from Beck’s work, and has been formalized into what is called the Four-Phase Test. In the Four-Phase Test, every test has four distinct phases that are executed in sequence: setup, exercise SUT (system under test), result verification, and fixture teardown [6]. The purpose of creating clear distinctions in the phases was to make the system under test extremely obvious.
The inspiration for the design was based around the fact that automated tests should serve at least two purposes:
First, they should act as documentation of how the system under test (SUT) should behave; we call this Tests as Documentation. Second, they should be a self-verifying executable specification.
— Gerard Meszaros, xUnitPatterns
The Four-Phase Test can be thought of as a state machine. In the fixture setup phase, the test establishes the prior state of the world. In the second phase we interact with the SUT, which transitions us to the next state. In the third phase we analyze the post state of the world and verify that it meets our expectations. Then in the fourth phase, we reset the state of the world prior to running the test.
Conclusion
Unit testing may sometimes become a laborious process, so it’s refreshing to take a step back and understand why we do the things that we do. The inspiration of unit testing frameworks in iOS or OS X has been around since the first version of SUnit in 1994 [7], and given that unit testing hasn’t changed much since then, it seems that the paradigms of one testcase class per class and four-phase testing are here to stay.
In Android Studio there are a lot of helpful lint warnings that help you avoid unwanted mistakes. Sometimes these warnings become superfluous and I wanted to suppress them, but I was having trouble figuring out the exact name of the warning I wanted to suppress. So I did some digging and found the full list of them in the Android ADT Source Code:
HTTP Live Streaming is a way to send audio and video over HTTP from a web server to client software on the desktop or to iOS-based devices. HTTP Live Streaming sends audio and video as a series of small files, typically of about 10 seconds duration, called media segment files. An index file, or playlist, gives the clients the URLs of the media segment files. The playlist can be periodically refreshed to accommodate live broadcasts, where media segment files are constantly being produced.
2. With the MP4 video (mine is Iron-Man-3.mp4) in the same directory:
$ mediafilesegmenter Iron-Man-3.mp4
dyn-209-2-221-215:tutorial ktran$ mediafilesegmenter Iron-Man-3.mp4
Jul 16 2013 14:25:35.304: Using floating point is not backward compatible to iOS 4.1 or earlier devices
Jul 16 2013 14:25:35.304: Processing file /Users/ktran/Desktop/tutorial/Iron-Man-3.mp4
Jul 16 2013 14:25:35.338: Finalized fileSequence0.ts
Jul 16 2013 14:25:35.343: segment bitrate 1.98 Mbits/sec is new max
Jul 16 2013 14:25:35.370: Finalized fileSequence1.ts
Jul 16 2013 14:25:35.377: segment bitrate 4.38 Mbits/sec is new max
Jul 16 2013 14:25:35.401: Finalized fileSequence2.ts
Jul 16 2013 14:25:35.401: segment bitrate 5.24 Mbits/sec is new max
Jul 16 2013 14:25:35.420: Finalized fileSequence3.ts
Jul 16 2013 14:25:35.440: Finalized fileSequence4.ts
Jul 16 2013 14:25:35.470: Finalized fileSequence5.ts
Jul 16 2013 14:25:35.471: segment bitrate 6.56 Mbits/sec is new max
Jul 16 2013 14:25:35.490: Finalized fileSequence6.ts
Jul 16 2013 14:25:35.514: Finalized fileSequence7.ts
Jul 16 2013 14:25:35.549: Finalized fileSequence8.ts
Jul 16 2013 14:25:35.550: segment bitrate 8.19 Mbits/sec is new max
Jul 16 2013 14:25:35.586: Finalized fileSequence9.ts
Jul 16 2013 14:25:35.613: Finalized fileSequence10.ts
Jul 16 2013 14:25:35.653: Finalized fileSequence11.ts
Jul 16 2013 14:25:35.703: Finalized fileSequence12.ts
Jul 16 2013 14:25:35.739: Finalized fileSequence13.ts
Jul 16 2013 14:25:35.765: Finalized fileSequence14.ts
Jul 16 2013 14:25:35.766: Finalized fileSequence15.ts
Jul 16 2013 14:25:35.766: segment does not contain sync frame
Jul 16 2013 14:25:35.767: average bit rate is 5.28 Mbits/sec - max file bit rate is 8.19 Mbits/sec
dyn-209-2-221-215:tutorial ktran$
3. Install Ruby Sinatra and Thin (if not installed)
$ gem install sinatra
$ gem install thin
dyn-209-2-214-100:tutorial ktran$ gem install sinatra
Successfully installed sinatra-1.4.3
1 gem installed
Installing ri documentation for sinatra-1.4.3...
Installing RDoc documentation for sinatra-1.4.3...
dyn-209-2-214-100:tutorial ktran$
dyn-209-2-214-100:tutorial ktran$ gem install thin
Building native extensions. This could take a while...
Successfully installed thin-1.5.1
1 gem installed
Installing ri documentation for thin-1.5.1...
Installing RDoc documentation for thin-1.5.1...
dyn-209-2-214-100:tutorial ktran$
3. Create the server.rb file and index.html file in the same directory as your video segments.
server.rb
require 'sinatra'
require 'rubygems'
get '/' do
File.read(File.join('.', 'index.html'))
end
get '/:filename' do
File.read(File.join('.', "#{params[:filename]}"))
end
The most important thing to learn is how to think recursively. This allows you to solve a large class of problems relatively simply. It's important to know for job interviews. I had interviewed at Google six months ago and because I botched an interview question that could have been solved recursively, the interviewer told the recruiter I "lacked fundamental understanding of computer science".
To solve a problem recursively:
1) Think about how to solve the problem for simple cases (base case).
2) Determine how to break down larger cases into smaller instances (recursive decomposition).
Remember that every recursive algorithm has two components: the base case and the recursive decomposition.
Problem #1 Reverse A String
Base Case: When the string is the empty string is it the same backwards as it is forwards
Recursive Decomposition: For strings, to shrink the string to make forward progress is the same as solving the problem for substrings of the string, and then combining the sub-solutions.
/* Returns the reverse of the indicated string. */
string reverseString(string line) {
if (line == "")
return "";
else
return reverseString(line.substr(1)) + line[0];
}
Problem #2 Count Spaces in A String
Base Case: When the string is empty is cannot have a space so the count of spaces is 0.
Recursive Decomposition: Check character by character by working with substrings of the string, and then sum the counts of the strings.
/* Returns the count of white spaces in a string*/
int countSpaces(string line){
if (line.length() == 0)
return 0;
else
return ((isspace(line[0]) ? 1 : 0) + countSpaces(line.substr(1)));
}
Problem #3 Find Last Occurrence of Character in String
Base Case: Well if you are at the end of the string and no characters follow, it must be the last occurrence if there is a match.
Recursive Decomposition: Start at the end of the string and after each call remove the last character.
/* Return the index of the last occurence of a character in the string */
int find_last_occurence(string line, char character){
if (line[line.length()-1] == character)
return (int)line.length();
else if(line.length() == 0)
return -1;
else
return find_last_occurence(line.substr(0,line.length()-1), character);
}