2019年6月10日 星期一

Enumeration 列舉

enum SomeEnumeration{
    //成員
}
//定義enum
enum CompassPoint{
    case north
    case south
    case east
    case west
}
//定義enum時,指定資料類型Int,會給予成員rawValue,從0開始
enum Planet:Int{
    case mercury, venus, earth, mars, jupiter, ssturn, uranus, neptuneㄤ;
}
print(Planet.earth.rawValue)
//實作
var directionToHead:CompassPoint = CompassPoint.west
directionToHead = .east
//directionToHead = .south
//利用switch檢查
switch directionToHead {
case .north:
    print("north");
case .south:
    print("south");
case .east:
    print("east");
case .west:
    print("west");
}
//let button = UIButton(type:UIButton.ButtonType.infoLight);
let button = UIButton(type: .infoLight);
//建立可以被for in的列舉,一定要有CaseIterable,CaseIterable:可重複使用
enum Beverage:CaseIterable{
    case coffee, tea, juice
}
//allCases:Enumeration內的所有case
print(Beverage.allCases.count)
for beverage in Beverage.allCases{
    print(beverage)
}

2019年6月3日 星期一

fuction

定義function
func 自訂func名稱(參數1:資料類型, 參數2:資料類型, 參數3:資料類型) -> 傳出值資料類型{
    code
    return type
}
參數可以省略,return type也可空白!
呼叫function
let 接收物 = 自訂func名稱(引數1, 引數2, 引數3)

func greet(person:String) -> String {
    let greeting = "Hello, " + person + "!";
    return greeting
}
print(greet(person: "Anna"));
print(greet(person:"Brian"));

func greetAgain(person: String) -> String {
    return "Hello again, " + person + "!"
}

print(greetAgain(person: "Anna"));

global Function:
apple 定義,使用者只呼叫

func greet(person:String) -> String{
    let greeting = "Hello, " + person +"!";
    return greeting;
}
func greetAgain(person:String) -> String{
    return "Hello again, " + person +"!";
}
//function 沒有參數
//function 有傳出,就一定要有return!
func sayHelloWorld() -> String {
    return "Hello, World";
}
//function 有多個參數
//function名稱相同,但參數名稱不同,或參數名稱相同,但參數的數量不同,皆視為不同的function
func greet(person:String, alreadyGreeted:Bool) -> Stringh{
    if alreadyGreeted {
        return greetAgain(person: String);
    }
}
print(greet(person: "Tim", alreadyGreeted: true));

//function 沒有return值
//func greet(person:String) -> Void { },-> Void:表示沒有傳出值!
func greet(person1:String){
    print("Hello, \(person1)");
}
func printAndCount(string:String) -> Int{
    print(string);
    return string.count;
}
func printWithoutCounting(string:String){
    let _ = printAndCount(string:string);
}
printWithoutCountin(string: "Hello, World!");

//利用tuple傳出多個值
func minMax(array:[Int]) -> (min:Int,max:Int){
    var currentMin = array[0];
    var currentMax = array[0];
    for value in array[1..<array.count]{
        if value < currentMin{
            currentMin = value;
        } else if value > currentMax{
            currentMax = value;
        }
    }
    return (currentmin,currentMax);
}
let bounds = minMax(array: [8, -6, 2, 109, 3, 71]);
bounds.max
bounds.min

//optional的寫法
func minMax(array:[Int]) -> (min:Int,max:Int)?{
    if array.isEmpty {
    return nil;
    }
    var currentMin = array[0];
    var currentMax = array[0];
    for value in array[1..<array.count]{
        if value < currentMin{
            currentMin = value;
        } else if value > currentMax{
            currentMax = value;
        }
    }
    return (currentmin,currentMax);
}
if let bounds = minMax(array: [8, -6, 2, 109, 3, 71]){
    bounds.max;
    bounds.min;
}
//function的引數與參數名稱,
func someFunction(firstParameterName:Int, secondParameterName:Int){
 
}
someFunction(firstParameterName: 3, secondParameterName:2)
//自訂引數名稱 argumentLabel ,parameterName是參數名稱
func someFunction(argumentLabel parameterName:Int){
 
}

