|
|
|||||||
While I have written several scripts I still need enlightment on how a couple of things work, and I come to you great gurus here to help me understand. First is multi-dimensional array's. How do use them, and where are they appropriate? Second is seeding of a RND, when would be the appropriate time to use them, and why would you seed a RND. Thanks. |
||||||||
|
|
|||||||
Multidimensional arrays, the simplest multi-dim arrays are. a 5x5 grid Code:
Take the values 3,C and you get 8 this is a 2 dimensional array, and the most common used. You can represent this type of an array two ways inside of KiXtart. Code:
or Code:
both ways have their advantages / disadvantages. The major disadvantage of example one, is that kix can only redim the last multi-dim value. But in example 2 you do not have that limitation. Example 2 on the other hand take a good deal bit more code to build the array, but i feel it is a good trade off for a more flexible setup. |
||||||||
|
|
|||||||
and example using a multidimensional array. you have a text file with the following data in it. Code:
Code:
when you print 2,3 you should get "8" |
||||||||
|
|
|||||||
Quote: you will always want to seed a RND, because you see... RND is not realt all that random. run the following code. Code:
you get this....? Code:
and... you get it everytime that you will run it too. now, run this. Code: SRND(@msecs) that should shake things up enough to get... "random numbers". but if you always use the same seed, you will always get the same random numbers. |
||||||||
|
|
|||||||
Re: RND so if I am using RND to generate a number in an UDF, will it generate the same RND each time I call the UDF, or will it generate the same RND each time I run the script? |
||||||||
|
|
|||||||
Quote: You need to seed it because it is a pseudo-random number generator, not a random number generator. The RNG (random number generator) works by taking a start value, pushing it through a complex calculation and ending up with another number. The problem is that first number. There is absolutely no random event that your PC can get to to establish that first number. This means that it is up to you to find a random-ish number. The other reason for having a seed is that a predictable stream of "random" number might be desirable. You might want to get the same numbers every time you run the program. I use this for password generation. The BIOS on our PCs is locked down with a password. Unfortunately somtimes we need to divulge this password to employees or third party engineers so we cannot use a common password. We could allocate random passwords and record them on a spreadsheet, but that would be an administrative nightmare. Instead we generate random passwords using a hash of the PC serial number as a seed. This means we can always regenerate the password by typing the PC serial number into the password program. The local administrator password is managed in the same way. Quote: The RNG state is in the KiXtart session scope. This means that you only need to seed the RNG once per kix32.exe execution. Even if you run a number of scripts e.g. "kix32.exe script1.kix script2.kix script3.kix" you will only need to seed the RNG in script1.kix The RNG is pretty basic, and one of it's flaws is that the first number returned is not very random at all. It is good practice to discard the first number after seeding the RNG. Also, don't seed the RNG in the UDF as that will restart the pseudo-RNG sequence making it even less random! Finally, don't used @MSECS alone to seed the RNG. Choose something else. @MSECS has a range of 0-999 which means that your "random" numbers will only be from a selection of a thousand possible results. We are moving from random numbers towards predictable! @TICKS is a better option for a simple seed. A reasonable (if not perfect) simple seed might be: Code: SRND(@TICKS*1000+@MSECS) |
||||||||
|
|
|||||||
Ok, so now I understand seeding. I am still absorbing the info on multi-dimensional arrays. Have not figured out where I would use them yet, but that could be just because I have not tried to use a script that would have use of them. I appreciate your explanations, it is making me a better scripter ever so slowly. |
||||||||
|
|
|||||||
Back to multi dim arrays. I now have a need for one of these, but need to verify my logic thought with you before I really get lost. With an array that is already populated with values can I add the second dimenstion to it? Assuming I have an array of 6 values, and I want to associate 6 other values to that value (a 6x6 array) would I write it something like this... Code:
What about 3 dimensional arrays? Can they be done? and how would you visualize it. I am thinking of an array that might be 6x6x3 so that you now have x,y,x axis to work with. Or is it easier to make two seperate 2 dimensional arrays that reference the other? Last question would be, which is read first down or across (x or y axis) Thanks. |
||||||||
|
|
|||||||
A simple way to picture a multi-dimensional array might be: $X[0,0,0] = Row, Col, Page $X[0,0,0,0] = Row, Col, Page, Book $X[0,0,0,0,0] = Row, Col, Page, Book, Shelf and so on.. Since you are desining the code, the row/col association can be anything you like - whatever makes sense to you. $X[0,0,0,0,0] = Shelf, Book, Page, Col, Row is NOT the SAME as above, but is equivelent, as long as you maintain the same references throughout your program. Glenn |
||||||||
|
|
|||||||
Thanks Glenn I get the dimensional aspect now. However when building array, can I take an already defined array and make it multidimensional? If so how do you add the second dimension? I assume (hopefully I understand it correctly) that Kix only will allow you to change the last dimension. So if I was to have 3 dimension array I could only change the 3rd dimension. |
||||||||
|
|
|||||||
Um, not exactly.. The ReDim function changes the array size declaration, optionally preserving the existing data. I don't think it allows you to add a dimension - it changes the size of an array. If your array already has 2 or more dimensions, you've reached the Twilight Zone and can only change the size of the last dimension. Arrays of Arrays, as was noted, are much more flexible in terms of resizing, but require a bit more skill and coding to manipulate. So, if your array was 10 rows of 3 columns, you could add columns (the last dimension) but not rows. If you structured it as 3 columns with 10 rows, you could add rows, but not columns. Very often, we create the array with the maximum number of cells we thnik we will need, and then use ReDim to resize it down to the actual number of required cells. For example, if I DIM $X[100] and then populate only 37 elements, if I later scan the array, I have to reference each element (using another counter variable) and constantly test for valid data. However, if I know that I only added 37 elements (0-36, remember - it's 0-based), I can resize my array - (assuming the counter var $Ctr post-incremented and is at 37) ReDim Preserve $X[$Ctr - 1] Then I could us a For Each loop to enumerate the elements of the array: For Each $Element in $X ; note the array is $X, not $X[] $Element ? Next Glenn |
||||||||
|
|
|||||||
So can I do this... Code:
|
||||||||
|
|
|||||||
No - wrong on 2 counts.. once you define an array with a spcific number of dimensions, you can't add or remove dimensions, you can only change the size of the array. So, your ReDim could increase or decrease the number of ELEMENTS (cells) in the array, but not the number of dimensions. A one-dimensional array is a collection of rows with 1 column. You can only change the number of rows, not columns. Secondly, [x][y] isn't a two-dimensional array, it's an array of arrays. Think of this: $X = "a", "b", "c" This creates and populates an array, with element 0 containing "a" and element 2 containing "c" So Dim $X[3] $X[0] = "a", "b", "c" $X[1] = "d", "e", "f" $X[2] = "g", "h", "i" Each element of the array "$X" contains yet another array, so you can specify $V = $X[1][1] 'v=' $V ? and $V will contain "e" - the second element of the $X array, and the second element of the array in that element. As you can see, it can get confusing. Copy the above into a test script.. Then add: $SubArray = $X[2] For Each $Element in $SubArray 'SubElement=' $Element ? Next That should make it clear. Then, you could actually re-dim $SubArray, and reassign it to your parent array. ReDim Preserve $SubArray[3] $SubArray[3] = "z" $X[2] = $SubArray '1: ' UBound($X[1]) ? '2: ' UBound($X[2]) ? You can see that the sub-arrays in element 1 and 2 of the parent array have different values now. Glenn |
||||||||
|
|
|||||||
Think I am getting it now. My goal with this is to get some user input ex: Your Name Then present them with a set of options that will be associated to each person that entered their name. The that I am reading it now is to build an array with each of the "names" as my columns, and then assign the options to a new row. So that it would look something like this $Array[0] = "Name1","Name2","Name3" etc... $Array[1] = 0, 3, 4 etc... $Array[2] = "C","F","J" etc... Then when I need to find what option Name3 picked I would $ = $Array[2][2][1] and would get Name3 4 F So in closing (I hope) My First DIM statement is the number Rows that I need. After that Each [] that I add to the end of $ARRAY[] references the Row that I am reading from. I.E. $Array[0][1][2][3][4][5] = Row 0 1 2 3 4 5 etc... The Columns will be defined by the data that is entered into each row. Then as I gather the options selected by the user I would do a $Array[2] = $Array[2] + $Option to add another column to this array element If this is all correct my last question would be can you have unequal columns in each row? |
||||||||
|
|
|||||||
You still don't seem to understand the difference between a multi-dimensinal array and an array of arrays. These are two distinct beasts. An Excel spreadsheet for exampel is a two-dimensional array, consisting of rows and columns.You'd reference it in KiXtart like this: Code:
A three-dimensional array is like a cube or multiple layers of two-dimensional arrays, like the tabs in Excel, where each tab references one dimension. Thus Code:
In an array of arrays, each element in an array is an array by itself, not a single value. Code:
$a[1] now references variable $b, which is an array. $a[1][2] references the second element in variable $b which is in $a[1]. |
||||||||
|
|
|||||||
Okay so I am showing the use of an array of arrays. Was the logic process correct? Can you show me using my example how to do it correctly, as there seems to be something that I am missing completly. Sealeopard, normally I understand exactly what you are saying, but you completly lost me that time. Maybe it is the way that I am describing what I am doing. I would post code, but I haven't done any yet. This is the very beginning of coding. Thanks. |
||||||||
|
|
|||||||
Paste the sample code snippets into a file and run them.. then play with them and see what changes. Experiment for a while, and don't be afraid to break the toys. Glenn PS - I probably have more "x.kix" and similar files in my Misc folder than all my scripts and UDFs combined, just examples to see how code works... |
||||||||
|
|
|||||||
I think I get the array of array deal (THINK). This Code: Then as I gather the options selected by the user I would do a Should be Code:
Is that correct? And what about the rest of my logic, as far as I can tell from what you are saying here it is correct. |
||||||||
|
|
|||||||
You're now introducing circular references of arrays. Please get your understanding of a simple array straight first. To add a column to an array, you use REDIM. For example, an array with three rows and three columns is defined as DIM $a[2,2]. To add another columns to it, you'd do a REDIM $a[2,3], if you want to preserve the existing array element contents you'd use PRESERVE, thus REDIM PRESERVE $a[2,3]. Please experiment with this first to fully understand it. You now have a total of three rows and four columns. Arrays beyond two dimensions work the same way. Imagine an array as a collections ofindividual data elements, e.g. wooden cubes. A variable is a single wooden cube. A row or column of wooden cubes would represent a one-dimensional array, with each cube being a single data element. Now add a second ropw of wooden cubes to the first one, you now have a two-dimensional array of wooden cubes. Then, put another two rows of cubes onto the existing ones, you now have a structure resembling a cube by itself, e.g. two cubes long, two cubes high, and two cubes in depth. Now comes the tricky, or easy part. Instead of considering a single cube as a data element assume that the cube itself is made of a number of red wooden cubes, e.g. a 3x3x3 cube of red wooden cubes. This is an array-of-arrays. I'm giving up now, I have no idea how to simplify it even more, maybe start with a drawing? You MUST understand the basics of arrays before you can start using them effectively. |
||||||||
|
|
|||||||
Quote: You might be correct, but it's hard to tell I think that you are over-complicating the process because you are new to arrays and how to use them. Take a step back, and describe for us exactly what it is you are trying to do. We can suggest a solution which might include arrays. Or it might not! For example, after understanding what you want to do we may well suggest that you would be better off writing the data directly to an INI file rather than storing it in an array. |
||||||||
|
|
|||||||
Quote: I have form that asks the user to enter a series of names from 2 - 6, the number of names is random and could change everytime the script is used. After that form information is submitted I am storing the names in an array $Names[5] I then present another form that has options on it. On the options page there are 4 sets of radio buttons where each will represent a single value to be stored. One set of checkboxes that will result in a single value to be stored. The options that are checked will be individual to each of the users set in the first form. My thought was that an array that is 6x5 would be perfect for this as I would have a single array that would hold the user name and the options selected per user. Hope that helps. The cube analogy is helping. I will be drawing it out on paper to make sure that I am getting it. To this point in all of my scripts I have alway's used a flat array (1 dimension). |
||||||||
|
|
|||||||
You have a 5x4 array like this: Code:
If you'd like to solve this as an array of arrays, then you have a options array $op[3] and a names array $nm[6,1] similar to this: Code:
The code would look like this: Code:
Some people consider the array-of-arrays more elegant, however, it requres more care in pulling data. Please be advised that this code is a figment of my imagination and has not undergone any testing whatsoever and might therefore not work. It is for illustration purposes only. |
||||||||
|
|
|||||||
Quote: I agree and hence why I have most here shaking their head at me. If I am understanding the explanation that Jens provided earlier.. For a 2 Dimension array... Dim the array as follows Dim $Array[Rows,Columns] Once you declare the array you can not change the number of Rows but with a Redim you can change the number of columns. In my particular use I would Code: Dim $Array[$index,5] I would then be able to assign to $array[0,0] the name of the first user, $array[0,1] would be the first option, $array[0,2] ... $array[0,5] for the remaining options. Then I would repeat the process for each user moving to the next row $array[1,0] .... So my data would end up looking like this.... Name1 Opt1 Opt2 Opt3 Opt4 Opt5 Name2 Opt1 Opt2 Opt3 Opt4 Opt5 This would then provide a 2 dimensional array instead of using an array of array's. If this is a correct understanding of how it works, then I have at least moved a bit forward. Now 3 dimensions.... Well lets just wait for awhile, I don't see a need for them at this point in my script. |
||||||||
|
|
|||||||
Yes, that's exactly whay I tried to convey. Now, a 3-D array is just like a 2D-array, but younow add yet another layer/dimension to it. For exampel, space coordinates are 3-D, you need length, width, height, to descirbe a location/point. In case of a 4-D array, you could consider the fourth dimension beigntime, you now need to also describe the time from when you want toe element. Anyway, hope you get the gist of it. |
||||||||
|
|
|||||||
Thank you. I think the problem was my mixing up Array of Array's and MultiDim. Once I looked at MultiDim like a database record it all made sense. I really appreciate everyones understanding in this. |
||||||||
|
|
|||||||
A database table is still two-dimensional, In my book, multi-dimensional starts when you go boyond two dimensions. Now, an OLAP cube in the data warehouse world, that's where the fun starts |
||||||||
|
|
|||||||
two dimensional is a multi-dimensional as in my book multi counts for everything else than single. |
||||||||
|
|
|||||||
Quote from http://www.yourdictionary.com/ahd/m/m0473300.html Quote: Two is several so imho two dimensions is also multidimensional. |
||||||||
|
|
|||||||
You obviously did not look up "several". Quote: http://www.yourdictionary.com/ahd/s/s0296200.html |
||||||||
|
|
|||||||
And to go back to the topic for just a second.... When using an array ex: [3,5], if you do a Ubound($array) What value would be returned. |
||||||||
|
|
|||||||
hmm... I think manual says it... it was the right most, or was it left most... hard to remember. |
||||||||
|
|
|||||||
Again you are correct Quote: So I geuss I would need to ask is it 0 based? With the default being 1 I would say not, but never hurts to ask. |
||||||||
|
|
|||||||
try it out logic indeed dictates that it would be from 1 up. first dimension and so on, right? on the other hand, with that logic array element 0 wouldn't exist. |
||||||||
|
|
|||||||
I have coded it that way (with a 1 for the first dimension) but have not completed enough code to test it really. Maybe by tomorrow. |