2014年9月26日金曜日

開発環境

Practical Programming: An Introduction to Computer Science Using Python 3 (Pragmatic Programmers) (Paul Gries (著)、Jennifer Campbell (著)、Jason Montojo (著)、Lynn Beighley (編集)、Pragmatic Bookshelf)のChapter 10(Reading and Writing Files)、10.10(Exercises) 4.をSwiftで考えてみる。

10.10(Exercises) 4.

コード(Xcode)

main.swift

//
//  main.swift
//  sample4
//
//  Created by kamimura on 9/26/14.
//  Copyright (c) 2014 kamimura. All rights reserved.
//

import Foundation

func skipHeader(s:String) -> String {
    var lines = s.slice(start: s.find("\n") + 1)
    while lines.indexAt(0) == "#" {
        lines = lines.slice(start: lines.find("\n") + 1)
    }
    return lines
}

func processFile(s:String) {
    var lines = skipHeader(s)
    let i:Int = lines.find("\n")
    println(lines.slice(end: i).strip)
    println(lines.slice(start: i + 1))
}

let s:String? = read("lynx.dat")
if s != nil {
    processFile(skipHeader(s!))
}

stdio.swift

//
//  stdio.swift
//  stdio
//
//  Created by kamimura on 8/21/14.
//  Copyright (c) 2014 kamimura. All rights reserved.
//

import Foundation

// 標準入力(STDIN)から読み込む
func input(msg:String = "") -> String {
    print(msg)
    var in_fh = NSFileHandle.fileHandleWithStandardInput()
    var data = in_fh.availableData
    in_fh.closeFile()
    var s = NSString(data: data, encoding: NSUTF8StringEncoding)
    s = s?.substringToIndex(s!.length - 1)
    return s!
}

func read(path:String) -> String? {
    var fh = NSFileHandle(forReadingAtPath: path)
    let data = fh?.readDataToEndOfFile()
    if fh == nil {
        error("file(\(path)) can't open.")
    }
    fh?.closeFile()
    return NSString(data: data!, encoding: NSUTF8StringEncoding)
}

func print(s:String, path:String, end:String = "\n") {
    (s + end).writeToFile(path, atomically: true, encoding: NSUTF8StringEncoding, error: nil)
}

func error(msg:String) {
    let stderr = NSFileHandle.fileHandleWithStandardError()
    stderr.writeData((msg + "\n").dataUsingEncoding(NSUTF8StringEncoding)!)
    exit(1)
}

// コマンドライン引数
let argv:[String] = NSProcessInfo.processInfo().arguments.map({(x:AnyObject) -> String in x as String})

string.swift

//
//  string.swift
//  string
//
//  Created by kamimura on 8/10/14.
//  Copyright (c) 2014 kamimura. All rights reserved.
//

import Foundation

extension String {
    var swapcaseString:String {
    var result: String = ""
        for ch in self {
            let s = String(ch)
            result += s.uppercaseString == s ? s.lowercaseString : s.uppercaseString
        }
        return result
    }
    var isUpper:Bool { return self.uppercaseString == self }
    var isLower:Bool { return self.lowercaseString == self }
    var length:Int { return (self as NSString).length }
    var strip:String { return self.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())}
    var floatValue:Float { return (self as NSString).floatValue }
    var doubleValue:Double { return (self as NSString).doubleValue }
    func count(sub:String) -> Int {
        var result:Int = 0
        var s = self
        let index:String.Index = "a".endIndex
        while s != "" {
            if s.hasPrefix(sub) {
                result += 1
                s = s.substringFromIndex(sub.endIndex)
            } else {
                s = s.substringFromIndex(index)
            }
            
        }
        return result
    }
    func find(sub:String, start:Int = 0, end:Int? = nil) -> Int {
        var s = self as NSString
        var s_temp = s.substringFromIndex(start)
        let end_temp:Int = end != nil ? end! : s.length
        for i in start..<end_temp {
            if (s_temp.hasPrefix(sub)) {
                return i
            }
            s_temp = s.substringFromIndex(i + 1) as NSString
        }
        return -1
    }
    func indexAt(i:Int) -> String {
        if i >= 0 {
            return (self as NSString).substringWithRange(NSRange(location: i, length: 1))
        }
        let new_i = self.length + i
        return (self as NSString).substringWithRange(NSRange(location: new_i, length: 1))
    }
    func replace(old_str:String, new_str:String) -> String {
        return self.stringByReplacingOccurrencesOfString(old_str, withString: new_str)
    }
    func slice(start:Int=0, end:Int?=nil) -> String {
        let s = self as NSString
        var new_end:Int
        if (end != nil) {
            new_end = end!
        } else {
            new_end = s.length
        }
        return  s.substringWithRange(NSRange(location: start, length:new_end - start))
    }
    func split(sep:String = "") -> [String] {
        var result:[String] = []
        if (sep == "") {
            for ch in self {
                result.append(String(ch))
            }
            return result
        }
        var s:String = self
        var len = sep.length
        var temp:String = ""
        while s != "" {
            if s.hasPrefix(sep) {
                if temp != "" {
                    result.append(temp)
                    temp = ""
                }
                s = s.slice(start: len)
            } else {
                temp += s.slice(start: 0, end: 1)
                s = s.slice(start: 1)
            }
        }
        if temp != "" {
            result.append(temp)
        }
        return result
    }
    var reversed:String { return "".join(self.split().reverse()) }
    func repeat(n:Int) -> String {
        var result:String = ""
        for i in 0..<n {
            result += self
        }
        return result
    }
}

