updte before bed

This commit is contained in:
Martin Donnelly 2020-08-12 00:29:04 +01:00
parent 59e89318de
commit 19fe4ce4a8
8 changed files with 422 additions and 102 deletions

View File

@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
</profile>
</component>

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,4 @@
<changelist name="Uncommitted_changes_before_Update_at_11_08_2020,_22_16_[Default_Changelist]" date="1597180616770" recycled="true" deleted="true">
<option name="PATH" value="$PROJECT_DIR$/.idea/shelf/Uncommitted_changes_before_Update_at_11_08_2020,_22_16_[Default_Changelist]/shelved.patch" />
<option name="DESCRIPTION" value="Uncommitted changes before Update at 11/08/2020, 22:16 [Default Changelist]" />
</changelist>

View File

@ -1,10 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="BranchesTreeState">
<expand>
<path>
<item name="ROOT" type="e8cecc67:BranchNodeDescriptor" />
<item name="LOCAL_ROOT" type="e8cecc67:BranchNodeDescriptor" />
</path>
<path>
<item name="ROOT" type="e8cecc67:BranchNodeDescriptor" />
<item name="REMOTE_ROOT" type="e8cecc67:BranchNodeDescriptor" />
</path>
<path>
<item name="ROOT" type="e8cecc67:BranchNodeDescriptor" />
<item name="REMOTE_ROOT" type="e8cecc67:BranchNodeDescriptor" />
<item name="GROUP_NODE:origin" type="e8cecc67:BranchNodeDescriptor" />
</path>
</expand>
<select>
<path>
<item name="ROOT" type="e8cecc67:BranchNodeDescriptor" />
<item name="LOCAL_ROOT" type="e8cecc67:BranchNodeDescriptor" />
<item name="BRANCH:master" type="e8cecc67:BranchNodeDescriptor" />
</path>
</select>
</component>
<component name="ChangeListManager">
<list default="true" id="8f59754f-8b0b-4496-b8f6-b19be929e084" name="Default Changelist" comment="">
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Buyer.js" beforeDir="false" afterPath="$PROJECT_DIR$/Buyer.js" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Seller.js" beforeDir="false" afterPath="$PROJECT_DIR$/Seller.js" afterDir="false" />
<change beforePath="$PROJECT_DIR$/main.js" beforeDir="false" afterPath="$PROJECT_DIR$/main.js" afterDir="false" />
<change beforePath="$PROJECT_DIR$/tests/buyer.test.js" beforeDir="false" afterPath="$PROJECT_DIR$/tests/buyer.test.js" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
@ -32,12 +57,19 @@
<property name="WebServerToolWindowFactoryState" value="true" />
<property name="dart.analysis.tool.window.visible" value="false" />
<property name="last_opened_file_path" value="$PROJECT_DIR$" />
<property name="node.js.detected.package.eslint" value="true" />
<property name="node.js.detected.package.standard" value="true" />
<property name="node.js.path.for.package.eslint" value="project" />
<property name="node.js.path.for.package.standard" value="project" />
<property name="node.js.selected.package.eslint" value="(autodetect)" />
<property name="node.js.selected.package.standard" value="" />
<property name="nodejs.jest.jest_package" value="$PROJECT_DIR$/node_modules/jest" />
<property name="settings.editor.selected.configurable" value="reference.settingsdialog.IDE.editor.colors" />
<property name="nodejs_package_manager_path" value="npm" />
<property name="settings.editor.selected.configurable" value="settings.javascript.linters.eslint" />
</component>
<component name="RunManager" selected="Jest.buyer.test.js">
<component name="RunManager" selected="Node.js.main.js">
<configuration name="Buyer" type="JavaScriptTestRunnerJest" temporary="true" nameIsGenerated="true">
<node-interpreter value="$USER_HOME$/.nvm/versions/node/v12.18.0/bin/node" />
<node-interpreter value="project" />
<node-options value="" />
<jest-package value="$PROJECT_DIR$/node_modules/jest" />
<working-dir value="$PROJECT_DIR$" />
@ -49,8 +81,21 @@
</test-names>
<method v="2" />
</configuration>
<configuration name="Seller" type="JavaScriptTestRunnerJest" temporary="true" nameIsGenerated="true">
<node-interpreter value="project" />
<node-options value="" />
<jest-package value="$PROJECT_DIR$/node_modules/jest" />
<working-dir value="$PROJECT_DIR$" />
<envs />
<scope-kind value="SUITE" />
<test-file value="$PROJECT_DIR$/tests/seller.test.js" />
<test-names>
<test-name value="Seller" />
</test-names>
<method v="2" />
</configuration>
<configuration name="buyer.test.js" type="JavaScriptTestRunnerJest" temporary="true" nameIsGenerated="true">
<node-interpreter value="$USER_HOME$/.nvm/versions/node/v12.18.0/bin/node" />
<node-interpreter value="project" />
<node-options value="" />
<jest-package value="$PROJECT_DIR$/node_modules/jest" />
<working-dir value="$PROJECT_DIR$" />
@ -59,10 +104,15 @@
<test-file value="$PROJECT_DIR$/tests/buyer.test.js" />
<method v="2" />
</configuration>
<configuration name="main.js" type="NodeJSConfigurationType" temporary="true" nameIsGenerated="true" path-to-js-file="$PROJECT_DIR$/main.js" working-dir="$PROJECT_DIR$">
<method v="2" />
</configuration>
<recent_temporary>
<list>
<item itemvalue="Node.js.main.js" />
<item itemvalue="Jest.buyer.test.js" />
<item itemvalue="Jest.Buyer" />
<item itemvalue="Jest.Seller" />
</list>
</recent_temporary>
</component>
@ -75,38 +125,75 @@
<option name="presentableId" value="Default" />
<updated>1597136254764</updated>
<workItem from="1597136255857" duration="11000" />
<workItem from="1597136289338" duration="11990000" />
<workItem from="1597136289338" duration="7691000" />
<workItem from="1597154817386" duration="1288000" />
<workItem from="1597180540366" duration="3965000" />
</task>
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="3" />
</component>
<component name="Vcs.Log.Tabs.Properties">
<option name="TAB_STATES">
<map>
<entry key="MAIN">
<value>
<State>
<option name="FILTERS">
<map>
<entry key="branch">
<value>
<list>
<option value="master" />
</list>
</value>
</entry>
</map>
</option>
</State>
</value>
</entry>
</map>
</option>
</component>
<component name="WindowStateProjectService">
<state x="1085" y="461" width="429" height="542" key="FileChooserDialogImpl" timestamp="1597154405421">
<screen x="0" y="29" width="2560" height="1411" />
<state x="778" y="303" width="485" height="511" key="FileChooserDialogImpl" timestamp="1597154877477">
<screen x="0" y="0" width="2048" height="1121" />
</state>
<state x="1085" y="461" width="429" height="542" key="FileChooserDialogImpl/0.29.2560.1411@0.29.2560.1411" timestamp="1597154405421" />
<state width="2183" height="383" key="GridCell.Tab.0.bottom" timestamp="1597176719490">
<screen x="0" y="29" width="2560" height="1411" />
<state x="778" y="303" width="485" height="511" key="FileChooserDialogImpl/0.0.2048.1121@0.0.2048.1121" timestamp="1597154877477" />
<state width="2000" height="268" key="GridCell.Tab.0.bottom" timestamp="1597187407035">
<screen x="0" y="0" width="2048" height="1121" />
</state>
<state width="2183" height="383" key="GridCell.Tab.0.bottom/0.29.2560.1411@0.29.2560.1411" timestamp="1597176719490" />
<state width="2183" height="383" key="GridCell.Tab.0.center" timestamp="1597176719490">
<screen x="0" y="29" width="2560" height="1411" />
<state width="2000" height="268" key="GridCell.Tab.0.bottom/0.0.2048.1121@0.0.2048.1121" timestamp="1597187407035" />
<state width="2463" height="519" key="GridCell.Tab.0.bottom/0.29.2560.1411@0.29.2560.1411" timestamp="1597146833789" />
<state width="2000" height="268" key="GridCell.Tab.0.center" timestamp="1597187407034">
<screen x="0" y="0" width="2048" height="1121" />
</state>
<state width="2183" height="383" key="GridCell.Tab.0.center/0.29.2560.1411@0.29.2560.1411" timestamp="1597176719490" />
<state width="2183" height="383" key="GridCell.Tab.0.left" timestamp="1597176719489">
<screen x="0" y="29" width="2560" height="1411" />
<state width="2000" height="268" key="GridCell.Tab.0.center/0.0.2048.1121@0.0.2048.1121" timestamp="1597187407034" />
<state width="2463" height="519" key="GridCell.Tab.0.center/0.29.2560.1411@0.29.2560.1411" timestamp="1597146833789" />
<state width="2000" height="268" key="GridCell.Tab.0.left" timestamp="1597187407034">
<screen x="0" y="0" width="2048" height="1121" />
</state>
<state width="2183" height="383" key="GridCell.Tab.0.left/0.29.2560.1411@0.29.2560.1411" timestamp="1597176719489" />
<state width="2183" height="383" key="GridCell.Tab.0.right" timestamp="1597176719490">
<screen x="0" y="29" width="2560" height="1411" />
<state width="2000" height="268" key="GridCell.Tab.0.left/0.0.2048.1121@0.0.2048.1121" timestamp="1597187407034" />
<state width="2463" height="519" key="GridCell.Tab.0.left/0.29.2560.1411@0.29.2560.1411" timestamp="1597146833788" />
<state width="2000" height="268" key="GridCell.Tab.0.right" timestamp="1597187407035">
<screen x="0" y="0" width="2048" height="1121" />
</state>
<state width="2183" height="383" key="GridCell.Tab.0.right/0.29.2560.1411@0.29.2560.1411" timestamp="1597176719490" />
<state x="799" y="369" key="SettingsEditor" timestamp="1597155550499">
<screen x="0" y="29" width="2560" height="1411" />
<state width="2000" height="268" key="GridCell.Tab.0.right/0.0.2048.1121@0.0.2048.1121" timestamp="1597187407035" />
<state width="2463" height="519" key="GridCell.Tab.0.right/0.29.2560.1411@0.29.2560.1411" timestamp="1597146833789" />
<state x="200" y="98" width="1642" height="923" key="MergeDialog" timestamp="1597180616716">
<screen x="0" y="0" width="2048" height="1121" />
</state>
<state x="799" y="369" key="SettingsEditor/0.29.2560.1411@0.29.2560.1411" timestamp="1597155550499" />
<state x="200" y="98" width="1642" height="923" key="MergeDialog/0.0.2048.1121@0.0.2048.1121" timestamp="1597180616716" />
<state x="611" y="381" key="SettingsEditor" timestamp="1597181517145">
<screen x="0" y="0" width="2048" height="1121" />
</state>
<state x="611" y="381" key="SettingsEditor/0.0.2048.1121@0.0.2048.1121" timestamp="1597181517145" />
<state x="814" y="475" width="413" height="169" key="com.intellij.openapi.vcs.update.UpdateOrStatusOptionsDialogupdate-v2" timestamp="1597180559540">
<screen x="0" y="0" width="2048" height="1121" />
</state>
<state x="814" y="475" width="413" height="169" key="com.intellij.openapi.vcs.update.UpdateOrStatusOptionsDialogupdate-v2/0.0.2048.1121@0.0.2048.1121" timestamp="1597180559540" />
</component>
<component name="com.intellij.coverage.CoverageDataManagerImpl">
<SUITE FILE_PATH="coverage/coding_challenge$buyer_test_js.info" NAME="buyer.test.js Coverage Results" MODIFIED="1597143325899" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="JestJavaScriptTestRunnerCoverage" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" />

