Functional coverage tree: Difference between revisions

m
m (→‎Python: Composition of pure functions: Tidied, updated primitives.)
m (→‎{{header|Wren}}: Minor tidy)
 
(8 intermediate revisions by 5 users not shown)
Line 136:
=={{header|Go}}==
{{trans|Kotlin}}
<langsyntaxhighlight lang="go">package main
 
import "fmt"
Line 289:
fmt.Printf("%8.6f to %8.6f\n", diff, topCoverage+diff)
h2Basement[2].setCoverage(0.75) // restore to original value if required
}</langsyntaxhighlight>
 
{{out}}
Line 348:
The raw table (supplied in the task description) is read in from a text file, parsed to a tree structure, and updated by two traversals (one bottom-up and one top down) before being serialised back to a completed outline text, with an additional 'Share of Residue' column:
{{Trans|Python}}
<langsyntaxhighlight lang="haskell">{-# LANGUAGE OverloadedStrings #-}
 
import System.Directory (doesFileExist)
import qualified Data.Text.Read as T
import qualified Data.Text.IO as T
import qualified Data.Text as T
import Numeric (showFFloat)
import Data.Bifunctor (first)
import Data.Char (isSpace)
import Data.Bool (bool)
import Data.TreeChar (isSpace)
import qualified Data.Text as T
import qualified Data.Text.IO as T
import qualified Data.Text.Read as T
import Data.Tree (Forest, Tree (..), foldTree)
import Numeric (showFFloat)
import System.Directory (doesFileExist)
 
----------------- FUNCTIONAL COVERAGE TREE ---------------
 
data Coverage = Coverage
{ name :: T.Text,
, weight :: Float,
, coverage :: Float,
, share :: Float
}
} deriving (Show)
deriving (Show)
 
-- TEST -------------------------- TEST -------------------------
fp = "./coverageOutline.txt"
 
main :: IO ()
main =
doesFileExist fp >>=
>>= bool
(print $ "File not found: " ++<> fp)
(T.readFile fp >>= T.putStrLn . updatedCoverageOutline)
 
-- UPDATED COVERAGE OUTLINE ---------------- UPDATED COVERAGE OUTLINE ---------------
updatedCoverageOutline :: T.Text -> T.Text
updatedCoverageOutline s =
let delimiter = "|"
indentedLines = T.lines s
columnNames = init $ tokenizeWith delimiter (head indentedLines)
init $
in T.unlines
tokenizeWith
[ tabulation delimiter (columnNames ++ ["SHARE OF RESIDUE"])
, indentedLinesFromTree " " (showCoverage delimiter) $
withResidueShares 1.0 $ ( head indentedLines
foldTree )
in T.unlines
weightedCoverage
[ tabulation
(parseTreeFromOutline delimiter indentedLines)
] delimiter
(columnNames <> ["SHARE OF RESIDUE"]),
indentedLinesFromTree
" "
(showCoverage delimiter)
$ withResidueShares 1.0 $
foldTree
weightedCoverage
(parseTreeFromOutline delimiter indentedLines)
]
 
------ WEIGHTED COVERAGE AND SHARES OF REMAINING WORK ---------
weightedCoverage :: Coverage -> Forest Coverage -> Tree Coverage
Coverage ->
Forest Coverage ->
Tree Coverage
weightedCoverage x xs =
let cws = ((,) . coverage <*> weight) . rootLabel <$> xs
totalWeight = foldr ((+) . snd) 0 cws
in Node
( x
{ coverage =
foldr (\(c, w) a -> (c * w) + a) (coverage x) cws /foldr
bool 1 totalWeight (0\(c, w) a -> (c * w) <+ totalWeighta)
} (coverage x)
xs cws
/ bool 1 totalWeight (0 < totalWeight)
}
)
xs
 
withResidueShares :: Float -> Tree Coverage -> Tree Coverage
Line 412 ⟶ 431:
weightTotal = sum weights
nodeRoot = rootLabel node
in Node
( nodeRoot
{ share = fraction *{ (1share - coverage nodeRoot)=
}) fraction
(zipWith go ((fraction *) . (/ weightTotal) <$> weights) forest * (1 - coverage nodeRoot)
}
in go shareOfTotal tree
)
( zipWith
go
((fraction *) . (/ weightTotal) <$> weights)
forest
)
in go shareOfTotal tree
 
-- OUTLINE PARSE --------------------- OUTLINE PARSE ---------------------
parseTreeFromOutline :: T.Text -> [T.Text] -> Tree Coverage
parseTreeFromOutline delimiter indentedLines =
partialRecord . tokenizeWith delimiter <$>
<$> head
head (forestFromLineIndents $ indentLevelsFromLines $ tail indentedLines)
( forestFromLineIndents $
indentLevelsFromLines $ tail indentedLines
)
 
forestFromLineIndents :: [(Int, T.Text)] -> [Tree T.Text]
forestFromLineIndents pairs =
let go [] = []
go ((n, s) : xs) =
let (firstTreeLines, rest) = span ((n <) . fst) xs
in Node s (go firstTreeLines) : go rest
in go pairs
 
indentLevelsFromLines :: [T.Text] -> [(Int, T.Text)]
Line 438 ⟶ 467:
indentUnit =
foldr
( \x a ->
let w = (T.length . fst) x
in bool a w (w < a && 0 < w))
)
(maxBound :: Int)
pairs
in first (flip div indentUnit . T.length) <$> pairs
 
