trigonometric ratios

tan, sin, cos
e.g. tanα = 231 /266

using angle table
534.6m, 401.0m

length of bar = 1.00m, length of shadow = 0.126m, α = 7.2°

Eratosthenes vs Reality
try out in Google
cos(44 degrees) = 0.7193319

reverse tangent -> arctan(0.932) in degrees -> 42.98
sin(30 degree) = 0.5
tan(79 degree) = 5.14
arcsin(0.62) in degrees = 38.32°
arctan(4/7) in degrees = 29.74°
arctan(1/40) in degrees = 1.42°

α = 7.2°+- 1.4°
αmin = 5.8°, C = 57,400km
αmax = 8.6°, C = 46,250km

Landmark of physics

Eratostheness

How long the earth’s circumstance?
Geometry sun’s position

Plato “The earth’s circumference is 400,000 stadia.”
≒ 74,000
1 stadium = 185m

True Circumference is 40,000 Km
Plato’s guess was 85% larger than the true circumference.

Archimedes: circumference of Earth is 300,000 stadia
Archimedes: Look at the geometry of a sphere and find a clever way to calculate the circumference

Delegation

AVAudioRecorder
Record VC

func audioRecorderDidFinishRecording(_ recorder: AVAudioRecorder, successfully flag: Bool){
	if flag {
		performSegue(withIdentifier: "stopRecording", sender: audioRecorder.url)
	} else {
		print("recording was not successful")
	}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?){
	if segue.identifier == "stopRecording"{
		let laySoundsVC = segue.destination as! PlaySoundsViewController
		let recordedAudioURL = sender as! url
		playSoundVC.recordedAudioURL = recordedAudioURL
	}
}

Stack Views: Horizontal, Vertical
-alignment, distribution, spacing

AVAudioEngine

var dollars:Int = 10
var cents:Int = 50
var amount = "$\(dollars).\(cents)"
print(amount)

dollars = 19
centsd = 99
amount = "$\(dollars).\(cents)"
print(amout)

func printMoneyString(dollars:Int, cents:Int){
	print("$\(dollars).\(cents)")
}

Tour of Xcode

Document Outline in Xcode

Model View Controller
view(UIView, UILabel, UIButton), controller, model

AutoLayout Basics

@IBOutlet weak var recordButton: UIButton!
@IBOutlet weak var recordingLabel: UILabel!
@IBOutlet weak var resumeButton: UIButton!
@IBOutlet weak var resumeLabel: UILabel!
@IBOutlet weak var pauseButton: UIButton!
@IBOutlet weak var pauseLabel: UILabel!
@IBOutlet weak var stopButton: UIButton!
@IBOutlet weak var stopLabel: UILabel!

@IBOutlet func recordButtonPressed(sender: UIButton){
	// ...
}

ViewController and Multiple Views
Not Running, Inactive, Active, Background, Suspended

Audio in iOS
Pitch Perfect App, AVFoundation, Core Audio, Audio Hardware

import AVFoundation

class ViewController: UIViewController {
	var audioRecorder: AVAudioRecorder!

	@IBAction func recordAudio(_ sender: AnyObject){
		recordingLabel.text = "Recording in progress"
		stopRecordingButton.isEnabled = true
		recordButton.isEnabled = false

		let dirPath = NSSearchPathForDirectoriesInDomains(.documentDirectory,.userDomainMask, true)[0] as String
		let recordingName = "recordedVoice.wav"
		let pathArray = [dirPath, recordingName]
		let filePath = URL(string: pathArray.joined(separator: "/"))

		let session = AVAudioSession.sharedInstance()
		try! session.setCategory(AVAudioSessionCategoryPlayAndRecord, with:AVAudioSessionCategoryOptions.defaultToSpeaker)

		try! audioRecorder = AVAudioRecorder(url: filePath!, settings: [:])
		audioRecorder.isMeteringEnabled = true
		audioRecorder.prepareToRecord()
		audioRecorder.record()
	}
}

Introduction X-code

import UIKit

var x: Int = 42
var x = 42
let y = 100

var myString = "Hello"

// Control Flow
if x < 50 {
	print("X is less than 50")
} else {
	print("X is greater than or equal to 50")
}

// Classes
class ViewController: UIViewController {
	// Instance Variables go here
	// Class functions go here
}

// Functions
func printHello(){
	print("Hello")
}

printHello()

