Wikipedia

Search results

20 November 2013

Update UICollectionView as a batch

1) get all the data you need

2) create array of index paths

3) update your view

sample code:

NSArray* dataArray = // however you get the data
  if (dataArray.count == 0) {
    moreTaps = NO;
    return;
  }
                    
NSMutableArray* indexArray = @[].mutableCopy;
NSInteger dataSourceCount = arrayDisplay.count;

for (int i = 0; i < dataArray.count; i++) {
                        
                        
if ([indexHolderArray containsObject:[[dataArray objectAtIndex:i] anId]]) {
  continue;
}
                        
[arrayDisplay addObject:[dataArray objectAtIndex:i]];

NSInteger indexPathItem = i + dataSourceCount;
  [indexArray addObject:[NSIndexPath indexPathForRow:indexPathItem inSection:0]];                      
}
                    
dispatch_sync(dispatch_get_main_queue(), ^{
  [_collectionView insertItemsAtIndexPaths:indexArray];
});

27 September 2013

Writing Pascal Triangle in Scala

The Pascal Triangle has some basic ground rules, all based on it's final/original structure:


1                        The first column/row is 1
11                      Where column = row is 1
121                    The inside variables are a sum of the above row (row - 1), and neighbor to it's left (row - 1, column - 1)
1331
14641

Granted we are dealing with integers, we can formulate the above logic with a little Scala as:

def pascalLogic(r:Int, c:Int) =
  // if first column/row or column = row
  if (c == 0 || r == c) 1
  // else sum of values
  else pascalLogic(r-1, c) + pascalLogic(r-1, c+1)

To print out the pretty Pascal Triangle sans spaces, print the integer result for each message, and create line breaks at all instances where (r == c):

for (r <- 0 to c by 1) {
  for (c <- 0 to r by 1)
      print(pascalLogic(r, c) + " ")
    println()
  }    

Combining the pieces :

   def drawPascalTriangle(c:Int) { // curly brace creates closure/block/scope
      for (r <- 0 to c by 1) {
        for (c <- 0 to r by 1)
          print(pascalLogic(r, c) + " ")
        println()

     def pascalLogic(r:Int, c:Int):Int =
       if (c == 0 || r == c) 1
       else pascalLogic(r-1, c) + pascalLogic(r-1, c-1)
       }
     }

drawPascalTriangle(12)

COMMON RECURSIVE PATTERNS

- Linear (eg factorial)
- Tree (eg Fibonacci, counting change)
- Primes and GCD

// factorial
def fac(x:Int, acc:Int):Int =
  if (x == 0) 1
  else if (x == 1) acc
  else fac(x-1, acc * x)

// fibonacci
def fibo(n:Int):Int =
  if (n==0) 0
  else if (n==1) 1
  else fibo(n-1) + fibo(n-2)

// counting change
def countChange(money:Int, coins:List[Int]):Int =
  if (money == 0) 1 else if (money < 0 || coins.isEmpty) 0 else {
    countChange(money - coins.head, coins) + countChange(money, coins.tail)
    }

23 August 2013

Sails Tutorial for iOS

Sails Tutorial for iOS

How to get started developing full stack applications with Sails


We are going to make an application for the iPhone in XCode v4.6 that displays messages from the Sails server to the iPhone. To get started, install Sails:

Click here to get started with installing Sails


Now that you have Sails installed, let's create a sails project. The first thing we will do is create the Xcode project. In Xcode, create a Single View application, and give it the name SampleAppSails.

Open Terminal, and go to your Xcode project's folder. Mine was on the desktop, and my path was '/User/aug2uag/desktop/SampleAppSails'. Once you are in your Xcode project directory, create the Sails application. Note, that we could have initially created the Sails application, and included the Xcode project in that directory. Since the Sails directory includes multiple other directories, I opted to organize it as mentioned above.

To create your new Sails project, in terminal type:
sails new sailsXcodeProject

You will notice Sails installs with many features right away. Among these are automagically generated RESTful API requests that we will be using for our application. Let's open our Sails project files, and inspect these elements.

In /config you will find the filename controllers.js that includes instructions for a blueprint. The blueprint is a prototype for the actual Sails application. Here, the blueprint for the app is specified to include:

 // Automatic REST blueprints enabled?
    // e.g.
    // 'get /:controller/:id?'
    // 'post /:controller'
    // 'put /:controller/:id'
    // 'delete /:controller/:id'
    rest: true,

