Re: [fpc-pascal] sorting and merging array of records
On 1/10/2012 16:41, Sven Barth wrote: On 10.01.2012 22:02, waldo kitty wrote: TList? hummm... better? smaller? faster? easier to use? small memory footprint? i'm game to try things as long as it works in the end ;) TList is basically an array wrapped in a class (though I would suggest TFPList as that is faster than TList (TList is based on TFPList)). Both can be found in unit Classes. The following you need to know: T(FP)List works on pointers, thus you need to 1. declare a pointer type to your record type (e.g. Pthree_line_data = ^three_line_data) 2. allocate a Pthree_line_data variable if you want to add a new entry to the list i tried this but could only get so far and then not further so i backed up and punted the ball... now i'm trying this with a sortedcollection and while i can apparently insert items, i haven't figured out how to access them and print their contents... unless their contents are garbage like the following prints out... program satsort; uses {$IFDEF DEBUG}heaptrc,{$ENDIF}objects,math,crt,dos; type vector = array [1..4] of double; cat_nbr= string[5]; sat_name = string[25]; line_data = string[69]; two_line = array [1..2] of line_data; PTLERec= ^TTLERec; TTLERec= record satname : sat_name; satdata : two_line; catnbr : cat_nbr; epoch : double; end; TTLERecObj = object(TObject) TLEData : PTLERec; constructor Init; destructor Done; virtual; end; constructor TTLERecObj.Init; begin new(TLEData); end; destructor TTLERecObj.Done; begin dispose(TLEData); end; type PTLECollection = ^TTLECollection; TTLECollection = object(TSortedCollection) TLERec : TTLERecObj; function Compare(Key1, Key2 : Pointer): longint; virtual; end; function TTLECollection.Compare(key1, key2: pointer): longint; begin if PTLERec(key1)^.catnbr = PTLERec(key2)^.catnbr then compare := 0 else if PTLERec(key1)^.catnbr PTLERec(key2)^.catnbr then compare := -1 else compare := 1; end; const data_type : byte = 3; // max_sats = {$IFDEF FPC}65536{$ELSE}250{$ENDIF}; var data_drive,data_dir, work_drive,work_dir : string; UTC_offset : double; DST : boolean; fsat,fobs: text; obs_name : string[25]; piss : vector; gigo : char; my_sats : word; aTLERec : PTLERec; aTLECollection : PTLECollection; [...] Function Input_Satellite_List(var aInputFile: TextFile) : word; var data: PTLERec; sat_cnt : word; i,x : longint; begin sat_cnt := 0; while not EOF(aInputFile) do begin new(data); Readln(aInputFile,data^.satname); Readln(aInputFile,data^.satdata[1]); Readln(aInputFile,data^.satdata[2]); data^.catnbr := Copy(data^.satdata[1],3,5); data^.epoch := Real_Value(data^.satdata[1],19,14); inc(sat_cnt); aTLECollection^.insert(data); dispose(data); {$IFDEF DEBUG} writeln(PTLERec(aTLECollection)^.satname); writeln(PTLERec(aTLECollection)^.satdata[1]); writeln(PTLERec(aTLECollection)^.satdata[2]); writeln(PTLERec(aTLECollection)^.catnbr); writeln(PTLERec(aTLECollection)^.epoch); {$ENDIF} end; {while not EOF} Input_Satellite_List := sat_cnt; end; {Procedure Input Satellite List} ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] sorting and merging array of records
Am 11.01.2012 09:27, schrieb waldo kitty: On 1/10/2012 16:41, Sven Barth wrote: On 10.01.2012 22:02, waldo kitty wrote: TList? hummm... better? smaller? faster? easier to use? small memory footprint? i'm game to try things as long as it works in the end ;) TList is basically an array wrapped in a class (though I would suggest TFPList as that is faster than TList (TList is based on TFPList)). Both can be found in unit Classes. The following you need to know: T(FP)List works on pointers, thus you need to 1. declare a pointer type to your record type (e.g. Pthree_line_data = ^three_line_data) 2. allocate a Pthree_line_data variable if you want to add a new entry to the list i tried this but could only get so far and then not further so i backed up and punted the ball... now i'm trying this with a sortedcollection and while i can apparently insert items, i haven't figured out how to access them and print their contents... unless their contents are garbage like the following prints out... You know that you're handling with pointer here as well? ;) I never used TP's T(Sorted)Collection, so the following are mostly guesses, but I'll try. Here is how you should (in my opinion) access an item at index Idx in the list: var rec: PTLERec; begin ... rec := PTLERec(aTLECollection^.At(Idx)); // You can now access the record's contents by dereferencing: if rec^.catnbr ... then ... end; function TTLECollection.Compare(key1, key2: pointer): longint; begin if PTLERec(key1)^.catnbr = PTLERec(key2)^.catnbr then compare := 0 else if PTLERec(key1)^.catnbr PTLERec(key2)^.catnbr then compare := -1 else compare := 1; end; You declared TTLERec.catnbr as a string, so you can't use or for comparison. You'd need to convert it to a ordinal type first. Function Input_Satellite_List(var aInputFile: TextFile) : word; var data : PTLERec; sat_cnt : word; i,x : longint; begin sat_cnt := 0; while not EOF(aInputFile) do begin new(data); Readln(aInputFile,data^.satname); Readln(aInputFile,data^.satdata[1]); Readln(aInputFile,data^.satdata[2]); data^.catnbr := Copy(data^.satdata[1],3,5); data^.epoch := Real_Value(data^.satdata[1],19,14); inc(sat_cnt); aTLECollection^.insert(data); dispose(data); Don't do this! You'll free the memory you allocated for your record. The collection will only contain a pointer to this data! (Many of the rules I mentioned for T(FP)List apply here as well) {$IFDEF DEBUG} writeln(PTLERec(aTLECollection)^.satname); writeln(PTLERec(aTLECollection)^.satdata[1]); writeln(PTLERec(aTLECollection)^.satdata[2]); writeln(PTLERec(aTLECollection)^.catnbr); writeln(PTLERec(aTLECollection)^.epoch); {$ENDIF} Ehm... you know that it can't work if you cast a TTLECollection pointer to a TTLERec pointer? These are two different structures. No wonder why you only see garbage as you most likely see the contents of the Collection (which consists mostly of pointers). See at the top of the mail how you'd access the contents correctly. Normally I'd suggest you to simply guery the Count - 1th item, but in this exact case you'd need to search the item again as you're using a sorting list and the last inserted item might not be at the last position of the list (as Insert maintains the order of the list). Regards, Sven ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
[fpc-pascal] Redis client for FPC
Hello, Does anyone know of a Redis client for FPC (and open source) ? Another question: If I need to implement it, how would you do it regarding dataset ? I'm not sure that it is suited for the task, what do you think ? Thanks, Ido ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Redis client for FPC
On Wed, 11 Jan 2012, ik wrote: Hello, Does anyone know of a Redis client for FPC (and open source) ? Another question: If I need to implement it, how would you do it regarding dataset ? I'm not sure that it is suited for the task, what do you think ? No. Dataset relies on a tabular format, so not key=value. The fact that each value in a column has the same type and/or length is also a must. Michael. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Redis client for FPC
On Wed, Jan 11, 2012 at 18:54, michael.vancann...@wisa.be wrote: On Wed, 11 Jan 2012, ik wrote: Hello, Does anyone know of a Redis client for FPC (and open source) ? Another question: If I need to implement it, how would you do it regarding dataset ? I'm not sure that it is suited for the task, what do you think ? No. Dataset relies on a tabular format, so not key=value. The fact that each value in a column has the same type and/or length is also a must. Here is a new request for the new year/version of FPC :) Additional way beside dataset to control databases, even if they are not table/structure based. I think that if it will be above dataset, so dataset will be inheriting from it, it will be easier to write components that are data driven, but not limited to dataset. Michael. Ido __**_ fpc-pascal maillist - fpc-pascal@lists.freepascal.**orgfpc-pascal@lists.freepascal.org http://lists.freepascal.org/**mailman/listinfo/fpc-pascalhttp://lists.freepascal.org/mailman/listinfo/fpc-pascal ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Redis client for FPC
On Wed, Jan 11, 2012 at 15:32, ik ido...@gmail.com wrote: Here is a new request for the new year/version of FPC :) Additional way beside dataset to control databases, even if they are not table/structure based. A Redis specialized TDatasource Descendant Could work. Is there any problem with this aproach? ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Redis client for FPC
On Wed, Jan 11, 2012 at 21:36, Daniel Gaspary dgasp...@gmail.com wrote: On Wed, Jan 11, 2012 at 15:32, ik ido...@gmail.com wrote: Here is a new request for the new year/version of FPC :) Additional way beside dataset to control databases, even if they are not table/structure based. A Redis specialized TDatasource Descendant Could work. Is there any problem with this aproach? Redis is a bit more then key=value It contains groups, sets and more. I for example try to use it for now (the reason for my original question) as message queue, that can also be made with it. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal Ido ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] How to get path to current theme icons on linux?
This is exactly what I needed! Thanks to all 2012/1/11 cobines cobi...@gmail.com: Take a look at the unit here: http://doublecmd.svn.sourceforge.net/viewvc/doublecmd/trunk/src/platform/unix/uunixicontheme.pas -- cobines ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] sorting and merging array of records
On 1/11/2012 11:11, Sven Barth wrote: Am 11.01.2012 09:27, schrieb waldo kitty: i tried this but could only get so far and then not further so i backed up and punted the ball... now i'm trying this with a sortedcollection and while i can apparently insert items, i haven't figured out how to access them and print their contents... unless their contents are garbage like the following prints out... You know that you're handling with pointer here as well? ;) yes... I never used TP's T(Sorted)Collection, so the following are mostly guesses, but I'll try. thanks... i finally got something working before reading your message... i ended up digging out my old Tom Swan Mastering Turbo Pascal 6 book... there was a clear example that i was able to follow with a few tweaks for my data structure... it was easier to flip the pages back and forth while looking than to keep trying to jump between different windows on the screen... gimme a nice paperback book like this one any day! ;) in any case, i'm needing a touch more assistance if you or anyone else are willing to give it... code at the end... questions coming up now... 1. right now the compare is working on the catalog number (TTLERec.catnbr) and with duplicates:=FALSE there are no duplicates... however, i need to be able to choose which record to keep when there is a duplicate catnbr but the epoch (TTLERec.epoch) is different... right now it is throwing out all but the first... how can i tell it how to decide which one to throw away? i saw earlier that one of the parent objects has neat functions like AtPut which would easily allow me to overwrite an existing record that's too old... i just don't know if i can use that in the middle of an insert or a search or just exactly where i would even put code to do this... 2. something else i'm running into is with duplicates:=FALSE, there's a whole bucket load of records that are not disposed of when i wipe out the collection... heaptrc hollers right nasty to me about'em on exit... i can only assume that these are the duplicates but i don't understand why they are still hanging around if insert or add threw them away already :/ [TRIM] data^.catnbr := Copy(data^.satdata[1],3,5); data^.epoch := Real_Value(data^.satdata[1],19,14); inc(sat_cnt); aTLECollection^.insert(data); dispose(data); Don't do this! You'll free the memory you allocated for your record. The collection will only contain a pointer to this data! (Many of the rules I mentioned for T(FP)List apply here as well) uh? for some reason i thought that the insert was copying the data to a place and then setting the pointer to there for the collection... i tried with and without the dispose(data) but it still looked the same... of course i was tired and might not have been looking at the right writeln debug output... writeln(PTLERec(aTLECollection)^.catnbr); writeln(PTLERec(aTLECollection)^.epoch); {$ENDIF} Ehm... you know that it can't work if you cast a TTLECollection pointer to a TTLERec pointer? These are two different structures. No wonder why you only see garbage as you most likely see the contents of the Collection (which consists mostly of pointers). i told ya i get confused with pointers at times :lol: i know it is a pointer but what's under it and how to get to it? :laugh: and with no easily found clear examples like i was able to find in my book, well... i should mention that it was also like very early in the morning and i hadn't slept yet ;) like i wrote above, i have it working now... i just need to get the duplicates elimination to keep the right one... this thing is fast, too! one goal accomplished :P See at the top of the mail how you'd access the contents correctly. Normally I'd suggest you to simply guery the Count - 1th item, but in this exact case you'd need to search the item again as you're using a sorting list and the last inserted item might not be at the last position of the list (as Insert maintains the order of the list). yeah, that was a debug attempt to read what was just put in... i resorted to filling the collection and then doing a foreach on them in a later step... now i have some output files that i can compare and see what's happening... i've saved all the posts in this thread for reference... i know there's some good tidbits in them... once i get more used to my code, i might actually see more of what you were showing me :) so... here's my current batch of code... it ain't pretty, its my brother ;) program satsort; uses {$IFDEF DEBUG}heaptrc,{$ENDIF}strings,objects,math,crt,dos; type Tvector= array [1..4] of double; Tcat_nbr = pstring; Tsat_name = pstring; Tline_data = pstring; PTLERec= ^TTLERec; TTLERec= object(TObject) satname : Tsat_name; satdata1 : Tline_data; satdata2 : Tline_data; catnbr : Tcat_nbr; epoch: double;
Re: [fpc-pascal] sorting and merging array of records
On 11 Jan 12, at 17:46, waldo kitty wrote: . . 1. right now the compare is working on the catalog number (TTLERec.catnbr) and with duplicates:=FALSE there are no duplicates... however, i need to be able to choose which record to keep when there is a duplicate catnbr but the epoch (TTLERec.epoch) is different... right now it is throwing out all but the first... how can i tell it how to decide which one to throw away? i saw earlier that one of the parent objects has neat functions like AtPut which would easily allow me to overwrite an existing record that's too old... i just don't know if i can use that in the middle of an insert or a search or just exactly where i would even put code to do this... The best solution is probably overriding the Insert method to fit your slightly modified logic. Copy the default implementation of TSortedCollection.Insert as found in objects.pp in FPC source tree and modify it according your needs (if Search returns true, perform the additional check for the epoch and depending on the result either use AtInsert (equally to the default implementation) or Dispose the previously stored record at position I (I returned by Search, At (I) used to access the previously stored record) and then use AtPut. 2. something else i'm running into is with duplicates:=FALSE, there's a whole bucket load of records that are not disposed of when i wipe out the collection... heaptrc hollers right nasty to me about'em on exit... i can only assume that these are the duplicates but i don't understand why they are still hanging around if insert or add threw them away already :/ If you already had them in the collection, they're not added again. You only dispose records added to the collection at the end, but these are lost this way. You can also sort this out in the overridden Insert method (if you don't want to use the newly created record, dispose it). [TRIM] data^.catnbr := Copy(data^.satdata[1],3,5); data^.epoch := Real_Value(data^.satdata[1],19,14); inc(sat_cnt); aTLECollection^.insert(data); dispose(data); Don't do this! You'll free the memory you allocated for your record. The collection will only contain a pointer to this data! (Many of the rules I mentioned for T(FP)List apply here as well) uh? for some reason i thought that the insert was copying the data to a place and then setting the pointer to there for the collection... i tried with and without the dispose(data) but it still looked the same... of course i was tired and might not have been looking at the right writeln debug output... . . No, Insert doesn't do any copying by default. In your current code, the copying is performed by calling the PTLERec constructor (in New(PTLERec, Init(...) but if the pointer isn't inserted, it is thrown away currently. If you use the overridden Insert method as suggested above, you can Dispose it from within the Insert call if you don't need to insert it. Tomas ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] sorting and merging array of records
On 1/11/2012 20:35, Tomas Hajny wrote: On 11 Jan 12, at 17:46, waldo kitty wrote: . . 1. right now the compare is working on the catalog number (TTLERec.catnbr) and with duplicates:=FALSE there are no duplicates... however, i need to be able to choose which record to keep when there is a duplicate catnbr but the epoch (TTLERec.epoch) is different... right now it is throwing out all but the first... how can i tell it how to decide which one to throw away? i saw earlier that one of the parent objects has neat functions like AtPut which would easily allow me to overwrite an existing record that's too old... i just don't know if i can use that in the middle of an insert or a search or just exactly where i would even put code to do this... The best solution is probably overriding the Insert method to fit your slightly modified logic. Copy the default implementation of TSortedCollection.Insert as found in objects.pp in FPC source tree and modify it according your needs (if Search returns true, perform the additional check for the epoch and depending on the result either use AtInsert (equally to the default implementation) or Dispose the previously stored record at position I (I returned by Search, At (I) used to access the previously stored record) and then use AtPut. i've been mulling this over for a few hours and i'm wondering if overriding the insert method or simply doing the lofic in my importation routine would be best... right now my code blindly inserts the record but i could do a search for a matching key (catnbr by keyof ??) and then if i find a match, look at the epoch of the two records, one in vars and the other in the collection... if the one in the vars is newer, then do an AtPut to overwrite the one currently stored... otherwise, just go on to read the next file record into the vars and check it from there... without looking at the code to copy if i want to override the insert method, it almost seems that there's a bug if it just throws away the record we're trying to insert... it would seem that if the code locates a duplicate record, it would properly dispose of unwanted data... unless i perform the previously mentioned logic checks manually to catch this, i don't see this happening... the number of records left in memory at the end of the program's execution is the same number as those not added because they are dupes... 2. something else i'm running into is with duplicates:=FALSE, there's a whole bucket load of records that are not disposed of when i wipe out the collection... heaptrc hollers right nasty to me about'em on exit... i can only assume that these are the duplicates but i don't understand why they are still hanging around if insert or add threw them away already :/ If you already had them in the collection, they're not added again. You only dispose records added to the collection at the end, but these are lost this way. You can also sort this out in the overridden Insert method (if you don't want to use the newly created record, dispose it). as above, i don't know that they are /in/ the collection... i'm (currently) simply calling the insert method and leaving the work up to it... if it should be handling this gracefully, it isn't... at least not in a way that heaptrc likes ;) [TRIM] data^.catnbr := Copy(data^.satdata[1],3,5); data^.epoch := Real_Value(data^.satdata[1],19,14); inc(sat_cnt); aTLECollection^.insert(data); dispose(data); Don't do this! You'll free the memory you allocated for your record. The collection will only contain a pointer to this data! (Many of the rules I mentioned for T(FP)List apply here as well) uh? for some reason i thought that the insert was copying the data to a place and then setting the pointer to there for the collection... i tried with and without the dispose(data) but it still looked the same... of course i was tired and might not have been looking at the right writeln debug output... . . No, Insert doesn't do any copying by default. In your current code, the copying is performed by calling the PTLERec constructor (in New(PTLERec, Init(...) but if the pointer isn't inserted, it is thrown away currently. thrown away by the default object insert code? why doesn't it properly wipe it out since it is tossing the pointer into the bitbucket? If you use the overridden Insert method as suggested above, you can Dispose it from within the Insert call if you don't need to insert it. understood... and with an eye on the above discussion about doing the logic myself using the available routines, i could also take care of it there by deciding to AtPut, or, insert or dispose instead of blindly performing an insert and hoping for the best?? i'll probably have broken my code by the time you read this... but i'll very likely be attempting to implement the logic in my Input_Satellite_List routine ;) OB-) i just gotta figure out the way that the search and such work as in if they are returning