Has_many: Through: Source:

Here’s a very simple model of Employee and her/his family

class Employee < ActiveRecord::Base
  has_many: :families
end

class Family < ActiveRecord::Base
  belongs_to: :employee
end

Now if I wanted to add a Company to which employees belong, so that I can invite all the family members of a company’s employees

class Employee < ActiveRecord::Base
  has_many: :families
  belongs_to: :company
end

class Family < ActiveRecord::Base
  belongs_to: :student
end

class Company < ActiveRecord::Base
  has_many: :employees
  has_many: :employee_families, :through => :employees, :source => :families
end

:employee_families is a name I would like to use in Company to refer to all the family members of a company’s employees. Employee class doesn’t have any :employee_families association on it, so I need to define it inside Company using :source => :famlies.

This provides context to :families. For example, an employee has families: @employee.families. If I wanted to get all the family members of a company’s employees, i can do something like this: @company.employees.families. This is same as @company.employee_families.

Another example. This time it’s a self-referential association. Let’s say I want to create a Twitter clone. A User follows another User.

class Relationship
  belongs_to: :followed, class_name: :User
  belongs_to: :follower, class_name: :User
end

class User
  has_many: :relationships, foreign_key: :followed_id
  has_many: :followed_users, through: :relationships, source: :followed

  has_many: :reverse_relationships, foreign_key: :follower_id
  has_many: :follower_users, through: :relationships, source: :follower
end

In this case, depending on what I specify as source: it can mean entirely different things, since User can play two different roles: followed and follower.

Rails 4

puts vs. print

  • puts : prints a string, followed by newline
  • print : prints a string, no newline

Ruby help

Coffeescript

Basic rules

  • Uses whitespace to delimit blocks of code
  • {} Instead, use indentation.
  • () implicit call wraps forward to the end.
    • console.log sys.inspect object is same as console.log(sys.inspect(object));

1. Function

Function with an argument

square = (x) -> x*x

Function without an argument

helloWorld = -> console.log "Hello World"

Implicit return

# returns the last command
do = (action) ->
    "Let's do #{action}"

Default argument

# default argument is 'nothing'
do = (action = 'nothing') -> 
    "Let's do #{action}"

2. Arrays

Same syntax as javascript

arr = ["this", "is", "an", "array"]

Array items can be separated by lines instead of commas

arr = [
    "this"
    "is"
    "an"
    "array"
]

Slicing Array

numbers = [1,2,3,4,5,6,7,8,9]

# Two dots mean it includes the last index
# In this case, start is [1,2,3]
start = numbers[0..2]

# Three dots mean it excludes the last index
# In this case, middle is [4,5]
middle = numbers[3...6]

# Omitted first index implies 0
# In this case, end is [7,8,9]
end = numbers[6..]

# Omitted last index implies the length of the array
# In this case, copy is [1,2,3,4,5,6,7,8,9]
copy = numbers[..]

Array membership

in is used to test membership in an array

1 in [1,2,3,4]
# returns true

3. String

Multiline strings are allowed.

mobyDick = "Call me Ishmael. Some years ago --
    never mind how long precisely -- having little
    or no money in my purse, and nothing particular
    to interest me on shore, I thought I would sail
    about a little and see the watery part of the
    world..."

Block strings for preserving indentation

html = """
        <strong>
                cup of coffeescript
        </strong>
        """

Block comments

###
This is a comment
###

2. Objects

Same syntax as javascript

obj = {name: "this is an object", language: "english"}

Object items can be written like YAML, without the braces

obj = 
    name: "this is an object"
    language: "english"

Object Membership

"john" in {john: 1, mary: 2, susan:3}
# returns true

3. Lexical Scoping

Everything is naturally declared within lexial scope

outer = 1
change = ->
    inner = -1
    outer = 10
inner = change()

Immediately Invoked Function

do is used to immeidately invoke a function in order to make sure variables are closed over. For example:

do (x) -> x*x

is same as:

(function(x){
    return x * x;
}());

Also, there is no global variable. If I really want to use window level global variable, I need to explicitly say it.

window.globalVariable = 1

4. Conditionals

if sexy and iKnowIt
    wiggle()
    wiggle()
else
    workOut()

postfix IF

singing = true
mood = "good" if singing

IF + THEN

date = if friday then sue else jill
# same as
# friday ? sue : jill;

Switch

  • case: in javascript translates to when + then
  • default in javascript translates to else in the end switch day when “Mon” then go work when “Tue” then go relax when “Thu” then go iceFishing when “Fri”, “Sat” if day is bingoDay go bingo go dancing when “Sun” then go church else go work

5. Loops

Comprehensions instead of Loops

Comprehensions are like for loops but is an expression, which can be passed around

# Iterating through an array and returning squares
square = (x) -> x*x
square(x) for x in [1,2,3,4,5]

# Adding two values
counter = (x,y) -> x + " is number " + y
counter(x, index) for x, index in ["John", "Mary", "Susan", "Ethan"]

# Using conditionals with comprehensions #1
square = (x) -> x*x
square(x) for x in [1,2,3,4,5] when x > 2

# Using conditionals with comprehensions #2
counter = (x,y) -> x + " is number " + y
counter(x, index) for x, index in ["John", "Mary", "Susan", "Ethan"] when x isnt "John"

Comprehension for objects

Use of intead of in

children = John:1, Mary:2, Susan:3, Ethan:4
"#{child} is #{age}" for child, age of children

While loop

While loop in Coffeescript can be used as an expression. Which means it as a return value. For example:

num = 6
lyrics = while num -= 1
  "#{num} little monkeys"

In this cas,e lyrics is “1 monkeys”

The above code is same as:

num = 6
lyrics = "#{num} little monkeys" while num -= 1

6. Misc

Logic

or is same as ||

and is same as &&

not is same as !

on is same as true

yes is same as true

off is same as false

no is same as false

is is same as ===

isnt is same as !==

Instance variable

@property is same as this.property

Existential ?

Just add ? to a variable to check if it’s not null and not undefined

mindless = true if not mind?

7. Class

Class declaration

class Animal
    constructor: (name) -> 
        @name = name        # assigning to instance variable
    move: (meters) ->
        alert @name + "{meters}m."
    price: 5        # instance variable

Class inheritance

  • extends is used for inheritance
  • super is used for calling its super class method class Snake extends Animal move: –> alert “slithering…” super 5

Instantiating a class

sam = new Snake "Sammy the Python"

Accessing prototype

String::dasherize = ->
      this.replace /_/g, "-"

in javascript, it would look like this:

String.prototype.dasherize = function() {
    return this.replace(/_/g, "-");
};

8. Destructuring assignment

Basically it’s a feature where an assignment can extract out values from right to left.

A. Array assignment

weatherReport = (location) -> [location, 72, "Mostly Sunny"]
[city, temp, forecast] = weatherReport "Berkeley, CA"

B. Object assignment

Here’s a basic usage:

drink = name: 'coffee', caffeine: true
{name: name, caffeine, caffeine} = drink
# At this point, 'name' is "coffee", and "caffeine" is true

We can even go shorter. no need to do the redundant {name: name, caffeine: caffeine}

drink = name: 'coffee', caffeine: true
{name, caffeine} = drink
# At this point, 'name' is "coffee", and "caffeine" is true

It doesn’t matter how deep we go, it still manages to extract the relevant fields

kid = name: 'John', age: 12, address: { city: 'San Francisco', state: 'CA' }
{ address: { city, state } } = kid
# This resluts in 'city' being assigned as 'San Francisco', and 'state' being assigned as 'CA'

Destructuring is also useful for class initialization

class Person
    constructor: (options) -> {@name, @age, @height} = options

