Welcome to Code Forum!

Join a community that supports you and your coding journey from day one. We strive to be a friendly, supportive community that empowers everyone to be better developers. By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!
  • Guest, before posting your code please take these rules into consideration:
    • It is required to use our BBCode feature to display your code. While within the editor click < / > or >_ and place your code within the BB Code prompt. This helps others with finding a solution by making it easier to read and easier to copy.
    • You can also use markdown to share your code. When using markdown your code will be automatically converted to BBCode. For help with markdown check out the markdown guide.
    • Don't share a wall of code. All we want is the problem area, the code related to your issue.

    GIF shows where to locate </> in the thread and or post editor toolbar.
    To learn more about how to use our BBCode feature, review our "How to post your code into threads" here.

    Thank you, Code Forum.

A tomato pasta recipe (in programming languages)

cli345

Coder
Hi, I've already told you about FuncSug 🙂
Here is a tomato pasta recipe.

In a recipe, there are actions done together with other actions. For example, the sauce is prepared while the pasta is cooking.

I suggest to code it in your favorite language and give me your opinion about my code.

Code:
parallel ||
    heatWaterToBoilingPoint()
    putPastaIntoWater()
    waitSeconds(10*60)
    turnOffTheWaterHeat()
||
    turnOnTheOilHeat()
    putGarlicIntoOil()
    putTomatoesIntoOil()
    putBasilIntoOil()
    waitSeconds(3*60)
    turnOffTheOilHeat()
transferPastaFromWaterPanToOilPan()
season()
putCheese()

What is your version?
 
Originally Java didn't have anything so neat BUT the latest Java release includes new threading classes that work in much the same way. A StructuredTaskScope lets you fork multiple threads then wait for them all to complete before continuing
Java:
        var scope = new StructuredTaskScope();
        scope.fork(() -> {
            heatWaterToBoilingPoint();
            putPastaIntoWater();
            waitSeconds(10 * 60);
            turnOffTheWaterHeat();
        });
        scope.fork(() -> {
            turnOnTheOilHeat();
            putGarlicIntoOil();
            putTomatoesIntoOil();
            putBasilIntoOil();
            waitSeconds(3 * 60);
            turnOffTheOilHeat();
        });
        scope.join(); // wait for all forks to complete
        transferPastaFromWaterPanToOilPan();
        season();
        putCheese();

of course, being Java there's also a ton of stuff fo handing errors, timeouts etc
 
Last edited:
Thank you for your feedback 🙂.
Yes, this is included in structured concurrency which, nowadays, is available for more and more programming languages (see this list). That's very good indeed 🙂.
Few programming languages include structured concurrency natively: Apart from Java and Swift, I don't know of any others.
 
I could also have written:

Code:
parallel ||
    @heatWater_branch
    heatWater()
||
    waitBoiling()
    putPastaIntoWater()
    waitSeconds(10*60)
    break heatWater_branch
||
    @heatOil_branch
    heatOil()
||
    putGarlicIntoOil()
    putTomatoesIntoOil()
    putBasilIntoOil()
    waitSeconds(3*60)
    break heatOil_branch
transferPastaFromWaterPanToOilPan()
season()
putCheese()

This time, I need to be able to:
  • name a branch (example: @heatWater_branch),
  • interrupt (example: break heatWater_branch) a named branch from another branch.

What is your version?
 
Java:
The fork method returns an instance of Future that you can use to check its status, get any returned results, cancel it etc eg



