Improved the object structures I was using

This commit is contained in:
NunoSempere 2021-06-10 23:52:33 +02:00
parent 9766165060
commit 4d6abd382b
7 changed files with 104 additions and 171 deletions

View File

@ -17,7 +17,7 @@ if (!String.prototype.replaceAll) {
} }
export function DisplayAsMarkdown({markdowntext}){ export function DisplayAsMarkdown({markdowntext}){
console.log(markdowntext) //console.log(markdowntext)
markdowntext = markdowntext.replaceAll("\n", "\n\n") markdowntext = markdowntext.replaceAll("\n", "\n\n")
return( <ReactMarkdown return( <ReactMarkdown
plugins={[gfm]} plugins={[gfm]}

View File

@ -12,7 +12,7 @@ export function DisplayElement({element}){
<a href={element.url} target="_blank"> <a href={element.url} target="_blank">
<h2>{`${element.name}`}</h2> <h2>{`${element.name}`}</h2>
</a> </a>
{otherpairs.map(pair => <p>{`${pair.key}: ${pair.value}`}</p>)} {otherpairs.map(pair => <p key={pair.value}>{`${pair.key}: ${pair.value}`}</p>)}
</div> </div>
) )
} }

View File

@ -6,7 +6,7 @@ let avg = arr => arr.reduce((a,b) => (a+b)) / arr.length
/* Main function */ /* Main function */
function findPathsInner({sourceElementId, targetElementId, pathSoFar, links, listOfElements, maxLengthOfPath}){ function findPathsInner({sourceElementId, targetElementId, pathSoFar, links, nodes, maxLengthOfPath}){
let paths = [] let paths = []
if(maxLengthOfPath > 0){ if(maxLengthOfPath > 0){
@ -16,65 +16,47 @@ function findPathsInner({sourceElementId, targetElementId, pathSoFar, links, lis
((link.source == targetElementId) && (link.target == sourceElementId)) ((link.source == targetElementId) && (link.target == sourceElementId))
){ ){
paths.push(pathSoFar.concat(link).flat()) paths.push(pathSoFar.concat(link).flat())
//console.log(`Final path found at recursion level: ${maxLengthOfPath}. Source: ${sourceElementId}, target=${targetElementId}`)
//console.log(link)
} else if((link.source == sourceElementId)){ } else if((link.source == sourceElementId)){
let newPaths = findPathsInner({sourceElementId:link.target, targetElementId, pathSoFar: pathSoFar.concat(link).flat(), links, listOfElements, maxLengthOfPath: (maxLengthOfPath-1)}) let newPaths = findPathsInner({sourceElementId:link.target, targetElementId, pathSoFar: pathSoFar.concat(link).flat(), links, nodes, maxLengthOfPath: (maxLengthOfPath-1)})
if(newPaths.length != 0){ if(newPaths.length != 0){
//console.log(`New link, at recursion level: ${maxLengthOfPath}. Source: ${sourceElementId}, target=${targetElementId}. PathSoFar: ${pathSoFar}`)
//console.log(link)
//console.log(newPaths)
paths.push(...newPaths) paths.push(...newPaths)
} }
}else if((link.target == sourceElementId)){ }else if((link.target == sourceElementId)){
let newPaths = findPathsInner({sourceElementId:link.source, targetElementId, pathSoFar: pathSoFar.concat(link).flat(), links, listOfElements, maxLengthOfPath: (maxLengthOfPath-1)}) let newPaths = findPathsInner({sourceElementId:link.source, targetElementId, pathSoFar: pathSoFar.concat(link).flat(), links, nodes, maxLengthOfPath: (maxLengthOfPath-1)})
if(newPaths.length != 0){ if(newPaths.length != 0){
//console.log(`New link, at recursion level: ${maxLengthOfPath}. Source: ${sourceElementId}, target=${targetElementId}. PathSoFar: ${pathSoFar}`)
//console.log(link)
//console.log(newPaths)
paths.push(...newPaths) paths.push(...newPaths)
} }
} }
} }
} }
return paths return paths
} }
function findPaths({sourceElementId, targetElementId, links, listOfElements}){ function findPaths({sourceElementId, targetElementId, links, nodes}){
let positionSourceElement = listOfElements.map((element, i) => (element.id)).indexOf(sourceElementId) let positionSourceElement = nodes.map((element, i) => (element.id)).indexOf(sourceElementId)
let positionTargetElement = listOfElements.map((element, i) => (element.id)).indexOf(targetElementId) let positionTargetElement = nodes.map((element, i) => (element.id)).indexOf(targetElementId)
let maxLengthOfPath = Math.abs(positionSourceElement - positionTargetElement) let maxLengthOfPath = Math.abs(positionSourceElement - positionTargetElement)
console.log(maxLengthOfPath)
return findPathsInner({sourceElementId, targetElementId, pathSoFar: [], links, listOfElements, maxLengthOfPath}) return findPathsInner({sourceElementId, targetElementId, pathSoFar: [], links, nodes, maxLengthOfPath})
} }
function findDistance({sourceElementId, targetElementId, links, listOfElements}){ function findDistance({sourceElementId, targetElementId, nodes, links}){
let paths = findPaths({sourceElementId, targetElementId, links, listOfElements}) let paths = findPaths({sourceElementId, targetElementId, nodes, links})
// console.log(paths)
let weights = [] let weights = []
for(let path of paths){ for(let path of paths){
let currentSource = sourceElementId let currentSource = sourceElementId
let weight = 1 let weight = 1
// console.log(path)
for(let element of path){ for(let element of path){
// console.log(element)
// console.log(element.source)
// console.log(element.target)
let distance = 0 let distance = 0
if(element.source == currentSource){ if(element.source == currentSource){
// console.log("A")
distance = element.distance distance = element.distance
currentSource = element.target currentSource = element.target
}else if(element.target == currentSource){ }else if(element.target == currentSource){
// console.log("B")
distance = 1/Number(element.distance) distance = 1/Number(element.distance)
currentSource = element.source currentSource = element.source
} }
weight = weight*distance weight = weight*distance
// console.log(weight)
} }
weights.push(weight) weights.push(weight)
@ -84,64 +66,53 @@ function findDistance({sourceElementId, targetElementId, links, listOfElements})
return weights.map(weight => Math.round(weight*100)/100) return weights.map(weight => Math.round(weight*100)/100)
} }
function findDistancesForAllElements({links, listOfElements}){ function findDistancesForAllElements({nodes, links}){
let referenceElement = listOfElements.filter(x => x.isReferenceValue)[0] let referenceElements = nodes.filter(x => x.isReferenceValue)
console.log(referenceElement.id) let midpoint = Math.round(nodes.length/2)
let distances = listOfElements.map(element =>{ let referenceElement = referenceElements.length > 0 ? referenceElements[0] : nodes[midpoint]
if(element.isReferenceValue){
return [1] let distances = nodes.map(element =>
}else{ element.isReferenceValue ? [1] : findDistance({sourceElementId: referenceElement.id, targetElementId: element.id, nodes, links})
// console.log({sourceElementId: referenceElement.id, targetElementId: element.id, links, listOfElements}) )
return findDistance({sourceElementId: Number(referenceElement.id), targetElementId: Number(element.id), links, listOfElements})
}
})
return distances return distances
} }
export function CreateTableWithDistances({isListOrdered, quantitativeComparisons, listOfElements, referenceValueId}){ export function CreateTableWithDistances({isListOrdered, nodes, links}){
if(!isListOrdered){ // listOfElements if(!isListOrdered){
console.log return (<div>{""}</div>)
console.log("List of Elements: ")
console.log(listOfElements)
return (<div></div>)
} else { } else {
console.log(`isListOrdered: ${isListOrdered}`) let distances = findDistancesForAllElements({nodes, links})
console.log("List Of Elements:") let rows = nodes.map((element, i) => ({id: element.id, name: element.name, distances: distances[i]}))
console.log(listOfElements)
let links = quantitativeComparisons.map(([element1, element2, distance]) => ({source: element1, target: element2, distance: distance}))
let distances = findDistancesForAllElements({links, listOfElements}) return(
<div>
let rows = listOfElements.map((element, i) => ({id: element.id, name: element.name, distances: distances[i]})) <table className="">
<thead >
return(<div> <tr >
<table className=""> <th >Id</th>
<thead > <th>&nbsp;&nbsp;&nbsp;</th>
<tr > <th >Element</th>
<th >Id</th> <th> &nbsp;&nbsp;&nbsp;</th>
<th>&nbsp;&nbsp;&nbsp;</th> <th >Possible relative values</th>
<th >Element</th> <th> &nbsp;&nbsp;&nbsp;</th>
<th> &nbsp;&nbsp;&nbsp;</th> <th >Average relative value</th>
<th >Possible relative values</th> </tr>
<th> &nbsp;&nbsp;&nbsp;</th> </thead>
<th >Average relative value</th> <tbody>
</tr> {rows.map(row => <tr key={row.id}>
</thead> <td className="" >{row.id}</td>
<tbody> <td>&nbsp;&nbsp;&nbsp;</td>
{rows.map(row => <tr> <td className="">{row.name}</td>
<td className="">{row.id}</td> <td>&nbsp;&nbsp;&nbsp;</td>
<td>&nbsp;&nbsp;&nbsp;</td> <td className="">{JSON.stringify(row.distances, null, 2)}</td>
<td className="">{row.name}</td> <td>&nbsp;&nbsp;&nbsp;</td>
<td>&nbsp;&nbsp;&nbsp;</td> <td className="">{avg(row.distances).toFixed(2)}</td>
<td className="">{JSON.stringify(row.distances, null, 2)}</td> </tr>
<td>&nbsp;&nbsp;&nbsp;</td> )}
<td className="">{avg(row.distances).toFixed(2)}</td> </tbody>
</tr> </table>
)} </div>
</tbody> )
</table>
</div>
)
} }
} }
@ -152,16 +123,16 @@ export function CreateTableWithDistances({isListOrdered, quantitativeComparisons
/* /*
const directory = path.join(process.cwd(),"pages") const directory = path.join(process.cwd(),"pages")
let links = JSON.parse(fs.readFileSync(path.join(directory, 'distancesExample.json'), 'utf8')); let links = JSON.parse(fs.readFileSync(path.join(directory, 'distancesExample.json'), 'utf8'));
let listOfElements = JSON.parse(fs.readFileSync(path.join(directory, 'listOfPosts.json'), 'utf8')); let nodes = JSON.parse(fs.readFileSync(path.join(directory, 'listOfPosts.json'), 'utf8'));
let paths = findPathsInner({sourceElementId:2, targetElementId:0, pathSoFar: [], links, listOfElements, maxLengthOfPath: 2}) let paths = findPathsInner({sourceElementId:2, targetElementId:0, pathSoFar: [], links, nodes, maxLengthOfPath: 2})
console.log(JSON.stringify(paths, null, 2)) console.log(JSON.stringify(paths, null, 2))
*/ */
/* /*
let paths = findPaths({sourceElementId:2, targetElementId:0, links, listOfElements}) let paths = findPaths({sourceElementId:2, targetElementId:0, links, nodes})
console.log(JSON.stringify(paths, null, 2)) console.log(JSON.stringify(paths, null, 2))
*/ */
/* /*
let distances = findDistance({sourceElementId:2, targetElementId:4, links, listOfElements}) let distances = findDistance({sourceElementId:2, targetElementId:4, links, nodes})
console.log(distances) console.log(distances)
*/ */

View File

@ -5,19 +5,7 @@ function getlength(number) {
return number.toString().length; return number.toString().length;
} }
function drawGraphInner(list, quantitativeComparisons){ function drawGraphInner({nodes, links}){
// Build the graph object
let nodes = list.map((x,i) => ({id: i, name: x}))
let links = quantitativeComparisons.map(([element1, element2, distance]) => ({source: list.indexOf(element1), target: list.indexOf(element2), distance: distance}))
console.log("Links")
console.log(links)
let data = ({
nodes,
links: links
})
console.log(data)
// Build the d3 graph // Build the d3 graph
let margin = {top: 0, right: 30, bottom: 20, left: 30}; let margin = {top: 0, right: 30, bottom: 20, left: 30};
@ -31,22 +19,21 @@ function drawGraphInner(list, quantitativeComparisons){
.append("g") .append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")"); .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
console.log(data) // List of node ids
// List of node names var nodeids = nodes.map(function(d){return d.id})
var nodeNames = data.nodes.map(function(d){return d.name})
// A linear scale to position the nodes on the X axis // A linear scale to position the nodes on the X axis
var x = d3.scalePoint() var x = d3.scalePoint()
.range([0, width]) .range([0, width])
.domain(nodeNames) .domain(nodeids)
// Add the circle for the nodes // Add the circle for the nodes
svg svg
.selectAll("mynodes") .selectAll("mynodes")
.data(data.nodes) .data(nodes)
.enter() .enter()
.append("circle") .append("circle")
.attr("cx", function(d){ return(x(d.name))}) .attr("cx", function(d){ return(x(d.id))})
.attr("cy", height-30) .attr("cy", height-30)
.attr("r", 8) .attr("r", 8)
.style("fill", "#69b3a2") .style("fill", "#69b3a2")
@ -54,37 +41,24 @@ function drawGraphInner(list, quantitativeComparisons){
// And give them a label // And give them a label
svg svg
.selectAll("mylabels") .selectAll("mylabels")
.data(data.nodes) .data(nodes)
.enter() .enter()
.append("text") .append("text")
.attr("x", function(d){ return(x(d.name))}) .attr("x", function(d){ return(x(d.id))})
.attr("y", height-10) .attr("y", height-10)
.text(function(d){ return(d.name)}) .text(function(d){ return(d.id)})
.style("text-anchor", "middle") .style("text-anchor", "middle")
// Add links between nodes.
// In the input data, links are provided between nodes -id-, not between node names.
// So one has to link ids and names
// Note Nuño: This is inefficient, and we could have built the data object to avoid this. However, every time I try to refactor this, the thing breaks.
var nodesById = {};
data.nodes.forEach(function (n) {
nodesById[n.id] = n;
});
// Cool, now if I do nodesById["2"].name I've got the name of the node with id 2
// Add the links // Add the links
svg svg
.selectAll('mylinks') .selectAll('mylinks')
.data(data.links) .data(links)
.enter() .enter()
.append('path') .append('path')
.attr('d', function (d) { .attr('d', function (d) {
let start = x(nodesById[d.source].name) let start = x(d.source)
// X position of start node on the X axis // X position of start node on the X axis
let end = x(nodesById[d.target].name) let end = x(d.target)
// X position of end node // X position of end node
return ['M', return ['M',
start, start,
@ -105,20 +79,20 @@ function drawGraphInner(list, quantitativeComparisons){
// labels for links // labels for links
svg svg
.selectAll('mylinks') .selectAll('mylinks')
.data(data.links) .data(links)
.enter() .enter()
.append("text") .append("text")
.attr("x", function(d){ .attr("x", function(d){
let start = x(nodesById[d.source].name) let start = x(d.source)
// X position of start node on the X axis // X position of start node on the X axis
let end = x(nodesById[d.target].name) let end = x(d.target)
// X position of end node // X position of end node
return start + (end-start)/2 -4*getlength(d.distance) return start + (end-start)/2 -4*getlength(d.distance)
}) })
.attr("y", function(d){ .attr("y", function(d){
let start = x(nodesById[d.source].name) let start = x(d.source)
// X position of start node on the X axis // X position of start node on the X axis
let end = x(nodesById[d.target].name) let end = x(d.target)
// X position of end node // X position of end node
return height-32-(Math.abs(start-end)/2)//height-30 return height-32-(Math.abs(start-end)/2)//height-30
}) })
@ -130,10 +104,10 @@ function drawGraphInner(list, quantitativeComparisons){
} }
export function DrawGraph({list, quantitativeComparisons, isListOrdered}) { export function DrawGraph({isListOrdered, nodes, links}) {
if(isListOrdered){ if(isListOrdered){
drawGraphInner(list, quantitativeComparisons); drawGraphInner({ nodes, links});
} }
return ( return (

View File

@ -11,6 +11,7 @@ import {CreateTableWithDistances} from '../lib/findPaths'
// Utilities // Utilities
let increasingList = (n) => Array.from(Array(n).keys()) let increasingList = (n) => Array.from(Array(n).keys())
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 = {}; var hash = {};
@ -20,7 +21,7 @@ Array.prototype.containsArray = function(val) {
return hash.hasOwnProperty(val); return hash.hasOwnProperty(val);
} }
let checkIfListIsOrdered = (arr, binaryComparisons) => { // list of ids let checkIfListIsOrdered = (arr, binaryComparisons) => {
let l = arr.length let l = arr.length
let isOrdered = true let isOrdered = true
for(let i=0; i<l-1; i++){ for(let i=0; i<l-1; i++){
@ -30,6 +31,7 @@ let checkIfListIsOrdered = (arr, binaryComparisons) => { // list of ids
} }
let simplifySliderValue = value => 10**value >= 3 ? Math.round(10**value) : Math.round(10*10**value)/10 let simplifySliderValue = value => 10**value >= 3 ? Math.round(10**value) : Math.round(10*10**value)/10
let displayFunctionSlider = (value) => { let displayFunctionSlider = (value) => {
let result let result
if(value >= 0){ if(value >= 0){
@ -45,13 +47,14 @@ let displayFunctionSlider = (value) => {
let nicelyFormatLinks = (quantitativeComparisons , list) => quantitativeComparisons.map(([element1, element2, distance]) => ({source: list.indexOf(element1), target: list.indexOf(element2), distance: distance})) let nicelyFormatLinks = (quantitativeComparisons , list) => quantitativeComparisons.map(([element1, element2, distance]) => ({source: list.indexOf(element1), target: list.indexOf(element2), distance: distance}))
// data /* React components */
// fs can only be used here.
export async function getStaticProps() { export async function getStaticProps() {
//getServerSideProps //getServerSideProps
// const { metaforecasts } = await getForecasts(); // const { metaforecasts } = await getForecasts();
const directory = path.join(process.cwd(),"pages") const directory = path.join(process.cwd(),"pages")
let listOfPosts = JSON.parse(fs.readFileSync(path.join(directory, 'listOfPosts.json'), 'utf8')); let listOfPosts = JSON.parse(fs.readFileSync(path.join(directory, 'listOfPosts.json'), 'utf8'));
console.log(directory) //console.log(directory)
//console.log("metaforecasts", metaforecasts) //console.log("metaforecasts", metaforecasts)
return { return {
props: { props: {
@ -60,16 +63,17 @@ export async function getStaticProps() {
}; };
} }
// Main // Main react component
export default function Home({listOfPosts}) { export default function Home({listOfPosts}) {
// State // State
let list = increasingList(listOfPosts.length)//[1,2,3,4,5,6,7,8,9,10] // listOfPosts.map(element => element.id)// let list = increasingList(listOfPosts.length) // [0,1,2,3,4]
let referenceValueId = 1//listOfPosts.filter(post => post.isReferenceValue || false)[0].id listOfPosts = listOfPosts.map((element, i) => ({...element, id: i}))
const [toComparePair, setToComparePair] = useState([list[list.length-2], list[list.length-1]])
const [binaryComparisons, setBinaryComparisons] = useState([])
const [toComparePair, setToComparePair] = useState([list[list.length-2], list[list.length-1]])
const [sliderValue, setSliderValue] = useState(0) const [sliderValue, setSliderValue] = useState(0)
const [quantitativeComparisons, setQuantitativeComparisons] = useState([])
const [binaryComparisons, setBinaryComparisons] = useState([])
const [quantitativeComparisons, setQuantitativeComparisons] = useState([]) // More expressive, but more laborious to search through. For the ordering step, I only manipulate the binaryComparisons.
const [isListOrdered, setIsListOrdered] = useState(false) const [isListOrdered, setIsListOrdered] = useState(false)
const [orderedList, setOrderedList] = useState([]) const [orderedList, setOrderedList] = useState([])
@ -82,9 +86,9 @@ export default function Home({listOfPosts}) {
return element1Greater && !element2Greater return element1Greater && !element2Greater
} else{ } else{
setToComparePair([element1, element2]) setToComparePair([element1, element2])
console.log(`No comparison found between ${element1} and ${element2}`) //console.log(`No comparison found between ${element1} and ${element2}`)
console.log(`Comparisons:`) //console.log(`Comparisons:`)
console.log(JSON.stringify(newBinaryComparisons, null, 4)); //console.log(JSON.stringify(newBinaryComparisons, null, 4));
return "No comparison found" return "No comparison found"
} }
} }
@ -134,19 +138,19 @@ export default function Home({listOfPosts}) {
} }
let nextStepSimple = (binaryComparisons, element1, element2) => { let nextStepSimple = (binaryComparisons, element1, element2) => {
console.log("Binary comparisons: ") //console.log("Binary comparisons: ")
console.log(JSON.stringify(binaryComparisons, null, 4)); //console.log(JSON.stringify(binaryComparisons, null, 4));
let newComparison = [element1, element2] // [element1, element2] let newComparison = [element1, element2] // [element1, element2]
let newBinaryComparisons = [...binaryComparisons, newComparison] let newBinaryComparisons = [...binaryComparisons, newComparison]
console.log("New binaryComparisons: ") //console.log("New binaryComparisons: ")
console.log(JSON.stringify(newBinaryComparisons, null, 4)); //console.log(JSON.stringify(newBinaryComparisons, null, 4));
setBinaryComparisons(newBinaryComparisons) setBinaryComparisons(newBinaryComparisons)
let result = mergeSort(list, newBinaryComparisons) let result = mergeSort(list, newBinaryComparisons)
console.log(result) //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(result) //console.log(result)
setIsListOrdered(true) setIsListOrdered(true)
setOrderedList(result) setOrderedList(result)
} }
@ -218,15 +222,14 @@ export default function Home({listOfPosts}) {
<DrawGraph <DrawGraph
isListOrdered={isListOrdered} isListOrdered={isListOrdered}
list={orderedList} nodes={orderedList.map(i => listOfPosts[i])}
quantitativeComparisons={quantitativeComparisons}> links={buildLinks(quantitativeComparisons)}>
</DrawGraph> </DrawGraph>
<div className={`inline items-center text-center mt-10 ${isListOrdered? "": "hidden" }`}> <div className={`inline items-center text-center mt-10 ${isListOrdered? "": "hidden" }`}>
<CreateTableWithDistances <CreateTableWithDistances
isListOrdered={isListOrdered} isListOrdered={isListOrdered}
quantitativeComparisons={quantitativeComparisons} nodes={orderedList.map(i => listOfPosts[i])}
listOfElements={orderedList.map(i => listOfPosts[i])} links={buildLinks(quantitativeComparisons)}
referenceValueId={referenceValueId}
> >
</CreateTableWithDistances> </CreateTableWithDistances>
</div> </div>

View File

@ -1,20 +1,17 @@
[ [
{ {
"id": 0,
"name": "Relative Impact of the First 10 EA Forum Prize Winners", "name": "Relative Impact of the First 10 EA Forum Prize Winners",
"url": "https://forum.effectivealtruism.org/posts/pqphZhx2nJocGCpwc/relative-impact-of-the-first-10-ea-forum-prize-winners", "url": "https://forum.effectivealtruism.org/posts/pqphZhx2nJocGCpwc/relative-impact-of-the-first-10-ea-forum-prize-winners",
"author": "Nuño Sempere", "author": "Nuño Sempere",
"karma": 80 "karma": 80
}, },
{ {
"id": 1,
"name": "Introducing Metaforecast: A Forecast Aggregator and Search Tool", "name": "Introducing Metaforecast: A Forecast Aggregator and Search Tool",
"url": "https://forum.effectivealtruism.org/posts/tEo5oXeSNcB3sYr8m/introducing-metaforecast-a-forecast-aggregator-and-search", "url": "https://forum.effectivealtruism.org/posts/tEo5oXeSNcB3sYr8m/introducing-metaforecast-a-forecast-aggregator-and-search",
"author": "Nuño Sempere", "author": "Nuño Sempere",
"karma": 115 "karma": 115
}, },
{ {
"id": 2,
"name": "Forecasting Prize Results", "name": "Forecasting Prize Results",
"url": "https://forum.effectivealtruism.org/posts/8QFWHzmur4roAcnCf/forecasting-prize-results", "url": "https://forum.effectivealtruism.org/posts/8QFWHzmur4roAcnCf/forecasting-prize-results",
"author": "Nuño Sempere", "author": "Nuño Sempere",
@ -22,14 +19,12 @@
"isReferenceValue": true "isReferenceValue": true
}, },
{ {
"id": 3,
"name": "A Funnel for Cause Candidates", "name": "A Funnel for Cause Candidates",
"url": "https://forum.effectivealtruism.org/posts/iRA4Dd2bfX9nukSo3/a-funnel-for-cause-candidates", "url": "https://forum.effectivealtruism.org/posts/iRA4Dd2bfX9nukSo3/a-funnel-for-cause-candidates",
"author": "Nuño Sempere", "author": "Nuño Sempere",
"karma": 34 "karma": 34
}, },
{ {
"id": 4,
"name": "2020: Forecasting in Review", "name": "2020: Forecasting in Review",
"url": "https://forum.effectivealtruism.org/posts/8shCj2eoQygQvtoZP/2020-forecasting-in-review", "url": "https://forum.effectivealtruism.org/posts/8shCj2eoQygQvtoZP/2020-forecasting-in-review",
"author": "Nuño Sempere", "author": "Nuño Sempere",

View File

@ -1,69 +1,59 @@
[ [
{ {
"id": "0",
"name": "Relative Impact of the First 10 EA Forum Prize Winners", "name": "Relative Impact of the First 10 EA Forum Prize Winners",
"url": "https://forum.effectivealtruism.org/posts/pqphZhx2nJocGCpwc/relative-impact-of-the-first-10-ea-forum-prize-winners", "url": "https://forum.effectivealtruism.org/posts/pqphZhx2nJocGCpwc/relative-impact-of-the-first-10-ea-forum-prize-winners",
"author": "Nuño Sempere", "author": "Nuño Sempere",
"karma": 80 "karma": 80
}, },
{ {
"id": "1",
"name": "Introducing Metaforecast: A Forecast Aggregator and Search Tool", "name": "Introducing Metaforecast: A Forecast Aggregator and Search Tool",
"url": "https://forum.effectivealtruism.org/posts/tEo5oXeSNcB3sYr8m/introducing-metaforecast-a-forecast-aggregator-and-search", "url": "https://forum.effectivealtruism.org/posts/tEo5oXeSNcB3sYr8m/introducing-metaforecast-a-forecast-aggregator-and-search",
"author": "Nuño Sempere", "author": "Nuño Sempere",
"karma": 115 "karma": 115
}, },
{ {
"id": "2",
"name": "Forecasting Prize Results", "name": "Forecasting Prize Results",
"url": "https://forum.effectivealtruism.org/posts/8QFWHzmur4roAcnCf/forecasting-prize-results", "url": "https://forum.effectivealtruism.org/posts/8QFWHzmur4roAcnCf/forecasting-prize-results",
"author": "Nuño Sempere", "author": "Nuño Sempere",
"karma": 44 "karma": 44
}, },
{ {
"id": "3",
"name": "A Funnel for Cause Candidates", "name": "A Funnel for Cause Candidates",
"url": "https://forum.effectivealtruism.org/posts/iRA4Dd2bfX9nukSo3/a-funnel-for-cause-candidates", "url": "https://forum.effectivealtruism.org/posts/iRA4Dd2bfX9nukSo3/a-funnel-for-cause-candidates",
"author": "Nuño Sempere", "author": "Nuño Sempere",
"karma": 34 "karma": 34
}, },
{ {
"id": "4",
"name": "2020: Forecasting in Review", "name": "2020: Forecasting in Review",
"url": "https://forum.effectivealtruism.org/posts/8shCj2eoQygQvtoZP/2020-forecasting-in-review", "url": "https://forum.effectivealtruism.org/posts/8shCj2eoQygQvtoZP/2020-forecasting-in-review",
"author": "Nuño Sempere", "author": "Nuño Sempere",
"karma": 35 "karma": 35
}, },
{ {
"id": "5",
"name": "Big List of Cause Candidates", "name": "Big List of Cause Candidates",
"url": "https://forum.effectivealtruism.org/posts/SCqRu6shoa8ySvRAa/big-list-of-cause-candidates", "url": "https://forum.effectivealtruism.org/posts/SCqRu6shoa8ySvRAa/big-list-of-cause-candidates",
"author": "Nuño Sempere", "author": "Nuño Sempere",
"karma": 182 "karma": 182
}, },
{ {
"id": "6",
"name": "An experiment to evaluate the value of one researcher's work", "name": "An experiment to evaluate the value of one researcher's work",
"url": "https://forum.effectivealtruism.org/posts/udGBF8YWshCKwRKTp/an-experiment-to-evaluate-the-value-of-one-researcher-s-work", "url": "https://forum.effectivealtruism.org/posts/udGBF8YWshCKwRKTp/an-experiment-to-evaluate-the-value-of-one-researcher-s-work",
"author": "Nuño Sempere", "author": "Nuño Sempere",
"karma": 55 "karma": 55
}, },
{ {
"id": "7",
"name": "Predicting the Value of Small Altruistic Projects: A Proof of Concept Experiment", "name": "Predicting the Value of Small Altruistic Projects: A Proof of Concept Experiment",
"url": "https://forum.effectivealtruism.org/posts/qb56nicbnj9asSemx/predicting-the-value-of-small-altruistic-projects-a-proof-of", "url": "https://forum.effectivealtruism.org/posts/qb56nicbnj9asSemx/predicting-the-value-of-small-altruistic-projects-a-proof-of",
"author": "Nuño Sempere", "author": "Nuño Sempere",
"karma": 51 "karma": 51
}, },
{ {
"id": "8",
"name": "Incentive Problems With Current Forecasting Competitions", "name": "Incentive Problems With Current Forecasting Competitions",
"url": "https://forum.effectivealtruism.org/posts/ztmBA8v6KvGChxw92/incentive-problems-with-current-forecasting-competitions", "url": "https://forum.effectivealtruism.org/posts/ztmBA8v6KvGChxw92/incentive-problems-with-current-forecasting-competitions",
"author": "Nuño Sempere", "author": "Nuño Sempere",
"karma": 54 "karma": 54
}, },
{ {
"id": "9",
"name": "Shapley Values: Better Than Counterfactuals", "name": "Shapley Values: Better Than Counterfactuals",
"url": "https://forum.effectivealtruism.org/posts/XHZJ9i7QBtAJZ6byW/shapley-values-better-than-counterfactuals", "url": "https://forum.effectivealtruism.org/posts/XHZJ9i7QBtAJZ6byW/shapley-values-better-than-counterfactuals",
"author": "Nuño Sempere", "author": "Nuño Sempere",