someFunction(argumentLabel: 54);

func greet(person:String, from hometown:String) -> String{
    return "Hello \(person)! Glad you could visit from \(hometown)"
}
greet(person: "Bill", form: "Cupertino");

//省略引數名稱
func someFunction(_ firstParameterName:Int, secondParamaterName:Int){

}
someFunction(5, secondParamaterName:3)

//default parameter value,有default value的參數要寫在後面!
func someFunction(parameterWithoutDefault:Int,patameterWithDefault:Int = 12){
 
}
someFunction(parameterWithoutDefault: 3, patameterWithDefault: 6)
someFunction(parameterWithoutDefault: 5)

//不限參數數量,這時引述名稱大多省略!參數內容則為陣列!
func arithmeticMean(_ numbers:Double...) -> Double{
    var total:Double = 0;
    for number in numbers{
        total += number
    }
    return total / Double(numbers.count)
}
arithmeticMean(1,2,3,4,5,6)
arithmeticMean(1.4,6,8,4.6,7.8)

//inout parameter,參數值為常數(let),無法變更!要在function內變更已設定的參數值,需用inout!
func swapTwoInt(_ a:inout Int, _ b:inout Int){
    let temporaryA = a;
    a = b;
    b = temporaryA;
}

var someInt = 3;
var anotherInt = 107;
//inout參數的呼叫,名稱前會多&
swap(&someInt, &anotherInt);
someInt;
anotherInt;

//function type,不管function名稱,只管參數和return值
//function type可以被存在變數,可以當作引數,可以當return type
func addTwoInts(_ a:Int, _ b:Int) -> Int{
    return a + b;
}

func mutiplyTwoInts(_ a:Int, _ b:Int) -> Int{
    return a * b;
}

func printHelloWorld(){
    print("hello, world");
}
//func printHelloWorld()的function type表示法:() -> Void

//將func addTwoInts指定給變數mathFunction,mathFunction的資料類型是function type:(Int, Int) -> Int
var mathFunction:(Int, Int) -> Int = addTwoInts;
print("result:\(mathFunction(2,3))");
mathFunction = mutiplyTwoInts
print("result:\(mathFunction(2, 3))");

//把function當作參數
func printMathResult(_ mathFunction:(Int, Int) -> Int, _ a:Int, _ b:Int) {
    print("Result:\(mathFunction(a,b))")
}
printMathResult(addTwoInts, 3, 5);

Nested Function
//Nested Function
//傳出function
func chooseStepFunction(backward:Bool) -> (Int) -> Int{
    func stepForward(input:Int) -> Int{
        return input + 1
    }
   
    func stepBackward(input:Int) -> Int{
        return input - 1
    }
    //三元運算式 Bool ?true的運算:false的運算
    //下列只是傳出function,不是執行function,所以只輸入function名稱,沒有()!
    return backward ? stepBackward : stepForward
}

var currentValue = -4;
let moveNearerToZero = chooseStepFunction(backward: currentValue > 0)

while currentValue != 0 {
    print("\(currentValue)...");
    currentValue = moveNearerToZero(currentValue)
}

Closure(閉鎖)--> 匿名的Function
用在當一個function的參數需求是一個function時,可以直接closure的方式給予。
Closure呼叫時語法:
mainFunction({
    (參數名:資料類型,參數名:資料類型) -> return typr in
    coding................
    coding................
})

