Murtan 317 Practically a Master Poster

You were right about his number, but that's not really C++, that's just basic logic. You could understand that and correct it. (And just to back you up, if you had posted that code, I would have said something, his code was a suggestion. If you want to post functions that you have completed that you're not sure are correct, I'll review them for you.)

in displayTime() you need to do something so that 5 hours and 5 minutes displays as 05:05 and not 5:5

Maybe you should print the tens digit and the ones digit of each number. If you don't understand that, you could look into "iomanip, setfill and setw".

In elapsed(), realize that t1 is the 'start' time and t2 is the 'end' time, and think back to your basic math:

  • How much time has elapsed between 08:45 and 10:15?
  • How did you figure out that it was 01:30?
  • Make the computer do that...
Murtan 317 Practically a Master Poster

Ok, so I have the values 0,1,2,3,4,5,6,7,8,9,10 in those positions in the input array...

You caclulate mid as (low + high) /2 so the first mid is 5?

we put 5 at the root and iterate left with (0,4) and right with (6,10)

(0,4): mid=2 we put 2 to the left of 5 [left: (0,1) right: (3,4)]
(0,1): mid=0 we put 0 to the left of 2 [left: none right: (1,1)]
(1,1): mid=1 we put 1 to the right of 0 [none]
(3,4): mid=3 we put 3 to the right of 2 [left:none right: (4,4)]
(4,4): mid=4 we put 4 to the right of 3

(6,10): mid=8 we put 8 to the right of 5 [left: (6,7) right: (9,10)]
(6,7): mid=6 we put 6 to the left of 8 [left: none right: (7,7)]
(7,7): mid=7 we put 7 to the right of 6
(9,10): mid=9 we put 9 to the right of 8 [left:none right: (10,10)]
(10,10): mid=10 we put 10 to the right of 9 [none]

so we built something like:

5
    2      8
 0   3   6   9
z 1 z 4 z 7 z 10

The z's are empty nodes. How much more balanced does that need to be?

Murtan 317 Practically a Master Poster

Ok, so what kind of tree does it build?

How is it sub-optimal?

What would you have to change to make it optimal?

Murtan 317 Practically a Master Poster

I'd like to experiment with the code to try it, but in the interest of a quick answer, try low < mid on line 20 and mid < high on line 25.

Basic translation: If there are values between low and high that are lower than mid, add them to the left. If there are values between low and high that are higher than mid, add them to the right.

Murtan 317 Practically a Master Poster

It doesn't really matter which side of the comment is on, comments are for us to read, the compiler doesn't care.

Your code

if (h < 0)
{
return 1; // error code +1 = underflow hours
}
else
{
return 2; // error code +2 = overflow hours
}

Will always return 1 or 2 and never get to the rest of the code.

You aren't really testing for overflow.

(The minutes testing has the same problem.)

Murtan 317 Practically a Master Poster

As we stated in your previous thread, we will help you if you put in some effort, but we don't solve your problems for you.

When posting c++ code, please use c++ code tags
[code=c++] // Your code here

[/code]

Just pick one function at a time and write them. Lets start with set time...it has some great comments about how it should be implemented, here I'll even implement one case for you, see if you can write the other three and post your code:

int setTime(Mytime& t, int h, int m );   
{
   
// if valid time sets hh and mm to h and m 
// and returns 0
// if invalid returns integer > 0 as error code
// error code +1 = underflow hours
// error code +2 = overflow hours
// error code +4 = underflow mins
    if (m < 0) return 4;
// error code +8 = overflow mins
                                     
    t.hours = h;                         
    t.mins = m;
    return 0;
}
Murtan 317 Practically a Master Poster

To help me and you think about it, write down in english what you think the compare function should be doing.

It will help me to understand what you intended and whether or not it will accomplish your goal, along with whether or not the function is doing what you think it does.

Murtan 317 Practically a Master Poster

if words[answer] == r

Murtan 317 Practically a Master Poster

On line 2, r is coming from the values in the dictionary, not the keys.
So you can't use it as a key on line 8, you can't index a dictionary by the definition.

You could either test to see if the answer is a key and if it is, if the value matches the definition you have.

Alternatively (and probably better) iterate the keys on line 2 and then don't print the key, but print what you lookup from the dictionary using the key on line 6. Then you can just compare the answer with the key value.

SoulMazer commented: A big help. Followed through. +1
Murtan 317 Practically a Master Poster

