Virtualenv with sudo

Virtualenv is a great way to manage Python environments. Today I ran into an issue when I had to run the script parts of which required sudo privileges and the rest of it needed all my virtual environment packages. When we run sudo all virtualenv settings (environment variables, aliases, functions, etc) become unavailable.
Virtualenv user guide offers following solution:

activate_this = '/path/to/env/bin/activate_this.py'
execfile(activate_this, dict(__file__=activate_this))

Adding this lines to my script saved me a lot of trouble – now I have my environment available when I run sudo!

iOS8 and custom UIViewControllers transitions

Currently there is a but in iOS8 custom transitions. When the custom transition is complete, i.e. [transitionContext completeTransition: YES] is called, UIWindow shows empty with no view hierarchy at all. That is seen as a black screen which is appearing instead of destination view controller’s view.
The workaround is to add all views back:

[[UIApplication sharedApplication].keyWindow addSubview:  [destinationViewController].view];

Clean solution for now, probably will be fixed soon)

Pascal triangle in Xcode console

Pascal triangle is one of the most famous recursive problems. It has a simple and elegant implementation in Objective-C as well as in many other languages. It turned out, that formatting the output seems more challenging than actual calculation for triangle elements:

+(NSInteger)pascalTriangleForRow: (NSInteger)row Column: (NSInteger)column
{
     if (row == column || column == 0) {
     return 1;
     } else {
     return [self pascalTriangleForRow:row-1 Column:column-1] + [self pascalTriangleForRow:row-1 Column:column];
     }
}
+(void)showTriangle
{
     NSMutableArray *triangle = [NSMutableArray new]; 
     for (NSInteger row = 0; row < 10; row ++) { 
         NSMutableArray *currentRow = [NSMutableArray new]; 
         for (NSInteger column = 0; column <= row; column++) { 
             [currentRow addObject:@([self pascalTriangleForRow:row Column:column])]; 
         } 
         NSString *rowAsString = [currentRow componentsJoinedByString:@" "];
         [triangle addObject:rowAsString]; 
      } 
      NSString *triangleString = [triangle componentsJoinedByString:@"\n"]; 
      NSLog(@"\n%@", triangleString);
}

Insertion sort

Insertion sort is a simple sorting algorithm:

+(NSInteger)InsertionSort:(NSMutableArray*)array
{
    for (NSInteger index = 1; index < [array count]; index++) {
        NSInteger currentValue = [array[index] integerValue];
        NSInteger position = index;
        while (position > 0 && ([array[position -1] integerValue] > currentValue 
             {
             array[position] = array[position-1];
             steps++;
             position = position-1;
             }
       array[position] = @(currentValue);
       }
       return steps;
}

					

Change annotation view for state of annotation on MapView

Imagine that we need to change color of custom annotationView, when an annotation has been selected.
Our steps:

  • retrieve the annotation’s current view using the MKMapView instance method viewForAnnotation (the catch here is that it is not the same as mapView:viewForAnnotation: delegate method)
  • modify properties of current view
for (MyAnnotation *selectedAnotation in selectedAnnotations) 
{
    MKAnnotationView *selectedAnnotationView =[self.mapView viewForAnnotation:selectedAnotation];
    selectedAnnotationView.image = newImage;
}

Center view within UIScrollView on zoom

- (void)centerContent 
{
    CGFloat top = 0, left = 0;
    if (self.scrollView.contentSize.width < self.scrollView.bounds.size.width) {
        left = (self.scrollView.bounds.size.width-self.scrollView.contentSize.width) * 0.5f;
     }
    if (self.scrollView.contentSize.height < self.scrollView.bounds.size.height) {
        top = (self.scrollView.bounds.size.height-self.scrollView.contentSize.height) * 0.5f;
    }
    self.scrollView.contentInset = UIEdgeInsetsMake(top, left, top, left);
}

We call this method in UIScrollViewDelegate method:

- (void)scrollViewDidZoom:(UIScrollView *)scrollView
{
    [self centerContent];    
}

Don’t forget to center content in your UIScrollView setup (most likely, it is in
– (void)viewDidLoad or in scroll view setter)!

NSSortDescriptors with Collections Operations

Suppose we need to sort objects based on the length of the array (property named transactions).
We can use NSSortDescriptors like that:

NSSortDescriptor *desc = [NSSortDescriptor sortDescriptorWithKey:@"transactions.@count" ascending:YES]; 
NSArray *descriptors = @[desc];
return [self.items sortedArrayUsingDescriptors:descriptors];

The general case for it is  Collections Operations:

NSNumber *numberOfTransactions = [transactions valueForKeyPath:@"@count"];

 

 

Recursive base converter

We solve the problem recursively, when we break it into smaller and smaller subproblems, until the solution becomes obvious.
There are three rules of recursion:

  1. Define a base case
  2. Change a state and move towards base case
  3. Call itself

Let’s see how they can be fulfilled using the base converter:

- (NSString *)recursiveBace: (NSInteger)number ToBase: (NSInteger)base
{
    NSArray *convert = @[@"0", @"1", @"2", @"3", @"4", @"5", @"6", @"7", @"8", @"9", @"A", @"B", @"C", @"D", @"E", @"F"];
    NSMutableString *result = [[NSMutableString alloc]init];
    if (number < base) { //detect the base case
        [result appendString:convert[number]]; //then return a string from sequence
    } else {
        [result appendString:[self recursiveBace:number/base ToBase:base]]; //reduce problem size and change state
        [result appendString:convert[number%base]];
    }
    return result;
}

Convert decimal to binary

Helps to understand how binary count works:

- (NSString *)divideByTwo: (NSInteger) decimalNumber
{
    NSMutableString *binary = [[NSMutableString alloc]init];
    if (binary == 0) {
        [binary appendString:@"%@"];
    }
    while (decimalNumber > 0) {
        NSInteger rem = decimalNumber % 2;
        [binary appendString:[NSString stringWithFormat:@"%d", rem]];
        decimalNumber = decimalNumber / 2;
    }
    return binary;
}

There is also Any base converter on Github, which is a general case of base 2 conversion. It converts any decimal number to any base from 2 to 16 and mimics a stack behavior.