From 010a9b3b2768b94ad076277e42996ae894f90a22 Mon Sep 17 00:00:00 2001 From: NunoSempere Date: Wed, 22 Sep 2021 21:45:18 +0200 Subject: [PATCH] feat: Added GiveWell points of comparison Taken from: https://docs.google.com/spreadsheets/d/11HsJLpq0Suf3SK_PmzzWpK1tr_BTd364j0l3xVvSCQw/edit#gid=1362437801 --- lib/slider.js | 7 +- pages/index.js | 204 ++++++++++++++++++------------------ pages/listOfMoralGoods.json | 29 +++++ 3 files changed, 136 insertions(+), 104 deletions(-) create mode 100644 pages/listOfMoralGoods.json diff --git a/lib/slider.js b/lib/slider.js index 4a4e33d..830eb8c 100644 --- a/lib/slider.js +++ b/lib/slider.js @@ -16,7 +16,7 @@ const railStyle = { position: 'absolute', width: '100%', height: 15, - marginTop: 30, + marginTop: 25, borderRadius: 5, backgroundColor: 'lightgrey', } @@ -77,12 +77,13 @@ function Track({ source, target, getTrackProps }) { /* Body */ // Two functions, essentially identical. export function SliderElement({ onChange, value, displayFunction }) { - + let toLogDomain = (arr) => [Math.log(arr[0])/Math.log(10), Math.log(arr[1])/Math.log(10)] return ( diff --git a/pages/index.js b/pages/index.js index f3add9a..83d60fb 100644 --- a/pages/index.js +++ b/pages/index.js @@ -2,43 +2,45 @@ import Head from 'next/head' import React, { useState } from "react"; import fs from 'fs'; import path from 'path'; -import {DrawGraph, removeOldSvg} from '../lib/labeledgraph'; +import { DrawGraph, removeOldSvg } from '../lib/labeledgraph'; import { SliderElement, SubmitSliderButton } from "../lib/slider"; -import {DisplayElement} from '../lib/displayElement' -import {DisplayAsMarkdown} from '../lib/displayAsMarkdown' -import {CreateTableWithDistances} from '../lib/findPaths' -import {TextAreaForJson} from "../lib/textAreaForJson" +import { DisplayElement } from '../lib/displayElement' +import { DisplayAsMarkdown } from '../lib/displayAsMarkdown' +import { CreateTableWithDistances } from '../lib/findPaths' +import { TextAreaForJson } from "../lib/textAreaForJson" // Utilities let increasingList = (n) => Array.from(Array(n).keys()) -let buildLinks = quantitativeComparisons => quantitativeComparisons.map(([element1, element2, distance]) => ({source: element1, target: element2, distance: distance})) +let buildLinks = quantitativeComparisons => quantitativeComparisons.map(([element1, element2, distance]) => ({ source: element1, target: element2, distance: distance })) -Array.prototype.containsArray = function(val) { +Array.prototype.containsArray = function (val) { var hash = {}; - for(var i=0; i { +let checkIfListIsOrdered = (arr, binaryComparisons) => { let l = arr.length let isOrdered = true - for(let i=0; i 10**value >= 3 ? Math.round(10**value) : Math.round(10*10**value)/10 +let transformSliderValueToActualValue = value => 10 ** value //>= 2 ? Math.round(10 ** value) : Math.round(10 * 10 ** value) / 10 +let truncateValueForDisplay = value => value > 10 ? Math.round(value) : Math.round(value*10)/10 +let transformSliderValueToPracticalValue = value => truncateValueForDisplay(transformSliderValueToActualValue(value)) let displayFunctionSlider = (value) => { let result - if(value >= 0){ - result = simplifySliderValue(value) - }else{ - let inverseresult = simplifySliderValue(-value) + if (value >= 0) { + result = transformSliderValueToPracticalValue(value) + } else { + let inverseresult = transformSliderValueToPracticalValue(-value) result = `1/${inverseresult}` } result = `The first option is ${result}x as valuable as the second one` @@ -46,34 +48,34 @@ let displayFunctionSlider = (value) => { }; -let nicelyFormatLinks = (quantitativeComparisons , listOfElements) => quantitativeComparisons.map(([element1, element2, distance]) => ({source: listOfElements[element1].name, target: listOfElements[element2].name, distance: distance})) +let nicelyFormatLinks = (quantitativeComparisons, listOfElements) => quantitativeComparisons.map(([element1, element2, distance]) => ({ source: listOfElements[element1].name, target: listOfElements[element2].name, distance: distance })) /* React components */ // fs can only be used here. export async function getStaticProps() { //getServerSideProps // const { metaforecasts } = await getForecasts(); - const directory = path.join(process.cwd(),"pages") - let listOfPosts = JSON.parse(fs.readFileSync(path.join(directory, 'listOfPosts.json'), 'utf8')); + const directory = path.join(process.cwd(), "pages") + let listOfMoralGoods = JSON.parse(fs.readFileSync(path.join(directory, 'listOfMoralGoods.json'), 'utf8')); //console.log(directory) //console.log("metaforecasts", metaforecasts) return { props: { - listOfElementsDefault: listOfPosts, + listOfElementsDefault: listOfMoralGoods, }, }; } // Main react component -export default function Home({listOfElementsDefault}) { +export default function Home({ listOfElementsDefault }) { // State - let initialListOfElements = listOfElementsDefault.map((element, i) => ({...element, id: i})) + let initialListOfElements = listOfElementsDefault.map((element, i) => ({ ...element, id: i })) let initialPosList = increasingList(listOfElementsDefault.length) // [0,1,2,3,4] //let listOfElements = listOfElementsDefault.map((element, i) => ({...element, id: i})) //let list = increasingList(listOfElementsDefault.length) // [0,1,2,3,4] //let initialComparePair = [list[list.length-2], list[list.length-1]] - let initialComparePair = [initialPosList[initialPosList.length-2], initialPosList[initialPosList .length-1]] + let initialComparePair = [initialPosList[initialPosList.length - 2], initialPosList[initialPosList.length - 1]] let initialSliderValue = 0 let initialBinaryComparisons = [] let initialQuantitativeComparisons = [] @@ -93,7 +95,7 @@ export default function Home({listOfElementsDefault}) { const [binaryComparisons, setBinaryComparisons] = useState(initialBinaryComparisons) const [quantitativeComparisons, setQuantitativeComparisons] = useState(initialQuantitativeComparisons) // More expressive, but more laborious to search through. For the ordering step, I only manipulate the binaryComparisons. - const [isListOrdered, setIsListOrdered] = useState(initialIsListOdered) + const [isListOrdered, setIsListOrdered] = useState(initialIsListOdered) const [orderedList, setOrderedList] = useState(initialOrderedList) let [showAdvancedOptions, changeShowAdvanceOptions] = useState(initialShowAdvancedOptions); @@ -101,7 +103,7 @@ export default function Home({listOfElementsDefault}) { let [showChangeDataSet, changeshowChangeDataSet] = useState(initialShowChangeDataSet); let restart = (posList) => { - setToComparePair([posList[posList.length-2], posList[posList.length-1]]) + setToComparePair([posList[posList.length - 2], posList[posList.length - 1]]) setSliderValue(initialSliderValue) setBinaryComparisons(initialBinaryComparisons) setQuantitativeComparisons(initialQuantitativeComparisons) @@ -109,14 +111,14 @@ export default function Home({listOfElementsDefault}) { setOrderedList(initialOrderedList) removeOldSvg() } - + let changeDataSet = (listOfElementsNew) => { - listOfElementsNew = - listOfElementsNew.map((element, i) => ({...element, id: i})) + listOfElementsNew = + listOfElementsNew.map((element, i) => ({ ...element, id: i })) let newPosList = increasingList(listOfElementsNew.length) setListOfElements(listOfElementsNew) setPosList(increasingList(listOfElementsNew.length)) - setToComparePair([newPosList[newPosList.length-2], newPosList[newPosList.length-1]]) + setToComparePair([newPosList[newPosList.length - 2], newPosList[newPosList.length - 1]]) restart(newPosList) } @@ -124,9 +126,9 @@ export default function Home({listOfElementsDefault}) { let compareTwoElements = (newBinaryComparisons, element1, element2) => { let element1Greater = newBinaryComparisons.containsArray([element1, element2]) let element2Greater = newBinaryComparisons.containsArray([element2, element1]) - if(element1Greater || element2Greater){ + if (element1Greater || element2Greater) { return element1Greater && !element2Greater - } else{ + } else { setToComparePair([element1, element2]) //console.log(`No comparison found between ${element1} and ${element2}`) //console.log(`Comparisons:`) @@ -137,11 +139,11 @@ export default function Home({listOfElementsDefault}) { function merge(newBinaryComparisons, left, right) { let sortedArr = []; // the sorted elements will go here - + while (left.length && right.length) { // insert the biggest element to the sortedArr let comparison = compareTwoElements(newBinaryComparisons, left[0], right[0]) - if(comparison == "No comparison found"){ + if (comparison == "No comparison found") { return "No comparison found; unable to proceed" } else if (comparison) { // left[0] > right[0] @@ -150,31 +152,31 @@ export default function Home({listOfElementsDefault}) { sortedArr.push(right.shift()); } } - + // use spread operator and create a new array, combining the three arrays return [...sortedArr, ...left, ...right]; // if they don't have the same size, the remaining ones will be greater than the ones before } - - function mergeSort({array, comparisons}) { - if(array == "No comparison found; unable to proceed"){ - return "No comparison found; unable to proceed" + + function mergeSort({ array, comparisons }) { + if (array == "No comparison found; unable to proceed") { + return "No comparison found; unable to proceed" } const half = array.length / 2; - + // the base case is array length <=1 if (array.length <= 1) { return array; } - + const left = array.slice(0, half); // the first half of the array const right = array.slice(half, array.length) // Note that splice is destructive. - let orderedFirstHalf = mergeSort({array:left, comparisons}) - let orderedSecondHalf = mergeSort({array:right, comparisons}) - if(orderedFirstHalf != "No comparison found; unable to proceed" && orderedSecondHalf != "No comparison found; unable to proceed"){ + let orderedFirstHalf = mergeSort({ array: left, comparisons }) + let orderedSecondHalf = mergeSort({ array: right, comparisons }) + if (orderedFirstHalf != "No comparison found; unable to proceed" && orderedSecondHalf != "No comparison found; unable to proceed") { let result = merge(comparisons, orderedFirstHalf, orderedSecondHalf); return result - }else{ - return "No comparison found; unable to proceed" + } else { + return "No comparison found; unable to proceed" } } @@ -187,11 +189,11 @@ export default function Home({listOfElementsDefault}) { let newBinaryComparisons = [...binaryComparisons, newComparison] //console.log("New binaryComparisons: ") //console.log(JSON.stringify(newBinaryComparisons, null, 4)); - setBinaryComparisons(newBinaryComparisons) - - let result = mergeSort({array: posList, comparisons: newBinaryComparisons}) + setBinaryComparisons(newBinaryComparisons) + + let result = mergeSort({ array: posList, comparisons: newBinaryComparisons }) //console.log(result) - if(result != "No comparison found; unable to proceed" && checkIfListIsOrdered(result, newBinaryComparisons)){ + if (result != "No comparison found; unable to proceed" && checkIfListIsOrdered(result, newBinaryComparisons)) { // console.log(`isListOrdered: ${isListOrdered}`) console.log("poslist@nextStepSimple") console.log(posList) @@ -203,16 +205,16 @@ export default function Home({listOfElementsDefault}) { } } - let nextStepSlider = ({posList, binaryComparisons, sliderValue, element1, element2}) => { - if(sliderValue < 0){ + let nextStepSlider = ({ posList, binaryComparisons, sliderValue, element1, element2 }) => { + if (sliderValue < 0) { sliderValue = -sliderValue; - [element1,element2] = [element2,element1] + [element1, element2] = [element2, element1] } console.log(`posList@nextStepSlider:`) console.log(posList) nextStepSimple(posList, binaryComparisons, element1, element2) - let newQuantitativeComparison = [element1, element2, simplifySliderValue(sliderValue)] + let newQuantitativeComparison = [element1, element2, transformSliderValueToPracticalValue(sliderValue)] let newQuantitativeComparisons = [...quantitativeComparisons, newQuantitativeComparison] setQuantitativeComparisons(newQuantitativeComparisons) @@ -231,37 +233,37 @@ export default function Home({listOfElementsDefault}) {

