## to protect against loss of information whilst constructing patterns ${{ var workIsDone = false; window.onbeforeunload = confirmBrowseAway; function confirmBrowseAway() { if (!workIsDone) { return "Are you sure? If you leave this page now, your work will NOT be saved."; } }; }}$; html("

A simple shopping construal


Note: This construal has been developed for collaborative interaction using features that are only available in the most recent 'construit' variant of JS-EDEN which you find at the url http://jseden.dcs.warwick.ac.uk/construit . You may need to move this HTML window aside in order to see other windows in the display. You may also find it helpful to resize the display: this can be done by assigning a new value to the observable scaleWidth.


The purpose of this construal is to illustrate how the basic concepts of observables, dependencies and agents/agency are represented in a simple shopping scenario. Simple examples of observables are: the coins in the purse, the items for sale, the items in the basket, and whether or not you have enough money in your purse to buy the items in your basket. The value of an observable may be explicitly specified (in which case its value can be changed by making an assignment - designated by '='). It may also be specified implicitly in terms of the values of other observables (in which case, its value is specified via a definition - designated by 'is'). An 'is' definition expresses a dependency: if the value on the RHS of a definition changes at any point, the value on the LHS is automatically updated, as in a spreadsheet.

The construal can be viewed as a rather open-ended and incompletely specified explanatory, exploratory or educational resource. The precise way in which observables, dependencies and agency are configured will depend on how the construal is to be exercised - that is to say, what kind of explanatory, exploratory or educational role it is at present intended to serve. It is common for this role to be in flux, and reconfiguration is generally relatively straightforward. This is in contrast to what is typically involved in modifying a traditional program to meet a new requirement. The extent to which a construal can be readily adapted to serve different roles is a pragmatic measure of its quality. This is in keeping with the way in which the merits of commonsense everyday construals are assessed.

In its present form, the shopping construal is set up as an environment within which a learner unfamiliar with UK currency or unaccustomed to mental arithmetic can interact and experiment. The display has two parts - an upper portion which represents a purse with eight randomly generated UK coins, and a lower portion which represents six items for sale (at absurd prices!). Coins to be offered in making a purchase can be taken into / out of the purse by clicking on them using the mouse. Items to be placed in the basket for purchase can be selected / deselected in a similar fashion.

The observables, dependencies and agency in the model can be inspected by creating instances of views using the drop-down menu under the New tab on the left at the top of the JS-EDEN display, and inserting suitable 'regular expressions (RE)' into the search boxes in each of these views. The following views and REs can be used for instance:

For this particular way of exercising the construal, the eight coins in the purse have been defined by generating eight indices ix1, ix2, ..., ix8 at random. The values of these indices determine the denominations of the coins in the purse. For instance, the eight denominations of coin - 1,2,5,10,20,50,100,200 pence - are indexed by 1 to 8 in the list coinlist, so that if ix4 is 7, the 'fourth' coin in the purse is a pound coin etc. To change the contents of the purse, you can copy-and-paste the following code into the Input Window and press Submit:

ix1 = randomInteger(1, 8);
ix2 = randomInteger(1, 8);
ix3 = randomInteger(1, 8);
ix4 = randomInteger(1, 8);
ix5 = randomInteger(1, 8);
ix6 = randomInteger(1, 8);
ix7 = randomInteger(1, 8);
ix8 = randomInteger(1, 8);


Acknowledgements: The images and presentation of coins were adapted from these websites:

http://projectbritain.com/money/coins.htm
http://www.mathsisfun.com/money/currency.html


