import Foundation let fmtDbl = { String(format: "%10.3f", $0) } Task.detached { let formatter = DateFormatter() formatter.dateFormat = "yyyy-MM-dd" let (data, _) = try await URLSession.shared.bytes(from: URL(fileURLWithPath: CommandLine.arguments[1])) var rowStats = [(Date, Double, Int)]() var invalidPeriods = 0 var invalidStart: Date? var sumFile = 0.0 var readings = 0 var longestInvalid = 0 var longestInvalidStart: Date? var longestInvalidEnd: Date? for try await line in data.lines { let lineSplit = line.components(separatedBy: "\t") guard !lineSplit.isEmpty, let date = formatter.date(from: lineSplit[0]) else { fatalError("Invalid date \(lineSplit[0])") } let data = Array(lineSplit.dropFirst()) let parsed = stride(from: 0, to: data.endIndex, by: 2).map({idx -> (Double, Int) in let slice = data[idx.. longestInvalid { longestInvalid = invalidPeriods longestInvalidStart = invalidStart longestInvalidEnd = date } sumFile += val sum += val numValid += 1 readings += 1 invalidPeriods = 0 invalidStart = nil } } if numValid != 0 { rowStats.append((date, sum / Double(numValid), parsed.count - numValid)) } } for stat in rowStats.lazy.reversed().prefix(5) { print("\(stat.0): Average: \(fmtDbl(stat.1)); Valid Readings: \(24 - stat.2); Invalid Readings: \(stat.2)") } print(""" Sum File: \(fmtDbl(sumFile)) Average: \(fmtDbl(sumFile / Double(readings))) Readings: \(readings) Longest Invalid: \(longestInvalid) (\(longestInvalidStart!) - \(longestInvalidEnd!)) """) exit(0) } dispatchMain()