It is now clear yes, however looking things over I suspect there are easier ways. Going to post a little code here to clear up a few things.
Here is a simpler read_from_file. Bigarray and n are declared outside all handlers at the top of the script so that they are persistant script local variables.
No need to pass in values here because you set them all from inside the handler.
Code: Select all
on read_from_file
-- bigarray defined as script local at top, no declaration here. Makes it persistant.
-- handler locals are NOT persistant between calls.
#Define local variables
-- only need to declare if you have strict compilation mode on
-- n is used several places and needs to be persistant, so using it as a script local at the top
local counter, filedirectory, temp
#Clear output field "text"
put empty into field "text"
#Empty variables - livecode saves values
# since its declared as a script local, yes it needs to be cleared due to persistance
put empty into bigarray
put specialfolderpath("desktop") & "/box.txt" into filedirectory
#If there is a file, read the records from the file
if there is a file filedirectory then
-- could also do these three lines as a single command.. actually 4 lines. putting directly into temp
## put URL ("file:" & filedirectory) into temp
-- Depending on the file, might need to use "binfile:" instead of file, but from
-- your example, dont' think so
open file filedirectory
read from file filedirectory until EOF
close file filedirectory
put it into temp
put 0 into counter
-- repeat for each is VERy fast. saves a split and a double loop.
-- loop through once and place stuff into big array
repeat for each line tLine in temp
put item 1 of tLine into bigArray[counter][0]
put item 2 of tLine into bigArray[counter][1]
put item 3 of tLine into bigArray[counter][2]
add 1 to counter -- increment counter for next line
end repeat
else # If there is not a file, create a new empty file
-- unchanged. Could do a single line "put empty into url ("file:" & filedirectory) instead. Either works fine.
open file filedirectory for write -- creates a file
close file filedirectory -- closes/saves the file
end if
end read_from_file
Userinput works well, though notice the comment where the 2 arrays are put together. An array can be placed into an array so you don't have to loop through elements and tack them on by hand.
Code: Select all
on user_input
#Define local variables
local userinput
#Redefine "n" with bigarray as the subject - CLUNKY ENGLISH
-- since you start your array at 0 this works well without any extra hoops. Nice!
put the number of lines of (the keys of bigarray) into n
#Get new user input
ask "Where have you just been running?"
put it into userinput[0]
ask "In kilometres, how far did you run?"
put it into userinput[1]
ask "In minutes, how long did it take you to run those "&userinput[1]&" kilometres?"
put it into userinput[2]
-- No need for repeat loop here, you can put an array into an array element directly.
#Put the user input at the bottom of the array
put userinput into bigarray[n]
#The value of n must be increased by 1, as the number of records has been increased by 1
add 1 to n
end user_input
Having read through more of the code i'm struck by the thought that -- in this particular case-- arrays are not necessarily the best option. A flat file would work extremely well, and then when you need to do your sorts you can use the livecode abilities to get to the desired results pretty easy.
So for example, if you adjust your file format so that its a flat file with 3 items
location,distance,time
location,distance,time
its easy enough to add your new location distance time at the end of the file
If you have all your lines in a variable after loading from the file you can do
put the number of lines in myVariable into n
put theNewData into line (n + 1) of myVariable -- there are other ways do do this of course.
THen for your sorts.. distance is easy.
sort lines of myVariable descending numeric by item 2 of each -- will sort by item 2
For the speed use a temporary variable. Something along these lines. So if myVariable has the lines of data, items delimited by comma, rows by cr then
Code: Select all
put empty into temp
repeat for each line tLine in myVariable
put tLIne & comma & yourspeedcalculations go here & cr after temp
end repeat
delete the last char of temp
sort lines of temp descending numeric by item 4 of each
At this point temp contains your data sorted by speed (item 4 of each line) and all you have to do is grab the top line (or lines if you wish) (if there are that many) and use them as you see fit.
A complete rewrite of the script is here. Forgive me if you just really want to use arrays for this, and ignore the following code.
Code: Select all
local bigVar,n,filedirectory -- all these are used in various handlers, declare once at top for persistance.
on mouseUp
read_from_file
user_input
Sort_and_display_highest_distances n, bigarray, temp
display_fastest_speed
write_to_file
end mouseup
on read_from_file
local counter, temp
#Clear output field "text"
put empty into field "text"
put specialfolderpath("desktop") & "/box.txt" into filedirectory
#If there is a file, read the records from the file
if (there is a file filedirectory) then
put URL ("file:" & filedirectory) into bigVar
else
-- no need to create a file here, it will be created by write_to_file
put empty into bigVar
end if
end read_from_file
on user_input
-- Could calculate speed as part of the user input in this handler
-- it would end up being more efficient that way
-- so that only a simple sort, no loops would be necessary
-- to locate the fastest speed. Speed could be stored in the file as an additional item.
#Define local variables
local userinput, distance
put the number of lines of bigVar into n
#Get new user input
ask "Where have you just been running?"
put it & comma into userinput -- build up a string of items and tack it on to the end of bigVar which is the file contents
ask "In kilometres, how far did you run?"
put it into distance
put distance & comma after userinput
ask "In minutes, how long did it take you to run those "& distance &" kilometres?"
put it after userinput
-- No need for repeat loop here, you can put an array into an array element directly.
#Put the user input at the bottom of the array
if bigVar is empty then
put userinput into bigVar -- if its the first entry, no line break
else
put cr & userInput after bigVar -- else add line break
end if
#The value of n must be increased by 1, as the number of records has been increased by 1
add 1 to n
end user_input
on Sort_and_display_highest_distances
#Clear temp value
put empty into temp
sort lines of bigVar descending numeric by item 2 of each -- sorts by distance
if the number of lines in bigVar >= 5 then -- handle an empty or nearly empty file
put line 1 to 5 of bigVar into temp -- if more than 5 lines grab the first 5 after sort
else
put bigVar into temp -- otherwise grab em all
end if
-- loop for the number of lines in temp. Will be 1-5
put "These are the top" & the number of lines in temp & " distances you have ever ran:" & cr into line 1 of field "text"
repeat for each line tLine in temp
put "At "& item 1 of tLine &" you ran "& item 2 of tLine &" kilometres." & cr after field "text"
end repeat
end Sort_and_display_highest_distances
on display_fastest_speed temp, n, bigarray
#Clear temp variable value
put empty into temp
#Define local variables
-- local Kmphour, runlocation -- not needed this way
repeat for each line tLine in bigVar
-- do calcs and build flat data in temp variable
-- check to make sure i didn't munge your calculation
put tLine & comma & item 2 of tLine /(item 3 of tLine / 60) & cr after temp
end repeat
-- after loop, item 4 of each line contains the speed
delete the last char of temp -- remove extraneous line break
sort lines of temp numeric descending by item 4 of each -- the first line should contain the fastest time now
#Display the fastest speed ran
-- use the items in the first line of temp to display results
put cr & "The fastest speed at which you have ran is "& item 4 line 1 of temp & " kilometres per hour. This was at "& item 1 line 1 of temp &"." & cr after field "text"
end display_fastest_speed
on write_to_file
put bigVar into URL ("file:" & filedirectory)
end write_to_file
EDIT:
Last comment on this.. If you are going to have large amounts of data you might consider shifting to a simple sqlite database for storage. It would work very well. To get your top 5 distances select from the database order by that field descending numeric, and set a limit to however many top entries you wish to pull out. You could store times in the database also to make selecting top times easy. (for that you can order by speed, limit 1, or I believe you can use the max() database function to locate the entry in question)
EDIT2: edited rewrite slightly to correct ask text.