let names:[String] = ["Chris", "Alex", "Ewa", "Barry", "Daniella"];
let sotrdNames = names.sorted();
//定義一個function,省略參數名稱
func backward(_ s1:String,_ s2:String) -> Bool{
    return s1 > s2;
}
//func sorted(by: (Element, Element) -> Bool) -> [Element]
//Returns the elements of the sequence, sorted using the given predicate as the comparison between elements.
var reverseNames = names.sorted(by: backward)
//closure 標準寫法
reverseNames = names.sorted(by: {
    (s1:String, s2:String) -> Bool in
    return s1 < s2;
})
//closure 的所有資料類型,可以省略,因為透過推測
reverseNames = names.sorted(by: {
    (s1,s2) in
    return s1 < s2
})

//如果只有一行,可以省略return
reverseNames = names.sorted(by: {
    (s1,s2) in  s1 < s2
})

//s1,s2也可以省略去定義,用$0,$1替代
reverseNames = names.sorted(by: { $0 < $1 })
//連$0,$1都省略
reverseNames = names.sorted(by: < )

//trailing closure,在最後一 個參數
reverseNames = names.sorted(){
    $0 < $1;
}
//trailing closure,在最後一 個參數,連()都省略!
reverseNames = names.sorted{
    $0 < $1;
}
let numbers = [16, 58, 510];
let numberStrings = numbers.map({
    (n:Int) -> String in
    return String(n*2)
})
































2019年5月29日 星期三

control Flow

判斷
if...
else if ...
else...

switch

guard ... else

迴圈
(明確知道要執行的次數)
for in

(不知道要執行的次數)
while

(不知道要執行的次數)
repead
while

let names = ["Anna", "Alex", "Brian", "Jack"];
for name in names {
    print("Hello!\(name)");
}
let numberOfLegs = ["spider":8, "ant":6, "cat":4];
for (animalName, legCount) in numberOfLegs {
    print("\(animalName)s have \(legCount) legs");
}

for index in 1..<5{
    print(index);
}
let base = 3;
let power = 10;
var answer = 1;

for _ in 1...power {
    answer *= base;
}

let minutes = 60
let minuteInterval = 5
//從0開始,每次+5,到60(不包含60)
for tickMark in stride(from: 0, to: minutes, by: minuteInterval) {
    print(tickMark);
}

//從0開始,每次+5,到60(包含60)
for tickMark in stride(from: 0, through: minutes, by: minuteInterval) {
    print(tickMark);
}

while  判斷 {
 
}
//相當於C的for(int i=25,i>=0;i--)
var finalSquare = 25
while finalSquare >=0 {
    print(finalSquare);
    finalSquare -= 1;
}

finalSquare = 25;
repeat {
    finalSquare -= 1;
} while finalSquare >=0

單向式
if 判斷式 {

}

雙向式 (一定執行其中一個)
if 判斷式 {

} else {

}

多向式(一定執行其中一個)
if 判斷式 {

} else if 判斷式{

} else if 判斷式{

} else {

}

var temperatureInFahrenheit = 30;
if temperatureInFahrenheit <= 32 {
    print("非常冷");
}
temperatureInFahrenheit = 35;
if temperatureInFahrenheit <= 32 {
    print("非常冷");
} else {
    print("不會冷");
}
 temperatureInFahrenheit = 90;
if temperatureInFahrenheit <= 32 {
    print("非常冷");
} else if temperatureInFahrenheit >= 86{
    print("非常熱");
} else {
    print("舒適!")
}
//siwft的switch只會執行其中一個區段,執行完跳出switch!
let someCharacter:Character = "z";
switch someCharacter {
    case "a":
        print("a");
    case "z":
        print("z");
    default:
        print("b~y");
}

let anotherCharacter:Character = "a";
switch anotherCharacter {
    case "a","A":
        print("a,A");
    case "b","B":
        print("b,B");
    default:
        print("其他");
}

