Friday 31 August 2012

Turning on "git" when half way through an Xcode project.

The git source control system is installed within Xcode or possibly it was in OSX already. 
If you want a git repository and you did not install git as part of the process of creating your Xcode project, you may want to do the following from the command line.

You want to initialise git on your project but exclude the userstate files as they just change all the time regardless of any code changes and would just clutter stuff up and take git ages to look at.
cd to the folder where your project is. 
Look for your .xcuserstate file and echo it by name to a file called .gitignore. Alternatively use some other method to  create a file in your project folder called .gitignore with the relative path information for the .xcuserstate file. (Just in case you did not know, files with names starting '.' are invisible in the filer). "find ." will do a recursive listing of your folder and using "grep" will filter the file you want. This is done as follows. (Stop Xcode first, it is good enough at crashing without providing it with excuses!).
(In the root of your XCode project folder) (Some of this is pasted small to get all on one line)

cd Developer/HP11/

find . |grep xcuserstate
HP11.xcodeproj/project.xcworkspace/xcuserdata/brian.xcuserdatad/UserInterfaceState.xcuserstate

Then echo it to make the file .gitignore. The following up to and including >.gitignore is all one line.

echo HP11.xcodeproj/project.xcworkspace/xcuserdata/brian.xcuserdatad/UserInterfaceState.xcuserstate >.gitignore

Then, initialise your git repository and do the first commit.

git init
git add .
git commit -m "First commit"
git config --global user.name "Author Name"
git config --global user.email author@mail.com
git commit --amend --reset-author
git commit --amend --reset-author

Just type "git" to get other git options from the cli.
From here on in you should be able to use the File>Source Control >Commit menu within XCode.

Using source control allows you to roll back to earlier versions and see and (from your comment) understand exactly what changes you made. 

This site  has a good description of all your git options.



Monday 27 August 2012

XCode Notes Moving to XCode from Java


Looking at Objective C with a Java background is a bit of a challenge.

I am following Paul Hegarty IOS course which is ITunesU and I think is just follow-able by someone with Java knowledge. In fact Apple appear to be migrating aspects of Java into Objective C.

One thing I have noticed is that C++ Obj C people seem to make it a matter of pride to make "one liners". Code presented as an example is really long when a clear description (& clearer code IMO) is created by using several lines with well named intermediate variables. I admit there is a limit and the best way of writing a bug free line is to write no line at all, but I wonder how many long lines of code out there  reflect coding by rumourn or "chinese whispers" as opposed to understanding.

Reports here will probably reflect the tutorials and home work from there.

The best site for questions and answers appears to be Stackoverflow.

Answers tend to be larded with complex references however today I found out some useful stuff and record it here for future reference.

When to use pointers in referring to variables?

answer 1: From experience (!)
answer 2: In general use pointers for objects and not for primitives.

Strings

The @ symbol turns up a great deal when using strings. If you just use "" to denote strings, you will get a ! from the compiler because it will thin k you are trying to do things with characters.

Example. From the CHS sign button on my HP11 emulator.
NSString *leadingCharacter = [self.display.text:0] ;
if leadingCharacter != @"-";{<do something>}

One thing I had to do was make a CHS button which changes the sign of the number in the display (Which is a string). The following code checks if the first character is a '-' and puts one if if not and removes it if there is.
(Prior to calling I check that there is a string of length at least 1 already there.

if([self.display.text characterAtIndex:0] != '-')
   {
    self.display.text =  [NSString stringWithFormat:@"-%@", self.display.text])
     }
else
   {
    self.display.text = [self.display.text  substringFromIndex:1]
   }

How to find a substring in a string

Surprisingly difficult, in words you have to make a NSRange (not an object) by using the rangeOfString method on your string and then use the location instance variable location to compare to NSNotFound to see whether the ting was found.

I found a good answer here.

Here is my code

NSString *whatIAmLookingFor = @"sometext";
NSString *whereIAmLooking = @"some text maybe what I am looking for";
NSRange myRange = ( [whereIAmLooking rangeOfString:whatIAmLookingFor]);
if (myRange.location) !=NSNotFound} {do this} else {do that};
When asking question on stackoverflow the answers may often put three lines of code (for a beginner) into one. 

