Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: improve object simulator. #799

Merged
merged 15 commits into from
Oct 14, 2024
Merged
8 changes: 8 additions & 0 deletions public/data/object/examples.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
[
{
"id": "0d08a9ff-5683-4d3d-a7b8-dce74f37cd3b",
"name": "Produit vide",
n1k0 marked this conversation as resolved.
Show resolved Hide resolved
"category": "",
"query": {
"processes": []
}
},
{
"id": "7d78d30e-7c35-451f-b8ab-e590f39ed0e8",
"name": "Chaise",
Expand Down
1 change: 0 additions & 1 deletion public/data/object/processes.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
"id": "3295b2a5-328a-4c00-b046-e2ddeb0da823",
"name": "Plastic frame (PP)",
"display_name": "Composant en plastique (PP)",
"density": 900,
"unit": "kg",
"impacts": {
"acd": 0,
Expand Down
3 changes: 2 additions & 1 deletion src/Data/Bookmark.elm
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,8 @@ toQueryDescription db bookmark =

Object objectQuery ->
objectQuery
|> ObjectQuery.toString
|> ObjectQuery.toString db.object.processes
|> Result.withDefault "N/A"

Textile textileQuery ->
textileQuery
Expand Down
3 changes: 1 addition & 2 deletions src/Data/Object/Process.elm
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ module Data.Object.Process exposing
, encode
, encodeId
, findById
, idToString
)

import Data.Impact as Impact exposing (Impacts)
Expand Down Expand Up @@ -36,7 +35,7 @@ decodeProcess : Decoder Impact.Impacts -> Decoder Process
decodeProcess impactsDecoder =
Decode.succeed Process
|> Pipe.required "comment" Decode.string
|> Pipe.required "density" Decode.float
|> Pipe.optional "density" Decode.float 1
|> Pipe.required "display_name" Decode.string
|> Pipe.required "id" decodeId
|> Pipe.required "impacts" impactsDecoder
Expand Down
31 changes: 17 additions & 14 deletions src/Data/Object/Query.elm
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import Base64
import Data.Object.Process as Process exposing (Process)
import Json.Decode as Decode exposing (Decoder)
import Json.Encode as Encode
import Result.Extra as RE
import Url.Parser as Parser exposing (Parser)


Expand Down Expand Up @@ -120,21 +121,23 @@ updateItem newItem query =
}


toString : Query -> String
toString query =
query.items
|> List.map
(\i ->
(i.amount
|> amountToFloat
|> String.fromFloat
)
++ " "
++ (i.processId
|> Process.idToString
)
toString : List Process -> Query -> Result String String
toString processes =
.items
>> List.map
(\item ->
item.processId
|> Process.findById processes
|> Result.map
(\process ->
String.fromFloat (amountToFloat item.amount)
++ process.unit
++ " "
++ process.displayName
)
)
|> String.join " - "
>> RE.combine
>> Result.map (String.join ", ")



Expand Down
103 changes: 93 additions & 10 deletions src/Data/Object/Simulator.elm
Original file line number Diff line number Diff line change
@@ -1,17 +1,33 @@
module Data.Object.Simulator exposing
( availableProcesses
( Results(..)
, availableProcesses
, compute
, computeItemImpacts
, emptyResults
, expandItems
, extractImpacts
, extractItems
, extractMass
, toStepsImpacts
)

import Data.Impact as Impact exposing (Impacts)
import Data.Impact as Impact exposing (Impacts, noStepsImpacts)
import Data.Impact.Definition as Definition
import Data.Object.Process as Process exposing (Process)
import Data.Object.Query as Query exposing (Item, Query)
import Mass exposing (Mass)
import Quantity
import Result.Extra as RE
import Static.Db exposing (Db)


type Results
= Results
{ impacts : Impacts
, items : List Results
, mass : Mass
}


availableProcesses : Db -> Query -> List Process
availableProcesses { object } query =
let
Expand All @@ -22,19 +38,86 @@ availableProcesses { object } query =
|> List.filter (\{ id } -> not (List.member id usedIds))


compute : Db -> Query -> Result String Impacts
compute : Db -> Query -> Result String Results
compute db query =
query.items
|> List.map (computeItemImpacts db)
|> List.map (computeItemResults db)
|> RE.combine
|> Result.map Impact.sumImpacts
|> Result.map
(List.foldr
(\(Results { impacts, mass }) (Results acc) ->
Results
{ acc
| impacts = Impact.sumImpacts [ impacts, acc.impacts ]
, items = Results { impacts = impacts, items = [], mass = mass } :: acc.items
, mass = Quantity.sum [ mass, acc.mass ]
}
)
emptyResults
)
n1k0 marked this conversation as resolved.
Show resolved Hide resolved


computeItemImpacts : Db -> Item -> Result String Impacts
computeItemImpacts { object } { amount, processId } =
computeItemResults : Db -> Item -> Result String Results
computeItemResults { object } { amount, processId } =
processId
|> Process.findById object.processes
|> Result.map
(.impacts
>> Impact.mapImpacts (\_ -> Quantity.multiplyBy (Query.amountToFloat amount))
(\process ->
Results
{ impacts =
process.impacts
|> Impact.mapImpacts (\_ -> Quantity.multiplyBy (Query.amountToFloat amount))
, items = []
, mass =
Mass.kilograms <|
if process.unit == "kg" then
Query.amountToFloat amount

else
-- apply density
Query.amountToFloat amount * process.density
}
)


emptyResults : Results
emptyResults =
Results
{ impacts = Impact.empty
, items = []
, mass = Quantity.zero
}


expandItems : Db -> Query -> Result String (List ( Query.Amount, Process ))
expandItems db =
.items
>> List.map (\{ amount, processId } -> ( amount, processId ))
>> List.map (RE.combineMapSecond (Process.findById db.object.processes))
>> RE.combine


extractImpacts : Results -> Impacts
extractImpacts (Results { impacts }) =
impacts


extractItems : Results -> List Results
extractItems (Results { items }) =
items


extractMass : Results -> Mass
extractMass (Results { mass }) =
mass


toStepsImpacts : Definition.Trigram -> Results -> Impact.StepsImpacts
toStepsImpacts trigram results =
{ noStepsImpacts
-- FIXME: for now, as we only have materials, assign everything to the material step
| materials =
extractImpacts results
|> Impact.getImpact trigram
|> Just
}
Loading