//interval Matching
let approximateCount = 62
switch approximateCount {
    case 0:
        print("0");
    case 1..<5:
        print("1~4");
    case 5..<12:
        print("5..11");
    case 12..<100:
        print("12..99");
    case 100..<1000;
        print("100..999");
    default:
        print(">1000");
}
//範圍多值比對
let somePoint = (x:1,y:1);
switch    somePoint {
    case (0,0):
        print("0,0");
    case (_,0):
        print("y=0");
    case (0,_):
        print("x=0");
    case (-2...2,-2...2):
        print("-2...2,-2...2");
    default:
        print("其他");
}
//switch value binding
let anotherPoint = (2,0);
switch anotherPoint {
    case (let x, 0):
        print("y是0,x是\(x)");
    case (0, let y):
        print("x是0,y是\(y)");
    case let (x, y):
        print("x是\(x),y是\(y)");
    //因為一定會執行上方三個區塊其中一個,所以default可以省略!
    /*
    default:
        break;
    */
}
//switch value binding + where
let yetAnotherPoint = (1, -1);
switch yetAnotherPoint {
    //where 後面一定接bool
    case let (x, y) where x == y:
        print("x==y");
    case let (x, y) where x == -y:
        print("x==-y");
    case let (x, y):
        print("x=\(x), y=\(y)");
}

提早離開function
guard ... else,只執行false區段,true時不動作!
guard (false) else {
    false 區段
}
//guard else
func greet(person:[String:String]) {
    guard let name = person["name"] else {
        print("key沒有name");
        return;
    }
    print("Hello!\(name)!");

    gurade let location = person["location"] else {
        print("key沒有location");
        return;
    }
    print("name=\(name),location=\(location)");
}
greet(person: ["name":"John", "location":"Cupertino"]);


collection type

collection type(集合物件)
Array:有順序
Dictionary:沒有順序,key(必須是可以比較大小的(hashable))對應value
set:沒有順序,成員不會重複!hashable(可以比較大小的),Int,Double,Float,Bool,String


資料類型表示法:
陣列:
標準: Array<Int>
簡化:[Int]
var someInts = [Int]();
print(someInts.count); <----0
SomeInts.append(3);
SomeInts.append(4);
SomeInts.append(5);
print(someInts.count); <----3

objective-c
NSMutableArray:可變動(內容)的array
NSArray:不可變動(內容)的array

swift
var Array:可變動
let array:不可變動

var threeDoubles = Array(repeating: 0.0, count:30);
var anotherThreeDouble = Array(repesting: 2.5, count: 3);
var dixDoubles = threeDoubles + anotherThreeDouble;
var shoppingList:[String] = ["Effs", "Milk"];
if shoppingList.isEmpty {
    print("is empty");
} else {
    print("不是空的!有\(shoppingList.count)");
}
shoppingList.append("Flour");
shoppingList += ["Baking Powdwe"];
shoppingList += ["Chocolate Spread", "Cheese","Butter"];
shoppingList[0] = "Six eggs";
shoppingList[4...6];
shoppingList.insert("Maple Syrup", at: 0);
let mapleSyrup = shoppingList.remove(at: 0);

for item in shoppingList {
    print(item);
}

shoppingList.enumerated 傳出tuple (index,item)
for (index,item) in shoppingList.enumerated() {
    print("這個索引編號是\(index),內容是\(item)");
}

資料類型表示法:
Set<Int>
//建立一個空的Set,資料型態是Character,並初始化
var letters = Set<Character>();
print("letters is of type Set<Character> with \(letters.count)");
letters.insert("a");
//清空
letters = [];
//利用陣列值的表示法
var favoriteGenres:Set = ["Rock", "Classical", "Hip hop"];
favoriteGenres.count
favoriteGenres.insert("Jazz");
if favoriteGenres.remove("Rock") == nil {
    print("移除失敗!");
}
if favoriteGenres.contains("Funk") {
    print("有Funk這個值!");
} else {
    print("沒有Funk這個值!");
}
for genre in favoriteGenres {
    print("\(genre)");
}
//一般Set會轉成陣列使用
let sortedGenres = favoriteGenres.sorted();

