raptr_dflo 48 Posting Pro

your code doesnt compile.

Compiles fine for me, I made sure of it before I attached it. Which I made a point of saying.
g++ -c -g bankAccount.cpp

It doesn't link into an executable because it doesn't have a main() (or much of anything else that makes a complete program), it's a usable example of how to derive a subclass.

I like your code, raptr_dflo, buh why not make use of cout instead of printf()?

Thanks tkud! And to answer your question: no good reason, they both work just fine. :)

raptr_dflo 48 Posting Pro

It's been quite a while since I did C/C++ in MSVS, but try creating a new console-type program, and it will probably provide you a stub main() of some sort, along with all the libraries it thinks you'll need. Then rename your existing main() to something else (a "normal" function), add your file into your new project, and call your new function-name from within the main() that VS gives you.

If you then want to build the same project on Linux (or whatever you might have been using with the main() you started with, if that's what you were doing), then simply provide a separate file that you compile only on linux, which includes something like:

extern int my_func();

int main()
{
  int retval = my_func();
  return retval;
}
raptr_dflo 48 Posting Pro

Oh, and if a DACT string is always 142 bytes, and DACT_LENGTH = 142, then if you send the extra null byte (in addition to the 142), then you need to make sure you receive it as well, but I don't think that's your problem or your 2nd received DACT would be corrupted because it's off by one byte, and so on.

Your dact_line string maintains a trailing null byte for you, so you don't have to worry about parsing some infinite string into a DACT (as long as you're appending only the recsize bytes from the buffer onto the end).

raptr_dflo 48 Posting Pro

We humorously call bugs that disappear when you add debugging "Heisenbugs", after the Heisenberg Uncertainty Principle (that observing a quantum event affects the outcome of the event). But the truth is, it's usually a very hard-to-find memory error, often a buffer-overrun of some sort, and not really as "unpredictable" as we'd like to believe....

I don't think you're ever copying too much data (e.g., the start of the next DACT) into the buffer, but your code might be a little clearer if re-organized as follows:

DACT dact;
int recsize, total_rec_size, to_receive;
while (True) {
    // 1. reset values
    total_rec_size = 0;
    dact_line.clear();
    // 2. read entire DACT buffer
    while (total_rec_size < DACT_LENGTH) {
        to_receive = DACT_LENGTH - total_rec_size;
        recsize = recv(connectFd, (void *) buffer, to_receive, 0);
        if (recsize <= 0) {
            // connection closed (0) or error (-1)
            break;
        }
        dact_line.append(buffer, recsize);
        total_rec_size += recsize;
    }
    if (total_rec_size < DACT_LENGTH) {
        // broke out of above loop before done, break out of outer one now
        break;
    }
    // 3. convert to structure
    str2dact(&dact, dact_line);
    receivedDacts.push_back(dact);
}

I don't think I've changed anything important, but eliminated a recv() call and an append() call (from the source code, not the execution ... each will still be called the same number of times for the same conditions, just all inside the loop).

raptr_dflo 48 Posting Pro

To start, you aren't really clear on class inheritance. For example, you have:

class bankAccount
{
      private:
              int accNumber;
              float balance;
              float interestRate;
      public:
             void deposit(float amount);
             void withdraw(float amount);
             void displayAccount(int, float);
             void setupAccount(int, float, float);
             bool matchAccount(int);
             float getBalance();
};

...

class savingsAccount : public bankAccount
{
      private:
              int accNumber;
              float balance;
              float interestRate;
      public:
             void calculateInterest(float, float);
             savingsAccount (int, float, float);
};

Members of a class which are safe to be inherited by derived classes should be "protected:" instead of "private:". The "private:" designation is probably rarely needed and is only relevant for portions of a parent class which, for whatever reason, should not or cannot be inherited by derived classes.

So if you make accNumber and balance "protected:" in bankAccount, you then get them for free in savingsAccount, which is part of the point.