Testing Strings for Equality.When we want to test within an if statement for branching you might think that 
if (myString == @"*"){} would be a reasonable bit of code but because Objective C is an Object Oriented programming language, testing for equality is not quite as straightforward. 
With primitives such as double, int, char etc. this construct is fine but with a NSString, you  are dealing with an object and so first of all the line of code has to test for inequality between objects. This is compounded by the fact that in C you are dealing with NSString pointers and so the test above would only ever succeed if the two strings were one and the same object and so the pointers were the same.
What you need to do is test using the IsEqual method which is part of the NSString API.
This code is using the correct method.


if ([topOfStack isEqualToString:@"*"]){
    element = [NSString stringWithFormat:@"%@%@%@",rhs,topOfStack,lhs];    
    }

An object has to be completely equal to pass this equality test but this is what I want here.

XCode4 Wrinkles

Sometimes XCode throws a hissy fit and bungs loads of !s in the LH bar about faults on build. It is worth clicking the build  button and they may all just disappear.

How to manage memory.

XCode4 (which I am using) appears to have put in a (kind of ) garbage collector as in Java in the form of Automatic Reference Counting (ARC) which means that objects get removed when they have run out of use beacuse no other object is referencing them.
Hurray for that. I know memory management is a job that C++ programmers have to do and Java programmers do not.

Simple debugging.
At this stage I want to use print statement to debug. In Oh-C! this is

NSLog (@"Just done the thing in the line above, about to do the thing in the line below");

To print in some sensible way, the @ formatters are important for getting the outputs in a sensible form.  They are listed here.

To print the contents of an object there is something like the toString() method in Java and this takes the form (for printing out)

NSLog(@" array contents %@",[<object> description]);


The Debugger.One of the optional Paul Hegarty Lectures introduces the debugger. For the lazy, here is a brief intro to the most useful thing he shows in that lecture. But really, go and see the whole thing.
This is really useful. The debugger is introduced nicely 
here. The first thing you will want to do is stop crashes juts taking you back to 'main'. Use the LHS debugger screen to set a trap for all exceptions, that means that a crash will take you  back to the point where the crash occurred. Big improvement on main.  In the left hand pane you click on the second icon from the right. Alt text is "Show the breakpoint Navigator", click on the plus at the bottom and choose the defaults in "Add Exception Breakpoint" and this will give you the breakpoint Navigator view in the RH picture below.

This is the LH pane in the XCode viewThe All Exceptions Trap is in the Navigator














Accessing Values and Properties and some illumination on all these [] and () and dot notation.

In general, call a method by 
[<object> <method>] 
and if the method has a parameter to send use  
 [<object> <method>:<parameter>]
You can access a property using dot notation.
<value of correct type> = <object>.<property>;

If you do  
<object>.<method>; 
i.e. you do not assign to a value because the method is void, the method will run but you will get a compiler warning that you should not use getters for side effects. In other words, if object.method is void then you are calling the method an an object so do [<object> <method>].

Finding out about method calls

The course I am following builds on a RPN calculator built using Model:View:Controller
.I have to make a clear button and initially I used the code
self.display.text=@"0";
self.display.history=@"";
self.brain.clear;
In the model  the only instance variable is a NSMutableArray with the various things entered by the calculator user in it.
I put a method called "clear" into the model that clears the array using the removeAllObjects method.
I got a warning from Xcode that "property access unused getters should not be used for side effects"

After some effort and this help I realised that I needed to use

[self.brain clear]

The message was effectively saying the following,
'[self.brain clear]' is calling the method in the class brain with the name 'clear' which should be used when calling a method.

self.brain.clear would be used if I was accessing a property in the object brain with the name clear and so would be on the RHS of an assignment of the correct type.

e.g. NSString *clearProperty = self.brian.clear

(assuming the method clear returned a String)

The reason it worked was that OBj-C treated the method clear as a 'getter' and ran the method which had the required effect, however as it was not on the RHS of an assignment I had used the 'getter' for a side effect.

I think this means that a void method would always be called using the notation [object.method <method name>];

Friday 10 August 2012

CS193p Progress & Notes on the Course

CS193p The Stanford Course on IOS programming



What happened between Assignment 1 Calculator and The Start of Assignment II?

This course involves a steep learning curve. Assignment one helped me see how Java relates to Obj-C. I found Assignment 2 very tough. I think that understanding what happened in the demo and then what  is required is the main difficulty rather than the coding.
This blog is by someone who seems to know very well what they are about. Very helpful. 