9. Context binding

=> (fat arrow) is used instead of -> (normal arrow)

A. When thin arrow “–>” is wrong

For example, this is wrong, because “this” inside the click callback is the button object.

class Counter
    constructor: ->
        @count = 0
        $("button").click(e) ->
            @count++

In javascript it’s same as doing:

var Counter = function(){
    this.count = 0;
    $("button").click(function(e){
        this.count++;
    });
};

B. Fat arrow “=>” to the rescue

Instead, the click callback should use fat arrow, like this

class Counter
    constructor: ->
        @count = 0
        $("button").click(e) =>
            @count++

In javascript it’s same as doing:

var Counter = function(){
    this.count = 0;
    _.bind($("button").click(function(e){
        this.count++;
    }), this);
};

CMTime: How Time Is Represented in AVFoundation

CMTime

How is CMTime structured?

CMTime is a C structure that represents time using

  1. Numerator (int64_t)
  2. Denominator (int32_t)

Example

// time1 and time2 both represent 100 seconds, but using different timescales.
CMTime time1 = CMTimeMake(200, 2); // 200 half-seconds
CMTime time2 = CMTimeMake(400, 4); // 400 quarter-seconds

Special CMTime constants

  • kCMTimeZero
  • kCMTimeInvalid
  • kCMTimePositiveInfinity
  • kCMTimeNegativeInfinity

Special CMTime constant testers

  • CMTIME_IS_INVALID
  • CMTIME_IS_POSITIVE_INFINITY
  • CMTIME_IS_INDEFINITE

    CMTime myTime = CMTimeMake(200, 2); if (CMTIME_IS_INVALID(myTime)) { NSLog(@“Error”); }

CMTimeRange

How is CMTimeRange structured?

  1. Start time (CMTime)
  2. Duration (CMTime)

Example

CMTime time1 = CMTimeMake(200, 2);
CMTime time2 = CMTimeMake(400, 4);
CMTimeRange range = CMTimeRangeMake(time1, time2)

Testing for inclusion

CMTimeRangeContainsTimeRange(range, CMTimeRangeGetEnd(range));
// This is false

CMTimeRange special constants

  • kCMTimeRangeZero
  • kCMTimeRangeInvalid

CMTimeRange special constant testers

  • CMTIMERANGE_IS_VALID
  • CMTIMERANGE_IS_INVALID
  • CMTIMERANGE_IS_EMPTY
  • CMTIMERANGE_IS_EMPTY

How Is AVAsset Structured?

Types of AVAsset

  1. AVComposition: new media by composing multiple media
  2. AVURLAsset: media at a given URL

Types of AVAsset

AVAsset components

  1. AVMetaDataItem: metadata about the asset as a whole, such as duration, title, size, etc.
  2. AVAssetTrack: separate tracks that add up to the entire asset, such as video, audio, etc.
  3. AVAssetTrack in turn can be composed of AVAssetTrackSegment, which is a mapping from a source to the current track timeline.

AVAsset components

Core Image

Drawing With Core Graphics and Quartz2D

Various Quartz2D inititalization

Get the current view’s context

Each view has its own drawing context. Let’s first get the context.

CGContextRef graphics_context = UIGraphicsGetCurrentContext();

Generate color

// Create colorspace (In this case, RGB space)
CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();

// Set up RGB constant
CGFloat components[] = {0.0, 0.0, 1.0, 0.5};

// Create CGColorRef using the colorspace and the RGB variable from above
CGColorRef color = CGColorCreate(colorspace, components);

// When done with using the color, let it go
CGColorRelease (color);

// After done using the colorspace
CGColorSpaceRelease(colorspace);

When do I use UIColor with CGColorRef?

UIColor has lots of convenience methods such as:

[UIColor redColor]

So instead of going through all the tedious RGB specification, we can just create a [UIColor redColor] and then convert it to CGColor, and then use it to set context

CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);

UIColor avoids the necessity to create colorspaces and components when working with colors.

Let’s actually do some drawing!

1. Create a UIView

Just create a project with a UIView

2. Modify drawRect:

Drawing lines

- (void)drawRect:(CGRect)rect {
    // 1. Get context
    CGContextRef context = UIGraphicsGetCurrentContext();

    // From here, set the context's attributes

    // 2. Set Line Width
    CGContextSetLineWidth(context, 5.0);

    // 3. Set Stroke Color 
    CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
    CGFloat components[] = {0.0, 0.0, 1.0, 1.0};
    CGColorRef color = CGColorCreate(colorspace, components);
    CGContextSetStrokeColorWithColor(context, color);

    // 4. Move context's point
    CGContextMoveToPoint(context, 0, 0);

    // 5. Draw line from point to another point
    CGContextAddLineToPoint(context, 150, 150);
    CGContextAddLineToPoint(context, 100, 200);
    CGContextAddLineToPoint(context, 50, 150);
    CGContextAddLineToPoint(context, 100, 100);

    // 6. Actually "stroke" to draw
    CGContextStrokePath(context);

    // 6. Memory release
    CGColorSpaceRelease(colorspace);
    CGColorRelease(color);
}

Drawing rectangle

- (void)drawRect:(CGRect)rect {
    // 1. Init
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetLineWidth(context, 4.0);
    CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);

    // 2. Create CGRect area
    CGRect rectangle = CGRectMake(60,170,200,80);

    // 3. Add rectangle region to the context
    CGContextAddRect(context, rectangle);

    // 4. Actually "stroke" to draw
    CGContextStrokePath(context);
}

Drawing an ellipse

- (void)drawRect:(CGRect)rect {
    // 1. Init
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetLineWidth(context, 4.0);
    CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);

    // 2. Create CGRect area
    CGRect rectangle = CGRectMake(60,170,200,80);

    // 3. Add ellipse inside the CGRect in context
    CGContextAddEllipseInRect(context, rectangle);

    // 4. Actually "stroke" to draw
    CGContextStrokePath(context);
}

Drawing an arc

- (void)drawRect:(CGRect)rect {
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetLineWidth(context, 4.0);
    CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);

    // 1. Set begin point
    CGContextMoveToPoint(context, 100, 100);

    // 2. add arc to context
    CGContextAddArcToPoint(context, 100,200, 300,200, 100);

    // 3. stroke the context
    CGContextStrokePath(context);
}

Drawing an UIImage without scaling

- (void)drawRect:(CGRect)rect {
  // 1. Get UIIMage
  UIImage *myImage = [UIImage imageNamed:@"img.jpg"];

  // 2. Start point is (0,0)
  CGPoint imagePoint = CGPointMake(0, 0);

  // 3. Just add the image at (0,0)
  [myImage drawAtPoint:imagePoint];
}

Drawing an UIImage with scaling

- (void)drawRect:(CGRect)rect {
    // 1. Get UIImage
    UIImage *myImage = [UIImage imageNamed:@"pumpkin.jpg"];

    // 2. Get CGRect dimension for the entire screen
    CGRect imageRect =[[UIScreen mainScreen] bounds];

    // 3. Draw inside the CGRect
    [myImage drawInRect:imageRect];
}

Opaque Types in Objective-c

What is an Opaque type?

  • a type that wraps lower-level types
  • used when
    • the underlying implementation is complex
    • the user does not need to know about the inner workings.
  • The individual fields of an object based on an opaque type are hidden from clients, but the type’s functions offer access to most values of these fields

A. Opaque types in Core Foundation

Core foundation has many “opaque types’.

What is Core Foundation?

Core Foundation is a library with a set of programming interfaces conceptually derived from the Objective-C-based Foundation framework but implemented in the C language.

1. Makes it possible for the different frameworks and libraries on OS X to share code and data.

Applications, libraries, and frameworks can define C routines that incorporate Core Foundation types in their external interfaces; they can thus communicate data—as Core Foundation objects—to each other through these interfaces.

2. Makes some degree of operating-system independence possible

Some Core Foundation types and functions are abstractions of things that have specific implementations on different operating systems.

3. Supports internationalization with Unicode strings

Uses CFString, instances of which represent an array of 16-bit Unicode characters. Flexible enough to hold megabytes worth of characters and yet simple and low-level enough for use in all programming interfaces communicating character data

Opaque type examples in Core Foundation

  • CFString: an opaque type that “represents” and operates on Unicode character arrays.
  • CFArray: an opaque type for indexed-based collection functionality.

B. Opaque types in Quartz2D

  • CGPathRef: vector graphics
  • CGImageRef: bitmap images
  • CGLayerRef: drawling layer that can be used for repeated drawing and offscreen drawing
  • CGPatternRef: repeated drawing using patterns
  • CGShadingRef: for gradients
  • CGGradientRef: for gradients
  • CGColorRef: used for colors in Quartz2D
  • CGImageSourceRef: move data into and out of Quartz
  • CGFontRef: to draw text

Drawing on iOS

Quartz2D:

  • Two dimensional graphics drawing engine that makes up the bulk of the UIKit Core Graphics Framework.
  • C based API
  • Typically used on UIView object
  • Features
    • path-based drawing
    • painting with transparency
    • shading, drawing shadows
    • transparency layers
    • color management
    • anti-aliased rendering
    • PDF document generation
    • PDF metadata access
  • Works with other technologies like
    • Core Animation
    • OpenGL ES
    • UIKit

How Quartz2D works

  • Painter’s model:
    • each successive drawing operation applies a layer of “paint” to an output “canvas”
    • the drawing can be modified by overlaying more paint
  • The canvas can be:
    • PDF
    • Bitmap image
    • Printer

Graphics context (the “canvas”)

CGContextRef is the drawing destination. It can be: Window, Layer, Bitmap, PDF, Printer, etc. – No need to perform device-specific calculations. Quartz takes care of it.

Type of contexts

  1. Bitmap graphics context: rectangular array (or raster) of pixels
  2. PDF graphics context
  3. PDF files, unlike bitmaps, may contain more than one page.
  4. Drawing a page from a PDF file on a different device results in the image being optimized for the display characteristics of that device.
  5. Window graphics context
  6. Layer context: CGLayerRef is an offscreen drawing destination associated with another graphics context.
  7. PostScript graphics context: for printing

Graphics state

What is a Graphic state?

  • color
  • line width
  • current position
  • text font size

Graphics context maintains a stack of Graphic states

When context is created, the stack is empty. When i save a context, the current state is pushed to the stack – CGContextSaveGState pushes the current context onto stack – CGContextRestoreGState pops the stack to restore previous context

Quartz2D Coordinate systems

How Quartz2D achieves Device independent representation

uses a separate coordinate system (user space), mapping it to the coordinate system of the output device (device space), using the current transformation matrix (CTM). – CTM: affine transform matrix – maps points by applying translation (move), rotation (rotate), and scaling (resize) operations. – to draw a box 45 degrees rotated, rotate CTM first and then draw inside the box.

Origin (0,0) is bottom-left corner.

Quartz2D coordinate system This is different from some other drawing coordinate systems – UIView: top-left corner is (0,0) – to switch, apply a transform that translates the origin to the upper-left corner of the PDF context and scales the y-coordinate by -1. – However, if you use a UIImage object to wrap a CGImage object you create, no need to modify the CTM.

Modifying the coordinate system

CGImage vs. CIImage vs. UIImage

UIImage

  • From UIKit
  • a high level way of displaying image data.
  • Not mutable
  • Just displaying the image

CGImage

  • From Core Graphics
  • Can cut out areas of the image