Then your assignment specifically states:
"The generic bank account should contain an account number and balance data
members but no interest rate."
So I wonder why you have an interestRate member in your bankAccount class.

Your bankAccount class has no bankAccount() constructor. Instead it has a setupAccount() method which does the same thing. Resolve this by renaming setupAccount() to bankAccount(). Given that it shouldn't have an interest rate, do not provide or assign one in your constructor.

Then, also following the notion of inheritance, the constructor of your derived class should call the constructor of the base class, to avoid duplicating the same work …

raptr_dflo 48 Posting Pro

C++ or otherwise, are you familiar with the following concepts?
+ Linked lists
+ Stack data structure
+ Binary tree structure
+ Parsing tokens from a string
If not, you may be taking on an effort that's more complex than you're ready for.

The basic problem is: for an arbitrary expression entered by a user, you need to tokenize it (recognize what's a number, what's an operator, what's a function, and what's a grouping-via-parentheses), build a parse-tree (creates a structure which indicates which operations should be performed in which order ... and in the process determine whether the input makes sense and generate an error if it doesn't), and then evaluate the parse-tree to arrive at an answer.

This really is the same basic functionality as writing a computer-language interpreter (although in this more limited case, only the part that deals with arithmetic). Once you understand that what you're trying to do is (1) define a language [basic arithmetic and some simple functions] and (2) write an interpreter for that language, you can then decide if you're ready to undertake that level of effort.

I'm not going to provide you any additional direction at this point, because I don't have the extra time right now to start writing my own arithmetic interpreter! Best wishes!

raptr_dflo 48 Posting Pro

I'll save you the typing: http://www.google.com/search?q=recursive+descent+parser Feel free to ask if there's a concept you don't understand (after your own further investigation), or once you have more code to look at.

raptr_dflo 48 Posting Pro

Interesting. Among other things, your assignment sheet specifically instructs you to do what I suggested: start with a GenericAccount class and derive the other accounts from that. The assignment is so specific and detailed, you should probably consider following it, step by step, and then post back here when you can't get a step to work the way you want.

raptr_dflo 48 Posting Pro

OK. I think I know what you mean, but since I don't know what code you got from your tutor, and what of the code you've added to, I'm not sure where you're stuck in doing what you need.

I see a Transact::readRecord() method. You could use something very similar to that to create a Customer::readCustomer() method, which would populate your Customer class. From the data file, it looks like account-types are K, S or C, or if you read an X then you're done with that customer and go on to the next one.

Write just enough code to do that, and test it. Then think about what you need to do next. Reading input from the user is as simple as replacing "infile >>" with "std::cin >>" for the interactive ATM functionality.

raptr_dflo 48 Posting Pro

searching for LPCTSTR on msdn.microsoft.com:

"LPCTSTR: An LPCWSTR if UNICODE is defined, an LPCSTR otherwise."

"LPCWSTR: typedef CONST WCHAR *LPCWSTR;"
"LPCSTR: typedef __nullterminated CONST CHAR *LPCSTR;"

Since your argv array is already defined as type char*[] (an array of char* elements), I'm going to assume you don't need Unicode support yet, and suggest that they're so close to one-and-the-same, that you can simply cast directly:

LPCTSTR *myStr1 = (LPCTSTR *)argv[1];
LPCTSTR *myStr2 = (LPCTSTR *)argv[2];
raptr_dflo 48 Posting Pro

Tony has a good point: whether or not you use command-line arguments for this program, you should get in the habit of defining your main() as:

int main (int argc, char *argv[])
{
    ...
}

It is also customary to return 0 from main on success, and non-zero on failure. The specific non-zero exit value would indicate what kind of error happened, but I that's probably better for programs that are intended to be run by other programs or the operating system, as opposed to programs run by users.

Your program doesn't find the string later in the file because, after copying the first N bytes into temp, you exit whether you found the string there or not. If you don't find the string, you'd want to try again starting at the next position, and only indicate 'NOT FOUND' after you've finished searching the file.

You will be much kinder to your disk, if instead of backing up the file N-1 bytes each time, and re-reading most of the same data, instead copy each character in your temp array down one position, and just read one more byte into the end:

0 <- 1 <- 2 <- ... <- n-1 <- byte_from_file

You no longer need the first character in the temp array (temp[0]), so you can just overwrite it. Don't forget to check fgetc() for EOF!

raptr_dflo 48 Posting Pro

I think your control in line 12 might be problematic. Try:

for (c=string; (c==string || *(c-1) != '\n') && c-string < 220;)
    *c++ = (char)getchar();

Or try:

if (fgets(string, 220, stdin)) {
    int last_char_index = strlen(string) - 1;
    if (string[last_char_index] == '\n')
        string[last_char_index] = '\0';
else
    string[0] = '\0';

Of course, yours is shorter....

As far as finding words, the others are right, you need a separate string object to input and store the word to look for, and the function strcmp() will be of interest.

raptr_dflo 48 Posting Pro

Since your savings-account, checking-account, and credit-account classes are identical (or nearly so), consider starting with a base class:

class GenericAccount
{
    /* mostly the same stuff you already have */
    GenericAccount(int accountNum, float balance, float interestRate);
};

and then inherit it, overriding any methods that need to change, or adding new ones:

class SavingsAccount(public GenericAccount)
{
    SavingsAccount(int accountNum, float balance, float interestRate):
      GenericAccount(accountNum, balance, interestRate)
    {
        /* anything extra you need to do, possibly nothing */
    }

    /* add or replace anything that's particular to a SavingsAccount */
};

You might want to make Customer.sAccount a pointer (and so on for chAccount, crAccount) so that they can be NULL if the customer doesn't have that kind of account, until he adds such an account. Though adding accounts isn't functionality usually found in an ATM! :)

As far as your code not working, what does it do? What does it -not- do? Does your program crash and if so what error message do you get?

raptr_dflo 48 Posting Pro

I think he was at least partly busting your chops. There have been at least two other threads on the exact same subject in the past few days, are you guys all in the same class? Try this one: http://www.daniweb.com/software-development/cpp/threads/365271

raptr_dflo 48 Posting Pro

Since your sender-code reads the DACT objects out of a file, and then sends them to the receiver, you should be able to save received DACT objects into a new file (whenever you receive a complete one). When you finish, you can just 'diff' the two files, and that will at least show you which lines are getting duplicated. If you also print a notice when you receive a partial DACT string, before you loop back to get more input, that might shed some more light on what's going wrong and where.

raptr_dflo 48 Posting Pro

Please, use CODE blocks around included code. Paste the code you want to include, then go back and select it, and click the conspicuously-named "[ CODE ]" button above the text-entry window.

Otherwise, your problem is trying to build a project with out-of-date files, or possibly an out-of-date macro definition. Your code checks whether macro _WIN32_WINNT is defined and if not, sets it to 0x400, which isn't as high as the 0x403 specified in the error message. You can specify this value yourself, in the build settings for your VS2010 project, although the code might be relying on older versions of functions, so it may cause other problems instead.

With any luck, somebody more familiar with your specific problem domain can shed more light.

raptr_dflo 48 Posting Pro

You need to add command-line arguments. Jason just told you how to do that, either through VisualStudio or by running the program from a command-prompt.

raptr_dflo 48 Posting Pro

Your logic is flawed in draw_rect(), for how you decide whether to draw a filled rect or a hollow rect. If you can say it to yourself clearly, you can get it right without any additional help.

Also, consider using your line_maker function for the empty space inside a non-filled rectangle:

cout << ch << line_maker([something]) << ch << '\n';
raptr_dflo 48 Posting Pro

Two things to consider:

1) Include your "char *payload;" as a member of your struct entry, rather than maintaining it in a separate array, especially since you're having your other struct members reference into it. At the end, your deallocation becomes