Here, the Sails application has by default set to yes for including methods in the controllers you will create. If you like to disable the default methods, and write your own custom methods, then you can set the parameter to false.

For the purposes of the application we are developing, the default controller methods will be selected to perform our actions. Specifically, we will want to:
    POST a message to the server, that includes our text and userId
    GET the messages from the server, and display them as a list on the iPhone
We will create a single Messages entity:
sails g Messages

This has created the Messages model, and controller. Let's open the model from the /api directory, and add the following attributes:
module.exports = {
    attributes: {
    text: 'string'
    }
 };
This says that we will be storing Messages objects on the server, and that the messages object will consist of text. Note that a timestamp will be generated automatically each time a new object is produced. We will incorporate the timestamp to our view output later. For now, let's move on, and take a look at the MessagesController.js file found in the /api directory.
module.exports = {
  sayHello: function (req, res) {
  res.send('hello world!');
    }
 };
There is a simple Hello World function to demonstrate the functional style language used in Sails that is common to Node. You can call this function via a GET request to the route with the corresponding name of the function you want to call. Each function operates in a block, and that makes it possible for the program to continue without the need for the result of the function to return. We will be sticking with the default controller methods, and those are abstracted away from us, unless we had decided to write our own custom methods.

Let's link up a Mongo database to hold our information. I already have my Mongo shell running on port 27017, please fire up your mongod, and in the /config/session.js file add the following:
module.exports.session = {
  secret: '7309c3e86f54d10dbcdf2b4e113ab393', //automatically generated by Sails for each application
  adapter: 'mongo',
  host: 'localhost',
  port: 27017,
  db: 'sails',
  collection: 'sessions'
};

We are telling Sails that for our project (secret: value is automatically generated for each application), we are going to be using (adapter: mongo), in path (host & port: local/27017), a database named 'sails' that stores collections.

Save everything, and run your Sails application, and you should see your sails application operating on localhost:1337. You can also verify your app is running by opening a new shell, and running:
curl http://localhost:1337
Let's move on, and create the iPhone client.

Your SampleApplicationSails.xcodeproj should be open on XCode. Go to your storyboard or xib file, and add:
    tableView
    textField
    button
Connect these UI elements to the @interface of the ViewController.m file. Make sure you connect your tableView data source outlet to the ViewController. Create an NSArray instance variable, and your ViewController.m @interface should look something like:

@interface ViewController () 
{
    SocketIO* socketIO;
    
    __weak IBOutlet UITextField *oTextField;
    __weak IBOutlet UITableView *oTableView;

    NSArray*        sailsArray;
}

- (IBAction)submitText:(id)sender;

@end



Create your tableViewDataSource methods, with logic to handle the empty array (i.e. since it may be initially empty):

#pragma mark-table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if (sailsArray.count == 0) {
        return 1;
    }
    double delayInSeconds = 2.0;
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
        oLabel.hidden = YES;
    });
    return sailsArray.count;
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"id"];
    
    if (cell == nil) {
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"id"];
    }
    
    if (sailsArray.count == 0) {
        cell.textLabel.text = @"array does not exist (yet)";
        return cell;
    }
    //declare string, assign to value at indexPath from array
    //array may be made from [dictionary allKeys];
    NSString* string = [[sailsArray objectAtIndex:indexPath.row] valueForKey:@"text"];
    
    //set string to textLabel of cell
    [cell.textLabel setText:string];
    [cell.detailTextLabel setText:subString];
    
    return cell;
}

To connect to our server (that should be running in the background), we need to create a socket to communicate to the server, and establish connection to the server's controller methods. Since Sails ships with Socket.io, we will establish the socket with Socket.io for Objective-C. Add the Socket.io files from Socket.IO / Objective C Library on Github.

To your ViewController.h @interface, add
#import "SocketIO.h"

Make ViewController conform to the SocketIO delegate methods by adding SocketIODelegate next to your ViewController.

In your ViewController.m file, create a SocketIO instance variable name socketIO. In the ViewController.m @implementation viewDidLoad, add the following:

socketIO = [[SocketIO alloc] initWithDelegate:self];
    [socketIO connectToHost:@"localhost" onPort:1337];