Are you sure the link to test1.cpp is the right file?

It is calling members of Logbook that are not defined in logbook.h and if I understand correctly, both files were given and you're not supposed to change them.

Murtan 317 Practically a Master Poster

If you were given the assignment to do it by hand, how would YOU do it?

(The manual process makes a good basis for the pseudo code for the computer.)

Murtan 317 Practically a Master Poster

Your implementation of find_text would only attempt to iterate to lower elements if the current element had no text.

Having text does not preclude having child nodes.

I rewrote your find_text as follows and I'm seeing output now:

def find_text(element):
        if element.text:
                yield element.text
                
        for subelement in element:
                for txt in find_text(subelement):
                        yield txt
Murtan 317 Practically a Master Poster

When posting c++ code, please use c++ code tags
[code=c++] // Your code here

[/code]

Don't try to print answer on the 'please enter in two numbers' lines.

Murtan 317 Practically a Master Poster

int(rand 10) returns numbers in the range 0 to 9
int (rand 10)+1 returns numbers in the range 1 to 10

while(1) is a continuous loop...it will keep looping until you 'break' or 'last'.

Murtan 317 Practically a Master Poster

Once you 'know' what class it actually is, you can cast the pointer...

if (typeid(*pacct) == typeid(SavingsAccount)) {
    SavingsAccount * pSave = (SavingsAccount *)pacct;
    // or more explicitly
    SavingsAccount * pSave = reinterpret_cast<SavingsAccount *>(pacct);
    // then
    pSave->credit(pSave->CalculateInterest());
}

But a better implementation really would be to define all of the functionality that you might ever expect from an account in the base class with virtual methods so you don't have to jump through the 'what type is it' and 'make it one of what it is' hoops.

You could either implement something like virtual int ProcessMonthEnd() which in the base Account class might do nothing. Then in the derived classes it is overridden to do what that account type needed (for example posting interest to a SavingsAccount).

for each (Account * pacct in accounts)
{
    pacct->ProcessMonthEnd();
}

Or you might decide that any account might earn interest. So you implement virtual bool EarnsInterest(); and virtual double CalculateInterest(); in Account. The base Account implementation would return false and 0, but the methods could be overridden (say in SavingsAccount) to return true and the current interest calculation.

for each (Account * pacct in accounts)
{
    if (pacct->EarnsInterest()) {
        pacct->credit(pacct->CalculateInterest());
    }
}

As long as the methods are declared as part of Account, you can call them without having to cast anything.

(My personal preference would be to avoid the RTTI and casting, but it is YOUR code.)

We are definitely headed into the 'implementation specific' details. …

Murtan 317 Practically a Master Poster

I agree with Comatose, you should probably put the part that prompts for and accepts new input inside the loop somehow. That way as the loop is run again you ask for input again.

The psuedo-code looks something like:

  • While the user has not guessed the number
  • Prompt for a guess
  • Accept the guess
  • Compare the guess and report one of:
    • too low
    • too high
    • That's it

And as far as printing thinking of, I usually give it its own print statement right after it was generated with the word DEBUG in the output so it helps to remind me to take it out later. Something like print "DEBUG: thinkingof $thinkingof\n";

Murtan 317 Practically a Master Poster

In your code, an "Account *" will never be a "SavingsAccount" you are directly comparing two types. You wanted to compare an instance and a type. The following worked for me:

if (typeid(*pacct) == typeid(SavingsAccount)) {
    cout << "  Savings Account" << endl;
} else if (typeid(*pacct) == typeid(CheckingAccount)) {
    cout << "  Checking Account" << endl;
} else {
    cout << "  Unrecognized: " << typeid(*pacct).name() << endl;
}

An alternative implementation might be to add a virtual 'month end' method that would add interest to a savings account and charge a service charge to a checking account (unless they met the minimum balance requirements :) )

Murtan 317 Practically a Master Poster

That first '0' you're seeing almost looks like unresolved input.

Your menu selection only reads a character from cin, if you have to hit a return before the menu option is selected, the return may still be in the input stream when you get to calcList. Then the first read gets an empty string. If this might be the problem, you could either make sure to clear the input stream before or at the start of calcList() or you could read a line like you have in calcList() when getting the menu selection.

Murtan 317 Practically a Master Poster

