//Sort a set NSSet *set = [[NSSet alloc] initWithArray:@[@(7), @(4), @(5), @(3), @(9), @(15)]]; //Ascending NSArray *sorted = [set sortedArrayUsingDescriptors:@[[[NSSortDescriptor alloc] initWithKey:nil ascending:YES]]]; NSLog(@"%@" , sorted); sorted = [set sortedArrayUsingDescriptors:@[[[NSSortDescriptor alloc] initWithKey:nil ascending:YES selector:@selector(compare:)]]]; NSLog(@"%@" , sorted); sorted = [set sortedArrayUsingDescriptors:@[[[NSSortDescriptor alloc] initWithKey:nil ascending:YES comparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) { return [obj1 compare:obj2]; }]]]; NSLog(@"%@" , sorted); //Descending sorted = [set sortedArrayUsingDescriptors:@[[[NSSortDescriptor alloc] initWithKey:nil ascending:NO]]]; NSLog(@"%@" , sorted); sorted = [set sortedArrayUsingDescriptors:@[[[[NSSortDescriptor alloc] initWithKey:nil ascending:YES comparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) { return [obj1 compare:obj2]; }] reversedSortDescriptor]]]; NSLog(@"%@" , sorted); sorted = [set sortedArrayUsingDescriptors:@[[[NSSortDescriptor alloc] initWithKey:nil ascending:YES comparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) { return [obj2 compare:obj1]; }]]]; NSLog(@"%@" , sorted);
Four ways for making an NSPredicate
I learn by examples. I find that it connects things in my brain that abstract description does not.
NSSet *set = [[NSSet alloc] initWithArray:@[@(3), @(4), @(5), @(7), @(9), @(15)]]; NSLog(@"%@", [set filteredSetUsingPredicate:[NSPredicate predicateWithFormat:@"SELF == %@", @(3)]]); NSLog(@"%@", [set filteredSetUsingPredicate:[NSPredicate predicateWithFormat:@"SELF == %@" argumentArray:@[@(3)]]]); NSLog(@"%@", [set filteredSetUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id _Nullable evaluatedObject, NSDictionary<NSString *,id> * _Nullable bindings) { return [(NSNumber *)evaluatedObject isEqualToNumber:@(3)]; }]]); NSLog(@"%@", [set filteredSetUsingPredicate:[[NSPredicate predicateWithFormat:@"SELF == $number"] predicateWithSubstitutionVariables:@{@"number" : @(3)}]]);
How iOS handles touches. Responder chain, touch event handling, gesture recognizers, scrollviews
I started out trying to make a scrollview with buttons in it. I ended up diving deep into the pool of touch events and gesture recognizers. Here’s what I found.
The problem with putting a UIbutton into a scrollview is that when you tap the button, there’s a noticeable delay before the button is highlighted. Not satisfied with this, I started Googling around. Found a stack overflow and it all worked, but how does it work?
I needed to go back to the start.
What happens after you touch an iPhone screen?
- How does a touch find the object that should respond to it?
- How does the view handle the touch without gesture recognizers?
- How do views use gesture recognizers?
- How do gesture recognizes interact with each other?
How does a touch find the object that should respond to it?
Basically, the window takes the touch and checks to see which of it’s subviews the touch is in (aka hit testing). The next view checks its subviews and so on until there are no more subviews to check and we’ve found the deepest view in the view tree that contains the touch. It’s helpful that views are responders, so they can handle the touch events.
If that view isn’t able to handle the touch, then it would be forwarded back up the responder chain to it’s superview until it finds a responder that can handle the touch.
How does the view handle the touch without gesture recognizers?
Touches have four phases: began, moved, ended and cancelled. When the touch changes to a phase, it calls the corresponding method on the view that it’s in.
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event; - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event; - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event; - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;
What happens if you start touching in viewA and then move out of that view without lifting your finger. Does the touch call the method on viewA or viewA’s superview?
Turns out that the messages are sent to the object’s where the touch began.
Within these four methods, you get all the touches involved and you can use these touches to define gestures and trigger actions. For example, if you want your view to recognize swipe gestures, you can keep track of where the swipe action starts in touchesBegan:withEvent: and then keep track of how far the touch has moved in touchesMoved:withEvent: and once it’s greater than a certain distance, you can call an action. That’s exactly what people did before gesture recognizers were introduced in iOS 3.2.
How do views use gesture recognizers?
Gesture recognizers (GRs) are awesome because makes takes touch event handling to a higher level. Instead of tracking individual touches, a gesture recognizer just tells you if you should act on a user’s touches.
Also, if you need to recognize a new type of gesture, you don’t need to make a new subclass of UIView. You can just make a new subclass of GR and add it to a vanilla UIView.
After the gesture is recognized, the GR calls an action on a target and that’s where your app reacts to the touch.
Gesture recognizers get first dibs. Touch events go to them before being handled by the view. That means, when a gesture recognizer recognizes a touch, it can prevent the delivery of touchesEnded:withEvent: to the view and instead call touchesCancelled:withEvent:.
By default, during a swipe gesture, the touchesBegan: and touchesMoved: events will still be called while the gesture hasn’t been recognized yet. If you don’t want these events to be called, you can set delaysTouchesBegan to true on the gesture recognizer.
There are awesome diagrams in the Apple docs for gesture recognizers (especially, Fig. 1-3, 1-5, 1-6).
How do gesture recognizers interact with other gesture recognizers?
By default, views with more than one GR can call the GRs in a different order each time.
You can define the order of GRs with
You can prevent touches going to GRs by setting their delegates with
How did this help solve my problem?
The original problem was that a button in a scrollview had a delay in response to touches. The reason is that scrollviews have a property called delaysContentTouches set to YES by default.
Turn delaysContentTouches to NO and you can tap buttons quickly now, but you can’t scroll anymore. That’s because “default control actions prevent overlapping gesture recognizer behavior”. The default control action is tapping a button. The gesture recognizer it was preventing was the panGestureRecognizer on the scrollview.
Meaning that when you tap a button in a scrollview, the tapping of the button takes precedence and you won’t be able to scroll because all touches starting in a button would be interpreted as taps.
In addition, I had to create a subclass of UIScrollview and overwrite touchesShouldCancelInContentView: to YES, so that not all touches are no longer sent the button and the scrollview is able to pan.
TL;DR
- User touches screen (ex. drags scrollview).
- Screen finds the view the user touched (i.e. scrollview).
- The view uses any gesture recognizers to process the touch, otherwise handles the touch itself (i.e. scrollview’s panGestureRecognizer).
- Gesture recognizers or the view trigger actions that change what appears on screen (i.e. scrollview moves) or changes the model.
ASCII, Unicode, UTF-8, UTF-16, Latin-1 and why they matter
In iOS, you have a string “hello world”. Most of the time you just need to assign it to a textLabel.text, uppercaseString it or stringByAppendingString it to another string.
If you stop to look under the hood of an NSString, and you have a deep complicated world with a rich history with tales of international conflict, competing standards and a conservation movement.
Why does this matter?
If you ever wondered imported a weird Word document before and seen a page with boxes and ? instead of accented letters, it’s because of encoding.
If you want your website to show up in other languages, you need to understand encoding.
Under the hood of NSString (in Objective-c)
If you want the first letter of an NSString, you can use characterAtIndex:
NSString *exampleString = "Hello world"
unichar c = [exampleString characterAtIndex:0];
You get this unichar.
What’s a unichar?
typedef unsigned short unichar;
It’s a number. For example, c = “H”, 72 represents “H” when your computer uses UTF-16 to translate between numbers and symbol.
What is UTF-16?
Unicode Transformation Format 16-bit
UTF-16 translates between a number and the Unicode symbol that it represents. Each of it’s code units are 16 bits. Some characters use one code unit, some need two.
Example Unicode chart (number under symbols are in base 16, so H = 0048, which is 72).
What is Unicode?
Computers don’t know what an “H” is. We need to tell it how to draw an “H”, so we use numbers to represent the H.
ASCII was an early way of translating between numbers and symbols, but it really basic. It could only represent 127 symbols and you only get numbers and letters and some punctuation. You only needed 7-bits to represent any ASCII symbol.
What happens when you don’t speak English?
ASCII doesn’t let you make accented letters in Spanish and French. So, if you’re trying to read French, it won’t have the accents or won’t show those letter at all. Forget about trying to reach Chinese or Russian because they have completely different characters and ASCII has no idea how to show those characters.
Obviously, people in France and Russia and China wanted their internet to show their native language, so they made systems for translating numbers to symbols too. The hard part was that many of these systems overlapped and only held one or a subset of language. Latin-1 was one of these encoding that had incomplete coverage.
How do we solve this problem?
We need a new system that has all the English characters, all the accents and all the Russian and Chinese characters too and every other possible symbol like emojis. That’s Unicode.
Check out all the code charts.
Does this actually work? Let’s find out
I looked at the Arabic code chart. So what I’m saying is that if you put in the number under any of these Arabic characters into a NSString, then it’ll show up on my screen?
Well yeah. Let’s try it.
Here are three random Arabic characters. Took the hexadecimal under the characters and converted them into numbers (1692, 1693, 1695) and then put them into an NSString with spaces in between on a Swift Playground.
Yay it works! (Arabic is read right to left.) 😎
What’s UTF-8?
Unicode Transformation Format 8-bit. Each code unit is only 8-bits instead of 16. It means that each code unit can only be one of 256 characters (2^8) instead of the 65,536 characters (2^16) you could potentially have with 16 bits. So is less more here?
In English, most of the characters that we use are in the range of 65 (0041 hexadecimal) to 122 (007A hexadecimal). The first 8 bits are always 00, so some people thought it would be a good idea to get rid of them to save space.
In UTF-16, storing “H” in memory requires one 16-bit unit.
In UTF-8, storing “H” requires one 8-bit unit. Your English characters take half as much space.
But what if I need to show our Arabic character above?
You just need more 8-bit units to represent them. In this case, two will do.
It’s really nice to be able to assume that one code unit is one character, but if you make the code unit too small, it means that you need to have more units.
The tradeoff between UTF-8 and UTF-16 is between having code units that are big enough to contain all or most of the characters you need and conserving space.
There’s also UTF-32, where each code unit is 32 bits. You can make any character with one code unit, but for most of your characters you’ll be using up a lot of useless space.
Right now UTF-8 is the de-facto standard on the web at 87.8% of web sites.
What is character encoding all about?
The story of Unicode is a success story of how people came together when faced with a difficult problem of incompatible systems and actually made one system that works for everyone.
This story also shows how connected the world is now that we need to be able to talk to each other in other countries and how the opportunities of the web are accessible to anyone with an internet connection.
Further reading:
Inspiration for biting the bullet and actually figuring this stuff out.
An excellent explanation of how UTF-8 works.
What are Homebrew, RVM, RubyGems, Bundler?
What is Homebrew?
Homebrew helps you easily install and uninstall programs to your computer (a package manager).
Examples: gcc, postgresql, heroku, gnuplot, redis, rbenv, python3, memcached, octave, git
Installing Homebrew
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
into terminal
Installing an application (formula) with Homebrew
brew install <programName>
brew install octave
Update Homebrew
brew update
Update applications with Homebrew
brew upgrade
What is RVM?
It allows you to manage the your ruby environment for each project. This usually means which ruby of version you’re using.
This is useful because you might have an old project that you built with ruby 2.2.1 and they made a change in 2.2.2 that breaks your app and you don’t have the time or can’t fix the problem.
Rbenv is another ruby version manager.
Installing RVM
gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
\curl -sSL https://get.rvm.io | bash -s stable
Looking at the versions of Ruby available
rvm list known
Installing a version of Ruby
rvm install <versionName>
rvm install 2.3.1
Changing the version of Ruby you’re using
rvm use <versionName>
rvm use 2.3.1
Changing the default version of Ruby
rvm use 2.3.1 --default
What is RubyGems?
It’s a package manager for ruby, a programming language. It helps to install, update and uninstall programs that run with ruby which other people have build and you might want to use. RubyGems is called an application level package manager because it’s focused only those programs that run with ruby.
More application level package managers:
- cocoapods and carthage for iOS development using objective-c and swift
- npm for node
- pip for python
- more
Examples of gems: nokogiri, rspec, bundler, rails, rake
Installing RubyGems
It comes with ruby. If gem -v doesn’t provide a number, then download it here.
Installing a gem
gem install <gemName>
gem install bundler
Updating RubyGems
gem update --system
Updating gems
gem update
What is Bundle?
Bundle manages the gems that you need for each project. Bundle is itself a gem. Instead of having to gem install <gemName>, you can add the list of gems you need and it will gem install of them for you.
If you already have the gem, then it doesn’t need to install it again, but it also knows the dependencies for gems you might want to use and will install those for you automatically.
RVM also has “gemsets” which is very similar.
In your project, you should have a Gemfile in the root directory.
It looks like this:
source 'https://rubygems.org' gem '<gemName>' gem '<gemName2>'
Install all the gems in the gemfile
bundle install
Update the version of the gems
bundle update
Update bundler
gem update
Installing Nokogiri
Nokogiri is notorious for being annoying to install because it has a couple dependencies. In 1.6, they tried to add the dependencies to the package so they it would just work. I was out of luck on that.
I found a solution that did work.
gem install nokogiri -v '1.6.8.1' -- --use-system-libraries=true --with-xml2-include=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/usr/include/libxml2
It uses the system libraries and specifies where to find libxml2.
Race conditions, threads, processes, tasks, queues in iOS
What is a race condition?
When you have two threads changing a variable simultaneously. It’s possible to get unexpected results. Imagine a bank account where one thread is subtracting a value to the total and the other is adding a value.
The order of events goes like this:
- Access the total to subtract to it. (total = 500, expense = 40)
- Compute the difference. (total =500, newTotal = 460)
- Save the new total. (total = 460)
- Access the total to add to it. (total = 460, income = 200)
- Compute the sum (total = 460, newTotal = 660)
- Save the new total (total = 660)
Great! 660 is exactly what we expected, but it could have gone like this:
- Access the total to subtract to it. (total = 500, expense = 40)
- Access the total to add to it. (total = 500, income = 200)
- Compute the difference. (total =500, newTotal = 460)
- Save the new total. (total = 460)
- Compute the sum (total = 500, newTotal = 700)
- Save the new total. (total = 700)
So the account is now at 700. That’s not what we expected. Uh oh.
When should we suspect a race condition?
When variables that have multiple threads operating on them and you’re getting unexpected results some of the time.
How do we fix this?
One option is to lock the variable total so that only one thread could operate on it at a time, the lock is called a mutex.
But in iOS, you want to use grand central dispatch (GCD) or OperationQueues to handle your tasks. So in the example of the bank total, we’d probably just want to use a serial dispatch queue which has sole access to the total variable. By using GCD or OperationQueues, you’re letting Apple do the thread management and removing the code for locking. Less code is good.
So what are threads, processes and tasks?
The task is an abstract concept for describing something you want to do. In the example above, adding money to the total or subtracting money from the total are both tasks. They use a process to actually affect the change in code.
A process keeps track of what needs to be done and delegates the tasks to the threads. A process can have one or multiple threads. The process is like a project manager and the thread is like a worker.
What’s the difference between hardware and software threads?
The threads we’ve been talking about so far have been software threads. They’re (generally) independent units of computation.
The hardware threads are based on the number of cores on the computer. For example, the current 12 inch MacBook has this processor with a 1.1GHz two-core processor. That means it have 2 cores, each with 1.1GHz of clock speed. Each of those core have two 2 hardware threads, so there are 4 hardware threads total.
Each of these hardware threads can run many software threads, depending on how the operating system uses them.
What’s the best Python IDE for beginners?
What I’m looking for:
- Good autocomplete tools and maybe debugging
- Short term use, therefore low cost
- Modern interface
A lot of people on Quora say Pycharm is really good ($89 a year for individual; $199 for organization; monthly plans $9).
As an iOS developer, I was interested to learn that Xcode works with Python too. You just have to do some configuration.
As a beginner with lower requirements, it seems like Komodo Edit (free) or a text editor like Sublime Text ($70) or Textmate (free) would also work.
Order for trying
- Komodo Edit
- Sublime Text or Textmate
- Pycharm
- Xcode
References:
https://www.quora.com/What-is-the-best-free-Mac-Python-IDE-for-a-beginner
https://www.quora.com/What-is-the-best-IDE-for-Python
http://stackoverflow.com/questions/5276967/python-in-xcode-7
What can we learn from Pokemon Go about designing incentive systems?
Last time I looked at why Pokemon Go is fun. Here’s what we can learn from it’s game mechanics.
What can we learn from Pokemon Go about designing incentive systems?
Start with why. Give people a purpose.
“I want to be the very best, like no one every was. To catch them is my real test, to train them is my cause.”
-Pokemon Theme Song
Clear purpose established. Being the best means beating other people in battle at these gyms or collecting all the Pokemon.
Give simple instructions for how to achieve their purpose.
They need strong Pokemon, how do they get those?
- Walk around
- Catch Pokemon
- Train them
- Bring your pokemon to battle other teams at gyms
Ok, it’s a little more complicated than that, but here are the different paths that you can take towards becoming the best. It involves a lot of walking and waiting. It’s a lot like fishing actually.
Make it advantageous to recruit their friends to help them.
This is way more fun when you do it with friends. It’s like you’re going on an epic adventure and you’re probably going to need a team to beat the other team at the gym.
People like being part of teams. Teams provide identity, belonging and purpose.
What draws people into the game?
Friends
I found out of about the game from a friend, who found out from their Facebook feed.
Nostalgia
To many people, Pokemon bring back fond memories of spending hours playing a fun game.
Low time commitment
It’s easy to get into because the game doesn’t take much time to play.
Novelty and quick progress
At first, everything you catch is new and leveling up is pretty fast.
Mystery
The game doesn’t teach you how to play it. It makes you feel special when you learn it’s secrets and share it with your friends.
What keeps people in the game?
Friends / News
Even if you managed for forget, new people discovering the game and posting it on Facebook sucked you back in. Just walking by Central Park, you can see lots of people standing around and playing at night, which makes you want to play the game.
Random rewards
There’s been research done by psychologist who showed that random rewards reinforced behaviors the most. Randomness is everywhere in the game: catching pokemon, which pokemon appear, what pokemon hatch from your eggs, what items you get from pokestops.
Progress bars
In the game, there’s progress bars for everything to show you how you’re doing and how far you are from completing the next challenge. Trainer level, egg hatching, pokedex, and candies needed to evolve. As you progress through the game, things get harder but not so hard that you can’t handle them. It kind of puts the blinders on you like a horse and keeps you focused on what’s straight ahead. Playing the game is easy. In life, you have to make your own progress bars and it’s not nearly as clear cut and you also have to know where to go.
Competition / Glory / Honor (“My life for Aiur” mentality)
At the higher levels of the game, it really comes down to making a better pokemon than everyone else and showing them off at the gym, which are like leaderboards. Rarer pokemon tend to have higher power caps, so that incentives people to go off the beaten path. The game gives gyms proment positioning and makes taking over enemy gyms easier by giving you six pokemon to use. This gives everyone a chance at holding the hill and feel the glory of winning.
What makes people quit?
The game keeps freezing
*Ragequit*
My ears keeps freezing
No one wants to walk around when it’s 30 degrees outside.
The virus harms the host
If you think of Pokemon Go as a virus, anyone who’s played pandemic would know that you don’t want to kill the host too quickly because it’s able to be spread to another person. In this case, if the game starts to take over too much time, people will stop.
People get bored
After you’ve caught most of the common Pokemon, you have to go out of your way to catch more, which might not be worth the effort. Then progress is slow to level up or catch Pokemon and people will get bored.
The competition gets serious
Horseraces aren’t fun if you’re way in the back, so once the gyms get to a high enough level, it becomes discouraging because you’re comparing yourself to others and you feel bad each time.
The competition isn’t fair
No one likes being part of a rigged system, whether that’s Pokemon or the economic system. Right now, the items in the game give people advantages, but most of them still require the user to commit a lot of time to getting results. If you can start trading or buying Pokemon, it might spell the end as people with more money can just buy what they want and people who grind through the game feel cheated. Part of the promise of the Pokemon theme song is that any 10 year old kid can become a Pokemon master. It’s like the American dream. If you walk around long enough, wait long enough, you will get your reward. That dream should not just be for the 10 year old kid with rich parents.
What makes Pokemon Go so fun?
Pokemon Go has been blowing up this week. As a product manager, I like to figure out what make products great, so here’s what’s I like about Pokemon Go.
What makes Pokemon Go so fun?
Pokemon Go is nostalgic because it fulfills the childhood dream of actually being a Pokemon trainer, except now we’re adults so we can go whereever we want and we have no curfew. Attributing it’s success to just nostalgia is oversimplifying and not recognizing that it addresses real psychological needs.
It turns an ordinary walk into a chance to catch a rare pokemon, an epic triumph. Much of life is routine and drudgery. This turns ordinary moments into potentially exciting ones.
It gives clear direction for how to be the very best in an otherwise open-ended world. A lot of young ambitious people want to be the best, but what the best means and how you get there are ambiguous. Pokemon Go is easy because it has answered those questions for you. Religion has a lot of value to a lot of people because it provides an organizing view of the world. It tells you what to do and tells you how to do it.
It shows progress in a world where you often don’t have a clear measure of progress. How often do you know for sure how well you’re doing in your job or your relationships. These are difficult cognitively taxing questions. If only life had progress bars too.
It helps break down walls between us and strangers on the street. In New York, standard protocol is not to talk to people on the street. This game is an easy way to connect people in the same way that sports teams are fodder for small talk.
It makes me walk even more. I already walk 5 miles a day, but now I walk 20% more.
It gives people a fun casual activity to do with friends at any time that doesn’t (necessarily) involve going to a bar. When you friends what they want to do, the first two things that come up are going to a bar or a having dinner. Museums are great, but there just aren’t that many things you can do at night. It’s addressing a real hole in the nightlife scene for people who don’t want to go to bars.
For these benefits, what does it cost me to play this game?
It’s not a big time commitment because you actually have to walk places to play the game and I mostly play it as I’m already walking to places.
Sure, my phone will die faster (so I bring a battery).
I have to recognize that games like this are meant to be addictive. Even if you’re not playing the game, it may affect how you experience other pleasures. In the brain, connections that are used more often are strengthened. If you spend too long getting most of your enjoyment from one source that may crowd out other enjoyable things.
The mind share is the biggest cost to playing the game. Just like how I only drink with friends, maybe it’s best to only play Pokemon Go with friends. And for goodness sake, pay attention when you’re crossing the street. #priorities