Run your Xcode project, and let's see what happens. Take a look at your shell running your Sails application, and you will notice that we received an error that no handshake occured. To address this, we will make a call to the Sails application prior to establishing the socket. In your ViewController.m, add the following before your code that instantiates your SocketIO object:

 //handshake
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://localhost:1337/"]
                                                           cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData
                                                       timeoutInterval:10];
    
    [request setHTTPMethod: @"GET"];
    
    NSError *requestError;
    NSURLResponse *urlResponse = nil;
    NSData *response1 = [NSURLConnection sendSynchronousRequest:request returningResponse:&urlResponse error:&requestError]; 

Also add the following to view the results of the GET request:

    //converts response to string (index.html)
    NSString* stringFromData = [[NSString alloc] initWithData:response1 encoding:NSUTF8StringEncoding];
    NSLog(@"data converted to string ==> string = %@", stringFromData);
Run your Xcode project again, and you should see a log that displays the contents of your /views/home/index.ejs file in your Sails directory.

We will send a POST request to the server for the message we will type in our TextField. We will limit the size of our input by using the UITextField delegate method
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string;

In your viewDidLoad set the oTextField.delegate to self, and in the ViewController.m file, add the following:

    - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    NSUInteger newLength = [textField.text length] + [string length] - range.length;
    if (newLength>30) {
     UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Your Text" message:@"is too lengthy" delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
     [alert show];
     return NO;
    }
    return YES;
}

We are limiting the textField to 30 characters, and sending an alert if the count is higher than our limit. So once we have that in place, we can create our submit POST action. To your button action method, add the following:

- (IBAction)submitText:(id)sender
{
    NSMutableURLRequest *request = [NSMutableURLRequest
         requestWithURL:[NSURL URLWithString:@"http://localhost:1337/messages"]];
    NSString* inputString = oTextField.text;
    NSString *params = [[NSString alloc] initWithFormat:@"text=%@&createdAt=%@", inputString, createdAt];
    oTextField.text = nil;
    [request setHTTPMethod:@"POST"];
    [request setHTTPBody:[params dataUsingEncoding:NSUTF8StringEncoding]];
    [[NSURLConnection alloc] initWithRequest:request delegate:self]; 
}

We will evaluate the response by logging it to our console via the NSURLConnection delegate. Declare a NSMutableData variable to your ViewController.m @interface. Add the following to implement your NSURLConnection delegate:

#pragma mark - NSURLConnectionDelegate
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    mutableData = [NSMutableData data];
}

-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    [mutableData appendData:data];
}

-(void)connectionDidFinishLoading:(NSURLConnection *)connection {
    NSLog(@"response => %@",[[NSString alloc] initWithData:mutableData encoding:NSUTF8StringEncoding]);
    
}

-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    NSLog(@"Error");
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:error.localizedDescription delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
    [alert show];
}

Run your Xcode project again, and you should see the status of your POST request to the server.

Now that we can access when the POST request did finish, we will call the server to recieve a list of the messages on the server to display on the tableView. To do this, we will send a GET request to the Messages controller of our Sails application, and assign the result to our NSArray variable we defined a while back. When we refresh our tableView, the results are now displayed.

In Summary

Sails is an amazingly efficient, and user-friendly technology to turn your iOS applications in to something so much more. The automagic REST integration allows for simple CRUD operations out of the box. For more references, please browse the online documentation. Cheers!

11 August 2013

NSURLConnectionDelegate snippet

#pragma mark - NSURLConnectionDelegate
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    mutableData = [NSMutableData data];
}

-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    [mutableData appendData:data];
}

-(void)connectionDidFinishLoading:(NSURLConnection *)connection {
    NSLog(@"mutableArray in finishedLoading => %@", [[NSString alloc] initWithData:mutableData encoding:NSUTF8StringEncoding]);
}

-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    NSLog(@"Error");
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:error.localizedDescription delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
    [alert show];
}

30 June 2013

Big Data Analysis

Big Data Analysis

There's a fantastic series made possible by the University of California, Davis Genome Center, and David Coil on how to access, parse, and analyze big data sequences.

How to display content, and basic grep commands

In summary:

      less fileNamePath
    • used to display file
    • grep item fileNamePath
    • searches and displays item at file
    • grep -c item fileNamePath
    • returns number of occurrences item exists at file

How to parse data with grep

In summary:

      grep item originalFilePath > newFilePath
    • create a new file that contains data with the item parsed
    • grep -v item originalFilePath > newFilePath
    • create a new file containing everything except data with the item parsed

How to analyse data

In summary:

    • find occurrences of item of interest
    • find total number of occurences

Please support this awesome series and subscribe to David's channel on Youtube, where you can also view the series, and more, in it's entirety.

