Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I am trying to get my nested loops to perform a check in / check out simulation. I have my functions set up and my loop at the end but it somehow always gives me the same output. Every patron has the same amount of books and a humongous fine instead of being totally randomized like the checkOut and isOverdue functions make them.
How do I make it so that the loops uses the randomly generated date from the functions and give each patron different amounts of fines and different books checked out? Instructions for the project.
My code:
var Book = function(title, Available, publicationDate, checkoutDate, callNumber, Authors) {
this.title = title;
this.Available = Available;
this.publicationDate = publicationDate;
this.checkoutDate = checkoutDate;
this.callNumber = callNumber;
this.Authors = Authors;
};
var Author = function(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
};
var Patron = function(firstName, lastName, libCardNum, booksOut, fine) {
this.firstName = firstName;
this.lastName = lastName;
this.libCardNum = libCardNum;
this.booksOut = booksOut;
this.fine = fine;
};
function randInRange(start, end) {
return Math.floor(Math.random() * (end - start + 1)) + start;
}
Book.prototype.checkOut = function() {
this.Available = false;
var dateChk = new Date();
var randDay = randInRange(1, 25);
dateChk.setDate(dateChk.getDate() - randDay);
this.checkoutDate = dateChk;
};
Book.prototype.checkIn = function() {
this.Available = true;
};
Book.prototype.isOverdue = function() {
var singleDay = 1000 * 60 * 60 * 24;
var todayDate = new Date().getTime();
var difference = todayDate - this.checkoutDate.getTime();
if (Math.round(difference / singleDay) >= 14) {
return true;
}
return false;
};
Patron.prototype.read = function(book) {
this.booksOut.add(book);
}
Patron.prototype.return = function(book) {
this.booksOut.remove(this.booksOut.length);
}
var authors = [];
authors[0] = new Author("Auth", "One");
authors[1] = new Author("AutL", "Two");
var catalog = [];
catalog[0] = new Book('Bk1', true, new Date(2001, 1, 21), new Date(), 123456, authors);
catalog[1] = new Book('Bk2', true, new Date(2002, 2, 22), new Date(), 987656, authors);
catalog[2] = new Book('Bk3', true, new Date(2003, 3, 23), new Date(), 092673, authors);
catalog[3] = new Book('Bk4', true, new Date(2004, 4, 24), new Date(), 658342, authors);
catalog[4] = new Book('Bk5', true, new Date(2005, 5, 25), new Date(), 345678, authors);
var patrons = [];
patrons[0] = new Patron('Pat1', 'Wat', 1, catalog, 0.00);
patrons[1] = new Patron('Pat2', 'Wot', 1, catalog, 0.00);
patrons[2] = new Patron('Pat3', 'Wit', 1, catalog, 0.00);
patrons[3] = new Patron('Pat4', 'Wet', 1, catalog, 0.00);
patrons[4] = new Patron('Pat5', 'Wut', 1, catalog, 0.00);
//while loop or for loop for 90 days
//For loop over catalog
//forloop over patrons
//Check if available , if so check book out
//If not available check book back in
//check checking back in check to see if book is overdue and if so add a fine
//When down loop over patrons to see their fees
for (var i = 0; i < 90; i++) {
for (var j = 0; j < catalog.length; j++) {
for (var k = 0; k < patrons.length; k++) {
var fine = patrons[k].fine;
if (catalog[k].Available) {
catalog[k].checkOut;
} else {
catalog[k].checkIn;
patrons[k].read;
}
if (catalog[k].isOverdue) {
fine = fine + 5.00;
}
patrons[k].fine = fine;
}
}
}
for (i = 0; i < patrons.length; i++) {
console.log(patrons[i].firstName + " has checked out the following books:");
for (j = 0; j < patrons[i].booksOut.length; j++) {
console.log(patrons[i].booksOut[j].title);
}
console.log(patrons[i].firstName + " has fine amount: $" + patrons[i].fine);
}
I had to make a number of changes to your example so it actually works.
One very important thing to know is that when you call a method of an object you have to put parenthesis behind the call: not catalog[j].checkOut but catalog[j].checkOut().
You can examine my changes and how the script works now. With this in hand you can formulate follow up questions.
Hope this helps.
var Book = function(title, Available, publicationDate, checkoutDate, callNumber, Authors) {
this.title = title;
this.Available = Available;
this.publicationDate = publicationDate;
this.checkoutDate = checkoutDate;
this.callNumber = callNumber;
this.Authors = Authors;
};
var Author = function(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
};
var Patron = function(firstName, lastName, libCardNum, booksOut, fine) {
this.firstName = firstName;
this.lastName = lastName;
this.libCardNum = libCardNum;
this.booksOut = booksOut;
this.fine = fine;
};
function randInRange(start, end) {
return Math.floor(Math.random() * (end - start + 1)) + start;
}
Book.prototype.checkOut = function() {
this.Available = false;
var dateChk = new Date();
var randDay = randInRange(1, 25);
dateChk.setDate(dateChk.getDate() - randDay);
this.checkoutDate = dateChk;
};
Book.prototype.checkIn = function() {
this.Available = true;
};
Book.prototype.isOverdue = function() {
var singleDay = 1000 * 60 * 60 * 24;
var todayDate = new Date().getTime();
var difference = todayDate - this.checkoutDate.getTime();
if (Math.round(difference / singleDay) >= 14) {
return true;
}
return false;
};
// Changed the read method
Patron.prototype.read = function(book) {
this.booksOut[book.callNumber] = book;
}
// Changed the return method
Patron.prototype.return = function(book) {
delete(this.booksOut[book.callNumber]);
}
var authors = [];
authors[0] = new Author("Auth", "One");
authors[1] = new Author("AutL", "Two");
var catalog = [];
catalog[0] = new Book('Bk1', true, new Date(2001, 1, 21), new Date(), 123456, authors);
catalog[1] = new Book('Bk2', true, new Date(2002, 2, 22), new Date(), 987656, authors);
catalog[2] = new Book('Bk3', true, new Date(2003, 3, 23), new Date(), 092673, authors);
catalog[3] = new Book('Bk4', true, new Date(2004, 4, 24), new Date(), 658342, authors);
catalog[4] = new Book('Bk5', true, new Date(2005, 5, 25), new Date(), 345678, authors);
// Changed how Patrons are initialised. Instead of passing the full
// catalog for booksRead an empty object is passed.
var patrons = [];
patrons[0] = new Patron('Pat1', 'Wat', 1, {}, 0.00);
patrons[1] = new Patron('Pat2', 'Wot', 1, {}, 0.00);
patrons[2] = new Patron('Pat3', 'Wit', 1, {}, 0.00);
patrons[3] = new Patron('Pat4', 'Wet', 1, {}, 0.00);
patrons[4] = new Patron('Pat5', 'Wut', 1, {}, 0.00);
//while loop or for loop for 90 days
//For loop over catalog
//forloop over patrons
//Check if available , if so check book out
//If not available check book back in
//check checking back in check to see if book is overdue and if so add a fine
//When down loop over patrons to see their fees
for (var i = 0; i < 3; i++) {
// changed the for loop
for (var j in catalog) {
// changed the for loop
for (var k in patrons) {
var fine = patrons[k].fine;
// Changed catalog[k] to catalog[j]
// moved and changed patrons[k].read() call
// added the patrons[k].return() call
if (catalog[j].Available) {
catalog[j].checkOut();
patrons[k].read(catalog[j]);
} else if (patrons[k].booksOut[catalog[j].callNumber]) {
catalog[j].checkIn();
patrons[k].return(catalog[j]);
}
if (catalog[j].isOverdue()) {
fine = fine + 5.00;
}
patrons[k].fine = fine;
}
}
}
for (i = 0; i < patrons.length; i++) {
console.log(patrons[i].firstName + " has checked out the following books:");
for (j in patrons[i].booksOut) {
console.log(patrons[i].booksOut[j].title);
}
console.log(patrons[i].firstName + " has fine amount: $" + patrons[i].fine);
}
Edit
Answer to the comment.
That is a result of how you set up your for loops. On the first day all the books go to the first patron, on the second day they go to the second partron and so on.
Day 1, book 1, patron 1: Book is available and goes to patron 1.
Day 1, book 1, patron 2: Book is not available.
...
Day 1, book 2, patron 1: Book is available and goes to patron 1.
Day 1, book 2, patron 2: Book is not available.
...
Day 2, book 1, patron 1: Book is not available, book is returned.
Day 2, book 1, patron 2: Book is available and goes to patron 2.
Day 2, book 1, patron 3: Book is not available.
...
and so on
The instructions did not say to shuffle the books or patrons, during the simulation so your results would not be as random as your hoping for. Also looping over the books and patrons we can use a standard forEach vs a regular for loop making the code much easier to follow. I'm using lodash _.shuffle to randomize the books and patrons during each loop for better results. We can also hide the fine logic in our patrons return prototype ending up with a simple simulation.
for (var i = 0; i < 90; i++) {
_.shuffle(books).forEach(function(book) {
_.shuffle(patrons).forEach(function(patron) {
if (patron.hasBookCheckedOut(book)) {
return patron.return(book);
}
if (book.available) {
patron.read(book);
}
});
});
};
Working example http://jsbin.com/teyipak/1/edit?js,console
Related
I want to create an app on Vue where I update through a slider a value and the other value get's updated. Something like this:
Can someone give me a helping hand? I'm going insane. I've been trying to get the formula right for the past 3 days.
This is what I've written so far:
updateRarities(trait, raritySlider){
var property = this.currentCollection.properties.items.find(property => property.id === trait.propertyID);
var numOfTraits = property.traits.items.length;
let newRarityCurrentTrait = 1 / numOfTraits * Number(raritySlider);
for (let i = 0; i < property.traits.items.length; i++) {
if (property.traits.items[i].id !== trait.id) {
let updatedTrait = {
id: property.traits.items[i].id,
// calculate the rarity of the other traits
rarity: (1 - newRarityCurrentTrait) * property.traits.items[i].raritySlider,
updatedAt: new Date(),
}
API.graphql(graphqlOperation(mutations.updateTrait, { input: updatedTrait}));
}
else {
let updatedTrait = {
id: trait.id,
rarity: newRarityCurrentTrait,
raritySlider: raritySlider,
updatedAt: new Date(),
}
API.graphql(graphqlOperation(mutations.updateTrait, { input: updatedTrait}));
}
}
}
Ok I figured it out, after messing a bit with Excel:
updateRarities(trait, raritySlider){
var property = this.currentCollection.properties.items.find(property => property.id === trait.propertyID);
// sum of every raritySlider
let sumOfSliders = 0;
for (let i = 0; i < property.traits.items.length; i++) {
sumOfSliders = Number(sumOfSliders) + Number(property.traits.items[i].raritySlider);
}
for (let i = 0; i < property.traits.items.length; i++) {
if (property.traits.items[i].id !== trait.id) {
let updatedTrait = {
id: property.traits.items[i].id,
// calculate the rarity of the other traits
rarity: 1/sumOfSliders*property.traits.items[i].raritySlider,
updatedAt: new Date(),
}
API.graphql(graphqlOperation(mutations.updateTrait, { input: updatedTrait}));
}
else {
let updatedTrait = {
id: trait.id,
rarity: 1/sumOfSliders*raritySlider,
raritySlider: raritySlider,
updatedAt: new Date(),
}
API.graphql(graphqlOperation(mutations.updateTrait, { input: updatedTrait}));
}
}
}
I just needed to sum the value of the sliders.
I am trying to run a simulation of a library check in/out system with prototypes, objects and nested loops. I am having trouble properly integrating the pseudo code into the loop itself and would appreciate any help.
//while loop or for loop for 90 days
//For loop over catalog
//forloop over patrons
//Check if available , if so check book out
//If not available check book back in
//check checking back in check to see if book is overdue and if so add a fine
//When down loop over patrons to see their fees
Loop
for (var i = 0; i < 90; i++) {
for (var j = 0; j < catalog.length; j++) {
for (var k = 0; k < patrons.length; i++) {
var fine = patrons[k].fine;
if (catalog[k].Available) {
catalog[k].checkOut;
} else {
catalog[k].checkIn;
patrons[k].read;
}
if (catalog[k].isOverdue) {
fine = fine + 5.00;
}
}
}
patrons[i].fine = fine;
}
All the code
var Book = function(title, Available, publicationDate, checkoutDate, callNumber, Authors) {
this.title = title;
this.Available = Available;
this.publicationDate = publicationDate;
this.checkoutDate = checkoutDate;
this.callNumber = callNumber;
this.Authors = Authors;
};
var Author = function(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
};
var Patron = function(firstName, lastName, libCardNum, booksOut, fine) {
this.firstName = firstName;
this.lastName = lastName;
this.libCardNum = libCardNum;
this.booksOut = booksOut;
this.fine = fine;
};
Book.prototype.checkOut = function() {
this.Available = false;
var temp = new Date(1000000000);
var date = new Date() - temp;
var res = new Date(date);
this.checkoutDate = res;
};
Book.prototype.checkIn = function() {
this.Available = true;
};
Book.prototype.isOverdue = function() {
var singleDay = 1000 * 60 * 60 * 24;
var todayDate = new Date().getTime();
var difference = todayDate - this.checkoutDate.getTime();
if (Math.round(difference / singleDay) >= 14) {
return true;
}
return false;
};
Patron.prototype.read = function(book) {
this.booksOut.add(book);
}
Patron.prototype.return = function(book) {
this.booksOut.remove(this.booksOut.length);
}
var authors = [];
authors[0] = new Author("Auth", "One");
authors[1] = new Author("AutL", "Two");
var catalog = [];
catalog[0] = new Book('Bk1', true, new Date(2001, 1, 21), new Date(), 123456, authors);
catalog[1] = new Book('Bk2', true, new Date(2002, 2, 22), new Date(), 987656, authors);
catalog[2] = new Book('Bk3', true, new Date(2003, 3, 23), new Date(), 092673, authors);
catalog[3] = new Book('Bk4', true, new Date(2004, 4, 24), new Date(), 658342, authors);
catalog[4] = new Book('Bk5', true, new Date(2005, 5, 25), new Date(), 345678, authors);
var patrons = [];
patrons[0] = new Patron('Pat1', 'Wat', 1, catalog, 0.00);
patrons[1] = new Patron('Pat2', 'Wot', 1, catalog, 0.00);
patrons[2] = new Patron('Pat3', 'Wit', 1, catalog, 0.00);
patrons[3] = new Patron('Pat4', 'Wet', 1, catalog, 0.00);
patrons[4] = new Patron('Pat5', 'Wut', 1, catalog, 0.00);
//while loop or for loop for 90 days
//For loop over catalog
//forloop over patrons
//Check if available , if so check book out
//If not available check book back in
//check checking back in check to see if book is overdue and if so add a fine
//When down loop over patrons to see their fees
for (var i = 0; i < 90; i++) {
for (var j = 0; j < catalog.length; j++) {
for (var k = 0; k < patrons.length; i++) {
var fine = patrons[k].fine;
if (catalog[k].Available) {
catalog[k].checkOut;
} else {
catalog[k].checkIn;
patrons[k].read;
}
if (catalog[k].isOverdue) {
fine = fine + 5.00;
}
}
}
patrons[i].fine = fine;
}
for (i = 0; i < patrons.length; i++) {
console.log(patrons[i].firstName + " has checked out the following books:");
for (j = 0; j < patrons[i].booksOut.length; j++) {
console.log(patrons[i].booksOut[j].title);
}
console.log(patrons[i].firstName + " has fine amount: $" + patrons[i].fine);
}
I am trying to write a loop that simulates checkouts and checkins for a 3 month period. Every day I iterate over the catalog, and every person in the patrons array. If the patron currently has the book checked out then I check it in. If it is not checked out then I add it to the patrons list of books via the patrons read method. If the book is overdue then I add a fine of $5.00 to the patron returning it. At the end of the 3 month period, I have to display each patron, the books they have currently checked out and any fine they may have.
you have typo error in your loops (for var k ... i++). See the snippet
var Book = function(title, Available, publicationDate, checkoutDate, callNumber, Authors) {
this.title = title;
this.Available = Available;
this.publicationDate = publicationDate;
this.checkoutDate = checkoutDate;
this.callNumber = callNumber;
this.Authors = Authors;
};
var Author = function(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
};
var Patron = function(firstName, lastName, libCardNum, booksOut, fine) {
this.firstName = firstName;
this.lastName = lastName;
this.libCardNum = libCardNum;
this.booksOut = booksOut;
this.fine = fine;
};
Book.prototype.checkOut = function() {
this.Available = false;
var temp = new Date(1000000000);
var date = new Date() - temp;
var res = new Date(date);
this.checkoutDate = res;
};
Book.prototype.checkIn = function() {
this.Available = true;
};
Book.prototype.isOverdue = function() {
var singleDay = 1000 * 60 * 60 * 24;
var todayDate = new Date().getTime();
var difference = todayDate - this.checkoutDate.getTime();
if (Math.round(difference / singleDay) >= 14) {
return true;
}
return false;
};
Patron.prototype.read = function(book) {
this.booksOut.add(book);
}
Patron.prototype.return = function(book) {
this.booksOut.remove(this.booksOut.length);
}
var authors = [];
authors[0] = new Author("Auth", "One");
authors[1] = new Author("AutL", "Two");
var catalog = [];
catalog[0] = new Book('Bk1', true, new Date(2001, 1, 21), new Date(), 123456, authors);
catalog[1] = new Book('Bk2', true, new Date(2002, 2, 22), new Date(), 987656, authors);
catalog[2] = new Book('Bk3', true, new Date(2003, 3, 23), new Date(), 092673, authors);
catalog[3] = new Book('Bk4', true, new Date(2004, 4, 24), new Date(), 658342, authors);
catalog[4] = new Book('Bk5', true, new Date(2005, 5, 25), new Date(), 345678, authors);
var patrons = [];
patrons[0] = new Patron('Pat1', 'Wat', 1, catalog, 0.00);
patrons[1] = new Patron('Pat2', 'Wot', 1, catalog, 0.00);
patrons[2] = new Patron('Pat3', 'Wit', 1, catalog, 0.00);
patrons[3] = new Patron('Pat4', 'Wet', 1, catalog, 0.00);
patrons[4] = new Patron('Pat5', 'Wut', 1, catalog, 0.00);
//while loop or for loop for 90 days
//For loop over catalog
//forloop over patrons
//Check if available , if so check book out
//If not available check book back in
//check checking back in check to see if book is overdue and if so add a fine
//When down loop over patrons to see their fees
for (var i = 0; i < 90; i++) {
for (var j = 0; j < catalog.length; j++) {
for (var k = 0; k < patrons.length; k++) {
var fine = patrons[k].fine;
if (catalog[k].Available) {
catalog[k].checkOut;
} else {
catalog[k].checkIn;
patrons[k].read;
}
if (catalog[k].isOverdue) {
fine = fine + 5.00;
}
patrons[k].fine = fine;
}
}
}
for (i = 0; i < patrons.length; i++) {
console.log(patrons[i].firstName + " has checked out the following books:");
for (j = 0; j < patrons[i].booksOut.length; j++) {
console.log(patrons[i].booksOut[j].title);
}
console.log(patrons[i].firstName + " has fine amount: $" + patrons[i].fine);
}
May be this is gonna help
Keep in mind that they are asking for 3 months period or 90 days period. we can't just iterate 90 times. Eventually you will be ended up in the same month. For an example: if today is 10/19/2017 that means this program should calculate until 01/19/2018 (3 months period)
//***************** library.js *****************//
/**
Create a constructor function for a Book object. The Book object should have the following properties:
Title: string
Available: Boolean representing whether the book is checked out or not. The initial value should be false.
Publication Date: Use a date object
Checkout Date: Use a date object
Call Number: Make one up
Authors: Should be an array of Author objects
**/
var Book = function(title, available, publicationDate, checkOutDate, callNumber, authors) {
this.title = title;
this.available = available;
this.publicationDate = publicationDate;
this.checkOutDate = checkOutDate;
this.callNumber = callNumber;
this.authors = authors;
}
/**
Create a constructor function for an object called Author. It should have a property for the
first name: string
last name: string
**/
var Author = function(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
/**
Create a constructor function for an object called Patron. This represents a person who is allowed to check out books from the library. Give it the following properties:
Firstname: string
Lastname: string
Library Card Number (Make one up): string
Books Out (make it an array): []
fine (Starts a 0.00): parseFloat(0.00)
**/
var Patron = function(firstName, lastName, libraryCardNumber, booksOut, fine) {
this.firstName = firstName;
this.lastName = lastName;
this.libraryCardNumber = libraryCardNumber;
this.booksOut = booksOut;
this.fine = parseFloat(fine) || 0.00;
}
// Methods
/**
Add a function to the Book prototype called "checkOut". The function will change the available property of the book from true to false and set the checkout date. The checkout date should be set to the current date minus some random number of days between 1 and 5. This will allow us to simulate books being overdue.
**/
Book.prototype.checkOut = function(date) {
this.available = false;
this.checkOutDate = new Date(date.setDate(date.getDate() - Math.floor((Math.random() * 5) + 1)));
}
/**
Add a function to the Book prototype called "checkIn". The function will change the available property of the book from false to true.
**/
Book.prototype.checkIn = function() {
this.available = true;
}
/**
Add a function called isOverdue that checks the current date and the checked out date and if it's greater than 5 days it returns true
**/
Book.prototype.isOverdue = function(date) {
var time = date.getTime();
var checkOutDate = (this.checkOutDate).getTime();
var timeDiff = Math.abs(time - checkOutDate);
var dayDiff = Math.ceil(timeDiff/ (1000 * 3600 * 24));
if (dayDiff > 5) {
return true;
} else {
return false;
}
}
/**
Add a function called isCheckedOut that returns true if the book is checked out to someone and false if not.
**/
Book.prototype.isCheckedOut = function() {
if (this.available === true) {
return false;
} else {
return true;
}
}
/**
Add a function to the Patron prototype called "read" that adds a book to it's books out property.
**/
Patron.prototype.read = function(book) {
this.booksOut.push(book);
}
/**
Add a function to the Patron prototype called "return" that removes a book from it's books out property.
**/
Patron.prototype.return = function(book) {
var booksOut = this.booksOut;
booksOut.forEach(function(existingBook, index) {
if (existingBook.title === book.title) {
booksOut.splice(index, 1);
}
});
}
/**
Create 5 different books from the Book Class and store them in an array called catalog.
**/
var catalog = [];
catalog[0] = new Book('Another Brooklyn', false, new Date(2017, 5, 30), new Date(), '201-360-9955', [new Author('Jacqueline', 'Woodson')]);
catalog[1] = new Book('Sunshine State', false, new Date(2017, 4, 11), new Date(), '888-888-888', [new Author('Sarah', 'Gerard')]);
catalog[2] = new Book('Homegoing', false, new Date(2017, 5, 2), new Date(), '877-990-3321', [new Author('Yaa', 'Gyasi')]);
catalog[3] = new Book('Round Midnight', false, new Date(2015, 11, 22), new Date(), '321-221-2100', [new Author('Laura', 'McBride')]);
catalog[4] = new Book('The Sport of Kings', false, new Date('08/22/2016'), new Date(), '813-289-0007', [new Author('C.E.', 'Morgan')]);
/**
Create 5 different patrons from the Patron Class and store them in an array called patrons.
**/
var patrons = [];
patrons[0] = new Patron('Bhaumik', 'Mehta', 'Lib-229781', [catalog[0]], 0.00);
patrons[1] = new Patron('Jeff', 'Reddings', 'Lib-337895', [catalog[1]], 0.00);
patrons[2] = new Patron('Andrew', 'Hansing', 'Lib-227896', [catalog[2]], 0.00);
patrons[3] = new Patron('Dylan', 'Marks', 'Lib-672563', [catalog[3]], 0.00);
patrons[4] = new Patron('Roop', 'Kapur', 'Lib-008936', [catalog[4]], 0.00);
/**
Write a loop that simulates checkouts and checkins for a 3 month period. Every day iterate over each book in the catalog, and every person in the patrons array(Nested Loops). If the current book is not checked out and the current patron does not have a book already, then add it to the patrons list of books via the patrons read method and check it out by calling the books checkout method. If the book is checked out to the current person, then check if it is overdue, and if so, check it in using the books check in method, and return it using the patrons return method. When checking in, if the book is overdue then add a fine of $5.00 to the patron returning it. At the end of the 3 month period, display each patron, the books they have currently checked out and any fine they may have.
**/
var now = new Date();
var threeMonthsFromNow = new Date(now.setMonth(now.getMonth() + 3));
var timeDiff = Math.abs(threeMonthsFromNow.getTime() - new Date().getTime());
var days = Math.ceil(timeDiff/ (1000 * 3600 * 24));
for (var i = 0; i < days; i ++) {
var date = new Date(new Date().setDate(new Date().getDate() + i));
catalog.forEach(function(item, index) {
patrons.forEach(function(patron, index) {
if (item.isCheckedOut() === false) {
var booksOut = (patron.booksOut).filter(function(book) {
return book.title === item.title;
});
if (booksOut.length === 0) {
patron.read(item);
item.checkOut(date);
}
} else if (item.isCheckedOut() === true) {
var booksOut = (patron.booksOut).filter(function(book) {
return book.title === item.title;
});
if (booksOut.length > 0) {
var isOverdue = item.isOverdue(date);
if (isOverdue === true) {
item.checkIn();
patron.return(item);
patron.fine += parseFloat(5.00);
}
}
}
});
});
}
/**
Object with the method to execute the record list for patrons
**/
var records = {
patronInfo: function() {
patrons.forEach(function(patron, index) {
console.log('Patron name: ' + patron.firstName + ' ' + patron.lastName);
console.log('Patron library card number: ' + patron.libraryCardNumber);
console.log('List of book(s) checked out currently by the patron:');
if ((patron.booksOut).length === 0) {
console.log('NO BOOKS ARE CHECKED OUT CURRENTLY');
} else {
(patron.booksOut).forEach(function(book, index) {
console.log((index + 1) + '. | ' + book.title + ' | Checked out on: ' + (book.checkOutDate).toDateString());
});
}
console.log('Patron ' + patron.firstName + ' ' + patron.lastName + ' has fine amout(till date): $' + (patron.fine).toFixed(2));
console.log('-----------------------------------------------------');
});
}
};
/**
Method execution
**/
records.patronInfo();
I have a function that is supposed to be able to compare automobiles based on year, type, make etc, but I'm having trouble getting it to work.
I define my automobiles like this:
function Automobile( year, make, model, type ){
this.year = year; //integer (ex. 2001, 1995)
this.make = make; //string (ex. Honda, Ford)
this.model = model; //string (ex. Accord, Focus)
this.type = type; //string (ex. Pickup, SUV)
}
var automobiles = [
new Automobile(1995, "Honda", "Accord", "Sedan"),
new Automobile(1990, "Ford", "F-150", "Pickup"),
new Automobile(2000, "GMC", "Tahoe", "SUV"),
new Automobile(2010, "Toyota", "Tacoma", "Pickup"),
new Automobile(2005, "Lotus", "Elise", "Roadster"),
new Automobile(2008, "Subaru", "Outback", "Wagon")
];
The above part has no issues, but my sorting function has some problems, and I can't figure out what they are. Running this code gives me the error:
Uncaught SyntaxError: Unexpected end of input
/*This function sorts arrays using an arbitrary comparator. You pass it a comparator and an array of objects appropriate for that comparator and it will return a new array which is sorted with the largest object in index 0 and the smallest in the last index*/
function sortArr( comparator, array ){
var sorted = array;
var min; var temp;
for(var i = 0; i < array.length-1; i++){
min = i;
for(var j = i+1; j < array.length; j++){
var comp = comparator(array[j], array[min]);
if(comp)
min = j;
}
if(min != i){
temp = sorted[i];
sorted[i] = sorted[min];
sorted[min] = temp;
}
}
return sorted;
}
function exComparator( int1, int2){
if (int1 > int2){
return true;
} else {
return false;
}
}
/*For all comparators if cars are 'tied' according to the comparison rules then the order of those 'tied' cars is not specified and either can come first*/
/*This compares two automobiles based on their year. Newer cars are "greater" than older cars.*/
function yearComparator( auto1, auto2){
return exComparator(auto1.make, auto2.make);
}
/*This compares two automobiles based on their make. It should be case insensitive and makes which are alphabetically earlier in the alphabet are "greater" than ones that come later.*/
function makeComparator( auto1, auto2){
return exComparator(auto1.make, auto2.make);
}
/*This compares two automobiles based on their type. The ordering from "greatest" to "least" is as follows: roadster, pickup, suv, wagon, (types not otherwise listed). It should be case insensitive. If two cars are of equal type then the newest one by model year should be considered "greater".*/
function typeComparator( auto1, auto2){
var auto1_type = switch(auto1.type.toLowerCase()){
case("roadster"): return 5;
case("pickup"): return 4;
case("suv"): return 3;
case("wagon"): return 2;
case("sedan"): return 1;
}
var auto2_type = switch(auto2.type.toLowerCase()){
case("roadster"): return 5;
case("pickup"): return 4;
case("suv"): return 3;
case("wagon"): return 2;
case("sedan"): return 1;
}
if(auto1_type > auto2_type) {
return auto1.type;
}
else if(auto2_type > auto1_type) {
return auto2.type;
}
else {
if(auto1.year > auto2.year) {
return auto1.type;
}
else {
return auto2.type;
}
}
}
function printArr(array){
for(var i = 0; i < array.length; i++){
var car = array[i];
console.log(car.year + ' ' + car.make + ' ' + car.model + ' ' + car.type);
}
}
Just some examples for sorting callbacks without switch, but with an hash table instead.
function Automobile(year, make, model, type) {
this.year = year; //integer (ex. 2001, 1995)
this.make = make; //string (ex. Honda, Ford)
this.model = model; //string (ex. Accord, Focus)
this.type = type; //string (ex. Pickup, SUV)
}
function yearComparator(a, b) {
return a.year - b.year;
}
function makeComparator(a, b) {
return a.make.localeCompare(b.make);
}
function modelComparator(a, b) {
return a.model.localeCompare(b.model);
}
function typeComparator(a, b) {
var types = { roadster: 5, pickup: 4, suv: 3, wagon: 2, sedan: 1 },
aa = types[a.type.toLowerCase()] || 0,
bb = types[b.type.toLowerCase()] || 0;
return aa - bb;
}
var automobiles = [new Automobile(1995, "Honda", "Accord", "Sedan"), new Automobile(1990, "Ford", "F-150", "Pickup"), new Automobile(2000, "GMC", "Tahoe", "SUV"), new Automobile(2010, "Toyota", "Tacoma", "Pickup"), new Automobile(2005, "Lotus", "Elise", "Roadster"), new Automobile(2008, "Subaru", "Outback", "Wagon")];
automobiles.sort(yearComparator);
document.write('<pre>sorted by year: ' + JSON.stringify(automobiles, 0, 4) + '</pre>');
automobiles.sort(makeComparator);
document.write('<pre>sorted by make: ' + JSON.stringify(automobiles, 0, 4) + '</pre>');
automobiles.sort(modelComparator);
document.write('<pre>sorted by model: ' + JSON.stringify(automobiles, 0, 4) + '</pre>');
automobiles.sort(typeComparator);
document.write('<pre>sorted by type: ' + JSON.stringify(automobiles, 0, 4) + '</pre>');
// bonus chained sort callbacks, get sorted by type DESC and year DESC
automobiles.sort(function (a, b) {
return -typeComparator(a, b) || -yearComparator(a, b);
});
document.write('<pre>sorted by type DESC and year DESC: ' + JSON.stringify(automobiles, 0, 4) + '</pre>');
You forget a curly brace { in the if statement
if (comp) <-- here
min = j;
}
Also you have wrong switch statement, you are trying assign the value from return statement
var auto1_type =
switch (auto1.type.toLowerCase()) {
case "roadster":
return 5;
...
Your switch statement should look like this
var auto1_type;
switch (auto1.type.toLowerCase()) {
case "roadster":
auto1_type = 5;
case ....
return auto1_type;
I'm trying to learn JavaScript and am going through an exercise where I'm creating a grocery list that populates with a food, quantity, and cost. I cannot seem to pass in multiple variables or make an array of arrays. I tried some other options like "new Object" but I can't get anything off the ground. Give me a clue?
var groceryList = function(food, quantity, price) {
var theItem = [food, quantity, price]
var theList = new Array();
theList.push(theItem)
}
myList = new groceryList("cookie", 2, 1.00)
console.log(myList)
Use this
var groceryList = function(food, quantity, price) {
var theItem = [food, quantity, price]
var theList = new Array();
theList.push(theItem);
return theList;
}
myList = new groceryList("cookie", 2, 1.00)
console.log(myList)
If you want to use objects, then you need to change your thinking a little bit. When you create an object with new then the constructor gets called.
function GroceryList(food, quantity, price) {
this.food = food;
this.quantity = quantity;
this.price = price;
}
GroceryList.prototype.toString = function() {
return this.food + (this.quantity).toString() + (this.price).toString();
}
// lazy array syntax
var GroceryListPool = [];
// popular the array list pool
var list1 = new GroceryList("Butter", 2, 3.999);
GroceryListPool.push(list1);
To iterate the GroceryListPool array:
for(var i = 0; i < GroceryListPool.length; i++) {
var list = GroceryListPool[i];
// list is an object of type GroceryList
// technically it is not a "type", but you know what I mean.
alert(list);
}
That's not even really a Constructor, yet. Check this out.
function groceryList(food, quantity, price){
this.items = {};
if(food !== undefined){
this.items[food] = {quantity:quantity, price:price, total:quantity*price};
}
this.addItem = function(food, quantity, price){
this.items[food] = {quantity:quantity, price:price, total:quantity*price};
}
this.getFood(food){
return this.items[food];
}
this.getQuantity = function(food){
return this.items[food].quantity;
}
this.getTotal = function(food){
return this.items[food].total;
}
this.getItemsByPrice(low, high){
var r = {}, t = this.items;
for(var i in t){
var f = t[i], p = f.price;
if(p >= low && p <= high){
r[i] = f;
}
}
return r;
}
}
var groc = new groceryList('potato', 4, 0.89);
groc.addItem('orange', 10, 1);
console.log(groc.getQuantity('potato'));
console.log(groc.getTotal('orange'));
console.log(groc.getFood('orange').price);
// same as
console.log(groc.getPrice('orange'));
// or
console.log(groc.items.orange.price);
groc.addItem('pear', 200, 0.75);
console.log(groc.getItemsByPrice(0.25, 0.99)); // should be Object with 'potato' and 'pear'
Hey everyone, so I am working on creating a small class to help me work with the Google visualization API. You can see how it works here...
http://code.google.com/apis/visualization/documentation/gallery/annotatedtimeline.html
Here is google's implementation.
google.load('visualization', '1', {'packages':['annotatedtimeline']});
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('date', 'Date');
data.addColumn('number', 'Sold Pencils');
data.addColumn('string', 'title1');
data.addColumn('string', 'text1');
data.addColumn('number', 'Sold Pens');
data.addColumn('string', 'title2');
data.addColumn('string', 'text2');
data.addRows([
[new Date(2008, 1 ,1), 30000, undefined, undefined, 40645, undefined, undefined],
[new Date(2008, 1 ,2), 14045, undefined, undefined, 20374, undefined, undefined],
[new Date(2008, 1 ,3), 55022, undefined, undefined, 50766, undefined, undefined],
[new Date(2008, 1 ,4), 75284, undefined, undefined, 14334, 'Out of Stock','Ran out of stock on pens at 4pm'],
[new Date(2008, 1 ,5), 41476, 'Bought Pens','Bought 200k pens', 66467, undefined, undefined],
[new Date(2008, 1 ,6), 33322, undefined, undefined, 39463, undefined, undefined]
]);
var chart = new google.visualization.AnnotatedTimeLine(document.getElementById('chart_div'));
chart.draw(data, {displayAnnotations: true});
Here is the class I made that I am having issues with.
The class makes adding data to the graph a little easier and better for what I am trying to do. Basically, instead of making columns with a bunch of undefined values, the class does it for you, and you don't have to keep track of the location/value of each column.
function GraphManager(dataTable)
{
this.graphData = new Array();
this.dataTable = dataTable;
this.titleFinder = new Object(); // used to keep track of the indices
this.dataTable.addColumn('date', 'Date');
this.addSet = function(title)
{
var setCount = (this.dataTable.getNumberOfColumns() -1) / 3; //used for the column name
var place = this.dataTable.getNumberOfColumns();
this.titleFinder[title] = place; //the title of the column and its location
this.dataTable.addColumn('number', title);
this.dataTable.addColumn('string', 'title' + setCount);
this.dataTable.addColumn('string', 'text' + setCount);
}
this.addPoint = function(title, date, number)
{
//this function finds the location of the category
//and inserts a column with data at the location
var place = titleFinder[title]; //get the location
var column = new Array(dataTable.getNumberOfColumns());
column[0] = date;
column[place] = number;
for (var i = 0;i<place; i++)
{
column[i] = undefined;
}
for (var i = place + 1; i<dataTable.getNumberOfColumns(); i++)
{
column[i] = undefined;
}
var next = this.graphData.length;
this.graphData[next] = column;
data.addRows(graphData);
}
}
And then this code can be used to do the same thing with a fewer amount of code.
function printGraph()
{
var data = new google.visualization.DataTable();
var gm = new GraphManager(data);
var title = "testcategory";
gm.addSet(title);
gm.addPoint(title, new Date[2010, 5, 10], 100);
gm.addPoint(title, new Date[2010, 6, 10], 200);
var chart = new google.visualization.AnnotatedTimeLine(document.getElementById('chart_div'));
chart.draw(gm.dataTable, {displayAnnotations: true});
}
With this HTML body
<input type="button" onclick="printGraph()" value="Draw Graph">
<div id='chart_div' style='width: 800px; height: 350px;'></div>
The issue: I am getting an "Object expected" error on the line gm.addSet(title). Basically, I am not able to use the class GraphManager. What am I doing wrong here?
Isn't supposed to be "dataTable" instead of "tableData"?
for (var i = place + 1; i<tableData.count; i++)
{
column[i] = undefined;
}
I don't know, as per:
http://code.google.com/apis/visualization/documentation/reference.html#DataTable
count is not an attribute, but I see you referring to it many places in your code:
var column = new Array(dataTable.count)
There is dataTable.getNumberOfColumns() however
Ok, I figured out the problem. Basically I had left out a bunch of "this" statements, and when I created a new date I used a bracket instead of a parentheses. I also realized that when I added a new set of data, I needed to go through the old data to add the empty columns. Here is the finished code if anyone is interested... It's pretty useful if you are adding data at different dates or if you don't know how many data sets you will have.
function GraphManager(adataTable)
{
this.graphData = new Array();
this.dataTable = adataTable;
this.titleFinder = new Object(); // used to keep track of the indices
this.dataTable.addColumn('date', 'Date');
this.addSet = function(title)
{
var setCount = (this.dataTable.getNumberOfColumns() -1) / 3; //used for the column name
var pointsCount = this.graphData.length;
var place = this.dataTable.getNumberOfColumns();
this.titleFinder[title] = place; //the title of the column and its location
this.dataTable.addColumn('number', title);
this.dataTable.addColumn('string', 'title' + setCount);
this.dataTable.addColumn('string', 'text' + setCount);
var newCount = this.dataTable.getNumberOfColumns();
for (var i = 0; i<pointsCount; i++)
{
for (var j=place; j<newCount; j++)
{
this.graphData[i][j] = undefined;
}
}
}
this.addPoint = function(title, date, number)
{
//this function finds the location of the category
//and inserts a column with data at the location
var place = this.titleFinder[title]; //get the location
var column = new Array(this.dataTable.getNumberOfColumns());
column[0] = date;
column[place] = number;
for (var i = 1;i<place; i++)
{
column[i] = undefined;
}
for (var i = place + 1; i<this.dataTable.getNumberOfColumns(); i++)
{
column[i] = undefined;
}
var next = this.graphData.length;
this.graphData[next] = column;
this.dataTable.addRows(this.graphData);
}
}
And its as easy to use as this:
var data = new google.visualization.DataTable();
var gm = new GraphManager(data);
var title = "testcategory";
var title2 = "cat";
gm.addSet(title);
gm.addPoint(title, new Date(2010, 5, 10), 100);
gm.addPoint(title, new Date(2010, 6, 10), 200);
gm.addPoint(title, new Date(2010, 2, 10), 300);
gm.addSet(title2);
gm.addPoint(title2, new Date(2010, 6, 10), 100);
gm.addPoint(title2, new Date(2010, 2, 10), 500);
var chart = newgoogle.visualization.AnnotatedTimeLine(document.getElementById('chart_div'));
chart.draw(gm.dataTable, {displayAnnotations: true});