free(contacts[index].payload);

2) As far as getting away from the MAXDATA constant and static allocation, take a look at function "realloc" (it's in the same family with malloc() and free()). While it's time-inefficient to grow an array for each new element, and space-inefficient to have an array much bigger than needed, an approach I've seen here and there (and now use myself as needed), is a combination: start with "a few" items in the array, and when you run out, grow the array by "a few" more. If you have a sense how the array is likely to be used, you can pick a sensible constant number for "a few" (maybe 10 for your case?). If you can't determine ahead of time how fast a program is likely to need more, or how many it might want over all, increasing by a factor works (e.g. 2 to double the length of the array each time, something more like 1.2 or 1.5 to grow by less, but more often). Then in addition to "i" (the number of entries you've populated), you need one more scalar variable "num_contacts_allocated" (to replace MAXDATA) so you can tell when i catches up to it and you need to grow again:

for(i = …
raptr_dflo 48 Posting Pro

Any chance this helps? http://delphi.about.com/od/delphitips2008/qt/format_richedit.htm

The source is in Pascal, but with any luck, your C++ interface is similar....

raptr_dflo 48 Posting Pro

Hi andy,
While helpful, sergent and mike missed the original problem: your main() failed to call p1.setDistFrOrigin() before printing it, so you were getting whatever garbage happened to be in that memory location.

Also, if I recall correctly, since pow() is written to support non-integer exponent values, it's not necessarily very efficient. For Point2D, just use sqrt(x*x + y*y), and for Line2D, consider using a couple of temporary values to make your expression more readable.

raptr_dflo 48 Posting Pro

I've been thinking a bit about "big picture" here, and one of the difficulties stems from poor object-oriented analysis. Basically, add(), isMember() and print() are funtions of the list, not of an individual ListNode. You still need the node class/structure you already have, to store a value in it and to hook them together with the "next" pointer.

I'd recommend creating a new List class that includes the "head" pointer (NULL until the first value is added), and the three basic member functions asked for. Then you can initialize the list by calling list.add(value) with successive values, list.isMember(value) to look through the nodes to see if the value appears anywhere, and list.print() to go through the nodes in order, and print out the values.

Then the main() can do things like ask the user for values to add to the list, ask for a value to search for, and so on.

Starting at line 119 of your main(), I have no idea what you're doing with your copy-constructor. You use it to create a new node "myCopy" from the current node pointed to by "curNode", then you immediately lose the new node you just created (and leak memory in the process, since now -nothing- points to that new node, it's just stranded out there) by reassigning myCopy to point back to "head".

Instead, it might be worth adding a copy() method to your List class, which uses the ListNode copy constructor to make a copy of …

raptr_dflo 48 Posting Pro

Patience, young Luke. I'm not a D3D expert, but there probably are a couple around here somewhere. They might not get back to you on the weekend.

While I know next-to-nothing about this, I'd like to think that the functions that load a compressed image would uncompress it as part of the loading process....

raptr_dflo 48 Posting Pro

Sorry, I guess that was it in the first comment.

There are a couple obvious problems in your "case 1" for creating a new account. You don't check the value of i, so you'll get an error if you try to add an account if i >= 10. Also, you increment the value of i first, so you have an account a[0] which you never use.

In your newaccount() method, you increment the instance member accno (which may or may not be initialized to zero -- if it is, then your accno will always be 1, otherwise it will be some arbitrary value), and ignore your static class-member (which I think you intended to provide successive new account numbers).

Your transfermoney() method also has problems -- first of all, you add the money to the destination account before you determine whether the source account has sufficient funds. Also, instead of copying the destination account into the method, and then copying back via assignment, consider passing a pointer to the destination account, and modifying it directly as needed in the method.

In case 5, where did the "b" variable come from?

raptr_dflo 48 Posting Pro

And did you have a question to go with your code?

raptr_dflo 48 Posting Pro

Hmmm, not sure right off. To see what's going on with the mystery point, add some debug printing. When it's incorrectly removed from the convex hull, also print out the three points supposedly around it so you can better determine what's going on.

raptr_dflo 48 Posting Pro

Lol, I'm an idiot. That last bit did exactly what I said. So I'll modify it to say:

... if you enclose your source code within a [-CODE-]...[-/CODE-] block (with the dashes removed), it will ...

I wrote it without the dashes last time, so it made a code-block, just like it was supposed to! :)

raptr_dflo 48 Posting Pro

Well, you've commented out your "while()" expression. {}s don't create a loop by themselves, they just define a "scope" -- a conceptual container where (a) anything declared within it, exists and is visible only within it, and (b) anything declared in an outer scope which contains this one is also visible and accessible.

If you want to loop forever, you can use "while (true) { ... }". The best route to basic programming is: slow down, and think through step by step what it is you want your program to do. In this case "I want a loop. Each time through the loop, the user will be prompted to enter two numbers and an operation. If the operation isn't supported, the loop should exit. Otherwise the operation should be performed, and the answer displayed." Then you can start with a loop, that prompts for an operation, and test that it exits when the user inputs an invalid operation. After that you can add prompts for the numbers, and print them out, so you can see that you got what you expected. Then you can actually perform the operations. And so on.

In the future, if you enclose your source code within a

...

block, it will number your lines and preserve your indentation. After pasting your code, select it all and click the "

" button above the editor.[code]
" button above the editor.

raptr_dflo 48 Posting Pro

A short answer ... if you want to have a separate thread for each client connection, then when you receive an incoming message from one client, you need to communicate to each of the other threads so they can send it out.

Unless your server process needs to do something besides service client connections, it may be simpler to skip the threading and use the select() function to wait for input on all of the client connections at once, loop over the connections on which there is input, and for each of those, get the input and then loop over all of the connections internally to send the message out to all the clients.

raptr_dflo 48 Posting Pro

The first problem I see is that you ask for T/F within a loop that depends on variable "check" which you never update. So your program can't possibly get beyond that point.

After that, it's clear that what you read in, in terms of an ENG or IT phrase, never makes it into the database, and then it seems you're really unclear about rand().

So ... what's your next question?

tagazin commented: I learned something +1
raptr_dflo 48 Posting Pro

hey strungoutfan78,

Despite all the intervening help, I think your original add() function was fine as written, and all you needed to do is, after calling "curNode->add( *( tv + i ), curNode );" (originally at line 40), to advance curNode:

curNode->add( *( tv + i ), curNode );
    curNode = curNode->next;

so that the add after that would be adding to the -new- end of the list. Also, since "add" is a method ("member function") of ListNode (and a struct in C++ is just a class where the data members are public by default), implicit variable "this" is a pointer to the ListNode instance in question. So you don't need to pass curNode, and change add to read:

void ListNode::add( double x ) {
    this->next = new ListNode; // Creates a ListNode at the end of the list
    this = this->next; // Points to that ListNode
    this->next = 0; // Prevents it from going any further
    this->value = x;
}

The only usefully-variable part of a ListNode is the value, so that's sufficient to pass in a constructor:

ListNode::ListNode( double val ) {
    this->value = val;
    this->next = 0;
}

Since nothing is dynamically allocated -within- a ListNode, it doesn't need a destructor, you just need to delete any nodes you new.

raptr_dflo 48 Posting Pro

Hey tonyjv,

If you use strok(), it successively replaces the next occurrence of the ';' (or whatever) with a '\0' (indicating end of string), and returns the location of the start of the preceding string. So, if you're stuck with fixed-size fields in your struct, you can use strncpy to copy the first N characters of each word into the next field, or if dynamic memory is OK, then replace each:

char fieldName[fixed_field_size];

with

char *fieldName;

and then with each return from strtok(), for the corresponding field:

...
    if ((ptr = strtok(NULL, ';') != NULL)
        contacts[i].fieldName = strdup(ptr);
    ...

Don't forget to correctly clean up your unused ENTRY objects by free()'ing the fields!

raptr_dflo 48 Posting Pro

If you look at your own code objectively (which is hard when you're in a blind panic about finishing an assignment on schedule), you'll see that you're running your grade-input-loop four times, and in each time through the loop, you're asking for each of four grades. Do one or the other, and your problem will be solved! (Hint: since you're keeping separate arrays for the grades, I'd recommend getting rid of the inner loop. ;) )

raptr_dflo 48 Posting Pro

So what does "no success" mean? Do you now sort your convex hull points by angle?

If you're going to use one of the existing points as the start-point, then (if it's also a convex-hull point) its angle will be undefined. Since you're using the output of atan2() directly, your angle values start and end at the -x-axis (as I mentioned previously), so you should start with the point farthest to the west (most negative X). Then angles to all other points will be in the range [-PI/2, PI/2], and if you can set the angle for the starting point to be either -PI or PI, your entire set will be correctly sortable.

Stay in touch!

raptr_dflo 48 Posting Pro

for ghosts, i'd start with the simplest thing first, and get that working. pseudocode:

next_ghost_pos = updateGhostPos();
  while (next_ghost_pos == wall) {
      ghost_direction = rand() % 4;
      next_ghost_pos = updateGhostPos();
  }
  ghost_pos = next_ghost_pos;

This will have a ghost move in one direction until it hits a wall, then spin around randomly until it finds a direction to go (turn a corner or go back the way it came). You can add more smarts by checking if there's more than one option (where a path opens to the left or right while there's still a path straight ahead), or weight your choice of direction towards the pacman.