13 June 2013

Native parsing in Objective-C

Native parsing in Objective-C

NSScan and NSString

Last week, I had written about the usefulness of the HPPLE library for parsing the internet. There's no doubt it's a great and powerful instrument for parsing XML, however, circumstances prompted me to dig a little more deep, and investigate whether or not there were a more simple or reliable means of parsing data.

After having seen how NSString methods can effectively displace the need for regular expressions, I did a bit of searching and came across the NSScan class. This class takes a string as a parameter, splits the input to the point where the parameter is reached, and saves the remainder of the input to a new string, if allowed.

http://stackoverflow.com/questions/6825834/objective-c-how-to-extract-part-of-a-string-e-g-start-with

Essentially, instead of traversing a path, the NSScan identifies a sequence of chars (as an NSString object), and splits the document at that site. This is the ideal method to parse CSS, something that was not possible with HPPLE, in addition to other sources including XML.

NSString *inputString = @"this is your input, can be CSS or XML"; 
NSString *startTag = @"enter first bound word or phrase to search up to";
NSString *endTag = @"enter last bound word or phrase to search up to";
                               
NSString *savedString = nil;
                               
NSScanner *scanner = [[NSScanner alloc] initWithString:inputString];
[scanner scanUpToString:startTag intoString:nil];
scanner.scanLocation += [startTag length];
[scanner scanUpToString:endTag intoString:&savedString];

This was then abstracted into a method, as below:
+ (NSString *)scanString:(NSString *)string startTag:(NSString *)startTag endTag:(NSString *)endTag
{
    
    NSString* scanString = @"";
    
    if (string.length > 0) {
        
        NSScanner* scanner = [[NSScanner alloc] initWithString:string];
        
        [scanner scanUpToString:startTag intoString:nil];
        scanner.scanLocation += [startTag length];
        [scanner scanUpToString:endTag intoString:&scanString];
    }
    
    
    return scanString;
    
}

Parsing can be carried out simply as a single or sequence of this method call to obtain the desired end string product. Thank you to Natasha Murashev for help to make this possible (http://natashatherobot.com/, https://twitter.com/NatashaTheRobot).

Thank you :)

Library for the native parser available on github at https://github.com/aug2uag/NativeParserLibrary

06 June 2013

HPPLE and accessing paths in XPATH

HPPLE and accessing paths in XPATH

WHY?? WHY OH WHY???

Ray Wenderlich's tutorial on utilizing HPPLE is freaking amazing! I highly recommend using these classes for parsing HTML and other XMLs. My experience with using HPPLE made me feel it was very similar to parsing JSON, although a wee bit more uhhh... challenging. Unfortunately for me, I was not able to find a good XPATH reader, as there are many available for JSON for free and online. Nonetheless, a little bit of experimentation and testing went a long way to find paths to the desired locations.

Here, I'll mention some of the three most used techniques for me during my process of parsing HTML with HPPLE:

1- Test, experiment, repeat

To access a path, there are numerous challenges. First and foremost, make sure you are using the correct path, and that the spelling of your path is correct. The Google Chrome Developer view is very helpful to view the path, make sure your quotes are alligned and balanced, and that your spelling is correct. Also be sure that you are parsing the correct URL. Check, and double check everything regarding your XPATH NSString path, and URL.

For instance, in Google Chrome Developer you can highlight most section(s) of a webpage and "Inspect Element". The path will then be provided to you at the bottom of the developer window, and you must then enter that information into your NSString. Such as seeing:

div#sectionOne, div#sectionTwo, a, p, h2

That would be translated to NSString as:
@"//div[id='sectionOne']/div[id='sectionTwo']/a/p/h2";
If your Breakpoint or NSLog shows a nil/null object, don't despair! Check your path again, check your quotes, make sure you are indicating the correct tag and whether it is id, class, etc. If you still have trouble, reduce your path. For instance, in the above, you would begin by removing the h2, and if that still doesn't work just keep removing until you have an array that you can use.

2- Access arrays, and access dictionaries

Sometimes, the XPATH array you will be returned is freakish looking. A monster string that is way too freakish to inspect as an array. In such cases, utilize fast enumeration! You can print out your array or dictionary via :

for (TFHppleElement *element in yourArray) {
 NSLog(@"\n%@\n\n", element);
}

