CoreData with NSOrderedSet does not work well on insertion

Usually, we generate an entity class with Editor->Create NSManagedOBject Subclass... For example we created a subclass of NSManagedObject

Xcode generates the .h file like this:

@interface MyEntity : NSManagedObject

@property (nonatomic, retain) NSOrderedSet manySubs;

//... some methods generated by Xcode
- (void)addManySubsObject:(MySubEntity*)value;
//... some other methods generated by Xcode

@end

and the .m file like this:

@implement MyEntity

@dynamic manySubs;

@end

If you use MyEntity just like this, you will get an error when you try to insert a new MySubEntity class by calling [myEntityObj addManySubsObject:aSubEntityObj];.

The error reads:

*** -[NSSet intersectsSet:]: set argument is not an NSSet

This is a bug Apple hasn’t resolved yet, but you can work around this bug by adding the following method to .m file.

- (void)addManySubsObject:(MySubEntity*)value{
    [self willChangeValueForKey:@"manySubs"];
    NSMutableOrderedSet *tempSet = [NSMutableOrderedSet orderedSetWithOrderedSet:self.manySubs];
    [tempSet addObject: value];
    self.manySubs = tempSet;
    [self didChangeValueForKey:@"manySubs"];
}

Be careful

[Updated]Billboard problem Resolved – Facebook Hacker Cup 2012

[Update@2012-01-24] I made a little mistake in a if...else... statement.

Facebook started Facebook Hacker Cup 2012 from January 20 at 4:00pm PST, and until January 23 at 4:00pm PST, the event is closed to receive submission.

There are three questions, when I learned the event, the event is already started and left me only near 16 hours to take some challenge.

I picked “Billboard problem”.

The original question

Billboards

We are starting preparations for Hacker Cup 2013 really early. Our first step is to prepare billboards to advertise the contest. We have text for hundreds of billboards, but we need your help to design them.

The billboards are of different sizes, but are all rectangular. The billboard widths and heights are all integers. We will supply you with the size in inches and the text we want printed. We want you to tell us how large we can print the text, such that it fits on the billboard without splitting any words across lines. Since this is to attract hackers like yourself, we will use a monospace font, meaning that all characters are of the same width (e.g.. ‘l’ and ‘m’ take up the same horizontal space, as do space characters). The characters in our font are of equal width and height, and there will be no additional spacing between adjacent characters or adjacent rows. If you print a word on one line and print the next word on the next line, you do not need to print a space between them.

Let’s say we want to print the text “Facebook Hacker Cup 2013″ on a 350×100″ billboard. If we use a font size of 33″ per character, then we can print “Facebook” on the first line, “Hacker Cup” on the second and “2013″ on the third. The widest of the three lines is “Hacker Cup”, which is 330″ wide. There are three lines, so the total height is 99″. We cannot go any larger.

Input

The first line of the input file contains a single integer T: the number of test cases. T lines follow, each representing a single test case in the form “W H S”. W and H are the width and height in inches of the available space. S is the text to be written.

Output

Output T lines, one for each test case. For each case, output “Case #t: s”, where t is the test case number (starting from 1) and s is the maximum font size, in inches per character, we can use. The size must be an integral number of inches. If the text does not fit when printed at a size of 1″, then output 0.

Constraints

  • 1 ≤ T ≤ 20
  • 1 ≤ W, H ≤ 1000

The text will contain only lower-case letters a-z, upper-case letters A-Z, digits 0-9 and the space character. The text will not start or end with the space character, and will never contain two adjacent space characters. The text in each case contains at most 1000 characters

Example input

5
20 6 hacker cup
100 20 hacker cup 2013
10 20 MUST BE ABLE TO HACK
55 25 Can you hack
100 20 Hack your way to the cup

Example output

Case #1: 3
Case #2: 10
Case #3: 2
Case #4: 8
Case #5: 7

My Solution

I used Objective-C to resolve this problem. I created a Mac app project. Later I think it’s completely unnecessary. I will try to use maybe pure C or Cocoa Console later.

Here is the my solution on github

The key idea behind my solution is divide and conquer.

1. Find the possible max font size

  1. Assume the billboard only show one line or one column, the MIN(width, height) will give the first guess of the max font size.
  2. Assume all the characters without space will be layout on the billboard one by one, the biggest font to whole all characters will be our possible max font size. Because if we add any space or non-hyphenation constraints to layout, we must shrink the font to hold these extra constraints.

Here I used the D&C to find the possible max font size:

- (NSInteger)maxFontSizeForText:(NSString *)text 
                withTextInArray:(NSArray *)textInArray 
               constraintToArea:(NSInteger)rectArea 
                     withBounds:(NSDictionary *)bounds
{
  NSParameterAssert(text);
  NSParameterAssert(textInArray);
  NSParameterAssert(bounds);

  NSInteger upperSize = [[bounds objectForKey:UPPER_BOUND_KEY] integerValue];
  NSInteger lowerSize = [[bounds objectForKey:LOWER_BOUND_KEY] integerValue];
//  NSLog(@"*** finding max size between %4ld...%ld", lowerSize, upperSize);

  NSInteger upperArea = upperSize * upperSize * ([text length] - ([textInArray count] - 1));
  NSInteger lowerArea = lowerSize * ([text length] - ([textInArray count] - 1));

  // No need to go further, there will be one size suitable for rectArea
  if (1 >= (upperSize - lowerSize)) { // there could be a case of 0
    if (upperArea <= rectArea) {
      return upperSize;
    }else if (lowerArea <= rectArea){
      return lowerSize;
    }else {
      return 0;
    }
  }

  // Otherwise, we need to go recursive routine to find the max size in lower...upper
  NSInteger middleSize = lowerSize + ((upperSize - lowerSize) >> 1);
  NSInteger middleArea = middleSize * middleSize * ([text length] - ([textInArray count] - 1));
  if (middleArea > rectArea) {
    NSDictionary *boundsDict = [NSDictionary dictionaryWithObjectsAndKeys:
                                [bounds objectForKey:LOWER_BOUND_KEY], LOWER_BOUND_KEY,
                                [NSNumber numberWithInteger:middleSize], UPPER_BOUND_KEY,
                                nil];
    return [self maxFontSizeForText:text withTextInArray:textInArray constraintToArea:rectArea withBounds:boundsDict];
  }else {
    NSDictionary *boundsDict = [NSDictionary dictionaryWithObjectsAndKeys:
                                [NSNumber numberWithInteger:middleSize], LOWER_BOUND_KEY,
                                [bounds objectForKey:UPPER_BOUND_KEY], UPPER_BOUND_KEY,
                                nil];
    return [self maxFontSizeForText:text withTextInArray:textInArray constraintToArea:rectArea withBounds:boundsDict];
  }
}

2. Find the correct max font size

Try to fit the text start with possible max font, then shrink the font size to meet the constraints.

This is simple but have some complex if...else... statements.

[Update 2012-01-24] Thanks to Chong, the following algorithm failed to find the correct font size for Case #7, it should be 9 instead of 8, to fix this, I need to modify 2 places, change realFontSize = width/[aWord length]; to realFontSize--; and change realFontSize = height/(currentLineIndex + 1); to realFontSize--;

// Another core algorithm that will try and shrink the font size to fit the billboard
- (NSInteger)correctMaxFontSizeForNoHyphenationFor:(NSArray *)textInArray 
                                      constraintTo:(NSInteger)possibleMaxFontSize 
                                        boardWidth:(NSInteger)width 
                                       boardHeight:(NSInteger)height
{
  NSParameterAssert(textInArray);

  if (possibleMaxFontSize == 0) {
    return 0;
  }

  NSInteger realFontSize = possibleMaxFontSize;
  BOOL finished = NO;
  do {
    NSInteger currentLineWidth = 0;
    NSInteger currentLineIndex = 0;

    for (int idx= 0; idx < [textInArray count]; idx++) {
      NSString *aWord = [textInArray objectAtIndex:idx];
      NSInteger wordLengthAppliedFontSize = [aWord length]*realFontSize;
      // width is not enough for a single word
      if (wordLengthAppliedFontSize > width) {
        realFontSize = width/[aWord length];
        currentLineIndex = 0;
        currentLineWidth = 0;
        break;
      }

      // current word is safe for at least one line, see if it is safe to add to current line.
      if (currentLineWidth + wordLengthAppliedFontSize > width) {
        // need a new line
        currentLineIndex++;
        currentLineWidth = wordLengthAppliedFontSize;

      }else{
        currentLineWidth += wordLengthAppliedFontSize;
      }

      if (currentLineWidth + realFontSize < width) {
        // current line is safe for one more space.
        currentLineWidth += realFontSize;
      //}else{   //<- Here cause the case #1 failed
      }else if (idx != ([textInArray count] -1)){
        // need a new line
        currentLineIndex++;
        currentLineWidth = 0;
      }

      // height is not enough for the whole text
      if ((currentLineIndex + 1) * realFontSize > height){
        realFontSize = height/(currentLineIndex + 1);
        currentLineIndex = 0;
        currentLineWidth = 0;
        break;
      }
      // done.
      if (idx == [textInArray count] -1) {
        // last line
        finished = YES;
      }

    }

  } while (realFontSize > 0 && !finished);

  return realFontSize;
}

3. Verify it

I created some test cases to test on it. It includes some extra test cases that need to be omitted when read in the file.

Download my test cases

Meanwhile, Facebook has an input file, you can also download it.

Output

Here is my output, what’s yours? Whose one is correct?

Case #1: 30 //<- Wrong, should be 60
Case #2: 5
Case #3: 31
Case #4: 6
Case #5: 30
Case #6: 83
Case #7: 8      //<- Wrong, should be 9
Case #8: 80
Case #9: 21
Case #10: 4
Case #11: 31
Case #12: 21
Case #13: 30
Case #14: 21
Case #15: 30
Case #16: 21
Case #17: 4
Case #18: 21
Case #19: 4
Case #20: 4

After modified step2, I think the following result is correct:

Case #1: 60 
Case #2: 5 
Case #3: 31 
Case #4: 6 
Case #5: 30 
Case #6: 83 
Case #7: 9 
Case #8: 80 
Case #9: 21 
Case #10: 4 
Case #11: 31 
Case #12: 21 
Case #13: 30 
Case #14: 21 
Case #15: 30 
Case #16: 21 
Case #17: 4 
Case #18: 21 
Case #19: 4 
Case #20: 4 

It’s fun, I’m no longer qualified for next round now, good luck, my friends. (hope I can enter the qualification round. And so do you.)

Transparent view vs. hidden view in iOS

Rise the question

Here comes the question,

how to create a transparent view without any contents?

Wow, the answer looks so easy to get! Almost every iOS developer has created one or even more ‘transparent view’s. Let’s take a look at those solutions. We have 2 solutions.

Solutions #1

Create a view with alpha=0.f. take a look at the code below

UIView *transparentView1 = [[UIView alloc] initWithFrame:CGRectMake(0.f, 0.f, 320.f, 460.f)];
transparentView1.alpha = 0.f;
[self.view addSubview:transparentView1];
[transparentView1 release];

It’s simple and straight forward. Hum? Let’s take a look at another solution.

Solution #2

Create a view with backgroundColor=[UIColor clearColor].

UIView *transparentView2 = [[UIView alloc] initWithFrame:CGRectMake(0.f, 0.f, 320.f, 460.f)];
transparentView2.backgroundColor = [UIColor clearColor];
[self.view addSubview:transparentView2];
[transparentView2 release];

This is also very simple.

So, what’s the difference between these 2 solutions?

The difference on surface

Before we talking about the difference, we need to review some basic yet key properties provided by iOS

  1. hidden: set this property to YES will cause the view invisible. default is NO;
  2. alpha: this property affect all the contents of the view, including drawing and subviews. animatable;
  3. backgroundColor: this only affect the background color, not affect the drawing and subviews of the view. animatable;
  4. opaque: set this property to YES, will gain some performance boost on UI rendering. But need to full fill the rectangle of the view. If opaque is set to YES and the view has full or partial transparent content, the behavior is not define.

Visit apple’s document for UIView for detail information.

With these basic knowledge, we can easily tell the difference between these 2 solutions.

  • Solution #1 uses alpha property to make the view transparent, in another word, it’s invisible because the view is hidden.
  • Solution #2 sets backgroundColor to transparent color to make it invisible.
  • Solution #2 only set the background to transparent, if you draw anything on the view, or add some subviews to the view, they are still visible, and solution #1 will make everything in the view invisible, including the custom drawings and all the subviews.
  • If the view is a clean view without any custom drawings and subviews, the result of these 2 solutions look the same.

They look the same? But actually not the same? Yes, they just look the same, but not exactly the same, so what’s the real difference?

Look the same, but…

There is always a BUT.

These 2 solutions look the same, but act differently on receiving touch event.

  • Solution #1: alpha=0.f;, according to Apple’s document:
    > To hide a view visually, you can either set its hidden property to YES or change its alpha property to 0.0. A hidden view does not receive touch events from the system. However, hidden views do participate in autoresizing and other layout operations associated with the view hierarchy. Thus, hiding a view is often a convenient alternative to removing views from your view hierarchy, especially if you plan to show the views again at some point soon.
    >
    > See Apple’s document
  • Solution #2: when background color is set to clear color, the alpha is still 1.0, so this view still can receive touch event.

Finally, we have the answer

Before we get the correct answer, we need to use the correct terminologies to clarify the answer:

  • Hidden View: when hidden=YES or alpha=0.f
  • Transparent background View: when backgroundColor is set to clear color

The answer

  • a hidden view will not accept touch event, while a transparent background view will.
  • a hidden view may look like a transparent background view if add no subviews and draw nothing on the view.

With this answer, I think we can use hidden view and transparent background view correctly.

How to sync WordPress blog entries to Blogger.com and Tumblr and Posterous

Do you have multiple blog sites?

If your answer is no, then, this blog entry is useless to you. Close this page please.

If you DO have multiple blog sites, and you don’t care about synchronizing one blog site to others, then this blog entry is also useless to you. Close this page please.

If you DO have multiple blog sites as me, and you DO want to synchronize your one blog site to others. You are viewing the right post.