You will also need a check (somewhere, either for the pacman move or the ghost move, or both) for when the pacman collides with a ghost.

Hope you're having fun with this!

raptr_dflo 48 Posting Pro

looking at the 1-D example(s) on the page you referenced:

grad[0] = (vals[1] - vals[0]) / dx;
grad[i] = (vals[i+1] - vals[i-1]) / (2*dx);  // for i in [1,N-2]
grad[N-1] = (vals[N-1] - vals[N-2]) / dx;

for the 2-D case, you have to figure out which direction in the input is X vs. Y (should be able to tell by specifying different values for dx and dy and seeing which output array changes in what way), but essentially the input is a 2-D array of scalar values and the output is a 3-D array, or two 2-D arrays matching the size/shape of the input. Each of the resulting 2-D arrays is the gradient in one direction: in this case, it looks like the Y gradients are output first, and the X gradients second, but again, it depends on the definition of X and Y.

Hope this helps!

raptr_dflo 48 Posting Pro

hey nightbreed,

you don't need to re-sort the points, a "half-way" point can be found simply by iterating over all your points and keeping track of the min & max value for x & y (hint: initialize min_x and max_x to the x of one of the points, same for y). or you can compute the "centroid" (i believe i've got the terminology right) by taking the mean of x and y values ... just compute a running x_sum and y_sum, and at the end divide each by the number of points.