You will often notice that your array will be a combination of strings, dictionaries, and/or arrays. If you come across trouble/difficulty with your data structure there are a couple approaches that may benefit you. These include to create a custom method in your TFHppleElement header and implementation files to access node(s) you are frequently encountering in your XPATH. Identify whether you are dealing with a string, array, or dictionary; and utilize the proper instrument to access the paths, as necessary. Common will be the TFHpple instance methods with the 'content' method, array brackets, and valueForPath:@"string". You can really benefit by breaking your large data structure down one piece at a time, instead of being stuck on trying to narrow it down in one stroke.

3- Regular expressions and string methods

Despite the awesomeness of HPPLE, you will sometime(s) reach a dead end where you are no longer working with XML, and are left with exorbitant whitespace and/or nasty tags. You can benefit from utilizing NSString methods and/or Regex to take care of such mishigas. Deal with what you have, and you will find at least some form of happiness with HPPLE, as many before have done for what may be considered a long or very long time in the world of iOS programming.

Alright!!

I hope this gives you a little bit of motivation in your pursuit of parsing XML, including HTML. If you are in the middle of a project currently, keep in there! There are great alternatives to HPPLE, and honestly your choice will probably not affect the growing pains that much AND HPPLE is a great and powerful instrument!

Sometimes though, the XML is embedded and not accessible. You can parse the entire accessible tags via assigning /html for the path, and you can do a basic find to see whether or not your element is accessible. If not, look for a different URL, or you may have to look to another instrument and/or approach for your immediate needs. For more, check out the example project I made to parse data in Toys'R Us at github.

18 May 2013

Unicode date and time format guide

Symbol
Meaning
Example
G
era designator
G
AD
y
year
yy
yyyy or y
96
1996
Y
year of "Week of Year"
Y
1997
u
extended year
u
4601
U
cyclic year name, as in Chinese lunar calendar
U
甲子
Q
quarter
Q or QQ
QQQ
QQQQ
02
Q2
2nd quarter
q
Stand Alone quarter
q or qq
qqq
qqqq
02
Q2
2nd quarter
M
month in year
M or MM
MMM
MMMM
MMMMM
09
Sept
September
S
L
Stand Alone month in year
L or LL
LLL
LLLL
LLLLL
09
Sept
September
S
w
week of year
w or ww
27
W
week of month
W
2
d
day in month
d
dd
2
02
D
day of year
D
189
F
day of week in month

2 (2nd Wed in July)
g
modified julian day
g
2451334
E
day of week
E, EE, or EEE
EEEE
EEEEE
Tues
Tuesday
T
e
local day of week
example: if Monday is 1st day, Tuesday is 2nd )
e or ee
eee
eeee
eeeee
2
Tues
Tuesday
T
c
Stand Alone local day of week
e or ee
eee
eeee
eeeee
2
Tues
Tuesday
T
a
am/pm marker
a
pm
h
hour in am/pm (1~12)
h
hh
7
07
H
hour in day (0~23)
H
HH
0
00
k
hour in day (1~24)
k
kk
24
24
K
hour in am/pm (0~11)
K
KK
0
00
m
minute in hour
m
mm
4
04
s
second in minute
s
ss
5
05
S
millisecond (maximum of 3 significant digits);
for S or SS, truncates to the number of letters

for SSSS or longer, fills additional places with 0
S
SS
SSS
SSSS
2
23
235
2350
A
milliseconds in day
A
61201235
z
Time Zone: specific non-location
z, zz, or zzz
zzzz
PDT
Pacific Daylight Time
Z
Time Zone: RFC 822
Time Zone: localized GMT
TIme Zone: ISO8601
Z, ZZ, or ZZZ
ZZZZ
ZZZZZ
-0800
GMT-08:00
-08:00
v
Time Zone: generic non-location
v
vvvv
PT
Pacific Time or United States (Los Angeles)
V
Time Zone: specific non-location, identical to z
V
PDT
VVVV
Time Zone: generic location
VVVV
United States (Los Angeles)
W
week in month

2
'
escape for text
'
(nothing)
' '
two single quotes produce one
' '
'




Format Pattern
Result
yyyy.MM.dd G 'at' HH:mm:ss zzz
1996.07.10 AD at 15:08:56 PDT
EEE, MMM d, ''yy
Wed, July 10, '96
h:mm a
12:08 PM
hh 'o''clock' a, zzzz
12 o'clock PM, Pacific Daylight Time
K:mm a, z
0:00 PM, PST
yyyyy.MMMM.dd GGG hh:mm aaa
01996.July.10 AD 12:08 PM