資料類型表示法:
標準:
Dictionary<String,String>
簡易:
[String:String]
值表示法 ["tw":"Taiwan"];

var namesOfIntegers = [Int:String]();
namesOfIntegers[16] = "sixteen";
//清空
namesOfIntegers = [:];
var airports = [
    "YYZ": "Toronto pearson",
    "DUB": "Dublin"
]
//如果沒有該值,就新增;如果有,就修改!
airports["LHR"] = "London"
airports["LHR"] = "London Heathrow"

//一般的更新法(update())
if let _ =  airports.updateValue("Dublin Airport", forkey: "DUB"){
    //true區段,表示有值
    print("成功!");
} else {
    //false區段得到nil
    print("失敗!");
}
//透過key取出值,會傳出optional type
if let airportName = airports["DUB"] {
    print("DUB的名字是\(airportName)");
} else {
    print("key有錯!");
}
//如果沒有該值,就新增;如果有,就修改!
airports["APL"] = "Apple Internation"
//刪除
airports["APL"] = nil;

for (airportCode, airportName) in airports {
    print("\(airportCode),\(airportName)");
}

for airportCode in airports.keys {
    print(airportCode);
}

for airportName in airports.values {
    print(airportName);
}
//轉陣列
let airportsCodes = [String](airports.keys)
let airportValues = [String](airports.values)


2019年5月27日 星期一

nil 運算子,範圍運算子,for in 迴圈

nil 運算子
正常的type = optional Int ?? 0 <----不明確宣告
let defaultColorName = "red";
var userDefinedColorName:String?;
var colorNameForUser = userDefinedColorName ?? defaultColorName;

範圍運算子
1...5   1,2,3,4,5
1..<5  1,2,3,4
for in 迴圈
for index in 1...5 {
     print(index)
}
let names = ["Anna", "Alex", "Brian", "Jack"];
let count = name.count;
for i in 0..<count {
    names[i];
}
for name in names[2...] {
    print(name);
}
for name in names[...2] {
    print(name);
}

邏輯運算子
!    ---> not
&& ---> and
||    ---> or

let allowedEntry = false;
if !allowedEntry {
    print("Access Denied");
}







2019年5月26日 星期日

optional binding

if let 常數名 = optional type {
     true 區塊
} else {
     false 區塊
}

如果“optional type” 的值不是nil,會自動解開,設定給“常數名”,並執行true區塊,否則就執行false區塊!

let possibleNumber = "123a";
//optional binding
if let convertedNumber = Int(passibleNumber) {
    print(convertedNumber );
} else {
    print("轉換錯誤!!");
}

if let firstNumber = Int("4"), secondNumber = Int("42") {
print(firstNumber);
print(secondNumber);
}



2019年5月23日 星期四

計算命令執行的時間

time

#time ls
folders.txt  PData        RD_Data  UB_packBackup.sh  user.txt
homes        RDBackup.sh  UB_pack  userbackup.sh

real 0m0.001s
user 0m0.001s
sys 0m0.000s


real:命令開始執行到结束的时间。包含cpu處理時間,系統io的時間等等,一般所指的跑多久,就是指這個時間。
user:cpu花在執行這個程式的時間,The amount of cpu time spent in user mode(outside the kernel).
sys:cpu核心花在執行這個程式的時間,The amount of cpu time spent in the kernel within the process.

重複執行 echo "run test..."' 10次
#time tsch -c 'repeat 10 echo "run test..."'
重複執行 test.sh 10次
#time tsch -c 'repeat 10 file test.sh'

/usr/bin/time
-o 将執行時間寫入指定檔案內
/usr/bin/time -o outfile.txt ls
-a 追加訊息
/usr/bin/time -a -o outfile.txt ls
-f 選擇輸出的時間格式
/usr/bin/time -f "time: %U" ls
%E real time
%U user time
%S sys time