i was just referring to the plain C function atan2() in math.h ... 'man atan2' if you have a *nix command-line, or see e.g. http://en.wikipedia.org/wiki/Atan2 (Google is your friend). it's nice because it returns a value all the way around the circle (-PI,PI]. this will sort with a start-point on the negative-x axis. If you like non-negative values, with a start-point on the positive-x axis (like I do), then it's just:

theta = atan2(dy, dx);
if (theta < 0.0)
    theta += 2*M_PI;

Do dy and dx make sense to you here? The signs (+/-) of each are significant if you use atan2(), so think about what the angle "to" another point means.

raptr_dflo 48 Posting Pro

pseudocode:

simulation_loop:
  new_time = old_time + time_step
  new_tank_pos = ComputeTankPos(tank_velocity, new_time)
  if new_tank_pos is too close to wall, other tank, whatever else:
    new_tank_pos = old_tank_pos
    tank_velocity = (0, 0)  # if you have velocity separated into x and y components
raptr_dflo 48 Posting Pro

Other issues:

In Intialize, the second two elif: blocks will not execute, because you've already handled those ranges in the first two. Instead, move the assignments to indented blocks starting on the following line, and consolidate your u[0][k] and u[1][k] assignments.

Also, since Initialize returns the u array, declare it in there (instead of as a global). Otherwise, don't return anything, and just reference u directly after calling Initialize()