The lecture / demo achieved the following.

Previously, the stack contained just numbers. Operations were applied when pressed in the method performOperation. pushOperand & popOperand just did exactly that, they pulled values off the stack or put numbers on the stack.

In the demo, the program was changed so that the stack could contain operands and operators. The method performOperation was changed so that we could deal with a stack that was full of operators and operands.

The code from performOperation was transferred to popOperandOffStack which might more correctly be called popOffStackWhateverHappensToBeAtTheTop because the stack has has been changed to contain Operators and Operands. More on popOperandOffStack later.

performOperation is now changed so that rather than just performing the operation sent, it pushes the operation (A string) onto the stack and calls runProgram with the parameter delivered by the getter program. The parameter program when got, is a copy of the programStack.

runProgram creates a mutable array called stack, it checks that the programStack delivered by program is in fact an Array by using introspection and if it is it stack becomes a mutable copy  of programStack.
Now we call popOperandOffStack with whatever stack has become, i.e. an empty stack or a mutable copy of the program stack.

popOperandOffStack is recursive. This is important fo several reasons, not least of which is that a RPN calculator stack, is a binary tree which can be traversed via preorder, postorder or inorder traversal. Depending on which one of these you do you will get different versions including an infix version which is the more familiar algebraic notation of most calculators.

popOperandOffStack sets its result to zero, sees if there is anything on the stack, if it is a number then it just returns it. If it is a String then it is treated as an operation using the same code as previously except that rather than calling popOperand to get the operand for the operation, the method is now calling itself. If you look here, wikipedia does a good job of explaining how this works.

Note. If the stack contained a load of numbers only, then nothing happens, popOperandOffStack  wil only consume as many numbers off the stack as it has operators to consume them.

What is Assignment II all about then?

Task 1. In Assignment II Task 1 we will be asked to allow the stack to contain any string at all and if that string is not an operator to replace that string with a value that will be in a Dictionary (hopefully), otherwise replace the string in the stack with a zero. In addition, you must create a class method that returns all the variables used in the program or nil if there are none.

Task 2. This is all about this programmability. You have to put in some Testcases which assign values to variables. You also put in some variable buttons. When you type in a 'program' using the variable buttons you might tap x enter y * 3 +. In your test case you might give values to x and y.
At the bottom of the screen you will return the values of those variables. My current screen looks like this.

The x at the very top is a label I am using to implement function keys f & g. The program is underneath and at the bottom is the values part which lists the values of any current variables. I have not implemented the parentheses removal which is part of one of the tasks. The display 'Error 0' is a piece of behaviour that I have introduced to emulate the HP11 as near as possible.

Removing excess Parentheses.
My code works through the stack until it is empty. If a particular sum is finished (because all the operators have gat their required number of operands ) and there is still stuff on the stack, I place a comma and drag the next complete sum out of the stack. Each sum is separated by a comma from the next.
As for removing parentheses. A complete calculation will always have () around it, so I just remove them like this
  1. A * surrounded by two numbers will never need brackets because multiply is the dominant operand.
  2. A complete expression does not need brackets around it.  e.g. (3+2*6) = 3+2*6
  3. A single operand operator does not need its argument bracketed if is a number. e.g. Cos (6) = Cos 6.
The code I have generated to deal with this situation is via a few methods that may be useful to others who are just learning like me.
is this a number takes a string and delivers a result telling if the answer is a number. The other one tells me if both the first and the last character of a string is a bracket.

I realise that the first one will leak memory if it weren't for the ARC in XCode 4 but I am seeking an improvement.

+ (BOOL)isThisANumber:(NSString *)candidate{
    
    NSNumberFormatter *fmtr = [[NSNumberFormatter alloc] init];
    [fmtr setNumberStyle:NSNumberFormatterDecimalStyle];
    NSNumber *myNumber = [fmtr numberFromString:candidate];
    if ( myNumber== nil) {
        return NO;
        } 
    else{
        return YES;
        }

+ (BOOL) isThisBracketed:(NSString *)candidate{
    if ([candidate length] <3) {
        return NO;
    }
    if (([candidate hasPrefix:(@"(")]) && ([candidate hasSuffix:(@")")])){
        return YES;
      }
    else{
        return NO;
    }
}