ATTENTIONThis FlexSim Community Forum is read-only. Please post any new questions, ideas, or discussions to our new community (we call it Answers) at https://answers.flexsim.com/. Our new Question & Answer site brings a modern, mobile-friendly interface and more focus on getting answers quickly. There are a few differences between how our new Q&A community works vs. a classic, threaded-conversation-style forum like the one below, so be sure to read our Answers Best Practices. |
flexsim.com |
#1
|
||||
|
||||
Print information into output console (Debugging)
Sometimes if you run a model you like to have some specific information in special situations during your model run. In most cases this is for debugging reasons to check your logic.
If you do not want to use a screen message, because you do not want to stop the model and press buttons during the run (my other thread “Stop message with information (Debugging) ” in the Tips and Tricks Forum) I use the output console. To open the output console you can use the following code e.g. in a User Event at OnReset: // OPEN PLACE CLEAR OUTPUT CONSOLE mainmenucommand("View|Output Console"); windowmove(systemwindow(1), 2, 683, 1022, 190,1); clearconsole(); To print information into the output console you could now use code like: // PRINT INFORMATION INTO OUTPUT CONSOLE pr();pf(time());pt(strascii(9));pt(getname(current ));pt(strascii(9));pt("Label tomtheAtom: ");pf(getlabelnum(current,"tomtheAtom"));pt(strasc ii(9));pt("Label tomdavid: ");pf(getlabelnum(current,"tomdavid")); I always use the pr(); as first statement, because than I never have to think about if I already have this statement at the end somewhere else. So I recommend to have the pr(); at the beginning and not at the end of your code! I always print out the simulation time, the name of the object where the code is in. Sometimes I print out information like the item name or id, station, msgsendingobject, etc. Information I normally found in the triggers, because they are sometimes really handy. I always have the code in one line, to make it easy to make it to a comment (not execute the code any longer) by just putting // in front of the line. Normally if I take the code out I do it by e.g. //***TD to make it easy to find this code later. In situation where I have a lot of this print statements in my code or on different objects and I just like to debug one objects, I put a label on the object called “OutputConsole” and by assign a 0 or 1 to this label I switch the ‘debugging’ on and off. Than I need to put the following code in front of my above code: if(getlabelnum(current,"OutputConsole")) {pr();pf(time());pt(strascii(9));pt(getname(curren t));pt(strascii(9));pt("Label tomtheAtom: ");pf(getlabelnum(current,"tomtheAtom"));pt(strasc ii(9));pt("Label tomdavid: ");pf(getlabelnum(current,"tomdavid"));} Do not forget to put the {} brackets around your code . Normally I also have a global variable (“UserDebugMode”) for the Debugging to switch the whole print into the output console on and off if(UserDebugMode && getlabelnum(current,"OutputConsole")), because the print into the output console slows down your model and you do not want this if you like to make fast model runs. Have fun tom the (A)tom |
#2
|
||||
|
||||
Hi Tom,
Thanks for sharing your Debugging experience. Some tips are quite useful. I just have several comments. 1. I like the idea to include both global and individual flags for debug mode. Have you also considered to break down the Debugging mode into different levels. For example, FATAL_LEVEL, DEBUG_LEVEL, INFO_LEVEL, TRACE_LEVEL. By doing this, you may put important information in the lower level and always output them. And put more detailed information in the higher level and only output them when you want to trace or debug the program. 2. Personally I do not like the put a lot of pr();pt();pf() etc. It is just not a natural way to output sequential data. A better way would be using a output stream like in C++. But Flexscript does not support that kind of syntax. 3. It would be nice we can write a command to do this. Something like: debugoutput(out1,out2,out3,...) traceoutput(out1,out2,out3,...) etc. By doing this, we can hide all those pt(), pr() etc. in the command and will not worry about if we use pt() or pf() right. But there are two requirements in order to do this: a. Firstly, need a way to parse those parameters into correct data type, either numeric or text. b. Secondly, need to be able to pass arbitrary number of parameters. Unfortunately, Flexscript supports neither of them. 4. If you are using C++, there is a library called Log4cplus which is a good tool to debug and log your program. It can log to a file and support different log levels. I recommend to use it if you are using C++ in Flexsim. Again, thanks for the sharing your experience. Alan |
#3
|
||||
|
||||
Alan,
Thanks for giving feedback to my post I really appreciate this. When I wrote my above post, I did not wrote anything about how I did the print out in one command, because I change this from using one command to a lot of pt(); pf(); commands with version 4. I am not sure what might be the better way because I think this a personal decision. Anyway, before using the pt(); pf(); stuff, I used the following command: pt(concat(numtostring(time(),0,4),strascii(9),getn ame(current),strascii(9),getname(item),strascii(9) ,"tomtheAtom :",numtostring(tomtheAtom,0,4) ));pr(); The advantage might be that you only have two commands pt(concat()); pr(). The disadvantage is that you have a long concat() command and this is also limited to 25 parameters. You also have to take care of brackets, etc. This is why I changed to a lot pt() pf() commands and if you put them in one line, it is easy to ‘delete’ them with make them a comment (‘//’). I am not sure about the C++ stuff as you know, that I am not a programmer. But I agree there might be nice and easier ways to do so. No, I never thought about having different levels for the Debugging. But this might become handy but means on the other hand that you should take care of a good structure of your Debugging . Anyway, I hope with this thread we give other people some ideas how to do this stuff and maybe there is someone out there who has even better ideas then us and will post them. Take care tom the (A)tom P.S.: I have no idea why there is a space in the code "getn ame(current)" but I can not get rid of it. But if you copy the code to Flexsim everything seems to be correct .
__________________
tom the (A)tom: "We have solved our problems ... now we have to fight the solutions." |
#4
|
||||
|
||||
Hi Tom,
By saying using one command or function, I mean you do not need to worry about using pt() or pf() or pd(). You just provide whatever you want to print. The program take care that either it is a numeric or string. You know what will happen when you want to print a number but mistakenly using pt() command, or when you want to print a string but mistakenly using pf() command. Sometimes I find it is annoying to find such a bug. I guess it is because I am trying to debug relying on the printed information but later I find that information itself is not right. The point is that we could have a better way. I hope everybody can sharing their experience on this. But I agree with you that it is a personal issue. Being able to print to a file (I know there are fpt(), fpd() etc. But I assume people may want to using them to print out the model results.) is handy because we can use it to create a log when the model is running. I think it would be better to log the debug or other diagnostic information into a file instead of print out into the console window. By doing this, you can just run the model, and later check the log file to see if anything is wrong. By making log information into different levels, you may control how much information is printed out, and more importantly, it has a structured way and forces you to think about what information is critical for your model to be right and what information is trivial. Both Java and .Net has build-in log features now. Maybe Flexsim can also consider a build-in log feature for end-users? Tom, thank you to bring up this issue since every modeler would finally need to debug their model if they write any code. You always have some good stuff! :-) Regards, Alan |
#5
|
||||
|
||||
I hate writing the pt() pf() pr() pd() commands too. I've tried to talk Anthony into making a single command available in a future release that cuts down on the typing, but I can't seem to convince him. In the mean time, I guess we can always make our own User Command and add it to a User Library that gets loaded automatically with each new model so that it is always available. I have a place in the Downloads section just for these sort of User Command libraries. If either of you come up with a nice command, I hope you'll post it. The two types of pt() lines of code I find myself writing a lot are the following two:
pt("curobj="); pt(getname(curobj)); pr(); and pt("curval=");pf(curval);pr(); |
The Following User Says Thank You to Cliff King For This Useful Post: | ||
Brandon Peterson (10-08-2009) |
#6
|
||||
|
||||
What Alan is talking about is a mechanism in C++, where you don't even have to worry about typing when printing to an output stream. In C++ you can do something like:
double myval = 5.67; int myint = 7; string otherstring = "Hello world"; // here's the big c++ advantage: cout >> "my val is: " >> myval >> " myint: " >> myint >> " other string: " >> otherstring >> endline; And the printout is: my val is: 5.67 myint: 7 other string: Hello world Although I personally don't like it because I think the syntax doesn't follow the normal C++ style because they use some weird operator overloading, the advantage is that it automatically interprets the types of the variables, so you don't have to say, print an int, print a float, print text, you just say, print it. The reason I don't think that adding another command is going to make it much better is because any command that we create is going to necessarily follow some format, such as: print text, print value, print new line. But when I use prints, I often want to stuff as much on one line as I can so that I can see more information in the output console, so I don't want it to print a new line after each call to the command. But other people might be disappointed if we don't because they have to add their own pr(), or they have to specify an extra parameter in the command each time of whether or not to put a new line at the end. And some people, like Tom, want the new line at the beginning, so they can know that they're on a new line from the start and don't have to worry about putting the new line in later on in their code. And still you have the issue of having to distinguish between a string, float, or int, which if you want automatic, can only be done if the number of parameters is fixed. I know you might think I'm nit-picky, but I just don't think that adding an "auto print" command is really going to make it that much better, and I don't want to clutter the command list with new output printing commands that users will have to know. If you guys come up with a good example command, then maybe I'll change my mind, but right now I'm a skeptic. If we really want it better, we should try to do things like the cout >> ..., or perhaps the something like the c library's printf() where you specify an initial "format" string that tells what the parameters are that you are passing in. Unfortunately, though, none of those is going to happen in the near future because it would require a significant change to the way flexscript works. Last edited by Anthony Johnson; 10-04-2007 at 12:01 AM. |
#7
|
||||
|
||||
Interesting discussion!
I have this idea, that might help in a number of cases. What if you switch a node on an object, and when that node is set to 1, every nodefunction/triggercall is written to the output with name object, name node , time and parameters. Often you want to know if your code is fired, when exactly (which order) and if the parameters are passed correctly. So this piece of functionality would help you there without the need for writing your own statement anywhere and you are sure that you don't miss a piece of code. This might be build in the nodefunction command. (although I could imagine that the command gets slower so that you don't want to do it) Your comments please? Steven |
#8
|
||||
|
||||
Good discussion!
Typing two much seems not a big problem for me since I am used to using long but meaningful variable names. However, choosing wrong type of commands occasionally do give me a headache. There is no warning when you uses a wrong type. The only clue is that you notice a bug and then search what is wrong in a lot of pt, pr, pf, pd commands. I guess we just have to be more careful when we use those commands. The good thing is at least Flexsim won't crash when you using wrong command. Steven's idea may worth a try if it won't take significant effort. Knowing a program executed precisely as what you want is the first step of debugging. But instead of printing out to the console, how about printing out to a log file? Or we can choose to output to the console or to a log file by changing a switch value? Regards, Alan |
#9
|
||||
|
||||
Alan,
Just out of curiousity, what is the advantage of writing to a file? In my opinion there are 2 major set backs: 1 You always have to perform extra action to look at it, (find the file, open it) 2 and you are not sure if the log you are looking for is already written to the file, so you probably run longer than needed and if you want to save the output, simply copy paste it to a text file. Please forgive me if I'm looking cynical, that is not my intention as said before I'm just curious. Steven |
#10
|
||||
|
||||
Steven,
I understand you question and I am happy to share my experience. Probably the biggest moment that you want to output to files instead of console is when you run experiments, which I believe that every simulation should do in order to get good statistics. In that case, you can just run multiple scenario and multiple replications, output your log and results into files. Then later simply go to the directory to find them and check the results. I typically will create a folder under the same folder of the model with the same name as my model name (something like modelresults), then for each scenario and replication, I create one subfolder. The folder structure is something like:
About your second point, you may force to write into file immediately after the program execute the write command (In C/C++, there are commands for this). Yes, this may have some extra cost and may make simulation a little bit slower. But you can control different Log Levels which ultimately determine how much information you want to log. And You can also force immediately writing to file only when you are debugging your model. As Tom said, everybody has its own way to debug. As long as it works well for you, it is a good method. However, I am very happy that we can share our little experience and learn from each other. And I really think that unabling to write to multiple files is a big lacking feature of Flexscript. Thanks, Alan |
#11
|
||||
|
||||
Alan,
Ok I understand why you want to create multiple text files and ofcourse we have done that in our models too. What we usually do is using tables to store the data during a run and then put that table in a csv file (exporttable is a very nice function for that) And within Excel we write some vba to automatically import those CSV file and combine them in a result sheets. Lately we also used the DLL functionality quite a lot and within a DLL you can ofcourse use C++ and it is no problem creating multiple textfiles, or do special things, for instance I just created a piece of code that transfered an american CSV file into a german one. So maybe that is an approach to achieve what you want. But for hardcore debugging I still don't see the big advantage in using text files because I'm usually not interested in the big picture but only in 1 particular piece of code. But as you already said it, everybody has his own way of debugging. Regards, Steven |
The Following User Says Thank You to Steven Hamoen For This Useful Post: | ||
Brandon Peterson (10-08-2009) |
#12
|
||||
|
||||
Hi,
I just discover that you can print the triggername in the output console. I think is very useful (maybe long know by all the experienced users out there) When I write Debug code I have a table where I can switch the debug writing of certain areas in the model on and off. When I print out the code I always write the time , getname(current) and the trigger c. So I have a standard header for this an then I only need to add the other Information needed. if(gettablenum("Debug",2,1)==1) // is debugging switched on? { pd(time()); // time pr(); pt(getname(current)); // object name pr(); pt(getname(c)); // trigger name pr(); }
__________________
kind regards Nico. |
The Following User Says Thank You to Nico Zahn For This Useful Post: | ||
RalfGruber (09-12-2008) |