"); ## Auto-Generated Script of Model by JS-Eden ## Auto calculation is turned off to until the model has been fully loaded autocalc = 0; ## Observable Assignments: price1 = 1.5; price2 = 0.36; price3 = 1.25; price4 = 1; price5 = 0.4; price6 = 2.48; imagelocation = "http://www.dcs.warwick.ac.uk/~jonny/ukcurrency/"; pounds = 2; pence = 0.3; /* width50 = 69; width200 = 72; width5 = 46; width10 = 62; width1 = 51; width100 = 57; width20 = 54; width2 = 66; */ scaleWidth = 60; ## Observable Definitions: ix1 is int(random()*8)+1; ix2 is int(random()*8)+1; ix3 is int(random()*8)+1; ix4 is int(random()*8)+1; ix5 is int(random()*8)+1; ix6 is int(random()*8)+1; ix7 is int(random()*8)+1; ix8 is int(random()*8)+1; item1 is [ "id1", price1]; item2 is [ "id2", price2]; item3 is [ "id3", price3]; item4 is [ "id4", price4]; item5 is [ "id5", price5]; item6 is [ "id6", price6]; forsale is [item1, item2, item3, item4, item5, item6]; basket is listitems(forsale, itemsselected); bill is costitems(forsale, itemsselected); coinlist is [1,2,5,10,20,50,100,200]; purse is [coinlist[ix1], coinlist[ix2], coinlist[ix3], coinlist[ix4], coinlist[ix5], coinlist[ix6], coinlist[ix7], coinlist[ix8]]; spendingmoney is (purse[1]+purse[2]+purse[3]+purse[4]+purse[5]+purse[6]+purse[7]+purse[8])/100; /* testcoindisplay is coindisplay(ix1); testdenomdisplay is denomdisplay(ix7); testdisplaycurrency is displaycurrency(spendingmoney); */ haveenoughmoney is (bill bill)? round(tendered - bill, 2) : 0; /* widths is [width1, width2, width5, width10, width20, width50, width100, width200]; currwidths is [widths[ix1], widths[ix2], widths[ix3], widths[ix4], widths[ix5], widths[ix6], widths[ix7], widths[ix8]]; */ items is [item1, item2, item3, item4, item5, item6]; coin1pic is HTMLImage("coin1pic",0,2*scaleWidth*coinsselected[1],scaleWidth,scaleWidth,imagelocation // coindisplay(ix1)); coin2pic is HTMLImage("coin2pic", scaleWidth,2*scaleWidth*coinsselected[2],scaleWidth,scaleWidth,imagelocation // coindisplay(ix2)); coin3pic is HTMLImage("coin3pic", scaleWidth*2,2*scaleWidth*coinsselected[3],scaleWidth,scaleWidth,imagelocation // coindisplay(ix3)); coin4pic is HTMLImage("coin4pic", scaleWidth*3,2*scaleWidth*coinsselected[4],scaleWidth,scaleWidth,imagelocation // coindisplay(ix4)); coin5pic is HTMLImage("coin5pic", scaleWidth*4,2*scaleWidth*coinsselected[5],scaleWidth,scaleWidth,imagelocation // coindisplay(ix5)); coin6pic is HTMLImage("coin6pic", scaleWidth*5,2*scaleWidth*coinsselected[6],scaleWidth,scaleWidth,imagelocation // coindisplay(ix6)); coin7pic is HTMLImage("coin7pic", scaleWidth*6,2*scaleWidth*coinsselected[7],scaleWidth,scaleWidth,imagelocation // coindisplay(ix7)); coin8pic is HTMLImage("coin8pic", scaleWidth*7,2*scaleWidth*coinsselected[8],scaleWidth,scaleWidth,imagelocation // coindisplay(ix8)); item1pic is HTMLImage("item1pic",scaleWidth*0.5,5.5*scaleWidth-2*scaleWidth*itemsselected[1],scaleWidth,scaleWidth,imagelocation // itemdisplay(1)); item2pic is HTMLImage("item2pic", scaleWidth*1.8, 5.5*scaleWidth-2*scaleWidth*itemsselected[2],scaleWidth,scaleWidth,imagelocation // itemdisplay(2)); item3pic is HTMLImage("item3pic", scaleWidth*3.1, 5.5*scaleWidth-2*scaleWidth*itemsselected[3],scaleWidth,scaleWidth,imagelocation // itemdisplay(3)); item4pic is HTMLImage("item4pic", scaleWidth*4.4, 5.5*scaleWidth-2*scaleWidth*itemsselected[4],scaleWidth,scaleWidth,imagelocation // itemdisplay(4)); item5pic is HTMLImage("item5pic", scaleWidth*5.7, 5.5*scaleWidth-2*scaleWidth*itemsselected[5],scaleWidth,scaleWidth,imagelocation // itemdisplay(5)); item6pic is HTMLImage("item6pic", scaleWidth*7, 5.5*scaleWidth-2*scaleWidth*itemsselected[6],scaleWidth,scaleWidth,imagelocation // itemdisplay(6)); /* item1pic0 is HTMLImage("item1pic",scaleWidth*0.5,5.5*scaleWidth,scaleWidth,scaleWidth,imagelocation // itemdisplay(1)); item2pic0 is HTMLImage("item2pic", scaleWidth*1.8, 5.5*scaleWidth,scaleWidth,scaleWidth,imagelocation // itemdisplay(2)); item3pic0 is HTMLImage("item3pic", scaleWidth*3.1, 5.5*scaleWidth,scaleWidth,scaleWidth,imagelocation // itemdisplay(3)); item4pic0 is HTMLImage("item4pic", scaleWidth*4.4, 5.5*scaleWidth,scaleWidth,scaleWidth,imagelocation // itemdisplay(4)); item5pic0 is HTMLImage("item5pic", scaleWidth*5.7, 5.5*scaleWidth,scaleWidth,scaleWidth,imagelocation // itemdisplay(5)); item6pic0 is HTMLImage("item6pic", scaleWidth*7, 5.5*scaleWidth,scaleWidth,scaleWidth,imagelocation // itemdisplay(6)); */ coin1text is Text(denomdisplay(ix1), 0.2*scaleWidth,1.5*scaleWidth); coin2text is Text(denomdisplay(ix2), 1.2*scaleWidth,1.5*scaleWidth); coin3text is Text(denomdisplay(ix3), 2.2*scaleWidth,1.5*scaleWidth); coin4text is Text(denomdisplay(ix4), 3.2*scaleWidth,1.5*scaleWidth); coin5text is Text(denomdisplay(ix5), 4.2*scaleWidth,1.5*scaleWidth); coin6text is Text(denomdisplay(ix6), 5.2*scaleWidth,1.5*scaleWidth); coin7text is Text(denomdisplay(ix7), 6.2*scaleWidth,1.5*scaleWidth); coin8text is Text(denomdisplay(ix8), 7.2*scaleWidth,1.5*scaleWidth); item1text is Text(pricedisplay(1), 0.6*scaleWidth,5*scaleWidth); item2text is Text(pricedisplay(2), 1.9*scaleWidth,5*scaleWidth); item3text is Text(pricedisplay(3), 3.2*scaleWidth,5*scaleWidth); item4text is Text(pricedisplay(4), 4.5*scaleWidth,5*scaleWidth); item5text is Text(pricedisplay(5), 5.8*scaleWidth,5*scaleWidth); item6text is Text(pricedisplay(6), 7.1*scaleWidth,5*scaleWidth); ## Action Definitions: proc coin1picMove : coin1pic_click { if(coin1pic_click) coinsselected[1] = 1 - coinsselected[1]; } proc coin2picMove : coin2pic_click { if(coin2pic_click) coinsselected[2] = 1 - coinsselected[2]; } proc coin3picMove : coin3pic_click { if(coin3pic_click) coinsselected[3] = 1 - coinsselected[3]; } proc coin4picMove : coin4pic_click { if(coin4pic_click) coinsselected[4] = 1 - coinsselected[4]; } proc coin5picMove : coin5pic_click { if(coin5pic_click) coinsselected[5] = 1 - coinsselected[5]; } proc coin6picMove : coin6pic_click { if(coin6pic_click) coinsselected[6] = 1 - coinsselected[6]; } proc coin7picMove : coin7pic_click { if(coin7pic_click) coinsselected[7] = 1 - coinsselected[7]; } proc coin8picMove : coin8pic_click { if(coin8pic_click) coinsselected[8] = 1 - coinsselected[8]; } proc item1picMove : item1pic_click { if(item1pic_click) itemsselected[1] = 1 - itemsselected[1]; } proc item2picMove : item2pic_click { if(item2pic_click) itemsselected[2] = 1 - itemsselected[2]; } proc item3picMove : item3pic_click { if(item3pic_click) itemsselected[3] = 1 - itemsselected[3]; } proc item4picMove : item4pic_click { if(item4pic_click) itemsselected[4] = 1 - itemsselected[4]; } proc item5picMove : item5pic_click { if(item5pic_click) itemsselected[5] = 1 - itemsselected[5]; } proc item6picMove : item6pic_click { if(item6pic_click) itemsselected[6] = 1 - itemsselected[6]; } ## Function Definitions: func listitems { para onsale, chosen; auto result, i; result = []; for (i=1; i<=onsale#; i++) if (chosen[i]) result = result // [onsale[i][1]]; return result; } func costitems { para onsale, chosen; auto result, i; result = 0; for (i=1; i<=onsale#; i++) if (chosen[i]) result = result + onsale[i][2]; return result; } func moneyinhand { para allcoins, chosen; auto result, i; result = 0; for (i=1; i<=allcoins#; i++) if (chosen[i]) result = result + allcoins[i]; return result/100; } func coindisplay { para ix; if (ix==1) return "1p.gif"; if (ix==2) return "2p.gif"; if (ix==3) return "5p.gif"; if (ix==4) return "10p.gif"; if (ix==5) return "20p.jpg"; if (ix==6) return "50p.jpg"; if (ix==7) return "pound.gif"; if (ix==8) return "2pounds.gif"; } func listcoins { para allcoins, chosen; auto result, i; result = []; for (i=1; i<=allcoins#; i++) if (chosen[i]) result = result // [allcoins[i]]; return result; } func itemdisplay { para ix, scaleWidth; if (ix==1) return "a.png"; if (ix==2) return "b.png"; if (ix==3) return "c.jpg"; if (ix==4) return "d.jpg"; if (ix==5) return "e.jpg"; if (ix==6) return "f.jpg"; } func denomdisplay { para ix; if (ix==1) return "1p"; if (ix==2) return "2p"; if (ix==3) return "5p"; if (ix==4) return "10p"; if (ix==5) return "20p"; if (ix==6) return "50p"; if (ix==7) return "£1"; if (ix==8) return "£2"; } func displaycurrency { para amount; auto pounds, pence; pence = 100*amount; pounds = int (pence / 100); pence = pence - pounds*100; return ("£" // (pounds>0) ? str(pounds) : "0") // ((pence>0) ? "-" // str(pence) : "") // "p"; } func pricedisplay { para ix; if (ix==1) return displaycurrency(items[1][2]); if (ix==2) return displaycurrency(items[2][2]); if (ix==3) return displaycurrency(items[3][2]); if (ix==4) return displaycurrency(items[4][2]); if (ix==5) return displaycurrency(items[5][2]); if (ix==6) return displaycurrency(items[6][2]); } ## Picture Definition: picture is [coin1pic,coin2pic,coin3pic,coin4pic,coin5pic,coin6pic,coin7pic,coin8pic, item1pic,item2pic,item3pic,item4pic,item5pic,item6pic, coin1text,coin2text,coin3text,coin4text,coin5text,coin6text,coin7text,coin8text,item1text,item2text,item3text,item4text,item5text,item6text]; ## Auto calculation is turned on and the updating is fired autocalc = 1; ## End of Auto-Generated Script coinsselected = [0,0,0,0,0,0,0,0]; itemsselected = [0,0,0,0,0,0]; ix1 = randomInteger(1, 8); ix2 = randomInteger(1, 8); ix3 = randomInteger(1, 8); ix4 = randomInteger(1, 8); ix5 = randomInteger(1, 8); ix6 = randomInteger(1, 8); ix7 = randomInteger(1, 8); ix8 = randomInteger(1, 8); PurseContentText is Text("Content of purse", 8.3*scaleWidth,0.5*scaleWidth, "blue", 18); CoinsInHandText is Text("Coins to hand", 8.3*scaleWidth,2.5*scaleWidth, "red", 18); BasketContentText is Text("Content of basket", 8.3*scaleWidth,4*scaleWidth, "red", 18); ItemsForSaleText is Text("Items for sale", 8.3*scaleWidth,6*scaleWidth, "blue", 18); picture is [coin1pic,coin2pic,coin3pic,coin4pic,coin5pic,coin6pic,coin7pic,coin8pic, item1pic,item2pic,item3pic,item4pic,item5pic,item6pic, coin1text,coin2text,coin3text,coin4text,coin5text,coin6text,coin7text,coin8text,item1text,item2text,item3text,item4text,item5text,item6text, PurseContentText,CoinsInHandText,BasketContentText,ItemsForSaleText]; /* picture is [coin1pic,coin2pic,coin3pic,coin4pic,coin5pic,coin6pic,coin7pic,coin8pic, item1pic,item2pic,item3pic,item4pic,item5pic,item6pic, item1pic0,item2pic0,item3pic0,item4pic0,item5pic0,item6pic0, coin1text,coin2text,coin3text,coin4text,coin5text,coin6text,coin7text,coin8text,item1text,item2text,item3text,item4text,item5text,item6text, PurseContentText,CoinsInHandText,BasketContentText,ItemsForSaleText]; */