開発環境
- OS X Mavericks - Apple(OS)
- Xcode 6.0 Beta 6
- Swift (プログラミング言語)
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) 8.をSwiftで考えてみる。
10.10(Exercises) 8.
コード(Xcode)
main.swift
// // main.swift // sample8 // // Created by kamimura on 10/1/14. // Copyright (c) 2014 kamimura. All rights reserved. // import Foundation func readMolecule(lines:[String]) -> ([String:[[String]]], [String]){ if lines.isEmpty { return ([:], []) } var line:String = lines[0] var new_lines:[String] = lines.slice(start: 1) if line.isEmpty { return ([:], new_lines) } var molecule:[String:[[String]]] = [:] var name:String if !line.isSpace && !line.startsWith("CMNT") { let splited:[String] = line.split(sep: " ") name = splited[1].strip molecule[name] = [] } else { return (molecule, new_lines) } var serial_number:Int = 1 while true { line = new_lines[0] new_lines = new_lines.slice(start: 1) if line.startsWith("END") { break } if !line.isSpace && !line.startsWith("CMNT") { let splited:[String] = line.split(sep: " ").map({(s:String) in s.strip}) let num:Int? = splited[1].toInt() if serial_number != num { println("\(num!): シリアル番号が\(serial_number)ではない。\(name)") } let rest:[String] = splited.slice(start: 2) if !splited.isEmpty { molecule[name]?.append(rest) } } serial_number += 1 } return (molecule, new_lines) } func readAllMolecules(lines:[String]) -> [[String:[[String]]]] { var result:[[String:[[String]]]] = [] var new_lines:[String] = lines var molecule:[String:[[String]]] while true { (molecule, new_lines) = readMolecule(new_lines) if !molecule.isEmpty { result.append(molecule) } else { break } } return result } var lines:[String]? = read(argv[1])?.split(sep: "\n") if lines != nil { let molecules:[[String:[[String]]]] = readAllMolecules(lines!) for molecule in molecules { println(molecule) } }
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 isSpace:Bool { return self.strip == "" } 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 startsWith(s:String) -> Bool { return s == self.slice(end: s.length) } } func * (left:String, right:Int) -> String{ return left.repeat(right) } func * (left:Int, right:String) -> String{ return right.repeat(left) }
array.swift
// // array.swift // array // // Created by kamimura on 8/21/14. // Copyright (c) 2014 kamimura. All rights reserved. // import Foundation extension Array { func indexAt(i:Int) -> T { if i >= 0 { return self[i] } let new_index:Int = self.count + i return self[new_index] } func slice(start:Int = 0, end:Int? = nil) -> Array { var new_start = start >= 0 ? start : self.count + start var new_end:Int if end == nil { new_end = self.count } else if end! >= 0 { new_end = end! } else { new_end = self.count + end! } var result:Array = [] if new_start >= new_end { return [] } for i in new_start..<new_end { result.append(self[i]) } return result } func forEach(f:(T) -> ()) { for e in self { f(e) } } } func sum(nums:[Int]) -> Int { return nums.reduce(0, combine: {(x, y) in x + y}) } func range(start:Int = 0, end:Int, step:Int = 1) -> [Int] { assert(step != 0, "arg 3 must not be zero") var result:[Int] = [] var elem = start if step > 0 { while elem < end { result.append(elem) elem += step } } else { while elem > end { result.append(elem) elem += step } } return result }
入出力結果(Console Output)
$ cat multimol.pdb COMPND AMMONIA ATOM 1 N 0.257 -0.363 0.000 ATOM 2 H 0.257 0.727 0.000 ATOM 3 H 0.771 -0.727 0.890 ATOM 4 H 0.771 -0.727 -0.890 END COMPND METHANOL ATOM 1 C -0.748 -0.015 0.024 ATOM 2 O 0.558 0.420 -0.278 ATOM 3 H -1.293 -0.202 -0.901 ATOM 4 H -1.263 0.754 0.600 ATOM 5 H -0.699 -0.934 0.609 ATOM 6 H 0.716 1.404 0.137 END $ cat multimol1.pdb COMPND AMMONIA ATOM 1 N 0.257 -0.363 0.000 ATOM 2 H 0.257 0.727 0.000 ATOM 2 H 0.771 -0.727 0.890 ATOM 4 H 0.771 -0.727 -0.890 END COMPND METHANOL ATOM 1 C -0.748 -0.015 0.024 ATOM 2 O 0.558 0.420 -0.278 ATOM 2 H -1.293 -0.202 -0.901 ATOM 4 H -1.263 0.754 0.600 ATOM 4 H -0.699 -0.934 0.609 ATOM 6 H 0.716 1.404 0.137 END $ ./sample8 multimol.pdb [AMMONIA: [[N, 0.257, -0.363, 0.000], [H, 0.257, 0.727, 0.000], [H, 0.771, -0.727, 0.890], [H, 0.771, -0.727, -0.890]]] [METHANOL: [[C, -0.748, -0.015, 0.024], [O, 0.558, 0.420, -0.278], [H, -1.293, -0.202, -0.901], [H, -1.263, 0.754, 0.600], [H, -0.699, -0.934, 0.609], [H, 0.716, 1.404, 0.137]]] $ ./sample8 multimol1.pdb 2: シリアル番号が3ではない。AMMONIA 2: シリアル番号が3ではない。METHANOL 4: シリアル番号が5ではない。METHANOL [AMMONIA: [[N, 0.257, -0.363, 0.000], [H, 0.257, 0.727, 0.000], [H, 0.771, -0.727, 0.890], [H, 0.771, -0.727, -0.890]]] [METHANOL: [[C, -0.748, -0.015, 0.024], [O, 0.558, 0.420, -0.278], [H, -1.293, -0.202, -0.901], [H, -1.263, 0.754, 0.600], [H, -0.699, -0.934, 0.609], [H, 0.716, 1.404, 0.137]]] $
0 コメント:
コメントを投稿