129
Buyer.js
View File

@ -7,14 +7,14 @@ class Buyer {
* Build an order preference table for particular product
* @param product
*/
buildOrderPreference(product) {
buildOrderPrefBestPrice(product) {
let sellers = [];
// build up the initial list
this.market.sellers.forEach((seller, i) => {
if (seller.inventory.hasOwnProperty(product)) {
const price = seller.quote(product);
sellers.push({id: seller.id, price: price, index: i, quantity:seller.inventory[product].quantity})
sellers.push({id: seller.id, price: price, index: i, quantity: seller.inventory[product].quantity})
}
});
@ -27,6 +27,47 @@ class Buyer {
return sellers;
}
buildOrderPrefFastFill(product) {
let sellers = [];
// build up the initial list
this.market.sellers.forEach((seller, i) => {
if (seller.inventory.hasOwnProperty(product)) {
const price = seller.quote(product);
sellers.push({id: seller.id, price: price, index: i, quantity: seller.inventory[product].quantity, deliveryWait:seller.deliveryWait})
}
});
// sort by best price
sellers.sort((a, b) => {
return a.deliveryWait - b.deliveryWait;
})
return sellers;
}
buildOrderPrefMostFill(product) {
let sellers = [];
// build up the initial list
this.market.sellers.forEach((seller, i) => {
if (seller.inventory.hasOwnProperty(product)) {
const price = seller.quote(product);
sellers.push({id: seller.id, price: price, index: i, quantity: seller.inventory[product].quantity, deliveryWait:seller.deliveryWait})
}
});
// sort by best price
sellers.sort((a, b) => {
return b.quantity - a.quantity;
})
return sellers;
}
/**
* This method should get the best price for a given product
* across all sellers
@ -52,12 +93,11 @@ class Buyer {
*/
fillWithBestPrices(product, quantity) {
let total = 0;
let wantedQuantity = quantity;
let sellerPreference = this.buildOrderPreference(product);
let sellerPreference = this.buildOrderPrefBestPrice(product);
console.log(sellerPreference);
let reciept = [];
let receipt = [];
while (sellerPreference.length > 0 && wantedQuantity > 0) {
@ -66,21 +106,16 @@ class Buyer {
let r = this.market.sellers[seller.index].sell(product, wantedQuantity);
wantedQuantity = (wantedQuantity - r.boughtQuantity) < 0 ? 0 : (wantedQuantity - r.boughtQuantity);
reciept.push(r);
receipt.push(r);
}
console.log(reciept);
console.log(reciept.reduce((a, cv) => {
return a.cost + cv.cost;
})
);
throw Error("Not Implemented");
if (receipt.length > 1) {
total = receipt.reduce((a, cv) => {
return (typeof a === 'number' ? a : a.cost) + cv.cost;
});
} else if (receipt.length === 1) total = receipt[0].cost;
return total;
}
@ -92,7 +127,63 @@ class Buyer {
* you should use the cheaper of the two.
*/
fillWithLargestSellers(product, quantity) {
throw Error("Not Implemented");
let total = 0;
let wantedQuantity = quantity;
let sellerPreference = this.buildOrderPrefMostFill(product);
let receipt = [];
while (sellerPreference.length > 0 && wantedQuantity > 0) {
let seller = sellerPreference.shift();
let r = this.market.sellers[seller.index].sell(product, wantedQuantity);
wantedQuantity = (wantedQuantity - r.boughtQuantity) < 0 ? 0 : (wantedQuantity - r.boughtQuantity);
receipt.push(r);
}
if (receipt.length > 1) {
total = receipt.reduce((a, cv) => {
return (typeof a === 'number' ? a : a.cost) + cv.cost;
});
} else if (receipt.length === 1) total = receipt[0].cost;
return total;
}
/**
* This fulfils orders based on time to deliver
* @param product
* @param quantity
* @returns {number}
*/
quicklyFill(product, quantity) {
let total = 0;
let wantedQuantity = quantity;
let sellerPreference = this.buildOrderPrefFastFill(product);
let receipt = [];
while (sellerPreference.length > 0 && wantedQuantity > 0) {
let seller = sellerPreference.shift();
let r = this.market.sellers[seller.index].sell(product, wantedQuantity);
wantedQuantity = (wantedQuantity - r.boughtQuantity) < 0 ? 0 : (wantedQuantity - r.boughtQuantity);
receipt.push(r);
}
if (receipt.length > 1) {
total = receipt.reduce((a, cv) => {
return (typeof a === 'number' ? a : a.cost) + cv.cost;
});
} else if (receipt.length === 1) total = receipt[0].cost;
return total;
}
}

View File

@ -36,6 +36,7 @@ class Seller {
const ec = getExpectedChange(this.random_generator);
const alpha = inventory.startingQuantity
const beta = inventory.quantity
// console.log(`${this.id} alpha: ${alpha} // beta: ${beta} // ec: ${ec}`);
const inv_based_change = Math.log10(beta / alpha) * (-v);
const sentimentChange = inv_based_change + ((ec - 0.5)*v)
return sentimentChange;
@ -53,7 +54,6 @@ class Seller {
tick() {
console.log('tick', this);
for (let [product, value] of Object.entries(this.inventory)) {
let inventory = value;
const isReadyForDelivery = (inventory.priceHistory.length % this.deliveryWait) == 0;

View File

@ -9,12 +9,12 @@ function main(){
let product = "Apples";
let quantity = 10;
buyerFunctions(product, quantity, buyer);
// observeMarket(market);
observeMarket(market);
};
function buyerFunctions(product, quantity, buyer){
console.log(`The best price for ${product} is ${buyer.getBestPrice(product)}`) ;
console.log(`To completely fill a order of ${quantity} ${product} costs ${buyer.completelyFill(product,quantity)}`) ;
console.log(`To completely fill a order of ${quantity} ${product} costs ${buyer.fillWithBestPrices(product,quantity)}`) ;
console.log(`To buy as quickly as possible ${quantity} ${product} costs ${buyer.quicklyFill(product,quantity)}`) ;
}

View File

@ -47,19 +47,19 @@ describe("Buyer", function () {
it("fill 50 apples", () => {
let buyer = new Buyer(market);
expect(buyer.fillWithBestPrices('Apples', 50)).toEqual(0);
expect(buyer.fillWithBestPrices('Apples', 50)).toEqual(233.60268569487857);
});
it("fill 100 apples", () => {
it("unable to fill 10 Kumquat", () => {
let buyer = new Buyer(market);
expect(buyer.fillWithBestPrices('Apples', 100)).toEqual(0);
expect(buyer.fillWithBestPrices('Kumquat', 10)).toEqual(0);
});
it("fill 1000 apples", () => {
it("Large fill 50 apples", () => {
let buyer = new Buyer(market);
expect(buyer.fillWithBestPrices('Apples', 100)).toEqual(0);
expect(buyer. fillWithLargestSellers('Apples', 50)).toEqual(312.5);
});