partialRecord :: [T.Text] -> Coverage
partialRecord xs =
let [name, weightText, coverageText] = take 3 (xs ++ repeat "")
in Coverage take
{ name = name 3
(xs <> repeat "")
, weight = defaultOrRead 1.0 weightText
in Coverage
, coverage = defaultOrRead 0.0 coverageText
, share { name = 0.0name,
weight = defaultOrRead 1.0 weightText,
}
coverage = defaultOrRead 0.0 coverageText,
share = 0.0
}
 
defaultOrRead :: Float -> T.Text -> Float
Line 461 ⟶ 494:
tokenizeWith delimiter = fmap T.strip . T.splitOn delimiter
 
-------- SERIALISATION OF TREE TO TABULATED OUTLINE -------------
indentedLinesFromTree :: T.Text -> (T.Text -> a -> T.Text) -> Tree a -> T.Text
T.Text ->
(T.Text -> a -> T.Text) ->
Tree a ->
T.Text
indentedLinesFromTree tab showRoot tree =
let go indent node =
showRoot indent (rootLabel node) :
(subForest node >>= go (T.append tab indent))
in T.unlines $ go "" tree
 
showCoverage :: T.Text -> T.Text -> Coverage -> T.Text
Line 473 ⟶ 510:
tabulation
delimiter
( [T.append indent (name x), T.pack (showN 0 (weight x))] ++
<> (T.pack . showN 4 <$> ([coverage, share] <*> [x])))
)
 
tabulation :: T.Text -> [T.Text] -> T.Text
tabulation delimiter =
T.intercalate (T.append delimiter " ") .
. zipWith (`T.justifyLeft` ' ') [31, 9, 9, 9]
 
justifyRight :: Int -> a -> [a] -> [a]
justifyRight n c = (drop . length) <*> (replicate n c ++<>)
 
showN :: Int -> Float -> String
showN p n = justifyRight 7 ' ' (showFFloat (Just p) n "")</langsyntaxhighlight>
{{Out}}
<pre>NAME_HIERARCHY | WEIGHT | COVERAGE | SHARE OF RESIDUE
Line 535 ⟶ 573:
Implementation part 1 of 4 (raw data):
 
<langsyntaxhighlight Jlang="j">raw=: 0 :0
NAME_HIERARCHY |WEIGHT |COVERAGE |
cleaning | | |
Line 579 ⟶ 617:
wine_cellar | |1 |
cinema | |0.75 |
)</langsyntaxhighlight>
 
Implementation part 2 of 4 (unpacking raw data):
 
<langsyntaxhighlight Jlang="j">labels=: {.<;._2;._2 raw
'hier wspec cspec'=:|:}.<;._2;._2 raw
level=: (%+./) (0 i.~' '&=)"1 hier
weight=: (+ 0=]) ,".wspec
coverage=: ,".cspec</langsyntaxhighlight>
 
To understand this implementation, it's best to run it and inspect the data.
Line 603 ⟶ 641:
Implementation part 3 of 4 (translation of leaf coverage to functional coverage):
 
