feat: Refactoring to make index.js and research.js use the same function
This commit is contained in:
parent
e3832ad202
commit
7ae03e791b
|
@ -1,3 +0,0 @@
|
|||
import listOfElements from 'listOfMoralGoods.js'
|
||||
|
||||
console.log(listOfElements)
|
402
lib/comparisonView.js
Normal file
402
lib/comparisonView.js
Normal file
|
@ -0,0 +1,402 @@
|
|||
/* Definitions */
|
||||
const elementsDocument = null//
|
||||
|
||||
/* Imports */
|
||||
import Head from 'next/head'
|
||||
import React, { useState } from "react";
|
||||
import path from 'path';
|
||||
import { DrawGraph, removeOldSvg } from './labeledgraph';
|
||||
import { SliderElement, SubmitSliderButton } from "./slider";
|
||||
import { DisplayElement } from './displayElement'
|
||||
import { DisplayAsMarkdown } from './displayAsMarkdown'
|
||||
import { CreateTableWithDistances } from './findPaths'
|
||||
import { TextAreaForJson } from "./textAreaForJson"
|
||||
import { pushToMongo } from "./pushToMongo.js"
|
||||
import { toLocale, transformSliderValueToPracticalValue, transformSliderValueToActualValue, numToAlphabeticalString } from "./utils.js"
|
||||
|
||||
/* Helpers */
|
||||
let increasingList = (n) => Array.from(Array(n).keys())
|
||||
let buildLinks = quantitativeComparisons => quantitativeComparisons.map(([element1, element2, distance, reasoning]) => ({ source: element1, target: element2, distance: distance, reasoning: reasoning }))
|
||||
|
||||
Array.prototype.containsArray = function (val) {
|
||||
var hash = {};
|
||||
for (var i = 0; i < this.length; i++) {
|
||||
hash[this[i]] = i;
|
||||
}
|
||||
return hash.hasOwnProperty(val);
|
||||
}
|
||||
|
||||
let checkIfListIsOrdered = (arr, binaryComparisons) => {
|
||||
let l = arr.length
|
||||
let isOrdered = true
|
||||
for (let i = 0; i < l - 1; i++) {
|
||||
isOrdered = isOrdered && binaryComparisons.containsArray([arr[i], arr[i + 1]])
|
||||
}
|
||||
return isOrdered
|
||||
}
|
||||
|
||||
let displayFunctionSliderInner = (value) => {
|
||||
let result
|
||||
if (value >= 0) {
|
||||
result = toLocale(transformSliderValueToPracticalValue(value))
|
||||
} else {
|
||||
let inverseresult = toLocale(transformSliderValueToPracticalValue(-value))
|
||||
if (inverseresult == 1) {
|
||||
result = '1'
|
||||
} else {
|
||||
result = `1/${inverseresult}`
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
let displayFunctionSlider = (value) => {
|
||||
let result = displayFunctionSliderInner(value)
|
||||
result = `The first option is ${result}x as valuable as the second one`
|
||||
return result
|
||||
|
||||
};
|
||||
|
||||
let nicelyFormatLinks = (quantitativeComparisons, listOfElements) => quantitativeComparisons.map(([element1, element2, distance, reasoning]) => ({ source: listOfElements[element1].name, target: listOfElements[element2].name, distance: distance, reasoning: reasoning }))
|
||||
|
||||
// Main react component
|
||||
export default function ComparisonView({ listOfElementsForView }) {
|
||||
// State
|
||||
let initialListOfElements = listOfElementsForView.map((element, i) => ({ ...element, id: i }))
|
||||
let initialPosList = increasingList(listOfElementsForView.length) // [0,1,2,3,4]
|
||||
//let listOfElements = listOfElementsForView.map((element, i) => ({...element, id: i}))
|
||||
//let list = increasingList(listOfElementsForView.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 initialSliderValue = 1
|
||||
let initialReasoning = ''
|
||||
let initialBinaryComparisons = []
|
||||
let initialQuantitativeComparisons = []
|
||||
let initialIsListOdered = false
|
||||
let initialOrderedList = []
|
||||
let initialShowAdvancedOptions = false
|
||||
let initialShowComparisons = false
|
||||
let initialShowChangeDataSet = false
|
||||
|
||||
const [listOfElements, setListOfElements] = useState(initialListOfElements)
|
||||
const [posList, setPosList] = useState(initialPosList)
|
||||
//const posList = initialPosList
|
||||
// let listOfElements = initialListOfElements
|
||||
|
||||
const [toComparePair, setToComparePair] = useState(initialComparePair)
|
||||
const [sliderValue, setSliderValue] = useState(initialSliderValue)
|
||||
const [reasoning, setReasoning] = useState(initialReasoning)
|
||||
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 [orderedList, setOrderedList] = useState(initialOrderedList)
|
||||
|
||||
let [showAdvancedOptions, changeShowAdvanceOptions] = useState(initialShowAdvancedOptions);
|
||||
let [showComparisons, changeShowComparisons] = useState(initialShowComparisons);
|
||||
let [showChangeDataSet, changeshowChangeDataSet] = useState(initialShowChangeDataSet);
|
||||
|
||||
let restart = (posList) => {
|
||||
setToComparePair([posList[posList.length - 2], posList[posList.length - 1]])
|
||||
setSliderValue(initialSliderValue)
|
||||
setBinaryComparisons(initialBinaryComparisons)
|
||||
setQuantitativeComparisons(initialQuantitativeComparisons)
|
||||
setIsListOrdered(initialIsListOdered)
|
||||
setOrderedList(initialOrderedList)
|
||||
removeOldSvg()
|
||||
}
|
||||
|
||||
let changeDataSet = (listOfElementsNew) => {
|
||||
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]])
|
||||
restart(newPosList)
|
||||
}
|
||||
|
||||
// Manipulations
|
||||
let compareTwoElements = (newBinaryComparisons, element1, element2) => {
|
||||
let element1Greater = newBinaryComparisons.containsArray([element1, element2])
|
||||
let element2Greater = newBinaryComparisons.containsArray([element2, element1])
|
||||
if (element1Greater || element2Greater) {
|
||||
return element1Greater && !element2Greater
|
||||
} else {
|
||||
setToComparePair([element1, element2])
|
||||
//console.log(`No comparison found between ${element1} and ${element2}`)
|
||||
//console.log(`Comparisons:`)
|
||||
//console.log(JSON.stringify(newBinaryComparisons, null, 4));
|
||||
return "No comparison found"
|
||||
}
|
||||
}
|
||||
|
||||
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") {
|
||||
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
|
||||
}
|
||||
|
||||
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 result = merge(comparisons, orderedFirstHalf, orderedSecondHalf);
|
||||
return result
|
||||
} else {
|
||||
return "No comparison found; unable to proceed"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
let nextStepSimple = (posList, binaryComparisons, element1, element2) => {
|
||||
//console.log("Binary comparisons: ")
|
||||
//console.log(JSON.stringify(binaryComparisons, null, 4));
|
||||
|
||||
let newComparison = [element1, element2] // [element1, element2]
|
||||
let newBinaryComparisons = [...binaryComparisons, newComparison]
|
||||
//console.log("New binaryComparisons: ")
|
||||
//console.log(JSON.stringify(newBinaryComparisons, null, 4));
|
||||
setBinaryComparisons(newBinaryComparisons)
|
||||
|
||||
let result = mergeSort({ array: posList, comparisons: newBinaryComparisons })
|
||||
//console.log(result)
|
||||
if (result != "No comparison found; unable to proceed" && checkIfListIsOrdered(result, newBinaryComparisons)) {
|
||||
// console.log(`isListOrdered: ${isListOrdered}`)
|
||||
console.log("poslist@nextStepSimple")
|
||||
console.log(posList)
|
||||
console.log("result@nextStepSimple")
|
||||
console.log(result)
|
||||
|
||||
setIsListOrdered(true)
|
||||
setOrderedList(result)
|
||||
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
let nextStepSlider = ({ posList, binaryComparisons, sliderValue, Reasoning, element1, element2 }) => {
|
||||
if (sliderValue < 1 && sliderValue > 0) {
|
||||
sliderValue = 1 / sliderValue;
|
||||
[element1, element2] = [element2, element1]
|
||||
}
|
||||
console.log(`posList@nextStepSlider:`)
|
||||
console.log(posList)
|
||||
let successStatus = nextStepSimple(posList, binaryComparisons, element1, element2)
|
||||
|
||||
let newQuantitativeComparison = [element1, element2, transformSliderValueToActualValue(sliderValue), reasoning]
|
||||
let newQuantitativeComparisons = [...quantitativeComparisons, newQuantitativeComparison]
|
||||
setQuantitativeComparisons(newQuantitativeComparisons)
|
||||
|
||||
setSliderValue(1)
|
||||
setReasoning('')
|
||||
if (successStatus) {
|
||||
let jsObject = nicelyFormatLinks(quantitativeComparisons, listOfElements)
|
||||
pushToMongo(jsObject)
|
||||
console.log(jsObject)
|
||||
}
|
||||
}
|
||||
|
||||
// Html
|
||||
return (
|
||||
<div className="flex flex-col items-center justify-center min-h-screen py-2">
|
||||
<div className="mt-20">
|
||||
<Head >
|
||||
<title>Utility Function Extractor</title>
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
</Head>
|
||||
</div>
|
||||
|
||||
<main className="flex flex-col items-center w-full flex-1 px-20 text-center">
|
||||
<h1 className="text-6xl font-bold">
|
||||
Utility Function Extractor
|
||||
</h1>
|
||||
|
||||
<div className={`${isListOrdered ? "hidden" : ""}`}>
|
||||
<div className="flex flex-wrap items-center max-w-4xl sm:w-full mt-10">
|
||||
<div
|
||||
className="flex m-auto border-gray-300 border-4 h-72 w-72 p-5"
|
||||
//onClick={() => nextStep(binaryComparisons, toComparePair[0], toComparePair[1])}
|
||||
>
|
||||
<div className="block m-auto text-center">
|
||||
<DisplayElement element={listOfElements[toComparePair[0]]}>
|
||||
</DisplayElement>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex m-auto w-72">
|
||||
<div className="block m-auto text-center">
|
||||
{/*`is ${displayFunctionSliderInner(sliderValue)}x times as valuable as`*/}
|
||||
<br />
|
||||
|
||||
<label>
|
||||
{`... is `}
|
||||
<br />
|
||||
<input
|
||||
type="number"
|
||||
value={sliderValue}
|
||||
onChange={(event) => {
|
||||
//console.log(event)
|
||||
//console.log(event.target.value)
|
||||
setSliderValue(event.target.value)
|
||||
}}
|
||||
className="text-center px-2 py-1 placeholder-blueGray-300 text-blueGray-600 relative bg-white bg-white rounded text-lg border-0 shadow outline-none focus:outline-none focus:ring w-8/12 m-2 h-10"
|
||||
/>
|
||||
<br />
|
||||
{`times as valuable as ...`}
|
||||
</label>
|
||||
<br />
|
||||
|
||||
<SubmitSliderButton
|
||||
posList={posList}
|
||||
binaryComparisons={binaryComparisons}
|
||||
sliderValue={sliderValue}
|
||||
reasoning={reasoning}
|
||||
toComparePair={toComparePair}
|
||||
nextStepSlider={nextStepSlider}
|
||||
/>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div
|
||||
className="flex m-auto border-gray-300 border-4 h-72 w-72 p-5 "
|
||||
//onClick={() => nextStep(binaryComparisons, toComparePair[1], toComparePair[0])}
|
||||
>
|
||||
<div className="block m-auto text-center">
|
||||
<DisplayElement element={listOfElements[toComparePair[1]]}>
|
||||
</DisplayElement>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
<label className="">
|
||||
Reasoning (optional):
|
||||
<br />
|
||||
<textarea className="mt-2 px-3 py-4 placeholder-blueGray-300 text-blueGray-600 relative bg-white bg-white rounded text-base border-0 shadow outline-none focus:outline-none focus:ring w-full"
|
||||
value={reasoning}
|
||||
onChange={(event) => setReasoning(event.target.value)}
|
||||
/>
|
||||
</label>
|
||||
<br />
|
||||
<div>
|
||||
</div>
|
||||
{/*
|
||||
|
||||
<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}
|
||||
domain={domain}
|
||||
/>
|
||||
</div>
|
||||
*/}
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<DrawGraph
|
||||
isListOrdered={isListOrdered}
|
||||
orderedList={orderedList}
|
||||
listOfElements={listOfElements}
|
||||
links={buildLinks(quantitativeComparisons)}>
|
||||
</DrawGraph>
|
||||
<div className={`inline items-center text-center mt-10 ${isListOrdered ? "" : "hidden"}`}>
|
||||
<CreateTableWithDistances
|
||||
isListOrdered={isListOrdered}
|
||||
orderedList={orderedList}
|
||||
listOfElements={listOfElements}
|
||||
links={buildLinks(quantitativeComparisons)}
|
||||
>
|
||||
</CreateTableWithDistances>
|
||||
</div>
|
||||
<div className="w-2/12 flex justify-center mt-10">
|
||||
<button
|
||||
className="text-gray-500 text-sm"
|
||||
onClick={() => changeShowAdvanceOptions(!showAdvancedOptions)}
|
||||
>
|
||||
Advanced options ▼
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className={`flex flex-wrap -mx-4 overflow-hidden ${showAdvancedOptions ? "" : "hidden"}`}>
|
||||
<div className="my-4 px-4 w-1/3 overflow-hidden">
|
||||
<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={() => restart(posList)}>
|
||||
Restart
|
||||
</button>
|
||||
</div>
|
||||
<div className="my-4 px-4 w-1/3 overflow-hidden">
|
||||
<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={() => changeShowComparisons(!showComparisons)}>
|
||||
Show comparisons
|
||||
</button>
|
||||
</div>
|
||||
<div className="my-4 px-4 w-1/3 overflow-hidden">
|
||||
<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={() => changeshowChangeDataSet(!showChangeDataSet)}>
|
||||
Use your own data
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={`inline mt-5 ${showChangeDataSet ? "" : "hidden"}`}>
|
||||
<TextAreaForJson handleSubmit={changeDataSet} />
|
||||
</div>
|
||||
|
||||
<div className={`inline mt-5 ${showComparisons ? "" : "hidden"}`}>
|
||||
{/*
|
||||
<DisplayAsMarkdown markdowntext={"## Ordered list\n\n" + JSON.stringify(orderedList.map(i => listOfElements[i]), null, 4)}></DisplayAsMarkdown>
|
||||
*/}
|
||||
<h2>Comparisons</h2>
|
||||
<div className="text-left">
|
||||
<DisplayAsMarkdown
|
||||
markdowntext={JSON.stringify(nicelyFormatLinks(quantitativeComparisons, listOfElements), null, 4)}
|
||||
className={""}>
|
||||
</DisplayAsMarkdown>
|
||||
</div>
|
||||
|
||||
{/*
|
||||
<p>{`Binary comparisons: ${JSON.stringify(binaryComparisons, null, 4)}`}</p>
|
||||
<p>{`Quantitative comparisons: ${JSON.stringify(quantitativeComparisons, null, 4)}`}</p>
|
||||
|
||||
*/}
|
||||
</div>
|
||||
</main>
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
410
pages/index.js
410
pages/index.js
|
@ -1,65 +1,16 @@
|
|||
/* Definitions */
|
||||
const elementsDocument = '../data/listOfMoralGoods.json'
|
||||
const domain = 250
|
||||
/* Notes */
|
||||
|
||||
// This function is just a simple wrapper around lib/comparisonView.
|
||||
// Most of the time, I'll want to edit that instead
|
||||
|
||||
/* Imports */
|
||||
import Head from 'next/head'
|
||||
import React, { useState } from "react";
|
||||
import React from "react";
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
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 { pushToMongo } from "../lib/pushToMongo.js"
|
||||
import { toLocale, transformSliderValueToPracticalValue, transformSliderValueToActualValue, numToAlphabeticalString } from "../lib/utils.js"
|
||||
import ComparisonView from '../lib/comparisonView.js'
|
||||
|
||||
/* Helpers */
|
||||
let increasingList = (n) => Array.from(Array(n).keys())
|
||||
let buildLinks = quantitativeComparisons => quantitativeComparisons.map(([element1, element2, distance, reasoning]) => ({ source: element1, target: element2, distance: distance, reasoning: reasoning }))
|
||||
|
||||
Array.prototype.containsArray = function (val) {
|
||||
var hash = {};
|
||||
for (var i = 0; i < this.length; i++) {
|
||||
hash[this[i]] = i;
|
||||
}
|
||||
return hash.hasOwnProperty(val);
|
||||
}
|
||||
|
||||
let checkIfListIsOrdered = (arr, binaryComparisons) => {
|
||||
let l = arr.length
|
||||
let isOrdered = true
|
||||
for (let i = 0; i < l - 1; i++) {
|
||||
isOrdered = isOrdered && binaryComparisons.containsArray([arr[i], arr[i + 1]])
|
||||
}
|
||||
return isOrdered
|
||||
}
|
||||
|
||||
let displayFunctionSliderInner = (value) => {
|
||||
let result
|
||||
if (value >= 0) {
|
||||
result = toLocale(transformSliderValueToPracticalValue(value))
|
||||
} else {
|
||||
let inverseresult = toLocale(transformSliderValueToPracticalValue(-value))
|
||||
if (inverseresult == 1) {
|
||||
result = '1'
|
||||
} else {
|
||||
result = `1/${inverseresult}`
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
let displayFunctionSlider = (value) => {
|
||||
let result = displayFunctionSliderInner(value)
|
||||
result = `The first option is ${result}x as valuable as the second one`
|
||||
return result
|
||||
|
||||
};
|
||||
|
||||
let nicelyFormatLinks = (quantitativeComparisons, listOfElements) => quantitativeComparisons.map(([element1, element2, distance, reasoning]) => ({ source: listOfElements[element1].name, target: listOfElements[element2].name, distance: distance, reasoning: reasoning }))
|
||||
/* Definitions */
|
||||
const elementsDocument = '../data/listOfMoralGoods.json'
|
||||
|
||||
/* React components */
|
||||
// fs can only be used here.
|
||||
|
@ -67,354 +18,17 @@ export async function getStaticProps() {
|
|||
//getServerSideProps
|
||||
// const { metaforecasts } = await getForecasts();
|
||||
const directory = path.join(process.cwd(), "pages")
|
||||
let listOfElementsDefault = JSON.parse(fs.readFileSync(path.join(directory, elementsDocument), 'utf8'));
|
||||
let listOfElementsForView = JSON.parse(fs.readFileSync(path.join(directory, elementsDocument), 'utf8'));
|
||||
//console.log(directory)
|
||||
//console.log("metaforecasts", metaforecasts)
|
||||
return {
|
||||
props: {
|
||||
listOfElementsDefault
|
||||
listOfElementsForView
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// Main react component
|
||||
export default function Home({ listOfElementsDefault }) {
|
||||
// State
|
||||
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 initialSliderValue = 1
|
||||
let initialReasoning = ''
|
||||
let initialBinaryComparisons = []
|
||||
let initialQuantitativeComparisons = []
|
||||
let initialIsListOdered = false
|
||||
let initialOrderedList = []
|
||||
let initialShowAdvancedOptions = false
|
||||
let initialShowComparisons = false
|
||||
let initialShowChangeDataSet = false
|
||||
|
||||
const [listOfElements, setListOfElements] = useState(initialListOfElements)
|
||||
const [posList, setPosList] = useState(initialPosList)
|
||||
//const posList = initialPosList
|
||||
// let listOfElements = initialListOfElements
|
||||
|
||||
const [toComparePair, setToComparePair] = useState(initialComparePair)
|
||||
const [sliderValue, setSliderValue] = useState(initialSliderValue)
|
||||
const [reasoning, setReasoning] = useState(initialReasoning)
|
||||
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 [orderedList, setOrderedList] = useState(initialOrderedList)
|
||||
|
||||
let [showAdvancedOptions, changeShowAdvanceOptions] = useState(initialShowAdvancedOptions);
|
||||
let [showComparisons, changeShowComparisons] = useState(initialShowComparisons);
|
||||
let [showChangeDataSet, changeshowChangeDataSet] = useState(initialShowChangeDataSet);
|
||||
|
||||
let restart = (posList) => {
|
||||
setToComparePair([posList[posList.length - 2], posList[posList.length - 1]])
|
||||
setSliderValue(initialSliderValue)
|
||||
setBinaryComparisons(initialBinaryComparisons)
|
||||
setQuantitativeComparisons(initialQuantitativeComparisons)
|
||||
setIsListOrdered(initialIsListOdered)
|
||||
setOrderedList(initialOrderedList)
|
||||
removeOldSvg()
|
||||
}
|
||||
|
||||
let changeDataSet = (listOfElementsNew) => {
|
||||
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]])
|
||||
restart(newPosList)
|
||||
}
|
||||
|
||||
// Manipulations
|
||||
let compareTwoElements = (newBinaryComparisons, element1, element2) => {
|
||||
let element1Greater = newBinaryComparisons.containsArray([element1, element2])
|
||||
let element2Greater = newBinaryComparisons.containsArray([element2, element1])
|
||||
if (element1Greater || element2Greater) {
|
||||
return element1Greater && !element2Greater
|
||||
} else {
|
||||
setToComparePair([element1, element2])
|
||||
//console.log(`No comparison found between ${element1} and ${element2}`)
|
||||
//console.log(`Comparisons:`)
|
||||
//console.log(JSON.stringify(newBinaryComparisons, null, 4));
|
||||
return "No comparison found"
|
||||
}
|
||||
}
|
||||
|
||||
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") {
|
||||
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
|
||||
}
|
||||
|
||||
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 result = merge(comparisons, orderedFirstHalf, orderedSecondHalf);
|
||||
return result
|
||||
} else {
|
||||
return "No comparison found; unable to proceed"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
let nextStepSimple = (posList, binaryComparisons, element1, element2) => {
|
||||
//console.log("Binary comparisons: ")
|
||||
//console.log(JSON.stringify(binaryComparisons, null, 4));
|
||||
|
||||
let newComparison = [element1, element2] // [element1, element2]
|
||||
let newBinaryComparisons = [...binaryComparisons, newComparison]
|
||||
//console.log("New binaryComparisons: ")
|
||||
//console.log(JSON.stringify(newBinaryComparisons, null, 4));
|
||||
setBinaryComparisons(newBinaryComparisons)
|
||||
|
||||
let result = mergeSort({ array: posList, comparisons: newBinaryComparisons })
|
||||
//console.log(result)
|
||||
if (result != "No comparison found; unable to proceed" && checkIfListIsOrdered(result, newBinaryComparisons)) {
|
||||
// console.log(`isListOrdered: ${isListOrdered}`)
|
||||
console.log("poslist@nextStepSimple")
|
||||
console.log(posList)
|
||||
console.log("result@nextStepSimple")
|
||||
console.log(result)
|
||||
|
||||
setIsListOrdered(true)
|
||||
setOrderedList(result)
|
||||
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
let nextStepSlider = ({ posList, binaryComparisons, sliderValue, Reasoning, element1, element2 }) => {
|
||||
if (sliderValue < 1 && sliderValue > 0) {
|
||||
sliderValue = 1 / sliderValue;
|
||||
[element1, element2] = [element2, element1]
|
||||
}
|
||||
console.log(`posList@nextStepSlider:`)
|
||||
console.log(posList)
|
||||
let successStatus = nextStepSimple(posList, binaryComparisons, element1, element2)
|
||||
|
||||
let newQuantitativeComparison = [element1, element2, transformSliderValueToActualValue(sliderValue), reasoning]
|
||||
let newQuantitativeComparisons = [...quantitativeComparisons, newQuantitativeComparison]
|
||||
setQuantitativeComparisons(newQuantitativeComparisons)
|
||||
|
||||
setSliderValue(1)
|
||||
setReasoning('')
|
||||
if (successStatus) {
|
||||
let jsObject = nicelyFormatLinks(quantitativeComparisons, listOfElements)
|
||||
pushToMongo(jsObject)
|
||||
console.log(jsObject)
|
||||
}
|
||||
}
|
||||
|
||||
// Html
|
||||
return (
|
||||
<div className="flex flex-col items-center justify-center min-h-screen py-2">
|
||||
<div className="mt-20">
|
||||
<Head >
|
||||
<title>Utility Function Extractor</title>
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
</Head>
|
||||
</div>
|
||||
|
||||
<main className="flex flex-col items-center w-full flex-1 px-20 text-center">
|
||||
<h1 className="text-6xl font-bold">
|
||||
Utility Function Extractor
|
||||
</h1>
|
||||
|
||||
<div className={`${isListOrdered ? "hidden" : ""}`}>
|
||||
<div className="flex flex-wrap items-center max-w-4xl sm:w-full mt-10">
|
||||
<div
|
||||
className="flex m-auto border-gray-300 border-4 h-72 w-72 p-5"
|
||||
//onClick={() => nextStep(binaryComparisons, toComparePair[0], toComparePair[1])}
|
||||
>
|
||||
<div className="block m-auto text-center">
|
||||
<DisplayElement element={listOfElements[toComparePair[0]]}>
|
||||
</DisplayElement>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex m-auto w-72">
|
||||
<div className="block m-auto text-center">
|
||||
{/*`is ${displayFunctionSliderInner(sliderValue)}x times as valuable as`*/}
|
||||
<br />
|
||||
|
||||
<label>
|
||||
{`... is `}
|
||||
<br />
|
||||
<input
|
||||
type="number"
|
||||
value={sliderValue}
|
||||
onChange={(event) => {
|
||||
//console.log(event)
|
||||
//console.log(event.target.value)
|
||||
setSliderValue(event.target.value)
|
||||
}}
|
||||
className="text-center px-2 py-1 placeholder-blueGray-300 text-blueGray-600 relative bg-white bg-white rounded text-lg border-0 shadow outline-none focus:outline-none focus:ring w-8/12 m-2 h-10"
|
||||
/>
|
||||
<br />
|
||||
{`times as valuable as ...`}
|
||||
</label>
|
||||
<br />
|
||||
|
||||
<SubmitSliderButton
|
||||
posList={posList}
|
||||
binaryComparisons={binaryComparisons}
|
||||
sliderValue={sliderValue}
|
||||
reasoning={reasoning}
|
||||
toComparePair={toComparePair}
|
||||
nextStepSlider={nextStepSlider}
|
||||
/>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div
|
||||
className="flex m-auto border-gray-300 border-4 h-72 w-72 p-5 "
|
||||
//onClick={() => nextStep(binaryComparisons, toComparePair[1], toComparePair[0])}
|
||||
>
|
||||
<div className="block m-auto text-center">
|
||||
<DisplayElement element={listOfElements[toComparePair[1]]}>
|
||||
</DisplayElement>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
<label className="">
|
||||
Reasoning (optional):
|
||||
<br />
|
||||
<textarea className="mt-2 px-3 py-4 placeholder-blueGray-300 text-blueGray-600 relative bg-white bg-white rounded text-base border-0 shadow outline-none focus:outline-none focus:ring w-full"
|
||||
value={reasoning}
|
||||
onChange={(event) => setReasoning(event.target.value)}
|
||||
/>
|
||||
</label>
|
||||
<br />
|
||||
<div>
|
||||
</div>
|
||||
{/*
|
||||
|
||||
<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}
|
||||
domain={domain}
|
||||
/>
|
||||
</div>
|
||||
*/}
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<DrawGraph
|
||||
isListOrdered={isListOrdered}
|
||||
orderedList={orderedList}
|
||||
listOfElements={listOfElements}
|
||||
links={buildLinks(quantitativeComparisons)}>
|
||||
</DrawGraph>
|
||||
<div className={`inline items-center text-center mt-10 ${isListOrdered ? "" : "hidden"}`}>
|
||||
<CreateTableWithDistances
|
||||
isListOrdered={isListOrdered}
|
||||
orderedList={orderedList}
|
||||
listOfElements={listOfElements}
|
||||
links={buildLinks(quantitativeComparisons)}
|
||||
>
|
||||
</CreateTableWithDistances>
|
||||
</div>
|
||||
<div className="w-2/12 flex justify-center mt-10">
|
||||
<button
|
||||
className="text-gray-500 text-sm"
|
||||
onClick={() => changeShowAdvanceOptions(!showAdvancedOptions)}
|
||||
>
|
||||
Advanced options ▼
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className={`flex flex-wrap -mx-4 overflow-hidden ${showAdvancedOptions ? "" : "hidden"}`}>
|
||||
<div className="my-4 px-4 w-1/3 overflow-hidden">
|
||||
<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={() => restart(posList)}>
|
||||
Restart
|
||||
</button>
|
||||
</div>
|
||||
<div className="my-4 px-4 w-1/3 overflow-hidden">
|
||||
<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={() => changeShowComparisons(!showComparisons)}>
|
||||
Show comparisons
|
||||
</button>
|
||||
</div>
|
||||
<div className="my-4 px-4 w-1/3 overflow-hidden">
|
||||
<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={() => changeshowChangeDataSet(!showChangeDataSet)}>
|
||||
Use your own data
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={`inline mt-5 ${showChangeDataSet ? "" : "hidden"}`}>
|
||||
<TextAreaForJson handleSubmit={changeDataSet} />
|
||||
</div>
|
||||
|
||||
<div className={`inline mt-5 ${showComparisons ? "" : "hidden"}`}>
|
||||
{/*
|
||||
<DisplayAsMarkdown markdowntext={"## Ordered list\n\n" + JSON.stringify(orderedList.map(i => listOfElements[i]), null, 4)}></DisplayAsMarkdown>
|
||||
*/}
|
||||
<h2>Comparisons</h2>
|
||||
<div className="text-left">
|
||||
<DisplayAsMarkdown
|
||||
markdowntext={JSON.stringify(nicelyFormatLinks(quantitativeComparisons, listOfElements), null, 4)}
|
||||
className={""}>
|
||||
</DisplayAsMarkdown>
|
||||
</div>
|
||||
|
||||
{/*
|
||||
<p>{`Binary comparisons: ${JSON.stringify(binaryComparisons, null, 4)}`}</p>
|
||||
<p>{`Quantitative comparisons: ${JSON.stringify(quantitativeComparisons, null, 4)}`}</p>
|
||||
|
||||
*/}
|
||||
</div>
|
||||
</main>
|
||||
|
||||
</div>
|
||||
)
|
||||
export default function Home({ listOfElementsForView }) {
|
||||
return(<ComparisonView listOfElementsForView={listOfElementsForView}/>)
|
||||
}
|
|
@ -1,71 +1,16 @@
|
|||
/*
|
||||
This is just a copy of index.js but with the constants changed.
|
||||
Don't edit this file, but rather make changes at index.js
|
||||
And copy them over here.
|
||||
*/
|
||||
/* Notes */
|
||||
|
||||
// This function is just a simple wrapper around lib/comparisonView.
|
||||
// Most of the time, I'll want to edit that instead
|
||||
|
||||
/* Imports */
|
||||
import React from "react";
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import ComparisonView from '../lib/comparisonView.js'
|
||||
|
||||
/* Definitions */
|
||||
const elementsDocument = '../data/listOfResearchOutputs.json'
|
||||
const domain = 10**7
|
||||
|
||||
/* Imports */
|
||||
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 { 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 { pushToMongo } from "../lib/pushToMongo.js"
|
||||
import { toLocale, transformSliderValueToPracticalValue, transformSliderValueToActualValue, numToAlphabeticalString } from "../lib/utils.js"
|
||||
|
||||
/* Helpers */
|
||||
let increasingList = (n) => Array.from(Array(n).keys())
|
||||
let buildLinks = quantitativeComparisons => quantitativeComparisons.map(([element1, element2, distance, reasoning]) => ({ source: element1, target: element2, distance: distance, reasoning: reasoning }))
|
||||
|
||||
Array.prototype.containsArray = function (val) {
|
||||
var hash = {};
|
||||
for (var i = 0; i < this.length; i++) {
|
||||
hash[this[i]] = i;
|
||||
}
|
||||
return hash.hasOwnProperty(val);
|
||||
}
|
||||
|
||||
let checkIfListIsOrdered = (arr, binaryComparisons) => {
|
||||
let l = arr.length
|
||||
let isOrdered = true
|
||||
for (let i = 0; i < l - 1; i++) {
|
||||
isOrdered = isOrdered && binaryComparisons.containsArray([arr[i], arr[i + 1]])
|
||||
}
|
||||
return isOrdered
|
||||
}
|
||||
|
||||
let displayFunctionSliderInner = (value) => {
|
||||
let result
|
||||
if (value >= 0) {
|
||||
result = toLocale(transformSliderValueToPracticalValue(value))
|
||||
} else {
|
||||
let inverseresult = toLocale(transformSliderValueToPracticalValue(-value))
|
||||
if (inverseresult == 1) {
|
||||
result = '1'
|
||||
} else {
|
||||
result = `1/${inverseresult}`
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
let displayFunctionSlider = (value) => {
|
||||
let result = displayFunctionSliderInner(value)
|
||||
result = `The first option is ${result}x as valuable as the second one`
|
||||
return result
|
||||
|
||||
};
|
||||
|
||||
let nicelyFormatLinks = (quantitativeComparisons, listOfElements) => quantitativeComparisons.map(([element1, element2, distance, reasoning]) => ({ source: listOfElements[element1].name, target: listOfElements[element2].name, distance: distance, reasoning: reasoning }))
|
||||
|
||||
/* React components */
|
||||
// fs can only be used here.
|
||||
|
@ -73,356 +18,17 @@ export async function getStaticProps() {
|
|||
//getServerSideProps
|
||||
// const { metaforecasts } = await getForecasts();
|
||||
const directory = path.join(process.cwd(), "pages")
|
||||
let listOfElementsDefault = JSON.parse(fs.readFileSync(path.join(directory, elementsDocument), 'utf8'));
|
||||
let listOfElementsForView = JSON.parse(fs.readFileSync(path.join(directory, elementsDocument), 'utf8'));
|
||||
//console.log(directory)
|
||||
//console.log("metaforecasts", metaforecasts)
|
||||
return {
|
||||
props: {
|
||||
listOfElementsDefault
|
||||
listOfElementsForView
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// Main react component
|
||||
export default function Home({ listOfElementsDefault }) {
|
||||
// State
|
||||
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 initialSliderValue = 1
|
||||
let initialReasoning = ''
|
||||
let initialBinaryComparisons = []
|
||||
let initialQuantitativeComparisons = []
|
||||
let initialIsListOdered = false
|
||||
let initialOrderedList = []
|
||||
let initialShowAdvancedOptions = false
|
||||
let initialShowComparisons = false
|
||||
let initialShowChangeDataSet = false
|
||||
|
||||
const [listOfElements, setListOfElements] = useState(initialListOfElements)
|
||||
const [posList, setPosList] = useState(initialPosList)
|
||||
//const posList = initialPosList
|
||||
// let listOfElements = initialListOfElements
|
||||
|
||||
const [toComparePair, setToComparePair] = useState(initialComparePair)
|
||||
const [sliderValue, setSliderValue] = useState(initialSliderValue)
|
||||
const [reasoning, setReasoning] = useState(initialReasoning)
|
||||
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 [orderedList, setOrderedList] = useState(initialOrderedList)
|
||||
|
||||
let [showAdvancedOptions, changeShowAdvanceOptions] = useState(initialShowAdvancedOptions);
|
||||
let [showComparisons, changeShowComparisons] = useState(initialShowComparisons);
|
||||
let [showChangeDataSet, changeshowChangeDataSet] = useState(initialShowChangeDataSet);
|
||||
|
||||
let restart = (posList) => {
|
||||
setToComparePair([posList[posList.length - 2], posList[posList.length - 1]])
|
||||
setSliderValue(initialSliderValue)
|
||||
setBinaryComparisons(initialBinaryComparisons)
|
||||
setQuantitativeComparisons(initialQuantitativeComparisons)
|
||||
setIsListOrdered(initialIsListOdered)
|
||||
setOrderedList(initialOrderedList)
|
||||
removeOldSvg()
|
||||
}
|
||||
|
||||
let changeDataSet = (listOfElementsNew) => {
|
||||
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]])
|
||||
restart(newPosList)
|
||||
}
|
||||
|
||||
// Manipulations
|
||||
let compareTwoElements = (newBinaryComparisons, element1, element2) => {
|
||||
let element1Greater = newBinaryComparisons.containsArray([element1, element2])
|
||||
let element2Greater = newBinaryComparisons.containsArray([element2, element1])
|
||||
if (element1Greater || element2Greater) {
|
||||
return element1Greater && !element2Greater
|
||||
} else {
|
||||
setToComparePair([element1, element2])
|
||||
//console.log(`No comparison found between ${element1} and ${element2}`)
|
||||
//console.log(`Comparisons:`)
|
||||
//console.log(JSON.stringify(newBinaryComparisons, null, 4));
|
||||
return "No comparison found"
|
||||
}
|
||||
}
|
||||
|
||||
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") {
|
||||
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
|
||||
}
|
||||
|
||||
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 result = merge(comparisons, orderedFirstHalf, orderedSecondHalf);
|
||||
return result
|
||||
} else {
|
||||
return "No comparison found; unable to proceed"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
let nextStepSimple = (posList, binaryComparisons, element1, element2) => {
|
||||
//console.log("Binary comparisons: ")
|
||||
//console.log(JSON.stringify(binaryComparisons, null, 4));
|
||||
|
||||
let newComparison = [element1, element2] // [element1, element2]
|
||||
let newBinaryComparisons = [...binaryComparisons, newComparison]
|
||||
//console.log("New binaryComparisons: ")
|
||||
//console.log(JSON.stringify(newBinaryComparisons, null, 4));
|
||||
setBinaryComparisons(newBinaryComparisons)
|
||||
|
||||
let result = mergeSort({ array: posList, comparisons: newBinaryComparisons })
|
||||
//console.log(result)
|
||||
if (result != "No comparison found; unable to proceed" && checkIfListIsOrdered(result, newBinaryComparisons)) {
|
||||
// console.log(`isListOrdered: ${isListOrdered}`)
|
||||
console.log("poslist@nextStepSimple")
|
||||
console.log(posList)
|
||||
console.log("result@nextStepSimple")
|
||||
console.log(result)
|
||||
|
||||
setIsListOrdered(true)
|
||||
setOrderedList(result)
|
||||
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
let nextStepSlider = ({ posList, binaryComparisons, sliderValue, Reasoning, element1, element2 }) => {
|
||||
if (sliderValue < 1 && sliderValue > 0) {
|
||||
sliderValue = 1 / sliderValue;
|
||||
[element1, element2] = [element2, element1]
|
||||
}
|
||||
console.log(`posList@nextStepSlider:`)
|
||||
console.log(posList)
|
||||
let successStatus = nextStepSimple(posList, binaryComparisons, element1, element2)
|
||||
|
||||
let newQuantitativeComparison = [element1, element2, transformSliderValueToActualValue(sliderValue), reasoning]
|
||||
let newQuantitativeComparisons = [...quantitativeComparisons, newQuantitativeComparison]
|
||||
setQuantitativeComparisons(newQuantitativeComparisons)
|
||||
|
||||
setSliderValue(1)
|
||||
setReasoning('')
|
||||
if (successStatus) {
|
||||
let jsObject = nicelyFormatLinks(quantitativeComparisons, listOfElements)
|
||||
pushToMongo(jsObject)
|
||||
console.log(jsObject)
|
||||
}
|
||||
}
|
||||
|
||||
// Html
|
||||
return (
|
||||
<div className="flex flex-col items-center justify-center min-h-screen py-2">
|
||||
<div className="mt-20">
|
||||
<Head >
|
||||
<title>Utility Function Extractor</title>
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
</Head>
|
||||
</div>
|
||||
|
||||
<main className="flex flex-col items-center w-full flex-1 px-20 text-center">
|
||||
<h1 className="text-6xl font-bold">
|
||||
Utility Function Extractor
|
||||
</h1>
|
||||
|
||||
<div className={`${isListOrdered ? "hidden" : ""}`}>
|
||||
<div className="flex flex-wrap items-center max-w-4xl sm:w-full mt-10">
|
||||
<div
|
||||
className="flex m-auto border-gray-300 border-4 h-72 w-72 p-5"
|
||||
//onClick={() => nextStep(binaryComparisons, toComparePair[0], toComparePair[1])}
|
||||
>
|
||||
<div className="block m-auto text-center">
|
||||
<DisplayElement element={listOfElements[toComparePair[0]]}>
|
||||
</DisplayElement>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex m-auto w-72">
|
||||
<div className="block m-auto text-center">
|
||||
{/*`is ${displayFunctionSliderInner(sliderValue)}x times as valuable as`*/}
|
||||
<br />
|
||||
|
||||
<label>
|
||||
{`... is `}
|
||||
<br />
|
||||
<input
|
||||
type="number"
|
||||
value={sliderValue}
|
||||
onChange={(event) => {
|
||||
//console.log(event)
|
||||
//console.log(event.target.value)
|
||||
setSliderValue(event.target.value)
|
||||
}}
|
||||
className="text-center px-2 py-1 placeholder-blueGray-300 text-blueGray-600 relative bg-white bg-white rounded text-lg border-0 shadow outline-none focus:outline-none focus:ring w-8/12 m-2 "
|
||||
/>
|
||||
<br />
|
||||
{`times as valuable as ...`}
|
||||
</label>
|
||||
<br />
|
||||
|
||||
|
||||
|
||||
<SubmitSliderButton
|
||||
posList={posList}
|
||||
binaryComparisons={binaryComparisons}
|
||||
sliderValue={sliderValue}
|
||||
reasoning={reasoning}
|
||||
toComparePair={toComparePair}
|
||||
nextStepSlider={nextStepSlider}
|
||||
/>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div
|
||||
className="flex m-auto border-gray-300 border-4 h-72 w-72 p-5 "
|
||||
//onClick={() => nextStep(binaryComparisons, toComparePair[1], toComparePair[0])}
|
||||
>
|
||||
<div className="block m-auto text-center">
|
||||
<DisplayElement element={listOfElements[toComparePair[1]]}>
|
||||
</DisplayElement>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
<label className="">
|
||||
Reasoning (optional):
|
||||
<br />
|
||||
<textarea className="mt-2 px-3 py-4 placeholder-blueGray-300 text-blueGray-600 relative bg-white bg-white rounded text-base border-0 shadow outline-none focus:outline-none focus:ring w-full"
|
||||
value={reasoning}
|
||||
onChange={(event) => setReasoning(event.target.value)}
|
||||
/>
|
||||
</label>
|
||||
<br />
|
||||
<div>
|
||||
</div>
|
||||
{/*
|
||||
|
||||
<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}
|
||||
domain={domain}
|
||||
/>
|
||||
</div>
|
||||
*/}
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<DrawGraph
|
||||
isListOrdered={isListOrdered}
|
||||
orderedList={orderedList}
|
||||
listOfElements={listOfElements}
|
||||
links={buildLinks(quantitativeComparisons)}>
|
||||
</DrawGraph>
|
||||
<div className={`inline items-center text-center mt-10 ${isListOrdered ? "" : "hidden"}`}>
|
||||
<CreateTableWithDistances
|
||||
isListOrdered={isListOrdered}
|
||||
orderedList={orderedList}
|
||||
listOfElements={listOfElements}
|
||||
links={buildLinks(quantitativeComparisons)}
|
||||
>
|
||||
</CreateTableWithDistances>
|
||||
</div>
|
||||
<div className="w-2/12 flex justify-center mt-10">
|
||||
<button
|
||||
className="text-gray-500 text-sm"
|
||||
onClick={() => changeShowAdvanceOptions(!showAdvancedOptions)}
|
||||
>
|
||||
Advanced options ▼
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className={`flex flex-wrap -mx-4 overflow-hidden ${showAdvancedOptions ? "" : "hidden"}`}>
|
||||
<div className="my-4 px-4 w-1/3 overflow-hidden">
|
||||
<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={() => restart(posList)}>
|
||||
Restart
|
||||
</button>
|
||||
</div>
|
||||
<div className="my-4 px-4 w-1/3 overflow-hidden">
|
||||
<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={() => changeShowComparisons(!showComparisons)}>
|
||||
Show comparisons
|
||||
</button>
|
||||
</div>
|
||||
<div className="my-4 px-4 w-1/3 overflow-hidden">
|
||||
<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={() => changeshowChangeDataSet(!showChangeDataSet)}>
|
||||
Use your own data
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={`inline mt-5 ${showChangeDataSet ? "" : "hidden"}`}>
|
||||
<TextAreaForJson handleSubmit={changeDataSet} />
|
||||
</div>
|
||||
|
||||
<div className={`inline mt-5 ${showComparisons ? "" : "hidden"}`}>
|
||||
{/*
|
||||
<DisplayAsMarkdown markdowntext={"## Ordered list\n\n" + JSON.stringify(orderedList.map(i => listOfElements[i]), null, 4)}></DisplayAsMarkdown>
|
||||
*/}
|
||||
<h2>Comparisons</h2>
|
||||
<div className="text-left">
|
||||
<DisplayAsMarkdown
|
||||
markdowntext={JSON.stringify(nicelyFormatLinks(quantitativeComparisons, listOfElements), null, 4)}
|
||||
className={""}>
|
||||
</DisplayAsMarkdown>
|
||||
</div>
|
||||
|
||||
{/*
|
||||
<p>{`Binary comparisons: ${JSON.stringify(binaryComparisons, null, 4)}`}</p>
|
||||
<p>{`Quantitative comparisons: ${JSON.stringify(quantitativeComparisons, null, 4)}`}</p>
|
||||
|
||||
*/}
|
||||
</div>
|
||||
</main>
|
||||
|
||||
</div>
|
||||
)
|
||||
export default function Home({ listOfElementsForView }) {
|
||||
return(<ComparisonView listOfElementsForView={listOfElementsForView}/>)
|
||||
}
|
Loading…
Reference in New Issue
Block a user