Last active
June 24, 2023 16:25
-
-
Save Codelaby/46ad40dd4e40014fd300800241557003 to your computer and use it in GitHub Desktop.
Funciones swift Precio de la luz
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
struct PriceNet: Decodable { | |
let price_id: String | |
let tariff: String | |
let price: Double | |
let created_at: String | |
} | |
let json = """ | |
[{"price_id":"c5f3ee68-fbf8-0df9-9af8-5bc44e5bffb3","tariff":"pcb","price":0.16611,"created_at":"2023-06-23T00:00:00+00:00"},{"price_id":"dac8df3a-17f1-3d65-f1b3-f673822d2cbf","tariff":"pcb","price":0.16026,"created_at":"2023-06-23T01:00:00+00:00"},{"price_id":"e4b31572-32b9-48e3-c694-2e2eaed6a4b0","tariff":"pcb","price":0.14731,"created_at":"2023-06-23T02:00:00+00:00"},{"price_id":"b29f0ef3-7226-9734-507d-350243dec14d","tariff":"pcb","price":0.14191,"created_at":"2023-06-23T03:00:00+00:00"},{"price_id":"1297743c-dd2e-3eba-a1ff-0e779b66f7e1","tariff":"pcb","price":0.13521,"created_at":"2023-06-23T04:00:00+00:00"},{"price_id":"aef5a278-2984-8d2a-9277-3d73ae290f8a","tariff":"pcb","price":0.13868,"created_at":"2023-06-23T05:00:00+00:00"},{"price_id":"773e7bc8-f98b-11c9-b993-09c71b0cf67d","tariff":"pcb","price":0.1522,"created_at":"2023-06-23T06:00:00+00:00"},{"price_id":"6beae10a-14e0-73b1-27ae-b6d5caf47241","tariff":"pcb","price":0.1661,"created_at":"2023-06-23T07:00:00+00:00"},{"price_id":"1bc57bdd-75d9-6b59-4bcc-7ef1613e3170","tariff":"pcb","price":0.19316,"created_at":"2023-06-23T08:00:00+00:00"},{"price_id":"008649f6-7f00-02ca-78ae-85252d59adca","tariff":"pcb","price":0.18285,"created_at":"2023-06-23T09:00:00+00:00"},{"price_id":"e70088a9-3f48-86a7-f345-de199bc7ec72","tariff":"pcb","price":0.21418,"created_at":"2023-06-23T10:00:00+00:00"},{"price_id":"d7ec3a97-75fd-75e1-fa68-a4c128491804","tariff":"pcb","price":0.20357,"created_at":"2023-06-23T11:00:00+00:00"},{"price_id":"c54e9eb0-4142-32eb-6324-8a9614757e75","tariff":"pcb","price":0.19822,"created_at":"2023-06-23T12:00:00+00:00"},{"price_id":"c2d774b4-82e2-5583-6935-280e66540d64","tariff":"pcb","price":0.19187,"created_at":"2023-06-23T13:00:00+00:00"},{"price_id":"caff8470-e860-49ed-fe3d-712453bbc4bc","tariff":"pcb","price":0.1412,"created_at":"2023-06-23T14:00:00+00:00"},{"price_id":"13815e99-de1a-52dd-0d1c-b0005610cdc0","tariff":"pcb","price":0.14132,"created_at":"2023-06-23T15:00:00+00:00"},{"price_id":"860585e7-251a-c8c7-f13f-ee0c54c84f6e","tariff":"pcb","price":0.15078,"created_at":"2023-06-23T16:00:00+00:00"},{"price_id":"1487767c-596a-d423-c3da-927d64fc9f33","tariff":"pcb","price":0.15319,"created_at":"2023-06-23T17:00:00+00:00"},{"price_id":"73689f2e-10de-0311-e912-7a4b8f9cdb4f","tariff":"pcb","price":0.21739,"created_at":"2023-06-23T18:00:00+00:00"},{"price_id":"e657533b-f278-0966-e70a-55b8675ce881","tariff":"pcb","price":0.23874,"created_at":"2023-06-23T19:00:00+00:00"},{"price_id":"f4f60d63-2a85-59ea-4174-0a33e7d8e758","tariff":"pcb","price":0.25073,"created_at":"2023-06-23T20:00:00+00:00"},{"price_id":"67e48efd-b4bb-50df-0e71-0c13fea278f6","tariff":"pcb","price":0.24621,"created_at":"2023-06-23T21:00:00+00:00"},{"price_id":"7bb28f7b-c369-36c0-4c79-0e2b8b8906ce","tariff":"pcb","price":0.19557,"created_at":"2023-06-23T22:00:00+00:00"},{"price_id":"4554a283-936f-1da0-a34d-86630a4e0f0b","tariff":"pcb","price":0.18627,"created_at":"2023-06-23T23:00:00+00:00"}] | |
""" | |
enum TypePrice { | |
case veryCheap | |
case cheap | |
case regular | |
case expensive | |
case veryExpensive | |
} | |
struct Price: Identifiable { | |
let id: UUID | |
let tariff: String | |
let price: Double | |
let created_at: String | |
let hour: String | |
} | |
extension Price { | |
static func toPrice(_ priceNet: PriceNet) -> Price { | |
let id = UUID(uuidString: priceNet.price_id) ?? UUID() | |
let hour = formatCreatedAt(priceNet.created_at) ?? "" | |
return Price(id: id, tariff: priceNet.tariff, price: priceNet.price, created_at: priceNet.created_at, hour: hour) | |
} | |
private static func formatCreatedAt(_ createdAt: String) -> String? { | |
let dateFormatter = DateFormatter() | |
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ" | |
if let date = dateFormatter.date(from: createdAt) { | |
let hourFormatter = DateFormatter() | |
hourFormatter.dateFormat = "HH" | |
let startHour = hourFormatter.string(from: date) | |
let endHour = hourFormatter.string(from: date.addingTimeInterval(3600)) // Agregar 1 hora (3600 segundos) | |
return "\(startHour)-\(endHour)" | |
} | |
return nil | |
} | |
} | |
func fetchPrices(completion: @escaping ([Price]?, Error?) -> Void) { | |
if let jsonData = json.data(using: .utf8) { | |
do { | |
let priceNets = try JSONDecoder().decode([PriceNet].self, from: jsonData) | |
let prices = priceNets.map { Price.toPrice($0) } | |
completion(prices, nil) | |
} catch { | |
completion(nil, error) | |
} | |
} else { | |
let error = NSError(domain: "com.example.app", code: -1, userInfo: [NSLocalizedDescriptionKey: "Failed to convert JSON data"]) | |
completion(nil, error) | |
} | |
} | |
func formatCreatedAt(_ createdAt: String) -> String? { | |
let dateFormatter = DateFormatter() | |
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ" | |
if let date = dateFormatter.date(from: createdAt) { | |
let hourFormatter = DateFormatter() | |
hourFormatter.dateFormat = "HH" | |
let startHour = hourFormatter.string(from: date) | |
let endHour = hourFormatter.string(from: date.addingTimeInterval(3600)) // Agregar 1 hora (3600 segundos) | |
return "\(startHour)-\(endHour)" | |
} | |
return nil | |
} | |
struct PriceStats { | |
let averagePrice: Double | |
let minPrice: Double | |
let maxPrice: Double | |
let minHour: String | |
let maxHour: String | |
let standardDeviation: Double | |
} | |
func calculateStats(from prices: [Price]) -> PriceStats? { | |
guard !prices.isEmpty else { | |
return nil | |
} | |
var sum: Double = 0.0 | |
var minPrice: Double = prices[0].price | |
var maxPrice: Double = prices[0].price | |
var minHour: String = prices[0].hour | |
var maxHour: String = prices[0].hour | |
for price in prices { | |
sum += price.price | |
if price.price < minPrice { | |
minPrice = price.price | |
minHour = price.hour | |
} | |
if price.price > maxPrice { | |
maxPrice = price.price | |
maxHour = price.hour | |
} | |
} | |
let averagePrice = sum / Double(prices.count) | |
var squaredDifferenceSum: Double = 0.0 | |
for price in prices { | |
let difference = price.price - averagePrice | |
squaredDifferenceSum += difference * difference | |
} | |
let standardDeviation = sqrt(squaredDifferenceSum / Double(prices.count)) | |
let stats = PriceStats(averagePrice: averagePrice, minPrice: minPrice, maxPrice: maxPrice, minHour: minHour, maxHour: maxHour, standardDeviation: standardDeviation) | |
return stats | |
} | |
func calculateStandardDeviation(from values: [Double]) -> Double { | |
// Calcular la desviación estándar desde los valores | |
// Ejemplo de cálculo de desviación estándar | |
let mean = values.reduce(0.0, +) / Double(values.count) | |
let squaredDifferences = values.map { pow($0 - mean, 2) } | |
let variance = squaredDifferences.reduce(0.0, +) / Double(values.count) | |
let standardDeviation = sqrt(variance) | |
return standardDeviation | |
} | |
func assignType(to price: Price, basedOn stats: PriceStats) -> TypePrice { | |
let priceRange = (stats.maxPrice - stats.minPrice) / 3.0 | |
let deviationThreshold = (stats.standardDeviation * 0.3) | |
if price.price <= stats.minPrice + priceRange { | |
if price.price <= stats.minPrice + deviationThreshold { | |
return .veryCheap | |
} else { | |
return .cheap | |
} | |
} else if price.price <= stats.minPrice + (2 * priceRange) { | |
return .regular | |
} else { | |
if price.price >= stats.maxPrice - deviationThreshold { | |
return .veryExpensive | |
} else { | |
return .expensive | |
} | |
} | |
} | |
func processPrices(_ prices: [Price]) { | |
if let stats = calculateStats(from: prices) { | |
for price in prices { | |
let type = assignType(to: price, basedOn: stats) | |
print("Price: \(price.price) - Type: \(type)") | |
} | |
} else { | |
print("No prices available.") | |
} | |
} | |
fetchPrices { prices, error in | |
if let error = error { | |
print("Error: \(error)") | |
} else if let prices = prices { | |
if let stats = calculateStats(from: prices) { | |
print(stats) | |
for price in prices { | |
let type = assignType(to: price, basedOn: stats) | |
print("Price: \(price.price) - Type: \(type)") | |
} | |
} else { | |
print("No prices available.") | |
} | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
struct PriceNet: Decodable { | |
let price_id: String | |
let tariff: String | |
let price: Double | |
let created_at: String | |
} | |
let json = """ | |
[{"price_id":"21010cca-3fa0-2cda-daec-adf31dd9304b","tariff":"pcb","price":0.15577,"created_at":"2023-06-24T00:00:00+00:00"},{"price_id":"2f0db71d-3b5f-aaa4-e3af-b9ba16203b00","tariff":"pcb","price":0.14761,"created_at":"2023-06-24T01:00:00+00:00"},{"price_id":"70516687-1da9-6fac-5a21-f9e9695535af","tariff":"pcb","price":0.143,"created_at":"2023-06-24T02:00:00+00:00"},{"price_id":"eef2bdfc-b36a-e241-ee42-f436ce5b098f","tariff":"pcb","price":0.14746,"created_at":"2023-06-24T03:00:00+00:00"},{"price_id":"c0ae643e-6cbe-de82-d4ac-81bb37ffea83","tariff":"pcb","price":0.14772,"created_at":"2023-06-24T04:00:00+00:00"},{"price_id":"c42c23ae-1ca8-f68d-2e97-f7ab98d36f56","tariff":"pcb","price":0.14758,"created_at":"2023-06-24T05:00:00+00:00"},{"price_id":"3a60be52-0deb-dbd3-2234-24863e2cae5b","tariff":"pcb","price":0.13287,"created_at":"2023-06-24T06:00:00+00:00"},{"price_id":"46848ee3-b48e-89f7-7675-95e02db1aa2b","tariff":"pcb","price":0.1322,"created_at":"2023-06-24T07:00:00+00:00"},{"price_id":"f0b0710a-2783-bb2e-240d-b3b331da57a3","tariff":"pcb","price":0.12956,"created_at":"2023-06-24T08:00:00+00:00"},{"price_id":"23d8503f-4a59-9b20-0005-420c6f1687d7","tariff":"pcb","price":0.12084,"created_at":"2023-06-24T09:00:00+00:00"},{"price_id":"803e9a21-3f26-1cf1-3050-4fd5e0cc9091","tariff":"pcb","price":0.09084,"created_at":"2023-06-24T10:00:00+00:00"},{"price_id":"87e4e5be-3c11-b5f6-8508-e21fbfd3c954","tariff":"pcb","price":0.04862,"created_at":"2023-06-24T11:00:00+00:00"},{"price_id":"a47e927a-ed63-abea-58f8-82a2ede94287","tariff":"pcb","price":0.04276,"created_at":"2023-06-24T12:00:00+00:00"},{"price_id":"b6f9d25b-714b-1031-0f69-6af10049106c","tariff":"pcb","price":0.04824,"created_at":"2023-06-24T13:00:00+00:00"},{"price_id":"b19dc040-5dc7-bbb6-684e-3241c042f6b7","tariff":"pcb","price":0.04871,"created_at":"2023-06-24T14:00:00+00:00"},{"price_id":"e48bbf3d-3a6a-e5bd-67df-579114d13753","tariff":"pcb","price":0.03184,"created_at":"2023-06-24T15:00:00+00:00"},{"price_id":"bb7672e2-b46b-1e27-caa5-1574a2fda7bf","tariff":"pcb","price":0.05274,"created_at":"2023-06-24T16:00:00+00:00"},{"price_id":"1db3e97d-498d-4479-1852-f9efe61dd6b4","tariff":"pcb","price":0.11547,"created_at":"2023-06-24T17:00:00+00:00"},{"price_id":"4447a66c-928c-df7a-e865-00713cd83dfa","tariff":"pcb","price":0.12863,"created_at":"2023-06-24T18:00:00+00:00"},{"price_id":"ff9d81bb-a366-ede1-76e2-a234d1bd3935","tariff":"pcb","price":0.14212,"created_at":"2023-06-24T19:00:00+00:00"},{"price_id":"549ab2f3-e67b-be1c-abe8-9cecf2cbab9b","tariff":"pcb","price":0.1536,"created_at":"2023-06-24T20:00:00+00:00"},{"price_id":"3c825a57-c371-4f38-db36-ff68a241e35d","tariff":"pcb","price":0.17064,"created_at":"2023-06-24T21:00:00+00:00"},{"price_id":"d7de4195-af5d-aa33-64e3-ccc48ef3419b","tariff":"pcb","price":0.17422,"created_at":"2023-06-24T22:00:00+00:00"},{"price_id":"c348c0b6-cc9e-cd81-ee5b-db2ac6af2842","tariff":"pcb","price":0.17265,"created_at":"2023-06-24T23:00:00+00:00"}] | |
""" | |
struct Price: Identifiable { | |
let id: UUID | |
let tariff: String | |
let price: Double | |
let created_at: String | |
let hour: String | |
} | |
extension Price { | |
static func toPrice(_ priceNet: PriceNet) -> Price { | |
let id = UUID(uuidString: priceNet.price_id) ?? UUID() | |
let hour = formatCreatedAt(priceNet.created_at) ?? "" | |
return Price(id: id, tariff: priceNet.tariff, price: priceNet.price, created_at: priceNet.created_at, hour: hour) | |
} | |
private static func formatCreatedAt(_ createdAt: String) -> String? { | |
let dateFormatter = DateFormatter() | |
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ" | |
if let date = dateFormatter.date(from: createdAt) { | |
let hourFormatter = DateFormatter() | |
hourFormatter.dateFormat = "HH" | |
let startHour = hourFormatter.string(from: date) | |
let endHour = hourFormatter.string(from: date.addingTimeInterval(3600)) // Agregar 1 hora (3600 segundos) | |
return "\(startHour)-\(endHour)" | |
} | |
return nil | |
} | |
} | |
func fetchPrices(completion: @escaping ([Price]?, Error?) -> Void) { | |
if let jsonData = json.data(using: .utf8) { | |
do { | |
let priceNets = try JSONDecoder().decode([PriceNet].self, from: jsonData) | |
let prices = priceNets.map { Price.toPrice($0) } | |
completion(prices, nil) | |
} catch { | |
completion(nil, error) | |
} | |
} else { | |
let error = NSError(domain: "com.example.app", code: -1, userInfo: [NSLocalizedDescriptionKey: "Failed to convert JSON data"]) | |
completion(nil, error) | |
} | |
} | |
func formatCreatedAt(_ createdAt: String) -> String? { | |
let dateFormatter = DateFormatter() | |
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ" | |
if let date = dateFormatter.date(from: createdAt) { | |
let hourFormatter = DateFormatter() | |
hourFormatter.dateFormat = "HH" | |
let startHour = hourFormatter.string(from: date) | |
let endHour = hourFormatter.string(from: date.addingTimeInterval(3600)) // Agregar 1 hora (3600 segundos) | |
return "\(startHour)-\(endHour)" | |
} | |
return nil | |
} | |
func calculateStats(from prices: [Price]) -> (averagePrice: Double, averagePriceDate: String, minPrice: Double, minPriceHour: String, maxPrice: Double, maxPriceHour: String, standardDeviation: Double, standardDeviationDate: String)? { | |
guard !prices.isEmpty else { | |
return nil | |
} | |
// Calculate average price and date | |
let averagePrice = prices.reduce(0.0) { $0 + $1.price } / Double(prices.count) | |
let averagePriceDate = prices[0].created_at | |
// Calculate min and max prices and their hours | |
var minPrice = prices[0].price | |
var minPriceHour = prices[0].hour | |
var maxPrice = prices[0].price | |
var maxPriceHour = prices[0].hour | |
for price in prices { | |
if price.price < minPrice { | |
minPrice = price.price | |
minPriceHour = price.hour | |
} | |
if price.price > maxPrice { | |
maxPrice = price.price | |
maxPriceHour = price.hour | |
} | |
} | |
// Calculate standard deviation and date | |
let sumOfSquaredDeviations = prices.reduce(0.0) { $0 + pow($1.price - averagePrice, 2) } | |
let standardDeviation = sqrt(sumOfSquaredDeviations / Double(prices.count)) | |
let standardDeviationDate = prices[0].created_at | |
return (averagePrice, averagePriceDate, minPrice, minPriceHour, maxPrice, maxPriceHour, standardDeviation, standardDeviationDate) | |
} | |
fetchPrices { prices, error in | |
if let error = error { | |
print("Error: \(error)") | |
} else if let prices = prices { | |
if let stats = calculateStats(from: prices) { | |
let (averagePrice, averagePriceDate, minPrice, minPriceHour, maxPrice, maxPriceHour, standardDeviation, standardDeviationDate) = stats | |
print("Average Price: \(averagePrice) - Date: \(averagePriceDate)") | |
print("Min Price: \(minPrice) - Hour: \(minPriceHour)") | |
print("Max Price: \(maxPrice) - Hour: \(maxPriceHour)") | |
print("Standard Deviation: \(standardDeviation) - Date: \(standardDeviationDate)") | |
} | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment