開発環境
- 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) 7.をSwiftで考えてみる。
10.10(Exercises) 7.
コード(Xcode)
main.swift
//
// main.swift
// sample7
//
// Created by kamimura on 9/29/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)
}
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}).slice(start: 2)
if !splited.isEmpty {
molecule[name]?.append(splited)
}
}
}
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 3 H 0.771 -0.727 0.890 ATOM 4 H 0.771 -0.727 -0.890 END COMPND METHANOL CMNT コメント 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 $ ./sample7 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]]] $ ./sample7 multimol1.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]]] $
0 コメント:
コメントを投稿