Why multiple blog site?

It’s complicated. I’m owning my own domain totodotnet.net, and is running WordPress on it. Then I also have an account in Blogger.com, it’s good, with elegant design and dashboard. I also happened to have an account in Tumblr.com all because it support markdown by default.

So, I like all of these 3 sites, and I don’t want to abandon any one of them. I decided to do a synchronization with all of these sites.

But, How?

Have you ever heard about “ifttt.com“?

This site is great! It saved me a lot of works. Synchronizing between each site is also done with ifttt.com‘s help.

Here is how:

  1. You need to have a main site.
    This means, you need to post your original posts to this site. Since all blog systems provide RSS output, we will use RSS to synchronize entries to other sites.

  2. Add a new rule in ifttt.com
    You usually, it can be read as “Sync any new items in RSS[your main site's RSS] to tumblr/posterous/Mail(etc.)”. It’s very straight forward, and easy to use. Just create a few such kind of rules to let it do the synchronizing works.

  3. Blogger.com is not directly supported by ifttt.com

My solution is enable the “Posting using email” option in blogger.com, then setup a rule to send an email to your posting email address on each new blog entry.

Ifttt.com can do much more things

[Ifttt.com] is such an awesome site, it integrated almost all the major web services in the world. You can send a tweet or a facebook post when your new blog entry is posted.

The concept can be separated as read in stream and output stream:

  • read in stream:
    services available for read in stream

  • output stream:
    services available for output stream

Now, just enjoy the internet!

How to set markdown as your default editor language for your WP based blog

Markdown is such a great Markup language

Without saying any words, if you’re familiar with Markdown language, and when you get used to it, you will not be able to leave it.

How to use markdown with WordPress

I’m using a plugin called “Markdown on save” which was written by Mark Jaquith. The biggest right thing this plugin had done is saving the raw markdown text in post_content_formatted column, and the converted HTML content will be stored in post_content. This idea brings 2 big advantages.

  1. No need to do the Markdown -> HTML conversion on the fly.
  2. Even the plugin is deactivated, you won’t loose your post, because the post will be rendered with post_content.

Simple and straightforward

All you need to do, is

  1. search the plugin(markdown as save), and install it, activate it.
  2. check the Markdown check on the up-right corner.
  3. Write your post and preview it if it is necessary.
  4. Post it

BOOM! You are done!

Some simple test

H1 headline

H2 headline

Following by a

H3 headline

without an empty line following an H4 headline

H4 headline

follow by an H5

H5 headline

follow by an H6

H6 headline.

Bold, italic, link to google,

b-quote,

  • quote with list1
  • quote with list2
  • quote with list3
  1. quote with list
  2. quote with list
  3. quote with list

strike-out

image

Blogging from Flock

How does this feel?
-> Not so bad.

What if I need a picture?
-> It’s too weak! I need the basic picture manipulation functions. Like position and size.

Category?
-> Damn it! Flock blogging does not support category! Unbelievable!
-> Oh, sorry, it does support category but not so obviously.

Blogging from Flock

How does this feel?
-> Not so bad.

What if I need a picture?
-> It’s too weak! I need the basic picture manipulation functions. Like position and size.

Category?
-> Damn it! Flock blogging does not support category! Unbelievable!

3 great videos you must see

 

The Carbon Economy

(View high quality video on YouTube)

It’s time for real

Hellmann’s – It’s Time for Real from CRUSH on Vimeo.

The State of The Internet

JESS3 / The State of The Internet from Jesse Thomas on Vimeo.

Gist

Higly recommend every developer to use Gist to share the snippets.

It’s really great!

OK, Singleton in Java.

Fine, this topic has been talked many many times, and you can find a lot of great answers over the internet. Stackoverflow.com listed a lot of answers. And also, you can find great approach from Joshua Bloch’s Effective Java also pointed out 2 effective approaches. What’s more, Joshua Bloch also provided an enum approach(Page 31) as the best practice for Serializable Singleton. If you like Wikipedia, you can also find a Java solution for Singleton, and for deep background knowledge behind this approach, please read “Double check locking” and “Java 5 memory management” by Bill Pugh.

If you are as lazy as me, just remember the following implementation, which is thread safe and can be used on all the java version. The key point in this implementation is using Java atomic class load mechanism to guarantee the thread safe and using static method to implement lazy initialization.

If you also have some curious on the other implementations, please keep reading.

  1. The simplest implementation(Immutable class, thread safe, but no lazy initialization)
  2. The double check locking implementation(Thread safe, lazy initialization, but requires Java 5+)
  3. The enum implementation(Thread safe, Serializable, also requires Java 5+)

After reading all of these, I don’t think you need any other implementations, but to understand why and how these implementations work, you need read something more[Typically those links I provided at the beginning]. There are things called Google and Bing on the earth, I guess you can find the answer very soon.