Reputation: 708
This question is a bit confusing so I will try to explain through code and example.
How can I decrement a counter if it meets a condition? Sounds simple right? But what if that method continuously gets evoked from within a for loop so that values passed to it, get reset?
Eample: I have a document with several pages, however some of those pages are blank and I don't want to count them.
For a 5 page document with the first page being blank. I want to accomplish the following behavior:
page 1: nothing...
page 2: 1 of 4
page 3: 2 of 4
page 4: 3 of 4
page 5: 4 of 4
Currently it's including the blank page as part of the page count.
Here is a code sample:
static main() {
// et cetera
for(Page page : pages) {
int pageNumber = page.getPageNo();
int pageCount = page.getTotalPageCount();
form.getTemplate().writePageNumber(page, pageNumber,pageCount);
}
}
So in the main routine I'm calling a method called writePageNumber()
from within a for loop where I pass in currentPageNumber and totalPage count.
public boolean writePageNumber(Page page, int currentPageNo, int totalPageCount) {
if ( !page.isBlank() ) {
this.write(currentPageNo, totalPageCount);
}
else if ( page.isBlank() ){
currentPageNo--;
totalPageCount--;
}
// et cetera
}
Now here in the writePageNumber() method, I get page context and I process. I check to see if the page is not blank then I write the currentPage of totalPages, if it is blank then I decrement the currentPage No and totalPage count...so as to not count the blank page...is this the right way to do it? Not sure
Since the method is called from within a for loop, the values after I decrement them get reset, how to maintain decremented values?
There probably is a better way to do this, any help would be appreciated.
Edit:
Just for clarity, the problem is that writePageNumber() is called from a for loop so the next time writePageNumber is called, the values are reset, so during the second iteration the else if condition is no longer true and the first condition is true so the wrong page number is written
Upvotes: 1
Views: 943
Reputation: 390
Here's what I believe the problem is:
You have a number (5) page objects; every object has its own currentPage
and totalPageCount
as follows:
Object 1: Page: current = 1; total = 5;
Object 2: Page: current = 2; total = 5;
Object 3: Page: current = 3; total = 5;
Object 4: Page: current = 4; total = 5;
Object 5: Page: current = 5; total = 5;
In your code, you are updating current
& total
(not in the object but only locally in the context they're being used), but these values are not updated in the remaining Objects; the for
loop is looping over these un-updated remaining objects.
I suggest you do something like this:
private int blanks = 0;
public boolean writePageNumber(Page page, int currentPageNo, int totalPageCount) {
if ( page.isBlank() ) {
blanks++;
// etcetera
} else {
this.write(currentPageNo - blanks, totalPageCount - blanks);
}
// et cetera
}
You should first iterate over all pages to get total blank pages, in order to get a fixed totalPageCount
, then remove the - blanks
in the totalPageCount - blanks
above, orelse you'll get data like this:
Object 1: Page: current = 1; total = 5;
Object 2: Page: current = BLANK; total = 5;
Object 3: Page: current = 2; total = 4;
Object 4: Page: current = BLANK; total = 4;
Object 5: Page: current = 3; total = 3;
Notice how the total keeps changing.
One more thing to note is that totalPageCount is not a property of a page and thus should not belong to the Page
object, but rather to the book object. See how it's complicating things?!
Upvotes: 1
Reputation: 2630
The problem is that in your current code, the variables currentPageNo
and totalPageCount
are on the stack, which means that their values get thrown away after the method returns. One way to solve your problem would be to extract the body of writePageNumber
into your for
loop. So rather than having something like,
Page page = /* ... */
int totalPages = 5;
for (int currentPage = 1; currentPage <= totalPages; i++) {
writePageNumber(page, currentPage, totalPages);
};
Your code could look like:
Page page = /* ... */
int totalPages = 5;
for (int currentPage = 1; currentPage <= totalPages; i++) {
if (!page.isBlank()) {
// ...
} else {
currentPage--;
totalPages--;
}
// ...
}
Edit: You mentioned not breaking code patterns, but you may have to compromise in this case. Currently, you are expecting writePageNumber
to be a function that takes two integer arguments, modifies them, and returns their updated values for the next function call somehow. You can't return multiple values from a function in Java. You need to have those values persist across method calls, so they need to be declared outside of the method's scope (or, like I suggested, you extract the method into the loop), which means using a field.
Upvotes: 2