func * (left:String, right:Int) -> String{
    return left.repeat(right)
}

func * (left:Int, right:String) -> String{
    return right.repeat(left)
}

入出力結果(Console Output)

$ ./sample4
184.  279.  409. 2285. 2685. 3409. 1824.  409.  151.   45.   68.  213.
  546. 1033. 2129. 2536.  957.  361.  377.  225.  360.  731. 1638. 2725.        
 2871. 2119.  684.  299.  236.  245.  552. 1623. 3311. 6721. 4245.  687.        
  255.  473.  358.  784. 1594. 1676. 2251. 1426.  756.  299.  201.  229.        
  469.  736. 2042. 2811. 4431. 2511.  389.   73.   39.   49.   59.  188.        
  377. 1292. 4031. 3495.  587.  105.  153.  387.  758. 1307. 3465. 6991.        
 6313. 3794. 1836.  345.  382.  808. 1388. 2713. 3800. 3091. 2985. 3790.        
  674.   81.   80.  108.  229.  399. 1132. 2432. 3574. 2935. 1537.  529.        
  485.  662. 1000. 1590. 2657. 3396.                                            
$ cat lynx.dat 
Annual Number of Lynx Trapped, MacKenzie River, 1821-1934
#Original Source: Elton, C. and Nicholson, M. (1942)
#"The ten year cycle in numbers of Canadian lynx",
#J. Animal Ecology, Vol. 11, 215--244.
#This is the famous data set which has been listed before in
#various publications:
#Cambell, M.J. and Walker, A.M. (1977) "A survey of statistical work on
#the MacKenzie River series of annual Canadian lynx trappings for the years
#1821-1934 with a new analysis", J.Roy.Statistical Soc. A 140, 432--436.
  269.  321.  585.  871. 1475. 2821. 3928. 5943. 4950. 2577.  523.   98.        
  184.  279.  409. 2285. 2685. 3409. 1824.  409.  151.   45.   68.  213.        
  546. 1033. 2129. 2536.  957.  361.  377.  225.  360.  731. 1638. 2725.        
 2871. 2119.  684.  299.  236.  245.  552. 1623. 3311. 6721. 4245.  687.        
  255.  473.  358.  784. 1594. 1676. 2251. 1426.  756.  299.  201.  229.        
  469.  736. 2042. 2811. 4431. 2511.  389.   73.   39.   49.   59.  188.        
  377. 1292. 4031. 3495.  587.  105.  153.  387.  758. 1307. 3465. 6991.        
 6313. 3794. 1836.  345.  382.  808. 1388. 2713. 3800. 3091. 2985. 3790.        
  674.   81.   80.  108.  229.  399. 1132. 2432. 3574. 2935. 1537.  529.        
  485.  662. 1000. 1590. 2657. 3396.                                            $ 

0 コメント:

コメントを投稿