<langsyntaxhighlight Jlang="j">merge=: ;@(({.@[,(+}.)~)&.> [: +/\1,_1}.#@>)
unrooted=: ([: merge <@(_1,$:@}.);.1)^:(0<#)
parent=: unrooted level
parent_cover=: (] (1}.~.parent)}~ 1}. * %&(parent +//. ]) [)^:_</langsyntaxhighlight>
 
<code>unrooted</code> translates indentation information to a [[Tree_traversal#J:_Alternate_implementation|parent tree structure]]. However, the limitations of recursion require we distinguish the parent node from its children, so we use _1 to denote the parent node of the recursive intermediate result unrooted trees. (This works well with using arithmetic to adjust sub-tree indices based on the lengths of preceding sub-trees.) <code>merge</code> combines a boxed sequence of these subtrees to form a single tree - we also rely on the first node of each tree being both _1 and the root node.
Line 614 ⟶ 652:
Task example part 4 of 4 (format and show result):
 
<langsyntaxhighlight Jlang="j"> 1 1 }._1 }.":labels,each ":each hier;(,.weight);,.weight parent_cover coverage
NAME_HIERARCHY │WEIGHT │COVERAGE │
cleaning │ 1 │0.409167 │
Line 657 ⟶ 695:
cellars │ 1 │ 1 │
wine_cellar │ 1 │ 1 │
cinema │ 1 │ 0.75 │</langsyntaxhighlight>
 
Extra credit:
 
<langsyntaxhighlight Jlang="j">trace=: (~.@,each (0 >. parent)&{)^:_ i.#parent
power=: */@:{&(parent (] % (i.~ ~.)@[ { +//.) weight)@> trace
 
power*1-weight parent_cover coverage
0.590833 0.2675 0.0375 0.025 0.00833333 0.0166667 0 0.0125 0.045 0.0375 0.0125 0.0125 0.0125 0 0.05 0.05 0.01 0.323333 0.17 0.05 0.0125 0.0125 0.0125 0.0125 0.05 0.05 0.02 0.136667 0.0333333 0.0333333 0.00833333 0.00833333 0.00833333 0.00833333 0.0333333 0.0333333 0.00333333 0 0.0166667 0 0 0.0166667</langsyntaxhighlight>
 
Explanation:
Line 676 ⟶ 714:
 
And, <code>weight parent_cover coverage</code> was the functional coverage for each node.
 
=={{header|Java}}==
<syntaxhighlight lang="java">
import java.util.ArrayList;
import java.util.List;
 
public final class FunctionalCoverageTree {
 
public static void main(String[] aArgs) {
FCNode cleaning = new FCNode("Cleaning", 1, 0.0);
List<FCNode> houses = List.of(
new FCNode("House_1", 40, 0.0),
new FCNode("House_2", 60, 0.0) );
cleaning.addChildren(houses);
List<FCNode> house_1 = List.of(
new FCNode("Bedrooms", 1, 0.25),
new FCNode("Bathrooms", 1, 0.0),
new FCNode("Attic", 1, 0.75),
new FCNode("Kitchen", 1, 0.1),
new FCNode("Living_rooms", 1, 0.0),
new FCNode("Basement", 1, 0.0),
new FCNode("Garage", 1, 0.0),
new FCNode("Garden",1, 0.8) );
houses.get(0).addChildren(house_1);
List<FCNode> bathrooms_house_1 = List.of(
new FCNode("Bathroom_1", 1, 0.5),
new FCNode("Bathroom_2", 1, 0.0),
new FCNode("Outside_lavatory", 1, 1.0) );
house_1.get(1).addChildren(bathrooms_house_1);
List<FCNode> living_rooms_house_1 = List.of(
new FCNode("lounge", 1, 0.0),
new FCNode("Dining_room", 1, 0.0),
new FCNode("Conservatory", 1, 0.0),
new FCNode("Playroom", 1, 1.0) );
house_1.get(4).addChildren(living_rooms_house_1);
List<FCNode> house_2 = List.of(
new FCNode("Upstairs", 1, 0.15),
new FCNode("Ground_floor", 1, 0.316667),
new FCNode("Basement", 1, 0.916667));
houses.get(1).addChildren(house_2);
List<FCNode> upstairs = List.of(
new FCNode("Bedrooms", 1, 0.0),
new FCNode("Bathroom", 1, 0.0),
new FCNode("Toilet", 1, 0.0),
new FCNode("Attics", 1, 0.6) );
house_2.get(0).addChildren(upstairs);
List<FCNode> ground_floor = List.of(
new FCNode("Kitchen", 1, 0.0),
new FCNode("Living_rooms", 1, 0.0),
new FCNode("Wet_room_&_toilet", 1, 0.0),
new FCNode("Garage", 1, 0.0),
new FCNode("Garden", 1, 0.9),
new FCNode("Hot_tub_suite", 1, 1.0) );
house_2.get(1).addChildren(ground_floor);
List<FCNode> basement = List.of(
new FCNode("Cellars", 1, 1.0),
new FCNode("Wine_cellar", 1, 1.0),
new FCNode("Cinema", 1, 0.75) );
house_2.get(2).addChildren(basement);
List<FCNode> bedrooms = List.of(
new FCNode("Suite_1", 1, 0.0),
new FCNode("Suite_2", 1, 0.0),
new FCNode("Bedroom_3",1, 0.0),
new FCNode("Bedroom_4",1, 0.0) );
upstairs.get(0).addChildren(bedrooms);
List<FCNode> living_rooms_house_2 = List.of(
new FCNode("lounge", 1, 0.0),
new FCNode("Dining_room", 1, 0.0),
new FCNode("Conservatory", 1, 0.0),
new FCNode("Playroom", 1, 0.0) );
ground_floor.get(1).addChildren(living_rooms_house_2);
final double overallCoverage = cleaning.getCoverage();
System.out.println("OVERALL COVERAGE = " + String.format("%.6f", overallCoverage) + System.lineSeparator());
System.out.println("NAME HIERARCHY | WEIGHT | COVERAGE |" );
System.out.println("--------------------------------|--------|----------|");
cleaning.display();
System.out.println();
basement.get(2).setCoverage(1.0); // Change House_2 Cinema node coverage to 1.0
final double updatedCoverage = cleaning.getCoverage();
final double difference = updatedCoverage - overallCoverage;
System.out.println("If the coverage of the House_2 Cinema node were increased from 0.75 to 1.0");
System.out.print("the overall coverage would increase by ");
System.out.println(String.format("%.6f%s%.6f", difference, " to ", updatedCoverage));;
basement.get(2).setCoverage(0.75); // Restore to House_2 Cinema node coverage to its original value
}
 
}
 
final class FCNode {
public FCNode(String aName, int aWeight, double aCoverage) {
name = aName;
weight = aWeight;
coverage = aCoverage;
}
public void addChildren(List<FCNode> aNodes) {
for ( FCNode node : aNodes ) {
node.parent = this;
children.add(node);
updateCoverage();
}
}
public double getCoverage() {
return coverage;
}
public void setCoverage(double aCoverage) {
if ( coverage != aCoverage ) {
coverage = aCoverage;
if ( parent != null ) {
parent.updateCoverage();
}
}
}
public void display() {
display(0);
}
private void updateCoverage() {
double value1 = 0.0;
int value2 = 0;
for ( FCNode node : children ) {
value1 += node.weight * node.coverage;
value2 += node.weight;
}
setCoverage(value1 / value2);
}
private void display(int aLevel) {
final String initial = " ".repeat(4 * aLevel) + name;
final String padding = " ".repeat(NAME_FIELD_WIDTH - initial.length());
System.out.print(initial + padding + "|");
System.out.print(" " + String.format("%3d", weight) + " |");
System.out.println(" " + String.format("%.6f", coverage) + " |");
 
for ( FCNode child : children ) {
child.display(aLevel + 1);
}
}
private String name;
private int weight;
private double coverage;
private FCNode parent;
private List<FCNode> children = new ArrayList<FCNode>();
private static final int NAME_FIELD_WIDTH = 32;
}
</syntaxhighlight>
{{ out }}
<pre>
OVERALL COVERAGE = 0.409167
 
NAME HIERARCHY | WEIGHT | COVERAGE |
--------------------------------|--------|----------|
Cleaning | 1 | 0.409167 |
House_1 | 40 | 0.331250 |
Bedrooms | 1 | 0.250000 |
Bathrooms | 1 | 0.500000 |
Bathroom_1 | 1 | 0.500000 |
Bathroom_2 | 1 | 0.000000 |
Outside_lavatory | 1 | 1.000000 |
Attic | 1 | 0.750000 |
Kitchen | 1 | 0.100000 |
Living_rooms | 1 | 0.250000 |
lounge | 1 | 0.000000 |
Dining_room | 1 | 0.000000 |
Conservatory | 1 | 0.000000 |
Playroom | 1 | 1.000000 |
Basement | 1 | 0.000000 |
Garage | 1 | 0.000000 |
Garden | 1 | 0.800000 |
House_2 | 60 | 0.461111 |
Upstairs | 1 | 0.150000 |
Bedrooms | 1 | 0.000000 |
Suite_1 | 1 | 0.000000 |
Suite_2 | 1 | 0.000000 |
Bedroom_3 | 1 | 0.000000 |
Bedroom_4 | 1 | 0.000000 |
Bathroom | 1 | 0.000000 |
Toilet | 1 | 0.000000 |
Attics | 1 | 0.600000 |
Ground_floor | 1 | 0.316667 |
Kitchen | 1 | 0.000000 |
Living_rooms | 1 | 0.000000 |
lounge | 1 | 0.000000 |
Dining_room | 1 | 0.000000 |
Conservatory | 1 | 0.000000 |
Playroom | 1 | 0.000000 |
Wet_room_&_toilet | 1 | 0.000000 |
Garage | 1 | 0.000000 |
Garden | 1 | 0.900000 |
Hot_tub_suite | 1 | 1.000000 |
Basement | 1 | 0.916667 |
Cellars | 1 | 1.000000 |
Wine_cellar | 1 | 1.000000 |
Cinema | 1 | 0.750000 |
 
If the coverage of the House_2 Cinema node were increased from 0.75 to 1.0
the overall coverage would increase by 0.016667 to 0.425833
</pre>
 
=={{header|JavaScript}}==
Line 682 ⟶ 938:
{{Trans|Haskell}}
{{Trans|Python}}
<langsyntaxhighlight lang="javascript">(() => {
'use strict';
 
Line 1,120 ⟶ 1,376:
// MAIN ---
return main();
})();</langsyntaxhighlight>
{{Out}}
<pre>NAME_HIERARCHY | WEIGHT | COVERAGE | SHARE OF RESIDUE
Line 1,169 ⟶ 1,425:
Most implementations of functional coverage are going to store values in a database. The implementation
stores the tree in a CSV file with an index to the parent of each entry to allow reconstitution of the tree.
<langsyntaxhighlight Julialang="julia">using CSV, DataFrames, Formatting
 
function updatecoverage(dfname, outputname)
Line 1,231 ⟶ 1,487:
println("\nUpdated data:")
displaycoveragedb(newdbname)
</langsyntaxhighlight>{{out}}
<pre>
Input data:
Line 1,371 ⟶ 1,627:
 
=={{header|Kotlin}}==
<langsyntaxhighlight lang="scala">// version 1.2.10
 
class FCNode(val name: String, val weight: Int = 1, coverage: Double = 0.0) {
Line 1,508 ⟶ 1,764:
println("${"%8.6f".format(diff)} to ${"%8.6f".format(topCoverage + diff)}")
h2Basement[2].coverage = 0.75 // restore to original value if required
}</langsyntaxhighlight>
 
{{out}}
Line 1,562 ⟶ 1,818:
</pre>
=={{header|Lua}}==
<langsyntaxhighlight lang="lua">-- DATA:
local function node(name, weight, coverage, children)
return { name=name, weight=weight or 1.0, coverage=coverage or 0.0, sumofweights=0, delta=0, children=children }
Line 1,655 ⟶ 1,911:
end
print("NAME_HIERARCHY |WEIGHT |COVERAGE |DELTA |")
printnode(root,0)</langsyntaxhighlight>
{{out}}
<pre>NAME_HIERARCHY |WEIGHT |COVERAGE |DELTA |
Line 1,700 ⟶ 1,956:
wine_cellar | 1 | 1.000000 | 0.000000 |
cinema | 1 | 0.750000 | 0.016667 |</pre>
 
=={{header|Nim}}==
{{trans|Go}}
<syntaxhighlight lang="nim">import strformat, strutils
 
type
 
FCNode = ref object
name: string
weight: int
coverage: float
children: seq[FCNode]
parent: FCNode
 
func newFCNode(name: string; weight: int; coverage: float): FCNode =
FCNode(name: name, weight: weight, coverage: coverage)
 
# Forward reference.
func updateCoverage(n: FCNode)
 
func addChildren(n: FCNode; nodes: openArray[FCNode]) =
for node in nodes:
node.parent = n
n.children = @nodes
n.updateCoverage()
 
func setCoverage(n: FCNode; value: float) =
if n.coverage != value:
n.coverage = value
# Update any parent's coverage.
if not n.parent.isNil:
n.parent.updateCoverage()
 
func updateCoverage(n: FCNode) =
var v1 = 0.0
var v2 = 0
for node in n.children:
v1 += node.weight.toFloat * node.coverage
v2 += node.weight
n.setCoverage(v1 / v2.toFloat)
 
proc show(n: FCNode; level: int) =
let indent = level * 4
let nl = n.name.len + indent
const Sep = "|"
echo &"{n.name.align(nl)}{Sep.align(32-nl)} {n.weight:>3d} | {n.coverage:8.6f} |"
for child in n.children:
child.show(level + 1)
 
#———————————————————————————————————————————————————————————————————————————————————————————————————
 
let houses = [newFCNode("house1", 40, 0), newFCNode("house2", 60, 0)]
 
let house1 = [
newFCNode("bedrooms", 1, 0.25),
newFCNode("bathrooms", 1, 0),
newFCNode("attic", 1, 0.75),
newFCNode("kitchen", 1, 0.1),
newFCNode("living_rooms", 1, 0),
newFCNode("basement", 1, 0),
newFCNode("garage", 1, 0),
newFCNode("garden", 1, 0.8)]
 
let house2 = [
newFCNode("upstairs", 1, 0),
newFCNode("groundfloor", 1, 0),
newFCNode("basement", 1, 0)]
 
let h1Bathrooms = [
newFCNode("bathroom1", 1, 0.5),
newFCNode("bathroom2", 1, 0),
newFCNode("outside_lavatory", 1, 1)]
 
let h1LivingRooms = [
newFCNode("lounge", 1, 0),
newFCNode("dining_room", 1, 0),
newFCNode("conservatory", 1, 0),
newFCNode("playroom", 1, 1)]
 
let h2Upstairs = [
newFCNode("bedrooms", 1, 0),
newFCNode("bathroom", 1, 0),
newFCNode("toilet", 1, 0),
newFCNode("attics", 1, 0.6)]
 
let h2Groundfloor = [
newFCNode("kitchen", 1, 0),
newFCNode("living_rooms", 1, 0),
newFCNode("wet_room_&_toilet", 1, 0),
newFCNode("garage", 1, 0),
newFCNode("garden", 1, 0.9),
newFCNode("hot_tub_suite", 1, 1)]
 
let h2Basement = [
newFCNode("cellars", 1, 1),
newFCNode("wine_cellar", 1, 1),
newFCNode("cinema", 1, 0.75)]
 
let h2UpstairsBedrooms = [
newFCNode("suite_1", 1, 0),
newFCNode("suite_2", 1, 0),
newFCNode("bedroom_3", 1, 0),
newFCNode("bedroom_4", 1, 0)]
 
let h2GroundfloorLivingRooms = [
newFCNode("lounge", 1, 0),
newFCNode("dining_room", 1, 0),
newFCNode("conservatory", 1, 0),
newFCNode("playroom", 1, 0)]
 
let cleaning = newFCNode("cleaning", 1, 0)
 
house1[1].addChildren(h1Bathrooms)
house1[4].addChildren(h1LivingRooms)
houses[0].addChildren(house1)
 
h2Upstairs[0].addChildren(h2UpstairsBedrooms)
house2[0].addChildren(h2Upstairs)
h2Groundfloor[1].addChildren(h2GroundfloorLivingRooms)
house2[1].addChildren(h2Groundfloor)
house2[2].addChildren(h2Basement)
houses[1].addChildren(house2)
 
cleaning.addChildren(houses)
let topCoverage = cleaning.coverage
echo &"TOP COVERAGE = {topCoverage:8.6f}\n"
echo "NAME HIERARCHY | WEIGHT | COVERAGE |"
cleaning.show(0)
 
h2Basement[2].setCoverage(1) # Change Cinema node coverage to 1.
let diff = cleaning.coverage - topCoverage
echo "\nIf the coverage of the Cinema node were increased from 0.75 to 1"
echo &"the top level coverage would increase by {diff:8.6f} to {topCoverage + diff:8.6f}"
h2Basement[2].setCoverage(0.75) # Restore to original value if required.</syntaxhighlight>
 
{{out}}
<pre>TOP COVERAGE = 0.409167
 
NAME HIERARCHY | WEIGHT | COVERAGE |
cleaning | 1 | 0.409167 |
house1 | 40 | 0.331250 |
bedrooms | 1 | 0.250000 |
bathrooms | 1 | 0.500000 |
bathroom1 | 1 | 0.500000 |
bathroom2 | 1 | 0.000000 |
outside_lavatory | 1 | 1.000000 |
attic | 1 | 0.750000 |
kitchen | 1 | 0.100000 |
living_rooms | 1 | 0.250000 |
lounge | 1 | 0.000000 |
dining_room | 1 | 0.000000 |
conservatory | 1 | 0.000000 |
playroom | 1 | 1.000000 |
basement | 1 | 0.000000 |
garage | 1 | 0.000000 |
garden | 1 | 0.800000 |
house2 | 60 | 0.461111 |
upstairs | 1 | 0.150000 |
bedrooms | 1 | 0.000000 |
suite_1 | 1 | 0.000000 |
suite_2 | 1 | 0.000000 |
bedroom_3 | 1 | 0.000000 |
bedroom_4 | 1 | 0.000000 |
bathroom | 1 | 0.000000 |
toilet | 1 | 0.000000 |
attics | 1 | 0.600000 |
groundfloor | 1 | 0.316667 |
kitchen | 1 | 0.000000 |
living_rooms | 1 | 0.000000 |
lounge | 1 | 0.000000 |
dining_room | 1 | 0.000000 |
conservatory | 1 | 0.000000 |
playroom | 1 | 0.000000 |
wet_room_&_toilet | 1 | 0.000000 |
garage | 1 | 0.000000 |
garden | 1 | 0.900000 |
hot_tub_suite | 1 | 1.000000 |
basement | 1 | 0.916667 |
cellars | 1 | 1.000000 |
wine_cellar | 1 | 1.000000 |
cinema | 1 | 0.750000 |
 
If the coverage of the Cinema node were increased from 0.75 to 1
the top level coverage would increase by 0.016667 to 0.425833</pre>
 
=={{header|Perl}}==
<langsyntaxhighlight lang="perl">use strict;
use warnings;
 
Line 1,775 ⟶ 2,215:
wine_cellar | |1 |
cinema | |0.75 |
</syntaxhighlight>
</lang>
{{out}}
<pre style="height:20ex" style="font-size:80%;">NAME_HIERARCHY |WEIGHT |COVERAGE |
Line 1,822 ⟶ 2,262:
 
=={{header|Phix}}==
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>-- demo\rosetta\Functional_coverage_tree.exw
<span style="color: #000080;font-style:italic;">--
constant data = """
-- demo\rosetta\Functional_coverage_tree.exw
NAME_HIERARCHY | WEIGHT | COVERAGE |
-- =========================================
cleaning | | |
--</span>
house1 |40 | |
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
bedrooms | |0.25 |
<span style="color: #008080;">constant</span> <span style="color: #000000;">data</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"""
bathrooms | | |
NAME_HIERARCHY bathroom1 | WEIGHT |0.5 COVERAGE |
cleaning bathroom2 | | |
house1 outside_lavatory | |140 | |
attic bedrooms | |0.7525 |
kitchen bathrooms | |0.1 |
living_rooms bathroom1 | | | |0.5 |
lounge bathroom2 | | |
dining_room outside_lavatory | | 1 |
attic conservatory | | |0.75 |
kitchen playroom | |0.1 |
basement living_rooms | | |
garage lounge | | |
garden dining_room | | | |0.8 |
house2 conservatory | |60 | |
upstairs playroom | | 1 |
basement bedrooms | | |
garage suite_1 | | |
garden suite_2 | | 0.8 |
house2 bedroom_3 | |60 | |
upstairs bedroom_4 | | |
bathroom bedrooms | | |
toilet suite_1 | | |
attics suite_2 | |0.6 |
groundfloor bedroom_3 | | |
kitchen bedroom_4 | | |
living_rooms bathroom | | |
toilet lounge | | |
attics dining_room | | | |0.6 |
groundfloor conservatory | | |
kitchen playroom | | |
wet_room_&_toilet living_rooms | | |
garage lounge | | |
garden dining_room | | | |0.9 |
hot_tub_suite conservatory | |1 |
basement playroom | | |
cellars wet_room_&_toilet | | |1 |
wine_cellar garage | |1 |
cinema garden | |0.759 |
hot_tub_suite | |1 |
"""
basement | | |
sequence lines = split(data,"\n",no_empty:=true),
pi = {}, cellars -- indents (to locate parents) | |1 |
pdx = {}, --wine_cellar indexes for "" | |1 |
cinema | |0.75 |
children
"""</span>
string desc, weights, covers
<span style="color: #004080;">sequence</span> <span style="color: #000000;">lines</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">split</span><span style="color: #0000FF;">(</span><span style="color: #000000;">data</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">),</span>
integer parent, child
<span style="color: #000000;">pi</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{},</span> <span style="color: #000080;font-style:italic;">-- indents (to locate parents)</span>
atom weight, coverage, childw = 0
<span style="color: #000000;">pdx</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{},</span> <span style="color: #000080;font-style:italic;">-- indexes for ""</span>
enum DESC, WEIGHT, COVERAGE, PARENT, CHILDREN, CHILDW
<span style="color: #000000;">children</span>
lines[1] &= " SHARE OF RESIDUE"
<span style="color: #004080;">string</span> <span style="color: #000000;">desc</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">weights</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">covers</span>
for i=2 to length(lines) do
<span style="color: #004080;">integer</span> <span style="color: #000000;">parent</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">child</span>
-- decode text to useable data, link up parents & children
<span style="color: #004080;">atom</span> <span style="color: #000000;">weight</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">coverage</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">childw</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
{desc,weights,covers} = split(lines[i],"|")
<span style="color: #008080;">enum</span> <span style="color: #000000;">DESC</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">WEIGHT</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">COVERAGE</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">PARENT</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">CHILDREN</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">CHILDW</span>
-- (nb this assumes /totally/ consistent indenting)
<span style="color: #000000;">lines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">&=</span> <span style="color: #008000;">" SHARE OF RESIDUE"</span>
integer indent = length(desc)-length(trim_head(desc)),
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lines</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
k = find(indent,pi)
<span style="color: #000080;font-style:italic;">-- decode text to useable data, link up parents & children</span>
if k=0 then
<span style="color: #0000FF;">{</span><span style="color: #000000;">desc</span><span style="color: #0000FF;">,</span><span style="color: #000000;">weights</span><span style="color: #0000FF;">,</span><span style="color: #000000;">covers</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">split</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #008000;">"|"</span><span style="color: #0000FF;">)</span>
pi = append(pi,indent)
<span style="color: #000080;font-style:italic;">-- (nb this assumes /totally/ consistent indenting)</span>
pdx = append(pdx,0)
<span style="color: #004080;">integer</span> <span style="color: #000000;">indent</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">desc</span><span style="color: #0000FF;">)-</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">trim_head</span><span style="color: #0000FF;">(</span><span style="color: #000000;">desc</span><span style="color: #0000FF;">)),</span>
k = length(pi)
<span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">indent</span><span style="color: #0000FF;">,</span><span style="color: #000000;">pi</span><span style="color: #0000FF;">)</span>
end if
<span style="color: #008080;">if</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
pdx[k] = i
<span style="color: #000000;">pi</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pi</span><span style="color: #0000FF;">,</span><span style="color: #000000;">indent</span><span style="color: #0000FF;">)</span>
parent = 0
<span style="color: #000000;">pdx</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pdx</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)</span>
if k>1 then
<span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pi</span><span style="color: #0000FF;">)</span>
parent = pdx[k-1]
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
lines[parent][CHILDREN] &= i
<span style="color: #000000;">pdx</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">i</span>
end if
<span style="color: #000000;">parent</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
children = {}
<span style="color: #008080;">if</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">></span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span>
weight = to_number(trim(weights),1)
<span style="color: #000000;">parent</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">pdx</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
coverage = to_number(trim(covers),0)
<span style="color: #000080;font-style:italic;">-- lines[parent][CHILDREN] &= i</span>
lines[i] = {desc, weight, coverage, parent, children, childw}
<span style="color: #000000;">lines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">parent</span><span style="color: #0000FF;">][</span><span style="color: #000000;">CHILDREN</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">parent</span><span style="color: #0000FF;">][</span><span style="color: #000000;">CHILDREN</span><span style="color: #0000FF;">])</span> <span style="color: #0000FF;">&</span> <span style="color: #000000;">i</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
for i=length(lines) to 2 by -1 do
<span style="color: #000000;">children</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
-- calculate the parent coverages, and save child weight sums
<span style="color: #000000;">weight</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">to_number</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">trim</span><span style="color: #0000FF;">(</span><span style="color: #000000;">weights</span><span style="color: #0000FF;">),</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
children = lines[i][CHILDREN]
<span style="color: #000000;">coverage</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">to_number</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">trim</span><span style="color: #0000FF;">(</span><span style="color: #000000;">covers</span><span style="color: #0000FF;">),</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)</span>
if length(children) then
<span style="color: #000000;">lines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">desc</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">weight</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">coverage</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">parent</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">children</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">childw</span><span style="color: #0000FF;">}</span>
coverage = 0
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
childw = 0
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lines</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">to</span> <span style="color: #000000;">2</span> <span style="color: #008080;">by</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
for c=1 to length(children) do
<span style="color: #000080;font-style:italic;">-- calculate the parent coverages, and save child weight sums</span>
child = children[c]
<span style="color: #000000;">children</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">lines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">CHILDREN</span><span style="color: #0000FF;">]</span>
atom w = lines[child][WEIGHT]
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">children</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
coverage += lines[child][COVERAGE]*w
<span style="color: #000000;">coverage</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
childw += w
<span style="color: #000000;">childw</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
end for
<span style="color: #008080;">for</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">children</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
lines[i][COVERAGE] = coverage/childw
<span style="color: #000000;">child</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">children</span><span style="color: #0000FF;">[</span><span style="color: #000000;">c</span><span style="color: #0000FF;">]</span>
lines[i][CHILDW] = childw -- (save for next loop)
<span style="color: #004080;">atom</span> <span style="color: #000000;">w</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">lines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">child</span><span style="color: #0000FF;">][</span><span style="color: #000000;">WEIGHT</span><span style="color: #0000FF;">]</span>
end if
<span style="color: #000000;">coverage</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">lines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">child</span><span style="color: #0000FF;">][</span><span style="color: #000000;">COVERAGE</span><span style="color: #0000FF;">]*</span><span style="color: #000000;">w</span>
end for
<span style="color: #000000;">childw</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">w</span>
for i=length(lines) to 2 by -1 do
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
-- calculate the share of residue, and format lines
<span style="color: #000000;">lines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">COVERAGE</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">coverage</span><span style="color: #0000FF;">/</span><span style="color: #000000;">childw</span>
child = i
<span style="color: #000000;">lines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">CHILDW</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">childw</span> <span style="color: #000080;font-style:italic;">-- (save for next loop)</span>
{desc, weight, coverage, parent} = lines[i]
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
atom residue = 1-coverage
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
while parent do
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lines</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">to</span> <span style="color: #000000;">2</span> <span style="color: #008080;">by</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
residue *= lines[child][WEIGHT]/lines[parent][CHILDW]
<span style="color: #000080;font-style:italic;">-- calculate the share of residue, and format lines</span>
{child, parent} = {parent, lines[parent][PARENT]}
<span style="color: #000000;">child</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">i</span>
end while
<span style="color: #0000FF;">{</span><span style="color: #000000;">desc</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">weight</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">coverage</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">parent</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">lines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
lines[i] = sprintf("%-32s| %6d | %-8g | %g",{desc,weight,coverage,residue})
<span style="color: #004080;">atom</span> <span style="color: #000000;">residue</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">-</span><span style="color: #000000;">coverage</span>
end for
<span style="color: #008080;">while</span> <span style="color: #000000;">parent</span> <span style="color: #008080;">do</span>
puts(1,join(lines,"\n")&"\n")</lang>
<span style="color: #000000;">residue</span> <span style="color: #0000FF;">*=</span> <span style="color: #000000;">lines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">child</span><span style="color: #0000FF;">][</span><span style="color: #000000;">WEIGHT</span><span style="color: #0000FF;">]/</span><span style="color: #000000;">lines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">parent</span><span style="color: #0000FF;">][</span><span style="color: #000000;">CHILDW</span><span style="color: #0000FF;">]</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">child</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">parent</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">parent</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">lines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">parent</span><span style="color: #0000FF;">][</span><span style="color: #000000;">PARENT</span><span style="color: #0000FF;">]}</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #000000;">lines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%-32s| %6d | %-8g | %g"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">desc</span><span style="color: #0000FF;">,</span><span style="color: #000000;">weight</span><span style="color: #0000FF;">,</span><span style="color: #000000;">coverage</span><span style="color: #0000FF;">,</span><span style="color: #000000;">residue</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lines</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">)&</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">wait_key</span><span style="color: #0000FF;">()</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 1,978 ⟶ 2,426:
It's actually some of the raw code used when researching this task.
 
<langsyntaxhighlight lang="python">from itertools import zip_longest
 
 
Line 2,130 ⟶ 2,578:
print('\n\nTOP COVERAGE = %f\n' % covercalc(lstc))
depth_first(lstc)
pptreefields(['NAME_HIERARCHY WEIGHT COVERAGE'.split()] + lstc)</langsyntaxhighlight>
 
{{out}}
Line 2,182 ⟶ 2,630:
A cleaner implementation that uses the class static variable path2node as in the previous example so you don't have to traverse the tree to work out the position to add new nodes. This relies on parent nodes appearing before their children which is the case in the order of the add_node calls.
 
<langsyntaxhighlight lang="python"># -*- coding: utf-8 -*-
 
SPACES = 4
Line 2,308 ⟶ 2,756:
assert isclose((delta + cover), 1.0), "Top level delta + coverage should " \
"equal 1 instead of (%f + %f)" % (delta, cover)
</syntaxhighlight>
</lang>
 
{{out}}
Line 2,375 ⟶ 2,823:
Mainly uses pre-existing generic functions, including '''forestFromLineIndents''', '''foldTree''' and '''fmapTree''':
{{Works with|Python|3.7}}
<langsyntaxhighlight lang="python">'''Functional coverage tree'''
 
from itertools import chain, product
Line 2,837 ⟶ 3,285:
wine_cellar | |1 |
cinema | |0.75 |'''
main()</langsyntaxhighlight>
{{Out}}
<pre>NAME_HIERARCHY | WEIGHT | COVERAGE | SHARE OF RESIDUE
Line 2,888 ⟶ 3,336:
(in this case <code>data/functional-coverage.txt</code>).
 
<langsyntaxhighlight lang="racket">#lang racket/base
(require racket/list racket/string racket/match racket/format racket/file)
 
Line 2,959 ⟶ 3,407:
(for-each
(compose print-coverage-tree find-wght-cvrg)
(build-hierarchies (report->indent.c/e-list (file->string "data/functional-coverage.txt")))))</langsyntaxhighlight>
 
{{out}}
Line 3,010 ⟶ 3,458:
(formerly Perl 6)
{{trans|Perl}}
<syntaxhighlight lang="raku" perl6line>sub walktree ($data) {
my (@parts, $cnt);
 
Line 3,081 ⟶ 3,529:
cinema | |0.75 |
END
</syntaxhighlight>
</lang>
{{out}}
<pre style="font-size:70%;">NAME_HIERARCHY |WEIGHT |COVERAGE |
Line 3,132 ⟶ 3,580:
{{trans|Kotlin}}
 
<langsyntaxhighlight lang="swift">import Foundation
 
extension String {
Line 3,298 ⟶ 3,746:
print("\nIf the coverage of the Cinema node were increased from 0.75 to 1.0")
print("the top level coverage would increase by ")
print("\(String(format: "%8.6f", diff)) to \(String(format: "%8.6f", top))")</langsyntaxhighlight>
 
{{out}}
Line 3,354 ⟶ 3,802:
{{trans|Kotlin}}
{{libheader|Wren-fmt}}
<langsyntaxhighlight ecmascriptlang="wren">import "./fmt" for Fmt
 
class FCNode {
Line 3,500 ⟶ 3,948:
System.write("the top level coverage would increase by ")
Fmt.print("$8.6f to $8.6f", diff, topCoverage + diff)
h2Basement[2].coverage = 0.75 // restore to original value if required</langsyntaxhighlight>
 
{{out}}
9,476

edits