Finally, your error is in the second call of Evolve_in_One_Timestep, since in the first call you return 1-D array u_new[0] and then pass that back in, expecting it to be 2-D. And don't you need to assign values into u[1] as well as u[0]? Or is that a fixed boundary condition?

When you're finished, you need a 1-D array to plot, but instead of trying to return the 1-D array from Evolve..., just pass u_data[0] into plot().

raptr_dflo 48 Posting Pro

"In a random order" would definitely be a problem! When you calculate the area, they should be in the same order they were in before (with the internal points removed), but that doesn't help if they weren't intelligently ordered previously.

You can order the points by determining the angle of each point from an arbitrary point. A good arbitrary point (if not just starting with the first one in your list) is somewhere in the middle of your convex hull. Write a function that determines that point. Determine the angle to each point on the convex hull as the arctangent of the slope of the line (function atan2() is perfect for this).

Let me know how it goes.

raptr_dflo 48 Posting Pro

If it "goes into GDB" you're in good shape, if you compile with the -g flag. You can solve most programming errors knowing only a few GDB commands:
+ "stop at <line>" tells the debugger to pause at the specified line
+ "run [args]" starts the program in the debugger
+ "step" continues to the next relevant line of code
+ "cont/continue" continues to the next breakpoint
+ "where" shows you what line you're at now
+ "print <var>" tells you the current value of the variable, e.g. "print i"
+ "up/down" move down into a called function's stack-frame, or up to the caller's
+ "help" always works! (especially in case I have the syntax slightly off here, I'm doing it from memory, and haven't used it in a year or so)

