0

How to find the length of a For loop? Here is a simple example:

For[i = 0, i < 4, i++, Print[i]]

0

1

2

3

How to find that there are in total 4 outputs using the //Length function or similar.

Let me take an example for comparison:

tb = Table[x, {x, 1, 5, 1}]
Length[tb]
5

The problem is that I have long For loop defined which is almost impossible to copy here, bcz its too complicated. There is an iteration

i = 0, i < 4, i++, Print[i]

defined inside the For loop. The actual problem in fractional, not integer as in the example above. I want know what is the length of the range between i = min and i = max just like we use "Length" for a table as shown above.

In the example above, obviously its 4, but how can we ask mathematica to find total number of outputs such as 4 for us.

SciJewel
  • 379
  • 1
  • 9
  • The parameters of the For loop tell you this explicitly: i = 0, i < 4, i++. Surely you're asking something more than that, but I'm not sure what. – lericr Oct 11 '22 at 20:49
  • I did not understand the question. Are you asking how to obtain the number of Prints from the evaluation of a cell ? If so that is independent of For and you could ask that question for any code. If you are asking how to programmatically get the number of iterations of a For loop that is held using Hold, then if the same structure as the one in the example you provided is being used, then one could use for example Hold[For[i = 0, i < 4, i++, Print[i]]][[1, 2, 2]]. The reason for the part choice can be visualized using For[i = 0, i < 4, i++, Print[i]] // Hold // TreeForm. – userrandrand Oct 11 '22 at 20:52
  • The For construct always produces Null, so there is no length to its output. If you're expecting your loop to terminate early, so that the iteration parameters cannot be used to calculate what you want directly, then you could just inspect i after the loop is finished, and determine the number of iterations that way. – lericr Oct 11 '22 at 20:54
  • 3
    Maybe what you want is your own counter: For[i = 0; counter = 0, i < 10, i += 3; counter++, Print[i]]. I altered your example to have a case where the loop iterator didn't increment by one, and therefore doesn't reflect the number of iterations. When the loop is done, just inspect counter. – lericr Oct 11 '22 at 20:59
  • By the way it is recommended to use Do instead of For (in which case the code I provided before does not work). To see whyDo is preferred there is this answer – userrandrand Oct 11 '22 at 20:59
  • 2
    I appreciate that you're probably trying to simplify your real problem to be able to ask the question more clearly, but as it stands, it doesn't really make much sense. I think giving us a bit more context--what you're actually trying to count--would help immensely. – lericr Oct 11 '22 at 21:01
  • Please see the appended part in body text. – SciJewel Oct 11 '22 at 21:19
  • 2
    (Length@Trace[For[...], TraceDepth -> 3] - 4)/3? If you want to predict the number of iterations, I doubt that is possible, since one may advance i in the body according to whatever condition, even WeatherData[First@CityData["Kathmandu"], "Temperature"]. – Michael E2 Oct 11 '22 at 22:21
  • 2
    Okay, I see the update, but I still don't understand why you can't just compute what you desire. If your iteration parameters are i = 0, i < 10, i+=.25, then the total number of iterations is 40. If you don't want to calculate manually, then the formula would be Celling[(max - min)/stepsize]. Or, if you want to do it while the for loop is running, use the counter idea I posted above. – lericr Oct 11 '22 at 22:22
  • 2
    Also, you keep using the term "outputs". Does your for loop actually generate results? Why can't you apply Length to that? – lericr Oct 11 '22 at 22:25
  • 1
    Actually, maybe that's your question. Are you asking how to get an output from a For loop? You could try something like this: output = {}; For[i = 0, i < 4, i++, AppendTo[output, i]]. Then output would be {0, 1, 2, 3}, and you can just apply Length to it. – lericr Oct 11 '22 at 22:27
  • 2
    You could also Sow/Reap: Reap[For[i = 0, i < 4, i++, Sow[i]]]. This gives {Null, {{0, 1, 2, 3}}} from which you can extract the "output" and check its length. – lericr Oct 11 '22 at 22:29
  • 2
    Internal`GetIteratorLength[{i, 0, 4}] assumes <=, not <. And Internal`GetIteratorLength[{i, 0, 4, 0.25}] - 1 won't always work either. – Michael E2 Oct 11 '22 at 22:33
  • 1
    @MichaelE2 Are these internal and developer context functions categorized somewhere or does one have to memorize them all ? Also how does one find them and how many different hidden contexts like this are there ? Maybe I should ask in a separate question if this has not already been asked (I know there is a question about which ones are useful). – userrandrand Oct 11 '22 at 22:39
  • 1
    @userrandrand See https://mathematica.stackexchange.com/questions/805/what-are-some-useful-undocumented-mathematica-functions. But I just remember that one. It may or may not be in that Q&A. – Michael E2 Oct 11 '22 at 22:41
  • 1
    @MichaelE2 yep i think that is the one I had in mind thanks. It's quite daunting to scroll through as some answers are specific to one context and others are on a bunch of hidden functions with hyperlinks. The one with Internal`GetIteratorLength is one that you posted it seems. – userrandrand Oct 11 '22 at 22:47
  • 1
    OP might also be interested in a progress bar – userrandrand Oct 11 '22 at 22:50

1 Answers1

1

Perhaps OP would like something to monitor the computation. I am guessing that is also why there was Print in the question. One could use a counter or Reap and Sow as @lericr suggested in the comments. If OP is willing to use Do instead of For then OP could use for example MonitorProgress from the resource function repository (Note : Resource functions might not be as reliable as native functions as they are not necessarily made by members of the Wolfram team, you can check the source notebook of the function for how it was made):

For example,

ResourceFunction["MonitorProgress"]@Do[i += 5; Pause[1], {i, 1, 8, 0.5}]

enter image description here

That image shows the total number of evaluations that will be needed next to Progress (15). With For it did not show the total number of computations.

One problem might be that you would have to visually register the total number of computations. That could be tedious to write down or difficult to see when the evaluation is fast. In that case one might want to consider the counter method by @lericr and maybe also monitor the counter with Monitor.

Resource functions can be stored locally on the computer with ResourceFunction["PersistResourceFunction"]. For example, after evaluating

ResourceFunction["PersistResourceFunction"]["MonitorProgress"]

One can then find MonitorProgress by just typing Mo and the function will appear from the autocomplete menu. Then it's as simple as MonitorProgress@Do[i += 5; Pause[1], {i, 1, 8, 0.5}]. That said, it is unclear to me what happens if in a future version of Mathematica a function has the same name.

userrandrand
  • 5,847
  • 6
  • 33