(I'm just slow I guess...but here it is anyway)

You can't just cast a character pointer (that is what inputVal.c_str() returns) to an int and expect to get the integer value represented by the string characters.

Sample code and output:

string foo = "124";
	cout << "foo=" << foo << endl;
	cout << "(int)foo.c_str()=" << (int)foo.c_str() << endl;
	cout << "atoi(foo.c_str())=" << atoi(foo.c_str()) << endl;
foo=124
(int)foo.c_str()=1963856
atoi(foo.c_str())=124
Murtan 317 Practically a Master Poster

I was able to get the vector to work and support the polymorphism:

vector<Account *> accounts;

	accounts.push_back(new SavingsAccount(25.00, 1.00));
	accounts.push_back(new CheckingAccount(80.00, 1.00));
	accounts.push_back(new SavingsAccount(200.00, 1.00));
	accounts.push_back(new CheckingAccount(400.00, 1.00));

	for each (Account * pacct in accounts)
	{
		cout << "Original Balance: " << pacct->getBalance() << endl;
		pacct->credit(5);
		cout << "New Balance: " << pacct->getBalance() << endl;
	}

The checking accounts get the fee applied to the credit.

Murtan 317 Practically a Master Poster

The Internet will remove all of the value.

So I if I have some IP that I paid for and want to preserve the value for I should never put it on the internet at all?

Murtan 317 Practically a Master Poster

Add some debug...

Does list[cnt] = (int)inputVal.c_str(); get you the numeric value you entered, or the address of the string?

Murtan 317 Practically a Master Poster

The counter and the array were both declared inside the sample code (calcList), they wouldn't be visible outside of it.

Murtan 317 Practically a Master Poster

I'm not sure why you're getting the stream errors, I'm using Visual C++ Express and I'm not seeing the compile errors.

Are you mixing options for char and wchar_t somewhere?

Murtan 317 Practically a Master Poster

I suspect your problem with multiple inheritance is actually a multiple-include problem.

If you put Freaky_Chris's example in one file, you have no problem.

If you put all 3 classes into separate files that don't include each other, no problem. If the file for b includes a and the file for c includes a and your main includes both b and c, your main sees the following unless you protect from it:

class a{};
class b: public a{};
class a{};
class c: public a{};

The compiler then complains about a being defined twice.

The code sample you posted is similar to the portable way to prevent multiple inclusion. In each of your include files that need to be protected, add the 'wrapper'. The wrapper changes depending on the name of the include file. So in Account.hpp it would be:

#ifndef Account.hpp
#define Account.hpp
// The rest of what you currently have in Account.hpp goes here
#endif

This causes the contents of the file to be parsed only once. The second time the compiler 'sees' the file the symbol is defined and it skips to the endif.

For SavingsAccount.hpp the wrapper would look like:

#ifndef SavingsAccount.hpp
#define SavingsAccount.hpp
// The rest of what you currently have in SavingsAccount.hpp goes here
#endif

In some older code I used to work on, we used _ characters on the symbols, so the symbol for Fruit.hpp would be something like _Fruit_hpp_

The actual symbol you use in …

Murtan 317 Practically a Master Poster

What errors are you seeing on that function, it looks like it should work.

Mine currently looks like:

void debit( double amount ) { 
    if (amount < 0) {
        cout << "Invalid debit amount (" << amount << "), debits must be >= 0" << endl;
    } else if (amount > currentBalance) {
        cout << "Debit amount (" << amount << ") exceeded account balance (" << currentBalance << ")" << endl;
    } else {
        currentBalance -= amount;
    }
}

I have not run test with the above code, but it does compile.

The last argument I was making was actually to keep the balance private and make the child classes use the member functions getBalance() to get the balance and debit() and credit() to update the balance.

The print statements about bad values are probably sufficient for this level of code, but normally, you wouldn't want to print that you had a problem, but to return an indication of a problem to the caller so they could decide how to handle it. This would allow the program to customize the response to the context in which it was encountered.

So if this were for a long-term project, a better prototype might be: int debit( double amount ); Where the method would return 0 for success and a non-zero error code to indicate a problem.

Murtan 317 Practically a Master Poster

I suggested that children should never be a friend of their parent.

Parents should define anything the children should have access to in the protected: section.

I was also arguing that in this case, the balance should remain private and the child classes would use debit() and credit() to update the balance.

Murtan 317 Practically a Master Poster

Bank Accounts tend to be very transactional...

Maybe it should do something like:

// Doesn't need parameters, its for 'this' savings account at the 'current' interest rate
void CalculateMonthlyInterest() {
    credit( getBalance() * (InterestRate / 12) /*, "Interest Earned"*/);
};
// and account's credit would do something like:
void credit( double creditamt /*, char const * description */) {
    currentBalance += creditamt;
}

PS- your last posted calculate interest method REPLACED the balance with the interest.


For your proposed initial balance handling:

Accout(double newbalance) {
    if (newbalance < 0) {
        cout << "Invalid opening balance specified, using zero";
        newbalance = 0;
    }
    currentBalance = newbalance;
}

as to calling the constructor, you are calling it when your SavingsAccount constructor is called:

SavingsAccount(double initBalance, double initInterestRate):
    Account(initBalance) // this is the Account constructor
{
    InterestRate = initInterestRate;
};

You made SavingsAccount a friend of Account so it can modify the balance directly. What if it wasn't a friend? SavingsAccount could look at the balance with getBalance() and modify the balance through the credit and debit methods. That would give Account a lot more control of the balance to make sure that all of the 'proper' rules were followed.

Murtan 317 Practically a Master Poster

currentBalance = newBalance is taken care of by calling Account(newBalance).

You could validate it in Account's constructor, but if the new balance is negative, there isn't much you can do about it.

You could exit the application or throw an exception, but if you don't handle the exception the application exits anyway, and exiting seems so unfriendly.

Murtan 317 Practically a Master Poster

I'm seeing a compile error in SavingsAccount:

void CalculateInterest(Account& ac, double InterestRate) {
			ac.getBalance *= InterestRate;
		};

Several comments / questions:

getBalance is a method of Account (that should return a double instead of an int) but you can't update a method.

Why does CalculateInterest take an account and an interest rate as parameters? It is a member of the SavingsAccount class and has access to the parent class account and the member variable InterestRate.

And every time I've seen it used, an interest calculation has a 'period' to which it applies. Is the stored interest rate in % / year? What period is CalculateInterest() supposed to calculate for?

Murtan 317 Practically a Master Poster

To use Agni's code, Account needs the Account(double newBalance) constructor.

Murtan 317 Practically a Master Poster

I was going to give you Agni's answer (lucky I saw it when I switched to Advanced).

Also, there is no requirement that a class have only one constructor.

You could actually declare both (not that you want to in this instance):

Account(double newBalance) {
	currentBalance = newBalance;
};
Account() {
	currentBalance = 0;
};

(Arg! I must type slow, Dragon said this already)

Design Comment:

I'm not overly fond of adding friends to a class (I do it when I need to, but try to avoid it when possible). You should not need to make derived classes a friend of the parent. If you have things that you want derived classes to be able to see / modify, make them protected instead of private, or provide protected accessors if that works better for you.

Murtan 317 Practically a Master Poster

Making it images makes it harder for people to extract, so fewer people will do it, so there is some benefit.

If the goal is to reduce automated screen scraping, they have at least increased the amount of effort required.

Your last comment about intellectual property being a thing of the past, should probaly have been in some social discussion forum, but just in passing, if information has no value, why would anyone spend money to acquire it in the first place?

Murtan 317 Practically a Master Poster

Ouch.

Why are you declaring and filling the array inside arraySearch()?

The array should either be passed in (in which case arraySearch needs more parameters) or arraySearch should reference the 'global' array. (Note that I don't like the global array answer as a matter of principle, but it would work.)

Ok, so if you have defined the array as const string secArray[10][2]; (oops, don't declare the global array const, we could declare the parameter const because we don't plan to change it, but the global one will need to be updated.)

Ok, so if you have defined the array as string secArray[10][2]; I presume that is an array of 10 users. Is secArray[ii][0] the name and secArray[ii][1] the callsign?

Why are you referencing secArray[index][2]?

Does this even compile?

if((secArray[index][2]) == (name,callSign))

Did you want to do something like:

if (secArray[index][0] == name && secArray[index][1] == callSign)

Are you really sure you want to search for both?

With the above test, if either one doesn't match, you don't find it.

Another slight modification to the 2 dimensional array would be an array of a class or struct. (I favor classes personally.)

You could do something like:

class RegisteredUser
{
    public:
        RegisteredUser();
        RegisteredUser(string name, string callsign);

        const string & getName() const;
        const string & getCallsign() const;

        void setName(string name);
        void setCallsign(string callsign);

    private:
        string mName;
        string mCallsign;
};

Then your array of users would be something like:

RegisteredUser secArray[10];
Murtan 317 Practically a Master Poster

Sorry for the delay, I forgot to check mail. Can you show me the declaration for the array (from main?)

Alternatively, based on the parameter declaration, you could use if(name == secArray[index][0]) in the test to see if the error will go away.

(and in reference to your post while I was posting -- this routine was never intended to compare the password, it was designed to be a NAME comparison)

Murtan 317 Practically a Master Poster

I doubt you're supposed to search for the password to look for duplicates. The common case is where you refuse to add a user (name) because it already exists.

So a function that took the array and a name to search for that returned where the name was found (or -1 for not found) would meet your needs.

After the user enters a name / password (or maybe even just after the name) you would search for the name and only add the new name if you didn't find it.

The prototype might look something like:

// The first argument should match your array declaration
// The second argument is the number of names already in the array
// The third argument is the name to search for
// The return values should be -1 for not found and the array index for the name if found
int findName(string names[], int numNames, const string & name);

If you use an STL collection class in place of the array in the call above, the numNames shouldn't be necessary, the STL classes can tell you how many items are in the collection.

You make an effort at writing the function and we can help you if you get stuck. If you get stuck, post your code along with a problem statement (i.e. "I expected ___ but I'm getting ___")

PS- When posting c++ code, please use c++ code tags
[code=c++] // Your code here

[/code]

Murtan 317 Practically a Master Poster

I thought we were trying to hint you toward a ShowPage(int pageno) type of implementation.

Then inside ShowPage, you could determine the start and end indexes for the page. (I'm presuming here that pageno starts at zero.)

int startidx = pageno * 15;
int endidx = min(startidx + 15, sldNum);
// sldNum is the member that has the maximum slide number, right?
for (ii = startidx; ii < endix; ii++)
{
    // size and position the control sldArray[ii]
    // I might have written the code differently, but your code should work.
}
btnNext.Enabled = endidx < sldNum;
btnPrev.Enabled = startidx > 0;
Murtan 317 Practically a Master Poster

You have to distinguish between the pointers and the data that they point to.

The mystrcpy works by changing its copy of the pointers, updating what the pointers point to.

When you call mystrcpy(s, d) s will not change as it is not a reference, and d will not change as it is also not a reference, but the contets of where d points (to the bufffer in main) IS updated from the input string.

In pad right, if you made a call like the following: void padRight(char const * src, int minwidth, char * dest) where minwidth is the minimum desired width and dest is a pointer to memory large enough to hold the greater of strlen(src) + 1 and minwidth + 1.

Then you would ALWAYS copy to dest and if strlen(src) was < minwidth, you would append spaces to dest until strlen(dest) >= minwidth.

If you wanted to be even safer, you could use a call like: void padRight(char const * src, int minwidth, char * dest, size_t destsize) and then your code could validate that dest (destsize) is large enough to hold the padded string.

Murtan 317 Practically a Master Poster

You'll have to free the memory back in main when you're done with it.

I would almost prefer that you pass an output buffer to the padRight function that is guaranteed to have enough space for the padded string. That would allow you to use either a buffer from the stack (that does not need to be allocated / deallocated) or a buffer from the heap (with new / delete) at the discretion of the calling code. It would then be the responsibility of the calling code to manage the allocation.

In your current implementation, you only allocate if the string needs padding, so sometimes 'a' will point to allocated memory and sometimes it will not. That makes management of the allocation much harder. The calling function must be aware of the internal implementation of padRight, generally not a good design.

Murtan 317 Practically a Master Poster

Did you attempt to walk through what your code does in your head?

Here's your code with my comments included:

// Assign a to temp
char *temp = a;
// temp and a both point to the original buffer

// Assign a to point to a new buffer n characters long
a = (char *)malloc(n);
// a points to the new buffer
// ? did you allocate space for the '\0' at the end of the string?

// Initialize the new space pointed to by a to all spaces
memset(a,' ',n);
// a points to the new buffer of spaces

// This one line does a bunch...
// each iteration copies one character from the original string to the new buffer
// both pointers are advanced  to point to the next character
// The loop continues until the '\0' is copied
while (*a++ = *temp++);
//cout << a << endl;

// Now the loop is done:
// temp points to one character beyond the '\0' in the original buffer
// a points to one character beyond the '\0' in the new buffer

// as a is a reference parameter, the pointer back in the main loop also points one beyond the '\0' in the new buffer.

Does that help with 1 & 2?

Murtan 317 Practically a Master Poster

Yes, your understanding was correct, the function was changing its 'copy' of the pointer and not the actual start address. (Changing the actual start address is probably a bad idea anyway.)

Your new trimleft would work as written.

A few things to think about:

This first might actually slow the code down a little, but I hate going past a corner and then backing up to turn:

// replace
while (*p++ == ' ');
*p--;
// with 
while (*p == ' ') 
    ++p;

Note that you could also use isspace(*p) if you #include <ctype.h> The second is a minor simplification:

// replace
memmove((void *)a,(void *)p,len);
*(a+len) = '\0';
// with
memmove((void *)a,(void *)p,len + 1);

The +1 makes memmove move the '\0' too.

Third, I'm pretty sure the (void *) casts are not needed, pointers will generally convert themselves to void * without help. (Getting back does require help.)

memmove(a, p, len + 1);

PS- When posting code in a source language, please use the appropriate language specific code tag:

For C++:
[code=c++] // your code here

[/code]

For C:
[code=c] /* your code here */

[/code]

Murtan 317 Practically a Master Poster

If the page starts with n+15, then page 1 starts with 16, page 2 with 17, page 3 with 18?

Doesn't seem quite right somehow.

Do we want to number the pages from 0 like we did the pictures, or do we want to number them from 1 like the user might expect?

Then it would appear that addition is not the correct mathematical operation to apply.

Murtan 317 Practically a Master Poster

Whether or not the text of the PDF is 'available' is an option for the PDF publisher. I remember several tech documents that were designed intentionally to not allow you to copy the text out of them.

It sounds as if your target document might fall into that category. You could check by using a 'normal' browser to save the file to disk. Then open the file with an 'official' reader and check the properties.

(This would also give you a pdf on disk that you could practice the pdf part of your code with.)

Murtan 317 Practically a Master Poster

Let me ask this a slightly different way to see if it helps you think about it.

You have 200 pictures, numbered 0 to 199. (I chose those numbers because that matches the index in almost all collection data types.)

I propose your screen has a layout something like this:

A   B   C   D   E
   F   G   H   I   J
   K   L   M   N   O
<prev            next>

What picture numbers are on the first page?

What pictures are on the second page?

(If you see a pattern, skip down to the 'N' question, if not fill in a couple more pages and look for the pattern.)

What pictures are on the third page?

What pictures are on the fourth page?

What is the first picture on page 'N'?

So if we had a collection of filenames (or images if you want to try and pre-load them all) and the above formula, we could write a function displayPage(N) to display that page of images from the collection. The display function would enable (or show) the Previous button for all pages except the first and enable (or show) the Next button for all pages except the last. The handler for the buttons would either reduce or increase the page number. (Remember the last page will require a little special handling, as it is likely to not have a full set of images to display.)

Murtan 317 Practically a Master Poster

That's what the comprehensions were for:

group1 = [listMain[x] for x in [0,4,9]]
Murtan 317 Practically a Master Poster

I'm not quite sure what you're trying to ask for, but did you know you can take a slice of a list?

For example, this produces almost the same output as what you had before.

list=['one','two','three','four','five','six']

group1 = list[0:2]
group2 = list[2:4]
group3 = list[4:]

print (group1,group2,group3)

Another fun thing to play with are list comprehensions:
(The comments are the result from the previous line)

[list[x] for x in [1,3,5]]
#['two', 'four', 'six']

[list[x] for x in range(0,len(list),2)]
#['one', 'three', 'five']

[list[x] for x in range(1,len(list),2)]
#['two', 'four', 'six']

[list[x] for x in [1,3,4]]
#['two', 'four', 'five']

Is any of that useful?
(If not, try to explain more what you're looking for.)

Murtan 317 Practically a Master Poster

From your code, when you call sort(name) :

if 'pile1'in ans:
	sort(pile1)
if 'pile2'in ans:
	sort(pile2)
if 'pile3'in ans:
	sort(pile3)

You pass in one of the lists, pile1, pile2 or pile3.

Then inside sort, you are comparing what you were passed with the strings 'pile1', 'pile2' or 'pile3'.

def sort(name):
    if name=='pile1':
        listMain=mod.passing(pile2,pile1,pile3)
        print(listMain)
    if name=='pile2':
        mod.passing(pile1,pile2,pile3)
    if name=='pile3':
        mod.passing(pile2,pile3,pile1)

In your code as written, none of the tests will ever be true. If you changed those tests to be like the tests in mod.passing (why you have mod still isn't really clear) should work (even though they are entirely un-necesary).

In mod.passing, you compare the argument with the value, not with a string:

def passing(t,m,b):
    if m==pile1:
        listMod1=mod2.calc(pile2,m,pile3)
        return listMod1
    if m==pile2:
        mod2.calc=(pile1,m,pile3)
    if m==pile3:
        mod2.calc=(pile2,m,pile1)

The reason I said the tests were un-necessary is that you could replace all of the code in passing(t,m,b) with:

def passing(t,m,b):
    return mod2.calc(t,m,b)

(I don't see any purpose for mod2 either unless calling between mods is the purpose.)

You could actually simplify the whole bit by changing sort to take 3 parameters as well and making the decision as to what order to pass the 3 in from your main code:

def sort(t,m,b):
    return mod.passing(t,m,b)
# then down in your main code:
if 'pile1'in ans:
    sort(pile2, pile1, pile3)
if 'pile2'in ans:
    sort(pile1, pile2, pile3)
if 'pile3'in ans:
    sort(pile2, pile3, pile1)

But none of that code ever does anything with the return value, so to …

Murtan 317 Practically a Master Poster

The only place in your code where you attempt to print listMain is from inside sort, if the name passed to sort is 'pile1', right?

When do you ever pass the name 'pile1' to sort?

(You pass the list that is named pile1 to sort, but it is not equal to 'pile1' it is equal to whatever is currently in the list pile1.)

PS- When posting python code, please use the python language code tags:
[code=Python] # Your code here

[/code]

Murtan 317 Practically a Master Poster

So 'list' is an index into the virtual heap, and each entry in the virtual heap is a structure that has an elem (the value at that node) and a next (the index in the virtual heap for the entry with the next higher elem).

When there are no entries in the list, the list * l passed to this function will point to -1 (indicating end of list).

So when you add 5, 2, 1 we should end up with:

l = 2
vh->h[0].elem = 5       vh->h[0].next = -1
vh->h[1].elem = 2       vh->h[1].next = 0
vh->h[2].elem = 1       vh->h[2].next = 1

When you add 5, 3, 6 you should get:

l=1
vh->h[0].elem = 5       vh->h[0].next = 2
vh->h[1].elem = 3       vh->h[1].next = 0
vh->h[2].elem = 6       vh->h[2].next = -1

But you appear to be getting:

l=2
vh->h[0].elem = 5       vh->h[0].next = ?
vh->h[1].elem = 3       vh->h[1].next = ?
vh->h[2].elem = 6       vh->h[2].next = -1

The next debugging step would normally be to add some code to dump the entire virtual heap just to confirm what you have is what you think you have. However, I think I see your problem. int * p starts out pointing to the passed in value list * l .

The for loop on line 10 is supposed to 'walk through' the list until it finds where the new value is supposed to go, then it is supposed to update the next value of the record that should …

Whilliam commented: smart post. +1
Murtan 317 Practically a Master Poster

To do more with the color, you're probably going to want to look at the component parts of the tuple.

For example, the following would count any pixel with more green than red and more green than blue:

for pixel in list(img_I):
    red, green, blue = pixel
    if green > red and green > blue:
        green_I += 1

This counts pixels with any green:

for pixel in list(img_I):
    red, green, blue = pixel
    if green > 0:
        green_I += 1

Some of the 'problem' values for the first case:

  • 254,255,254 - Almost pure white
  • 254,255,0 - Almost pure yellow

Some of the 'problem' values for the second case:

  • 0,1,255 - Almost pure blue
  • 255,1,255 - Almost pure purple

If you wanted to get pixels that were 'mostly' green, I would probably use something like the first case, but make sure the color parts are more than just 1 apart. How far apart would be part of the definition of 'mostly'. And if you want to make sure it was more of a 'pure' green than say a yellow-green or blue-green, you might want to include something about the ratio of blue to red. (In a 'true' green, there are equal parts of red and blue.)