VTK/MinimalExample: Difference between revisions

From KitwarePublic
< VTK
Jump to navigationJump to search
mNo edit summary
m (Typos)
 
(8 intermediate revisions by 2 users not shown)
Line 1: Line 1:
When asking questions on the mailing list, the goal must be to entice the readers to help you with your question. This means you should provide as much detail as you can about your situation. This includes things such as your operating system, compiler version, etc.
When asking questions on the mailing list, there are several goals which must all be met to extract the maximum benefit from the efforts of everyone involved. Please take careful note of the following points, as they are key to producing a "win-win" situation. By asking a question that follows the guidelines on this page, you are not only helping the community (which is your primary goal, right? :) ), but you are also greatly improving the chances of getting your question answered so you can go about the business that you were working on before you came across the problem.


Most importantly, you should provide a minimal, compilable, self-contained example of the problem.
# ''Entice the readers to help you with your question.''
#: If you don't ask the question in an engaging way, you will probably not get an engaged answer. This means you should provide as much detail as you can about your situation. Include things such as your operating system, compiler version, library versions (e.g. VTK 5.8), etc. You should also include details about the steps you have taken to try to solve the problem already (read XYZ documentation page, tried XYZ example, etc).
# ''Ask your question in a way that will benefit future users.''
#: Again, though it may not seem like something that is directly in your self-interest at first glance, it really is! Typically if someone recognizes an opportunity to answer a question that has not been answered before and can be preserved for future readers, they will be much more willing to spend time on it. If I were asked to spend an hour one person, I might consider it. If I were asked to spend an hour giving a lecture to 1000 people, I would be honored to do it.
# ''Most importantly, you should provide a minimal, compilable, self-contained example of the problem.''
#: This part is critical, so we elaborate in great detail below about what makes a good example. Saying "My code crashes when I do X, how do I fix it?" is often impossible to answer without seeing exactly what you have done. The short story is that  you should aim to allow the readers to "copy+paste+compile" and observe on their own machines exactly the behavior you are asking about.
# ''Well known secret - by creating a good example to ask your question, you will often solve your problem yourself!''
By following the guidelines below before posting your question to the mailing list, you will find that quite often you actually discover the answer in the process! By stripping away the extraneous code (see "Minimal"), you will help yourself identify where the problem is happening so you can focus in on debugging that section. By genericizing/abstracting the code (see Generic/Abstract), you will help yourself identify the VTK concept that is at the core of your problem, which may lead to you to new Google search terms. By removing external inputs to your program (see Self-contained), you will be able to tell if there is something wrong with your data set, or if there is something wrong with your procedure.  If it is very difficult to create an example from the code, it probably indicates that improvements to your design are required anyway.  By refactoring spaghetti code, bugs can be found, development will be faster in the long run, it becomes easier to perform complex tasks, and it becomes easier to write tests that will certainly improve the quality of your code.
 
==Minimal==
When creating your example, ask yourself ''Are there any lines of code that I can remove and still demonstrate my problem?''.


* '''Minimal'''
Do not include code that is not relevant to the problem. For example, if you are having a problem getting the neighbor of a cell that you click on (in the click event of an InteractorStyle), and getting to that point is not involved in the problem, then you should make the example specify the cell that you want to get the neighbor of programmatically, without involving any interaction or visualization.
Do not include code that is not relevant to the problem. For example, if you are having a problem getting the neighbor of a cell that you click on (in the click event of an InteractorStyle), and getting to that point is not involved in the problem, then you should make the example specify the cell that you want to get the neighbor of programmatically, without involving any interaction or visualization.


* '''Compilable'''
==Generic/Abstract==
When creating your example, try to think "How can I best write this so that it is immediately applicable to the most people?" and "If I were to put this example in a book, does it make sense as is?". That is, rather than use function and variable names that are specific to your problem, you should use generic names that help identify what is going on. For example, rather than:
 
"After I get the registration result, when I try to run DavesAlgorithm, it crashes."
<source lang="cpp">
void DavesAlgorithm(vtkPolyData* polyData)
{
...
double p[3];
polyData->GetPoint(0,p); // Crash here
}
 
int main()
{
...
vtkPolyData* icpResult = ...;
 
DavesAlgorithm(icpResult);
}
</source>
 
You should "genericize" everything, even removing the function all together if you do not suspect that it is part of the problem:
 
"I have a polydata that crashes when I try to get a point out of it."
<source lang="cpp">
 
int main()
{
...
vtkPolyData* polyData = ...;
 
...
double p[3];
polyData->GetPoint(0,p); // Crash here


}
</source>
We see that this is actually the exact same question, but the "application specifics" have been stripped away, and left with a VTK-only demonstration, which is much, much more useful for the future. That is, someone may certain Google "GetPoint crashes" and come across this mailing list thread. However, certainly no one will have Googled "DavesAlgorithm crashes after ICP", as these terms are very specific to only this specific persons problem.
==Compilable==
Do not send code like this:
Do not send code like this:


<source lang="cpp">
<source lang="cpp">
polydata = sphereSource->GetOutput();
polydata = sphereSource->GetOutput();
polydata->GetPoint(0, p); // crashes here
</source>
</source>


Line 24: Line 73:
{
{
   vtkSmartPointer<vtkSphereSource> sphereSource = vtkSmartPointer<vtkSphereSource>::New();
   vtkSmartPointer<vtkSphereSource> sphereSource = vtkSmartPointer<vtkSphereSource>::New();
  sphereSource->Update();


   vtkPolyData* polydata;
   double p[3];
   polydata = filter->GetOutput();
   sphereSource->GetOutput()->GetPoint(0,p); // crashes here
   return 0;
   return 0;
}
}
</source>
</source>


* '''Self-contained'''
Here, we can immediately notice that you have forgotten to call sphereSource->Update() before using the output of the filter.
 
==Self-contained==
Unless the problem is "I am having trouble reading this file", do not include external files in your examples. That is, rather than use a vtkXMLPolyDataReader, use a vtkSphereSource. Rather than read a text file with parameters, or accept command line parameters, hard code them into the example. Again, Copy+Paste+Compile is what makes life easy for the readers, and hence will get you an answer with higher probability.
Unless the problem is "I am having trouble reading this file", do not include external files in your examples. That is, rather than use a vtkXMLPolyDataReader, use a vtkSphereSource. Rather than read a text file with parameters, or accept command line parameters, hard code them into the example. Again, Copy+Paste+Compile is what makes life easy for the readers, and hence will get you an answer with higher probability.
Additionally, do not accept command line arguments, but rather hard code all values into the source code.
==Formatting/indention:==
Please recognize that the mailing list is a "plain text" environment. When you post code, realize that it may be read in an "80 character column" reader. Please ensure your tabs, indentation and line breaks look sensible. That is, rather than:
<source lang="cpp">
...
                        writer->Write();
                        }else{
                                std::cout << "file exists." << std::endl;
                            ofstream fichier ("file.xyz",ios::out | ios::app);
                                        if(fichier)  // if the opening was successful
                                        {
                                                    cerr << " the opening was successful!" << endl;
                                        *//    now here i want the code that makes me save the "combined" in
"file.xyz" without overwrite the existing*
...
</source>
post:
<source lang="cpp">
...
  writer->Write();
  }else{
  std::cout << "file exists." << std::endl;
  ofstream fichier ("file.xyz",ios::out | ios::app);
  if(fichier)  // if the opening was successful
  {
    cerr << " the opening was successful!" << endl;
    // now here i want the code that makes me save the "combined" in
    // "file.xyz" without overwrite the existing*
...
</source>
The more readable you can make the example, the more likely you are to get a quick response (or a response at all!). Remember, people are helping you not because they are getting paid to, but because they enjoy giving back to a wonderful open source community. That said, it is extremely easy to say "that question is way too long, and way too hard to read" and simply ignore it completely. That is not helpful for anyone!
Not only that, sometimes this wacky indention proves that you have simply copy/pasted from your real code, and not followed any of the guidelines on this page! There should never be 10 levels of indention like the above in a minimal example :)

Latest revision as of 18:46, 9 September 2012

When asking questions on the mailing list, there are several goals which must all be met to extract the maximum benefit from the efforts of everyone involved. Please take careful note of the following points, as they are key to producing a "win-win" situation. By asking a question that follows the guidelines on this page, you are not only helping the community (which is your primary goal, right? :) ), but you are also greatly improving the chances of getting your question answered so you can go about the business that you were working on before you came across the problem.

  1. Entice the readers to help you with your question.
    If you don't ask the question in an engaging way, you will probably not get an engaged answer. This means you should provide as much detail as you can about your situation. Include things such as your operating system, compiler version, library versions (e.g. VTK 5.8), etc. You should also include details about the steps you have taken to try to solve the problem already (read XYZ documentation page, tried XYZ example, etc).
  2. Ask your question in a way that will benefit future users.
    Again, though it may not seem like something that is directly in your self-interest at first glance, it really is! Typically if someone recognizes an opportunity to answer a question that has not been answered before and can be preserved for future readers, they will be much more willing to spend time on it. If I were asked to spend an hour one person, I might consider it. If I were asked to spend an hour giving a lecture to 1000 people, I would be honored to do it.
  3. Most importantly, you should provide a minimal, compilable, self-contained example of the problem.
    This part is critical, so we elaborate in great detail below about what makes a good example. Saying "My code crashes when I do X, how do I fix it?" is often impossible to answer without seeing exactly what you have done. The short story is that you should aim to allow the readers to "copy+paste+compile" and observe on their own machines exactly the behavior you are asking about.
  4. Well known secret - by creating a good example to ask your question, you will often solve your problem yourself!

By following the guidelines below before posting your question to the mailing list, you will find that quite often you actually discover the answer in the process! By stripping away the extraneous code (see "Minimal"), you will help yourself identify where the problem is happening so you can focus in on debugging that section. By genericizing/abstracting the code (see Generic/Abstract), you will help yourself identify the VTK concept that is at the core of your problem, which may lead to you to new Google search terms. By removing external inputs to your program (see Self-contained), you will be able to tell if there is something wrong with your data set, or if there is something wrong with your procedure. If it is very difficult to create an example from the code, it probably indicates that improvements to your design are required anyway. By refactoring spaghetti code, bugs can be found, development will be faster in the long run, it becomes easier to perform complex tasks, and it becomes easier to write tests that will certainly improve the quality of your code.

Minimal

When creating your example, ask yourself Are there any lines of code that I can remove and still demonstrate my problem?.

Do not include code that is not relevant to the problem. For example, if you are having a problem getting the neighbor of a cell that you click on (in the click event of an InteractorStyle), and getting to that point is not involved in the problem, then you should make the example specify the cell that you want to get the neighbor of programmatically, without involving any interaction or visualization.

Generic/Abstract

When creating your example, try to think "How can I best write this so that it is immediately applicable to the most people?" and "If I were to put this example in a book, does it make sense as is?". That is, rather than use function and variable names that are specific to your problem, you should use generic names that help identify what is going on. For example, rather than:

"After I get the registration result, when I try to run DavesAlgorithm, it crashes." <source lang="cpp"> void DavesAlgorithm(vtkPolyData* polyData) {

...
double p[3];
polyData->GetPoint(0,p); // Crash here

}

int main() { ...

vtkPolyData* icpResult = ...;
DavesAlgorithm(icpResult);

} </source>

You should "genericize" everything, even removing the function all together if you do not suspect that it is part of the problem:

"I have a polydata that crashes when I try to get a point out of it." <source lang="cpp">

int main() { ...

vtkPolyData* polyData = ...;
...
double p[3];
polyData->GetPoint(0,p); // Crash here

} </source>

We see that this is actually the exact same question, but the "application specifics" have been stripped away, and left with a VTK-only demonstration, which is much, much more useful for the future. That is, someone may certain Google "GetPoint crashes" and come across this mailing list thread. However, certainly no one will have Googled "DavesAlgorithm crashes after ICP", as these terms are very specific to only this specific persons problem.

Compilable

Do not send code like this:

<source lang="cpp"> polydata = sphereSource->GetOutput(); polydata->GetPoint(0, p); // crashes here </source>

instead, make sure that readers can copy+paste+compile:

<source lang="cpp">

  1. include <vtkPolyData.h>
  2. include <vtkSphereSource.h>
  3. include <vtkSmartPointer.h>

int main() {

 vtkSmartPointer<vtkSphereSource> sphereSource = vtkSmartPointer<vtkSphereSource>::New();
 double p[3];
 sphereSource->GetOutput()->GetPoint(0,p); // crashes here
 return 0;

} </source>

Here, we can immediately notice that you have forgotten to call sphereSource->Update() before using the output of the filter.

Self-contained

Unless the problem is "I am having trouble reading this file", do not include external files in your examples. That is, rather than use a vtkXMLPolyDataReader, use a vtkSphereSource. Rather than read a text file with parameters, or accept command line parameters, hard code them into the example. Again, Copy+Paste+Compile is what makes life easy for the readers, and hence will get you an answer with higher probability.

Additionally, do not accept command line arguments, but rather hard code all values into the source code.

Formatting/indention:

Please recognize that the mailing list is a "plain text" environment. When you post code, realize that it may be read in an "80 character column" reader. Please ensure your tabs, indentation and line breaks look sensible. That is, rather than:

<source lang="cpp"> ...

                       writer->Write();
                       }else{
                               std::cout << "file exists." << std::endl;
                           ofstream fichier ("file.xyz",ios::out | ios::app);
                                       if(fichier)  // if the opening was successful
                                       {
                                                   cerr << " the opening was successful!" << endl;
                                       *//     now here i want the code that makes me save the "combined" in

"file.xyz" without overwrite the existing* ... </source>

post: <source lang="cpp"> ...

 writer->Write();
 }else{
 std::cout << "file exists." << std::endl;
 ofstream fichier ("file.xyz",ios::out | ios::app);
 if(fichier)  // if the opening was successful
 {
   cerr << " the opening was successful!" << endl;
   // now here i want the code that makes me save the "combined" in
   // "file.xyz" without overwrite the existing*

... </source>

The more readable you can make the example, the more likely you are to get a quick response (or a response at all!). Remember, people are helping you not because they are getting paid to, but because they enjoy giving back to a wonderful open source community. That said, it is extremely easy to say "that question is way too long, and way too hard to read" and simply ignore it completely. That is not helpful for anyone!

Not only that, sometimes this wacky indention proves that you have simply copy/pasted from your real code, and not followed any of the guidelines on this page! There should never be 10 levels of indention like the above in a minimal example :)