I admit it, parsing text in C is just plain painful. :)

raptr_dflo 48 Posting Pro

rssk,

If you understand what I presented previously, then it should be a simple matter to create one loop and access the correct element from each list. jice's input is excellent too, as it removes the division and multiplication.

If you don't understand basic loop flow-control, you should consider getting an introductory programming book for Python (or your choice of other programming language). If you have specific questions other than "tell me how to do this", please feel free to ask.

raptr_dflo 48 Posting Pro

> but my key '596' is present in 'map_dict2'.

but according to the error, it's not present in map_dict1. Check for that using map_dict1.has_key(key) (or the new and preferred "key in map_dict1") before checking whether the value at that key equals the expected value.

novice20 commented: U showed me the right direction :) +3
raptr_dflo 48 Posting Pro

I think you're confused about the dict notation. It's

d = {key:value, key:value, ...}

Since you already have alternating keys and values in your list, you could do something like:

d = {}
for i in xrange(len(my_list)/2):
  key = my_list[i*2]
  value = my_list[i*2 + 1]
  d[key] = value

if you want to use integers in your dict, instead of the strings in your list, simply do for example:

...
  key = int(my_list[i*2])
...

I know there are clever (and probably much more efficient) ways of performing operations on entire lists, but this is simple and readable.

Of course, I have no idea why you'd want or need a dict indexed by successive integers, that's what a list gets you for free! But it's your problem-domain, so good luck and happy coding!

raptr_dflo 48 Posting Pro

Have you tried "%hd" for a short int? scanf() is -very- picky about pointer-types and how to deal with them.

(For people with more time on their hands, start reading up on stdarg and variable argument-list processing, which is why you can pass a format string and then the correct number of additional arguments into scanf/printf.)

raptr_dflo 48 Posting Pro

