Loading...

Prepr: Your Intelligent Meal Prepping Companion

June 20, 2024


Repository

Languages and Technologies

  1. SwiftUI
  2. Swift
  3. OpenAI API
  4. Firebase

Description

Prepr is an iOS application that generates saveable recipes using OpenAI's Completions API with 3.5turbo. Recipes can then be added to a queue—displayed on a calendar—to make planning meals easier. When a meal is queued, a dynamic grocery list is updated with needed ingredients. Firebase is used to store each user's data along with providing authentication so that each user can have their own profile. To protect any API keys from getting leaked, a .env file is stored on my device.

Code Snippets

AI Result Parser : Turns AI results into a dictionary of ingredients

//  The goal of this program is to turn a string of ingredients into a value Dictionary that is scalable by an optional factor

import Foundation

func parseFraction(_ fraction: String) -> Double? {
    let parts = fraction.split(separator: "/")
    if parts.count == 2 {
        if let numerator = Double(parts[0]), let denominator = Double(parts[1]) {
            return numerator / denominator
        }
    }
    return nil
}

//First, parseIngredients is called to turn a String into a Dictionary -> String: String
func parseIngredients(_ input: String) -> [String: String] {
    var ingredientsDict = [String: String]() // This is the dictionary that will be used
    
    let lines = input.split(separator: "\n") //This turns the string into an array split by \n.
    for line in lines { //Iterates over the lines array
        if line.starts(with: "-") { //If the first value of the line string begins with a dash below runs, else nothing happens
            let parts = line.dropFirst(2).split(separator: " ", maxSplits: 2) //dropFirst(2) ignores first two characters. A new array is then created split by a space [quantity, unit, ingredient]. Max split allows for the ingredient to be multiple words.
            if parts.count == 3 { //This ensures that there are only three elements in array
                let quantityPart = String(parts[0]) //The quantity is first element of parts array
                let unit = String(parts[1]) //The unit is second element of parts array
                let ingredient = String(parts[2]) //The ingredient is third element of parts array
                
                let quantity: Double //You want the quantity to be a double number, not a string. This begins that process. It shouldn't change for the lifespan of recipe, so it is constant.
                if let fractionValue = parseFraction(quantityPart) { //If fractionValue isn't nil it is a created variable that runs the code below.
                    quantity = fractionValue
                } else if let doubleValue = Double(quantityPart) { //Else the quanityPart (String) gets turned directly into quantity (Double)
                    quantity = doubleValue
                } else {
                    quantity = 0.0 // default value for non-numeric quantities
                }
                
                ingredientsDict["\(ingredient) (\(unit))"] = "\(quantity)" //This adds ingredients to the dictionary
            }
        }
    }
    
    return ingredientsDict //Dict is returned
}

func adjustQuantities(_ ingredients: [String: String], factor: Double) -> [String: String] {
    var adjustedIngredients = [String: String]()
    
    for (ingredient, quantity) in ingredients {
        if let quantityValue = Double(quantity) {
            let adjustedQuantity = quantityValue * factor
            adjustedIngredients[ingredient] = "\(adjustedQuantity)"
        } else {
            adjustedIngredients[ingredient] = quantity
        }
    }
    
    return adjustedIngredients
}

Images

Image Failed to Load Image Failed to Load Image Failed to Load Image Failed to Load