func printHelloMessage(helloString: String){
	print(helloString)
}

printHelloMessage("Oi!")

Create the Empty View

<red lines>
	<!-- Empty view for the list -->
	<RelativeLayout
		android:id="@+id/empty_view"
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:layout_centerInParent="true">

		<ImageView
			android:id="@+id/empty_shelter_image"
			android:layout_width="wrap_content"
			android:layout_height="wrap_content"
			android:layout_centerHorizontal="true"
			android:src="@drawable/ic_empty_shelter" />

		<TextView
			android:id="@+id/empty_title_text"
			android:layout_width="wrap_content"
			android:layout_height="wrap_content"
			android:layout_below="@+id/empty_shelter_image"
			android:layout_centerHorizontal="true"
			android:fontFamily="sans-serif-medium"
			android:paddingTop="16dp"
			android:text="@string/empty_view_title_text"
			android:textAppearance="?android:textAppearanceMedium" />

		<TextView
			android:id="@+id/empty_subtitle_text"
			android:layout_width="wrap_content"
			android:layout_height="wrap_content"
			android:layout_below="@+id/empty_title_text"
			android:layout_centerHorizontal="true"
			android:fontFamily="sans-serif"
			android:paddingTop="8dp"
			android:text="@string/empty_view_subtitle_text"
			android:textAppearance="?android:textAppearanceSmall"
			android:textColor="#A2AAB0">
	</RelativeLayout>

Using a CursorLoader
Activity -> LoaderCallbacks -> onCreate() ->getLoaderManager().initLoader()->onCreateLoader() -> onLoadFinished() swapCursor(cursor -> onLoaderReset() swapCursor(null)

CursorAdapter

ArrayAdapter
Data source: ArrayList of words
Data source: Cursor of pets

public class PetCursorAdapter extends CursorAdapter {

	public PetCursorAdapter(Context context, Cursor c){
		super(context, c, 0);
	}

	public view newView(Context context, Cursor c, ViewGroup parent){
		// create and return new blank list item
	}

	public void bindView(View view, Context context, Cursor c){
		// Populate list item view with pet data
	}
}

ContentProvider Update()

public class PetProvider extends ContentProvider {

	...

	@Override
	public int update(Uri uri, ContentValues contentValues, String selection,
		String[] selectionArgs){
		final int match = sUriMatcher.match(uri);
		switch (match){
			case PETS:
				return updatePet(uri, contentValues, selection, selectionArgs);
			case PET_ID:
				selection = PetEntry._ID + "=?";
				selectionArgs = new String[] { String.valueOf(ContentUris.parseId(uri))};
				return updatePet(uri, contentValues, selection, selectionArgs);
			default:
				throw new IllegalArgumentException("Update is not supported for " + uri);
		}
	}
}

Implement ContentProvider

public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
		String sortOrder){
	SQLiteDatabase database = mDbHelper.getReadableDatabase();

	Cursor cursor;

	int match = sUriMatcher.match(uri);
	switch(match){
		case PETS:
			// 
			break;
		case PET_ID:
			selection = PetEntry._ID + "=?";
			selectionArgs = new String[] { String.valueOf(ContentUris.parseId(uri))};
			cursor = database.query(PetEntry.TABLE_NAME, projection, selection, selectionArgs,
				null, null, sortOrder);
			break;
		default:
			throw new IllegalArgumentException("Cannot query unknown URI " + uri);
	}
	return cursor;
}
public class PetProvider extends ContentProvider {

	@Override
	public Uri insert(Uri uri, ContentValues contentValues){
		final int match = sUriMatcher.match(uri);
		switch (match){
			case PETS:
				return insertPet(uri, contentValues);
			default:
				throw new IllegalArgumentException("Insertion is not supported for " + uri);
		}
	}

	private Uri insertPet(Uri uri, ContentValues values){
		return ContentUris.withAppendedId(uri, id):
	}
}
private Uri insertPet(Uri uri, ContentValues values){
	String name = values.getAsString(PetEntry.COLUMN_PET_NAME);
	if (name == null){
		throw new IllegalArgumentException("Pet requires a name");
	}

	SQLiteDatabase database = mDbHelper.getWritableDatabse();

	long id = database.insert(PetEntry.TABLE_NAME, null, values);
	if (id == -1){
		Log.e(LOG_TAG, "Failed to insert row for " + uri);
		return null;
	}

	return ContentUris.withAppendedId(uri, id);
}