Following up, in case it helps:

Looking at your ENTRY struct, you say at the top it's a "struct entry" and then when you define the "next" pointer, you specify "struct contact" -- copy & paste & edit error?

Since the values you're reading into are all char-arrays, they already -are- pointers. It's perfectly valid to say:

char text[100];
char *ptr = &text[0];

However, if the values in your input file are actually comma-separated, you need to specify the commas in your format string to keep them from being included in your values. The %s also stops at and ignores white-space, so if a first name is "Mary Kay" or a last name is "van Wilder", you're going to have even more problems. Otherwise, it's useful to note that any number of spaces (or tabs or whatever) will be ignored, which is wonderfully useful when reading a set of column-aligned numbers (not that it's relevant to your use-case)! And sscanf() returns the number of arguments successfully read, so you can double-check your expectations.

So try:

while (fgets(temp, 160, pFile) != NULL ) {
    if (sscanf(temp, "%s,%s,%s,%s,%s,%s,%s,%s", ...) != 8) {
        fprintf(stderr, "wrong number of arguments read from string '%s'\n", temp);
        continue;
    }
    ...
}

But now that I think about it, I'm betting you have embedded white-space in the "address" field. So using strtok() will probably be a better bet. If you can also have commas inside your address field, you're in a world of …

raptr_dflo 48 Posting Pro

Ah, well, if you've written your own polymorphic mergesort, that's different. By all means go ahead and use it! :)

"... sorted by polar angle in counterclockwise order around p0"

I think what I've given you should resolve the sorting issue. The stack operations are clear enough, so that just leaves the magic inherent in

"the angle formed by points NEXT-TO-TOP(S), TOP(S), and p_i makes a nonleft turn".

Give a yell here if I can be of more help.

raptr_dflo 48 Posting Pro

I don't have pylab installed, but looking at page 15 of http://matplotlib.sourceforge.net/Matplotlib.pdf, it looks like you -might- be able to do something crazy like:

xlabel('letters')
ylabel('counts')
axis('a', 'z', 0, max_count)

If that doesn't work, I'd see if there are any transformation functions you can apply, that will take whatever values it wants to put along the x-axis, and lookup what to replace them with.

Other than that, consider starting with a more general-purpose drawing API. TkInter is quite primitive, wxWidgets seems popular on this forum, and I'm working with PyQt -- which I absolutely love -- for general-purpose user-interface development (but it can be painful to build and install).

raptr_dflo 48 Posting Pro

tonyjv, nice images there. For what it's worth, converting to polar coordinates is interesting:
If A = (a + bi) = (a, b) = (R, theta)
where R = sqrt(a^2 + b^2) and theta = atan2(b, a)
(and thus, a = R*cos(theta) and b = R*sin(theta))
then A^2 = (R^2, 2*theta)

raptr_dflo 48 Posting Pro

Hey rockerjhr.

First of all, a little less attitude would be great. There are many experienced programmers on here, but not all of them are mathematicians. And they're all answering questions in their spare time, because they care.

I got as far as hand-plotting your sorted points, and they appear to be correctly ordered, except that if you consider your minimum point (which I'll call #0) is at the minimum Y (or somewhere near the "south pole" on a map of the world), then the rest of the points start near just off of "due north", proceeding counter-clockwise to "west", and picking up again at "east" before continuing to exactly "due north".

Your theta() algorithm, as posted, first divides by deltax, and then later checks whether it was zero. Might want to fix that! But also, think about where your points are: if you're starting from the minimum Y value (and minimum X within that), then other points can only be "due east", or farther north, around towards the west, but can't be "due west" or anywhere south. So a more useful value would be atan(-deltax/deltay), returning 0 if deltay is zero. Do you see why (considering various points on our "map of the earth")?

Your mergesort() seems to be working just fine, but it's designed to be completely generic and reusable in any context. Since you're including it in your own code (instead of, say, compiling it into a library and using it separately), if …