Java:
var hwBranch = scope.fork( …
…
    hwBranch.cancel(true);
 
Yes, that's very good! 🙂

Now more detailed (waitBoiling and heatWater are explicitized):

Note: waitBoiling() is coded: awaitBool (waterTemperature = 100)

Code:
var waterTemperature := 20

def heatWater():
    while true:
        waitSeconds(2)
        if waterTemperature < 100:
            waterTemperature += 1

parallel ||
    @heatWater_branch
    heatWater()
||
    # --> waitBoiling() is explicitized
    awaitBool (waterTemperature = 100)
    
    putPastaIntoWater()
    waitSeconds(10*60)
    break heatWater_branch
||
    @heatOil_branch
    heatOil()
||
    putGarlicIntoOil()
    putTomatoesIntoOil()
    putBasilIntoOil()
    waitSeconds(3*60)
    break heatOil_branch
transferPastaFromWaterPanToOilPan()
season()
putCheese()

What is your version?
 
I think the problem with this model is the “break’. The idea that one thread can arbitrarily terminate/abort another thread sounds like a recipe for disaster. Who knows what state the aborted thread will be in - is the oil fully hot or not? And who’s going to deal with the InterruptedException or equivalent that it’s probably going to throw?
I think the first version was clearer and safer.
 
Thank you very much for your feedback 🙂.

Yes, you're very right. No one can know what state the aborted thread will be in.
In Java (and many contemporary programming languages), the execution threads are, in fact, operating system threads.
These are managed by the operating system according to a non-deterministic scheduler. The consistency of the whole application is managed by means of locks supplied by the programming language. These make aborting a thread very dangerous.

Nevertheless, other languages exist where:
  • execution threads aren't OS threads,
  • and scheduling is supplied by the language and is deterministic.

An iconic instance of these is SugarCubes. In it, the consistency is ensured thanks to the notion of logical clock: the execution is made up of steps, each of which is guaranteed to finish regardless of branch aborting.
 
Ok. Just fyi recent versions of Java have “virtual threads” that exist just in the jvm. They are designed to handle server situations with thousands of threads. There’s a whole load of api enhancements to manage and synchronise them.
 
Hi, I've already told you about FuncSug 🙂
Here is a tomato pasta recipe.

In a recipe, there are actions done together with other actions. For example, the sauce is prepared while the pasta is cooking.

I suggest to code it in your favorite language and give me your opinion about my code.

Python:
from dataclasses import dataclass
import random
from typing import List

@dataclass
class Ingredient:
    """Represents an ingredient with a name, quantity, and unit."""
    name: str
    quantity: float
    unit: str

    def __str__(self):
        return f"{self.quantity} {self.unit} of {self.name}"


@dataclass
class RecipeStep:
    """Represents a single step in the recipe."""
    step_number: int
    instruction: str

    def __str__(self):
        return f"Step {self.step_number}: {self.instruction}"


class TomatoPastaRecipe:                                                               
    """Sophisticated tomato pasta recipe generator."""
    def __init__(self):
        self.ingredients: List[Ingredient] = []
        self.steps: List[RecipeStep] = []
        self.recipe_name = "Tomato Pasta"

    def add_ingredient(self, name: str, quantity: float, unit: str):
        """Adds an ingredient to the recipe."""
        self.ingredients.append(Ingredient(name, quantity, unit))

    def add_step(self, instruction: str):
        """Adds a step to the recipe."""
        self.steps.append(RecipeStep(len(self.steps) + 1, instruction))

    def display_recipe(self):
        """Displays the recipe in a structured format."""
        print(f"\n{self.recipe_name}\n{'=' * len(self.recipe_name)}")
        print("\nIngredients:")
        for ingredient in self.ingredients:
            print(f"- {ingredient}")
        print("\nSteps:")
        for step in self.steps:
            print(step)                                                           

    def customize_recipe(self, servings: int):
        """Customizes the recipe based on the number of servings."""
        print(f"\nCustomizing recipe for {servings} servings...")
        for ingredient in self.ingredients:
            ingredient.quantity = round(ingredient.quantity * servings / 2, 2)  # Base recipe is for 2 servings
                                        
    @staticmethod
    def random_tip() -> str:
        """Provides a random cooking tip."""
        tips = [
            "Use fresh basil for better aroma.",
            "Add a pinch of sugar to balance the acidity of the tomatoes.",                                                                   
            "Reserve some pasta water to adjust sauce consistency.",
            "Toast the garlic lightly for a deeper flavor.",
        ]
        return random.choice(tips)


def main():
    recipe = TomatoPastaRecipe()

    # Adding ingredients
    recipe.add_ingredient("Spaghetti", 200, "g")
    recipe.add_ingredient("Tomatoes", 4, "medium-sized")
    recipe.add_ingredient("Olive oil", 2, "tbsp")
    recipe.add_ingredient("Garlic", 3, "cloves")
    recipe.add_ingredient("Basil", 10, "leaves")
    recipe.add_ingredient("Salt", 1, "tsp")
    recipe.add_ingredient("Black pepper", 0.5, "tsp")

    # Adding steps
    recipe.add_step("Boil water in a large pot and add a pinch of salt.")
    recipe.add_step("Cook the spaghetti until al dente, then drain and set aside.")
    recipe.add_step("Heat olive oil in a pan over medium heat.")
    recipe.add_step("Add minced garlic and sauté until fragrant.")
    recipe.add_step("Chop tomatoes and add them to the pan. Cook until soft.")
    recipe.add_step("Season with salt and black pepper.")
    recipe.add_step("Toss the cooked spaghetti in the pan with the tomato sauce.")
    recipe.add_step("Garnish with fresh basil leaves before serving.")

    # Displaying the original recipe
    recipe.display_recipe()

    # Customizing recipe for 4 servings
    recipe.customize_recipe(servings=4)
    recipe.display_recipe()

    # Displaying a random cooking tip
    print(f"\nCooking Tip: {recipe.random_tip()}")


if __name__ == "__main__":
    main()
 
Last edited:
Back
Top Bottom