2017년 5월 15일 월요일

"For each" loop that starts at 1 apparently indexes list at 0


Hello -- I keep running into this list problem during development. 


Depending on the stage of my project, I have either had this error (a) arise consistently or (b) occasionally, with no apparent reason why it arises or stops being a problem, though I suspect it has to do with the exact context of when this loop is executed in the order of things. Sometimes it stops the app, sometimes it lets the app run but also generates an error message. The message appears to arise from Appinventor trying to access index#0, but I start my "For each" loop at 1.

I suspect I am using or setting up my list incorrectly.  Please see the attached screen capture (attachment 1) of the list. It is a list of sets of 4 comma-delimited numbers.

To simplify my diagnosis of the problem, I abstracted part of my actual loop as a test, but have it still drawing from the actual list. That is attachment 2.

--
Sorry, here are the screen captures.



--
for lists it's easier to use the for each item in list loop instead of the for each number from loop

--
for lists it's easier to use the for each item in list loop instead of the for each number from loop
Ironically, it was the "each item" loop that first gave me trouble, so I switched to this.
Also, below is the more detailed message I got telling me that it was trying to access item#0

Select list item: Attempt to get item number 0, of the list (1,0,1,1 1,1,4,1 4,1,5,1 5,1,5,0 4,1,4,2 4,2,6,2 6,2,6,3 6,3,4,3 4,3,3,3 3,3,3,2 3,2,2,2 2,2,2,5 2,5,3,5 3,5,5,5 5,5,5,6 5,6,6,6 6,6,6,7 4,3,4,4 4,4,7,4 7,4,7,7 2,5,1,5 1,5,1,6 1,6,2,6 *empty-string* *empty-string* *empty-string* *empty-string* *empty-string* *empty-string* *empty-string*). The minimum valid item number is 1.

--
you might want to provide a screenshot of your relevant blocks using the for each item in list block

--
It looks correct to me.
I don't understand what would cause that error message.

--
Scott is right. There's nothing in the code you've posted so far that would cause this error. In particular, to get the long list (1,0,1,1,1,1,4,1, ...) mentioned in the error message, some other code has to be appending together the sublists of your global maze list. So something is happening elsewhere in the program that's causing this error.  I suspect the companion error is showing up on the wrong block (though I don't understand why) and is misleading you as to the source of the error. 

If you want us to help you debug this, you'll have to send us the .aia file for your program so we can see the whole thing. 

--
I got it.

This is a case of sleight of hand, and misdirection.

See my attached DoIts of your usage versus how it should be done.
Your strings might look like sublists, but they are just strings.
Notice how they word-wrap only at the fourth elements, really just end-of-string.

If you want to encode a two dimensional array, use the parentheses as shown in the DoIt result
for my second case, and feed it into a table-from-csv block,
or just nest your make-a-list blocks like I did.

--
He used list from csv row on each item of the master list eg. "1,2,3,4" in the list which would return (1 2 3 4). 
That is what is so puzzling.

--
Try replacing the hardwired '23' in your for loop limit with 'length-of-list(maze)'

This is more robust, and not susceptible to counting errors or maze size changes.

If you fall off the end of the list you will get a non-list in the intermediate list item selection.


--
Okay, here's another hypothesis to throw against the wall...

You clicked the DoIt on the inner expression of the For loop, but the For loop had already completed,
leaving the list index pointing at item 24, which was empty, or worse,
the list index might not even have a value or might be 0 after the for loop has completed.

I work around this in procedures and other local scopes by inserting a global variable as a test point
to receive the local value, and to feed the calculation I want to monitor.

Running DoIt with a global variable will show me the result for the last loop.

P.S.  Counting to 23 is not fun.

--
Here's a sample of how you can use Do It inside a loop.

--

...and this is what you get if you don't use that global variable index and use the local for each number variable directly with a do it:
--
Abraham's hypotheses are getting us closer to an explanation, but Scott's experiment shows they don't yet explain David's original error message. There's a bug in AI2 (which is on my to-fix list) where unbound local variable getters encountered in a DoIt are treated as Gnu package names inside the Companion interpreter. This is the explanation for the "package $number" in Scott's error bubble. I still can't see a scenario in which David's index variable "testindex" (or "number" in Scott's case) acquires the value 0, which is necessary to explain the error observed by David. 
Thanks to Abraham for noticing that the printed representation of the global maze list is consistent with David's error bubble. I hadn't noticed the missing commas between the groups of four numbers, so my hypotheses about needing to append lists to get the list mentioned in the error bubble was just plain wrong. The printed representation of lists is leading us astray here. I will add to my to-fix list changing it so that the maze list displays as something like ["1,0,1,1", "1,1,4,1", "4,1,5,1", ...]. 

--
Thank you all for the assembled brain-power on this arcane problem!  I am following with interest, if not full and immediate comprehension in all instances.

I have started by cleaning up my code (disposing of floor sweepings, eliminating redundancies, and resolving general "what the heck was I thinking" type stuff). I will follow up with some of your recommendations as well.

In particular, I removed my null strings from the end (beyond element 23) of my Maze list.

Subsequently, if not consequently, the error has not cropped up. 

However, "I am but an egg" in this strange world. (Well, perhaps an omelette) and I am treating this like a car which misbehaves only when it is not being examined by a mechanic.

--
I'm tripping over what appears to be exactly the same issue - the Segment function evaluates Start to be "package $number" rather than a numeric value. Screenshot attached for more info (I hope it's self-explanatory). I'm stepping through a user-entered string of text to remove any non-valid characters (provided by a reference string) to produce a "cleaned" version (which is later tested for being null before going on to further processing).

I've pulled out DoIt responses to illustrate the trace. The variable name for Each is the default (I've tried using my own variable names to no effect, and globally-defined variables make no difference). The error message from either Segment is the same: "Error from Companion: The operation segment cannot accept the arguments: 123456 package $number 1".

I wondered whether you had had a chance to fix the issue you identified, and if so, why the error might persist. At the moment this is something of a deal-breaker for me - I can find no way around needing to step through the input text in order to clean it up.

Grateful for any feedback,


--
you can't debug local variables
see again ABG's sample of how you can use Do It inside a loop.

--

댓글 없음:

댓글 쓰기