2021-06-06 21:14:05 +00:00
import Head from 'next/head'
import React , { useState } from "react" ;
2021-06-07 11:16:28 +00:00
import fs from 'fs' ;
import path from 'path' ;
2021-06-07 08:41:43 +00:00
import { DrawGraph } from '../lib/labeledgraph' ;
2021-06-07 17:09:30 +00:00
import { SliderElement } from "../lib/slider" ;
2021-06-07 11:16:28 +00:00
import { DisplayElement } from '../lib/displayElement'
2021-06-07 14:01:15 +00:00
import { DisplayAsMarkdown } from '../lib/displayAsMarkdown'
2021-06-07 17:09:30 +00:00
import { CreateTableWithDistances } from '../lib/findPaths'
2021-06-07 14:01:15 +00:00
2021-06-06 21:14:05 +00:00
// Utilities
2021-06-07 11:16:28 +00:00
let increasingList = ( n ) => Array . from ( Array ( n ) . keys ( ) )
2021-06-10 21:52:33 +00:00
let buildLinks = quantitativeComparisons => quantitativeComparisons . map ( ( [ element1 , element2 , distance ] ) => ( { source : element1 , target : element2 , distance : distance } ) )
2021-06-07 11:16:28 +00:00
2021-06-06 21:14:05 +00:00
Array . prototype . containsArray = function ( val ) {
var hash = { } ;
for ( var i = 0 ; i < this . length ; i ++ ) {
hash [ this [ i ] ] = i ;
}
return hash . hasOwnProperty ( val ) ;
}
2021-06-10 21:52:33 +00:00
let checkIfListIsOrdered = ( arr , binaryComparisons ) => {
2021-06-06 21:14:05 +00:00
let l = arr . length
let isOrdered = true
for ( let i = 0 ; i < l - 1 ; i ++ ) {
2021-06-06 22:18:40 +00:00
isOrdered = isOrdered && binaryComparisons . containsArray ( [ arr [ i ] , arr [ i + 1 ] ] )
2021-06-06 21:14:05 +00:00
}
return isOrdered
}
2021-06-06 22:18:40 +00:00
let simplifySliderValue = value => 10 * * value >= 3 ? Math . round ( 10 * * value ) : Math . round ( 10 * 10 * * value ) / 10
2021-06-10 21:52:33 +00:00
2021-06-06 22:18:40 +00:00
let displayFunctionSlider = ( value ) => {
let result
if ( value >= 0 ) {
result = simplifySliderValue ( value )
} else {
let inverseresult = simplifySliderValue ( - value )
result = ` 1/ ${ inverseresult } `
}
result = ` The first option is ${ result } x as valuable as the second one `
return result
} ;
2021-06-07 14:01:15 +00:00
let nicelyFormatLinks = ( quantitativeComparisons , list ) => quantitativeComparisons . map ( ( [ element1 , element2 , distance ] ) => ( { source : list . indexOf ( element1 ) , target : list . indexOf ( element2 ) , distance : distance } ) )
2021-06-10 21:52:33 +00:00
/* React components */
// fs can only be used here.
2021-06-07 11:16:28 +00:00
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' ) ) ;
2021-06-10 21:52:33 +00:00
//console.log(directory)
2021-06-07 11:16:28 +00:00
//console.log("metaforecasts", metaforecasts)
return {
props : {
listOfPosts ,
} ,
} ;
}
2021-06-10 21:52:33 +00:00
// Main react component
2021-06-07 11:16:28 +00:00
export default function Home ( { listOfPosts } ) {
2021-06-06 21:14:05 +00:00
// State
2021-06-10 21:52:33 +00:00
let list = increasingList ( listOfPosts . length ) // [0,1,2,3,4]
listOfPosts = listOfPosts . map ( ( element , i ) => ( { ... element , id : i } ) )
2021-06-06 22:18:40 +00:00
2021-06-10 21:52:33 +00:00
const [ toComparePair , setToComparePair ] = useState ( [ list [ list . length - 2 ] , list [ list . length - 1 ] ] )
2021-06-06 22:18:40 +00:00
const [ sliderValue , setSliderValue ] = useState ( 0 )
2021-06-10 21:52:33 +00:00
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.
2021-06-06 22:18:40 +00:00
2021-06-06 21:14:05 +00:00
const [ isListOrdered , setIsListOrdered ] = useState ( false )
2021-06-07 08:41:43 +00:00
const [ orderedList , setOrderedList ] = useState ( [ ] )
2021-06-06 21:14:05 +00:00
// Manipulations
2021-06-06 22:18:40 +00:00
let compareTwoElements = ( newBinaryComparisons , element1 , element2 ) => {
let element1Greater = newBinaryComparisons . containsArray ( [ element1 , element2 ] )
let element2Greater = newBinaryComparisons . containsArray ( [ element2 , element1 ] )
2021-06-06 21:14:05 +00:00
if ( element1Greater || element2Greater ) {
return element1Greater && ! element2Greater
} else {
setToComparePair ( [ element1 , element2 ] )
2021-06-10 21:52:33 +00:00
//console.log(`No comparison found between ${element1} and ${element2}`)
//console.log(`Comparisons:`)
//console.log(JSON.stringify(newBinaryComparisons, null, 4));
2021-06-06 21:14:05 +00:00
return "No comparison found"
}
}
2021-06-06 22:18:40 +00:00
function merge ( newBinaryComparisons , left , right ) {
2021-06-06 21:14:05 +00:00
let sortedArr = [ ] ; // the sorted elements will go here
while ( left . length && right . length ) {
// insert the biggest element to the sortedArr
2021-06-06 22:18:40 +00:00
let comparison = compareTwoElements ( newBinaryComparisons , left [ 0 ] , right [ 0 ] )
2021-06-06 21:14:05 +00:00
if ( comparison == "No comparison found" ) {
return "No comparison found; unable to proceed"
}
else if ( comparison ) { // left[0] > right[0]
sortedArr . push ( left . shift ( ) ) ;
} else {
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
}
2021-06-06 22:18:40 +00:00
function mergeSort ( arr , newBinaryComparisons ) {
2021-06-06 21:14:05 +00:00
if ( arr == "No comparison found; unable to proceed" ) {
return "No comparison found; unable to proceed"
}
const half = arr . length / 2 ;
// the base case is array length <=1
if ( arr . length <= 1 ) {
return arr ;
}
const left = arr . splice ( 0 , half ) ; // the first half of the array
const right = arr ;
2021-06-06 22:18:40 +00:00
let orderedFirstHalf = mergeSort ( left , newBinaryComparisons )
let orderedSecondHalf = mergeSort ( right , newBinaryComparisons )
2021-06-06 21:14:05 +00:00
if ( orderedFirstHalf != "No comparison found; unable to proceed" && orderedSecondHalf != "No comparison found; unable to proceed" ) {
2021-06-06 22:18:40 +00:00
let result = merge ( newBinaryComparisons , orderedFirstHalf , orderedSecondHalf ) ;
2021-06-06 21:14:05 +00:00
return result
} else {
return "No comparison found; unable to proceed"
}
}
2021-06-06 22:18:40 +00:00
let nextStepSimple = ( binaryComparisons , element1 , element2 ) => {
2021-06-10 21:52:33 +00:00
//console.log("Binary comparisons: ")
//console.log(JSON.stringify(binaryComparisons, null, 4));
2021-06-06 22:18:40 +00:00
2021-06-06 21:14:05 +00:00
let newComparison = [ element1 , element2 ] // [element1, element2]
2021-06-06 22:18:40 +00:00
let newBinaryComparisons = [ ... binaryComparisons , newComparison ]
2021-06-10 21:52:33 +00:00
//console.log("New binaryComparisons: ")
//console.log(JSON.stringify(newBinaryComparisons, null, 4));
2021-06-06 22:18:40 +00:00
setBinaryComparisons ( newBinaryComparisons )
let result = mergeSort ( list , newBinaryComparisons )
2021-06-10 21:52:33 +00:00
//console.log(result)
2021-06-06 22:18:40 +00:00
if ( result != "No comparison found; unable to proceed" && checkIfListIsOrdered ( result , newBinaryComparisons ) ) {
2021-06-10 21:52:33 +00:00
//console.log(result)
2021-06-06 21:14:05 +00:00
setIsListOrdered ( true )
setOrderedList ( result )
}
}
2021-06-06 22:18:40 +00:00
let nextStepSlider = ( binaryComparisons , sliderValue , element1 , element2 ) => {
if ( sliderValue < 0 ) {
sliderValue = - sliderValue ;
[ element1 , element2 ] = [ element2 , element1 ]
}
nextStepSimple ( binaryComparisons , element1 , element2 )
let newQuantitativeComparison = [ element1 , element2 , simplifySliderValue ( sliderValue ) ]
let newQuantitativeComparisons = [ ... quantitativeComparisons , newQuantitativeComparison ]
setQuantitativeComparisons ( newQuantitativeComparisons )
setSliderValue ( 0 )
}
2021-06-06 21:14:05 +00:00
// Html
return (
2021-06-07 14:01:15 +00:00
< div className = "flex flex-col items-center justify-center min-h-screen py-2 mt-10" >
2021-06-06 21:14:05 +00:00
< Head >
2021-06-07 14:01:15 +00:00
< title > Utility Function Extractor < / t i t l e >
2021-06-06 21:14:05 +00:00
< link rel = "icon" href = "/favicon.ico" / >
< / H e a d >
< main className = "flex flex-col items-center justify-center w-full flex-1 px-20 text-center" >
< h1 className = "text-6xl font-bold" >
2021-06-06 22:18:40 +00:00
Utility Function Extractor
2021-06-06 21:14:05 +00:00
< / h 1 >
2021-06-06 22:18:40 +00:00
< div className = { ` ${ isListOrdered ? "hidden" : "" } ` } >
< div className = "flex flex-wrap items-center max-w-4xl mt-6 sm:w-full mt-20" >
< div
2021-06-07 14:01:15 +00:00
className = "flex m-auto border-gray-300 border-4 h-72 w-72"
2021-06-06 22:18:40 +00:00
//onClick={() => nextStep(binaryComparisons, toComparePair[0], toComparePair[1])}
>
2021-06-07 17:09:30 +00:00
< div className = "block m-auto text-center" >
2021-06-07 11:16:28 +00:00
< DisplayElement element = { listOfPosts [ toComparePair [ 0 ] ] } >
< / D i s p l a y E l e m e n t >
2021-06-07 17:09:30 +00:00
< / d i v >
2021-06-06 22:18:40 +00:00
< / d i v >
< div
2021-06-07 14:01:15 +00:00
className = "flex m-auto border-gray-300 border-4 h-72 w-72 p-5"
2021-06-06 22:18:40 +00:00
//onClick={() => nextStep(binaryComparisons, toComparePair[1], toComparePair[0])}
>
2021-06-07 17:09:30 +00:00
< div className = "block m-auto text-center" >
2021-06-07 11:16:28 +00:00
< DisplayElement element = { listOfPosts [ toComparePair [ 1 ] ] } >
< / D i s p l a y E l e m e n t >
2021-06-07 17:09:30 +00:00
< / d i v >
2021-06-06 22:18:40 +00:00
< / d i v >
< / d i v >
< div className = { ` flex row-start-3 row-end-3 col-start-1 col-end-4 md:col-start-3 md:col-end-3 md:row-start-1 md:row-end-1 lg:col-start-3 lg:col-end-3 lg:row-start-1 lg:row-end-1 items-center justify-center mb-4 mt-10 ${ isListOrdered ? "hidden" : "" } ` } >
< SliderElement
className = "flex items-center justify-center"
onChange = { ( event ) => ( setSliderValue ( event [ 0 ] ) ) }
value = { sliderValue }
displayFunction = { displayFunctionSlider }
/ >
< / d i v >
< button
className = "bg-transparent hover:bg-blue-500 text-blue-700 font-semibold hover:text-white py-2 px-4 border border-blue-500 hover:border-transparent rounded mt-5"
onClick = { ( ) => nextStepSlider ( binaryComparisons , sliderValue , toComparePair [ 1 ] , toComparePair [ 0 ] ) } >
Submit
< / b u t t o n >
2021-06-06 21:14:05 +00:00
< / d i v >
2021-06-06 22:18:40 +00:00
2021-06-07 08:41:43 +00:00
< DrawGraph
isListOrdered = { isListOrdered }
2021-06-10 21:52:33 +00:00
nodes = { orderedList . map ( i => listOfPosts [ i ] ) }
links = { buildLinks ( quantitativeComparisons ) } >
2021-06-07 08:41:43 +00:00
< / D r a w G r a p h >
2021-06-07 17:09:30 +00:00
< div className = { ` inline items-center text-center mt-10 ${ isListOrdered ? "" : "hidden" } ` } >
< CreateTableWithDistances
isListOrdered = { isListOrdered }
2021-06-10 21:52:33 +00:00
nodes = { orderedList . map ( i => listOfPosts [ i ] ) }
links = { buildLinks ( quantitativeComparisons ) }
2021-06-07 17:09:30 +00:00
>
< / C r e a t e T a b l e W i t h D i s t a n c e s >
< / d i v >
2021-06-07 14:01:15 +00:00
< / m a i n >
< div className = { ` inline text-left w-full flex-1 px-20 ${ isListOrdered ? "" : "hidden" } ` } >
< DisplayAsMarkdown markdowntext = { "## Ordered list\n\n" + JSON . stringify ( orderedList . map ( i => listOfPosts [ i ] ) , null , 4 ) } > < / D i s p l a y A s M a r k d o w n >
< DisplayAsMarkdown markdowntext = { "## Distances\n\n" + JSON . stringify ( nicelyFormatLinks ( quantitativeComparisons , list ) , null , 4 ) } > < / D i s p l a y A s M a r k d o w n >
{ / *
< p > { ` Binary comparisons: ${ JSON . stringify ( binaryComparisons , null , 4 ) } ` } < / p >
2021-06-06 22:18:40 +00:00
< p > { ` Quantitative comparisons: ${ JSON . stringify ( quantitativeComparisons , null , 4 ) } ` } < / p >
2021-06-07 14:01:15 +00:00
* / }
2021-06-07 17:09:30 +00:00
< / d i v >
2021-06-06 21:14:05 +00:00
< / d i v >
)
}