- Utility Function Extractor + Utility Function Extractor

-
+
-
nextStep(binaryComparisons, toComparePair[0], toComparePair[1])} - > -
- - -
+
nextStep(binaryComparisons, toComparePair[0], toComparePair[1])} + > +
+ +
-
nextStep(binaryComparisons, toComparePair[1], toComparePair[0])} - > -
- - -
+
+
nextStep(binaryComparisons, toComparePair[1], toComparePair[0])} + > +
+ +
+
-
+
(setSliderValue(event[0]))} - value={sliderValue} - displayFunction={displayFunctionSlider} - /> + className="flex items-center justify-center" + onChange={(event) => (setSliderValue(event[0]))} + value={sliderValue} + displayFunction={displayFunctionSlider} + />
- +
- - -
- - +
+ +
-
+
-
-
-
- -
- + +
+
-
+
{/* listOfElements[i]), null, 4)}> */}

Comparisons

- diff --git a/pages/listOfMoralGoods.json b/pages/listOfMoralGoods.json new file mode 100644 index 0000000..5d5f26a --- /dev/null +++ b/pages/listOfMoralGoods.json @@ -0,0 +1,29 @@ +[ + { + "name": "Doubling consumption for one person for one year", + "note": "(at fairly low levels of wealth)", + "isReferenceValue": true + }, + { + "name": "Averting the death of an individual under 5 from malaria" + }, + { + "name": "Averting the death of an individual 5 or older from malaria" + }, + { + "name": "Averting the death of a 6- to 59-month-old child", + "note": "(through Vitamin A Supplementation)" + }, + { + "name": "Averting the death of an individual under 5 from vaccine-preventable diseases" + }, + { + "name": "Averting the death of an individual 5-14 years old from vaccine-preventable diseases" + }, + { + "name": "Averting the death of an individual 15-49 years old from vaccine-preventable diseases" + }, + { + "name": "Averting the death of an individual 50-74 years old from vaccine-preventable diseases" + } +]