Author Topic: help read txt1.txt  (Read 3061 times)

0 Members and 1 Guest are viewing this topic.

Q1241274614

  • Guest
help read txt1.txt
« on: January 30, 2013, 08:34:51 PM »
txt1.txt
content:
box
a1
a2
a3

cir
b1
b2
b3
b4
b5

rectang
c1
c2
c3
c4

result:
(list box cir rectang)
(list a1 a2 a3)
(list b1 b2 b3 b4 b5)
(list c1 c2 c3 c4)

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
Re: help read txt1.txt
« Reply #1 on: January 30, 2013, 10:17:03 PM »
Is this close to what you are looking for?

Code: [Select]
(defun _fread (filename / dataIn dataOut flag fn header temp)
  (setq fn (open filename "r"))
  (setq flag t)
  ;; Prime the loop
  (setq dataIn "")
  ;; Skip any blank lines in the beginning of the file
  (while (= dataIn "")
    (setq dataIn (read-line fn))
  )
  (while dataIn
    (if flag ;Is dataIn a header?
      (progn
(setq header (append header (list dataIn))
      flag   nil
)
;; dataIn is not a header, it is data or an empty row
;; read until we get an empty row
(while (not flag)
  (setq dataIn (read-line fn))
  (if (and dataIn (/= dataIn ""))
    ;; Save data
    (setq temp (append temp (list dataIn)))
    ;; Get next header
    (progn
      (setq dataIn (read-line fn)
    flag   T
      )
      (while (= dataIn "")
(setq dataIn (read-line fn))
      )
    )
  )
)
;; Save the list to our dataOut list
(setq dataOut (append dataOut (list temp))
      temp    nil
)
      )
    )
  )
  (close fn)
  (cons header dataOut)
)

Quote
Command: (_fread "c:/data.txt")
Command: (("box" "cir" "rectang") ("a1 " "a2" "a3") ("b1 " "b2" "b3" "b4"
"b5") ("c1" "c2" "c3" "c4"))

The output is a list of lists, verbatim from the text file. Note that there are some extra spaces in the text file following a1 and b1.
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Find me on https://parler.com @kblackie

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: help read txt1.txt
« Reply #2 on: February 01, 2013, 01:27:27 AM »
My variant:
Code - Auto/Visual Lisp: [Select]
  1. (defun read_txt  (fname / f str group result)
  2.   (if (setq f (open fname "r"))
  3.     (progn (while (setq str (read-line f))
  4.              (if (eq str "")
  5.                (setq result (cons (reverse group) result)
  6.                      group  nil)
  7.                (setq group (cons str group))))
  8.            (close f)
  9.            (reverse (cons (reverse group) result)))))
You can use it thus to split it into the lists as the OP's requirements:
Code - Auto/Visual Lisp: [Select]
  1. (defun test  (/ data headers box cir rect)
  2.   (if (setq data (read_txt "G:\\Documents\\AutoLisp Tests\\txt1.txt"))
  3.     (setq headers (mapcar 'car data)
  4.           box     (cdar data)
  5.           cir     (cdadr data)
  6.           rect    (cdaddr data)))
  7.   (foreach sym '(headers box cir rect) (print sym) (princ "\t= ") (prin1 (eval sym)))
  8.   (princ))
E.g.:
Code: [Select]
_$ (test)
HEADERS     = ("box" "cir" "rectang")
BOX     = ("a1 " "a2" "a3")
CIR     = ("b1 " "b2" "b3" "b4" "b5")
RECT     = ("c1" "c2" "c3" "c4")
« Last Edit: February 01, 2013, 01:31:27 AM by irneb »
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: help read txt1.txt
« Reply #3 on: February 01, 2013, 01:35:10 AM »
Or to get the same output as Keith's  ;)
Code - Auto/Visual Lisp: [Select]
  1. (defun test1  (/ data)
  2.   (if (setq data (read_txt "G:\\Documents\\AutoLisp Tests\\txt1.txt"))
  3.     (cons (mapcar 'car data) (mapcar 'cdr data))))
Code: [Select]
_$ (test1)
(("box" "cir" "rectang") ("a1 " "a2" "a3") ("b1 " "b2" "b3" "b4" "b5") ("c1" "c2" "c3" "c4"))
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

Lee Mac

  • Seagull
  • Posts: 12929
  • London, England
Re: help read txt1.txt
« Reply #4 on: February 01, 2013, 06:51:50 AM »
If I were writing this for a general application, I would likely follow the same route as Irné has demonstrated: reading the file into a list of lists, with a sub-list for each group of text separated by the newline, and then use mapcar to manipulate the lists as required.

However, to offer an alternative:

Code: [Select]
(defun read-it ( f / h l m n r )
    (if
        (and
            (setq f (findfile f))
            (setq f (open f "r"))
        )
        (progn
            (while (setq r (read-line f))
                (cond
                    (   (= "" r)
                        (setq l (cons h l)
                              m (cons (reverse n) m)
                              h nil
                              n nil
                        )
                    )
                    (   (null h)
                        (setq h r)
                    )
                    (   (setq n (cons r n)))
                )
            )
            (close f)
            (cons (reverse (cons h l)) (reverse (cons (reverse n) m)))
        )
    )
)

Code: [Select]
_$ (read-it "txt1.txt")
(("box" "cir" "rectang") ("a1 " "a2" "a3") ("b1 " "b2" "b3" "b4" "b5") ("c1" "c2" "c3" "c4"))

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: help read txt1.txt
« Reply #5 on: February 01, 2013, 07:51:43 AM »
Lee, any way you can think of to use mapcar (or some similar) to transpose the generalized list such that the 1st sublist is the headers and the next sublists is each item from the relevant portion?

I mean it's possible to do this:
Code - Auto/Visual Lisp: [Select]
  1. (defun test2 (/ data)
  2.   (if (setq data (read_txt "G:\\Documents\\AutoLisp Tests\\txt1.txt"))
  3.     (apply 'mapcar (cons 'list data))))
But that cuts off the items from longer groups. E.g. in the sample text file the result is:
Code: [Select]
_$ (test2)
(("box" "cir" "rectang") ("a1 " "b1 " "c1") ("a2" "b2" "c2") ("a3" "b3" "c3"))
It should be something like this:
Code: [Select]
(("box" "cir" "rectang")
 ("a1 " "b1 " "c1")
 ("a2" "b2" "c2")
 ("a3" "b3" "c3")
 (nil "b4" "c4")
 (nil "b5" nil))
No "easy" way I can think of, will have to make some rather complex iteration structure. Or first figure out the longest sublist's length then add nils onto each sublist to make each the same length. Possibly something like this:
Code - Auto/Visual Lisp: [Select]
  1. (defun test3  (/ data len)
  2.   (if (setq data (read_txt "G:\\Documents\\AutoLisp Tests\\txt1.txt"))
  3.     (progn (setq len  (apply 'max (mapcar 'length data))
  4.                  data (mapcar
  5.                         '(lambda (sub) (while (< (length sub) len) (setq sub (append sub '(nil)))) sub)
  6.                         data))
  7.            (apply 'mapcar (cons 'list data)))))
IMO not extremely "clean" or simple, but at least it provides the needed result.
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

Lee Mac

  • Seagull
  • Posts: 12929
  • London, England
Re: help read txt1.txt
« Reply #6 on: February 01, 2013, 07:57:54 AM »
Lee, any way you can think of to use mapcar (or some similar) to transpose the generalized list such that the 1st sublist is the headers and the next sublists is each item from the relevant portion?

Not a single expression, but perhaps:

Code - Auto/Visual Lisp: [Select]
  1. (defun f ( l )
  2.     (if (apply 'or l)
  3.         (cons (mapcar 'car l) (f (mapcar 'cdr l)))
  4.     )
  5. )

Code - Auto/Visual Lisp: [Select]
  1. _$ (f '(("box" "a1 " "a2" "a3") ("cir" "b1 " "b2" "b3" "b4" "b5") ("rectang" "c1" "c2" "c3" "c4")))
  2. (("box" "cir" "rectang") ("a1 " "b1 " "c1") ("a2" "b2" "c2") ("a3" "b3" "c3") (nil "b4" "c4") (nil "b5" nil))

JohnK

  • Administrator
  • Seagull
  • Posts: 10669
Re: help read txt1.txt
« Reply #7 on: February 01, 2013, 08:13:02 AM »
Off topic:
Save yourself now if you can.
Code: [Select]
(defun f ( l s / s )there be dragons here (you will get sloppy later).

Dave Stein used to post code using only vowels, to confuse me I'm sure.  I developed the habit of using single chars to represent lists, strings, ints and whatnot too. Ugh! Missed vars, unchanged types, etc.. Run away, run far.
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

Lee Mac

  • Seagull
  • Posts: 12929
  • London, England
Re: help read txt1.txt
« Reply #8 on: February 01, 2013, 08:29:55 AM »
Off topic:
Save yourself now if you can.
Code: [Select]
(defun f ( l s / s )there be dragons here (you will get sloppy later).

Dave Stein used to post code using only vowels, to confuse me I'm sure.  I developed the habit of using single chars to represent lists, strings, ints and whatnot too. Ugh! Missed vars, unchanged types, etc.. Run away, run far.

Ah yes, my lazy variable naming...
A bad habit, I admit, though I do only tend to use single-letter variables for short 'throw-away' programs & functions posted around the forums - for larger applications, more descriptive naming is certainly a necessity, for both readability and the fact I'd quickly run out of letters!  :-D

JohnK

  • Administrator
  • Seagull
  • Posts: 10669
Re: help read txt1.txt
« Reply #9 on: February 01, 2013, 09:07:44 AM »
yep! That was my thinking as well (you're stuck now). ...I started to realize that the lazy var names maybe weren't a "good idea" when I started to think that someone might actually use those snips in their code.  Have you started prefixing your var names yet? *lol* sMyString or s_myString

I actually went full circle with the `lazy names' now (my names are too long). *facepalm*

Temporary vars don't count of course.
Code - C++: [Select]
  1. for (unsigned i = 0; i < count ; ++i) {
  2.     /* code */
  3. }
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: help read txt1.txt
« Reply #10 on: February 02, 2013, 02:19:16 AM »
Yep, I too go with full words as much as possible. Sometimes even 2 or 3 words combined, though how to combine is yet another ballgame (CamelCase / under_scores / minus-signs / whatnot). And don't get me started on the prefixing stuff, had run into that "fad" a few years ago myself - to the point where I couldn't understand my own code any more  :| . But you're correct about temporary vars, especially indexes for loops where I tend to go with I or n (or some such) - it gets funky when there's nested loops  :lmao: . One letter I find particularly unreadable is 'l' (that's the small L), just too similar to I or worse 1 and could easily cause someone reading the code for the first time to get the wrong impression  :pissed: .

About the readability / understandability of the code: There's a whole debate about commenting vs descriptive var/func names: http://www.codeproject.com/Lounge.aspx?msg=4473812#xx4473812xx

Thanks Lee for the recursive idea to rearrange the list, much less coding  :kewl: . Though I'd be scared of large data lists. Oh the woe's of a non-tail-call-optimized language, give me Scheme any day of the week and twice on Sundays!
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

Lee Mac

  • Seagull
  • Posts: 12929
  • London, England
Re: help read txt1.txt
« Reply #11 on: February 02, 2013, 09:08:37 AM »
Have you started prefixing your var names yet?

Not local variables, but for larger applications I do tend to prefix supporting functions and any global variables with the application name, purely to avoid potential clashes with any similar functions which may be defined in the same namespace. Previously to avoid naming clashes, I would define any supporting functions as being local to the main function, but when there are numerous local functions, it soon becomes inefficient & impractical to redefine every function every time the main program is evaluated.

Thanks Lee for the recursive idea to rearrange the list, much less coding  :kewl: . Though I'd be scared of large data lists. Oh the woe's of a non-tail-call-optimized language, give me Scheme any day of the week and twice on Sundays!

Thanks Irneb  :-)
I agree, although recursion usually provides elegant & concise solutions, its suitability is heavily dependent on the application and size of the data set.

JohnK

  • Administrator
  • Seagull
  • Posts: 10669
Re: help read txt1.txt
« Reply #12 on: February 04, 2013, 08:59:03 AM »
irneb, Ugh! The commenting debate is as old as the Vim-Emacs editor wars. ...That kind of stuff comes from writing your 10,000 lines. I haven't written my 10,000 lines--I still don't write good code yet-- so just choose to steer clear of that one and comment a bunch (can always delete).

Lee, that's one of the reasons I made that utility LiFP (good for people with large libs of code).
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

JohnK

  • Administrator
  • Seagull
  • Posts: 10669
Re: help read txt1.txt
« Reply #13 on: February 19, 2013, 10:02:50 AM »
Still off topic, I know, but I was just re-reading the LLVM coding standards and I thought of this thread so I thought I would share this little section.

***

Name Types, Functions, Variables, and Enumerators Properly

Poorly-chosen names can mislead the reader and cause bugs. We cannot stress enough how important it is to use descriptive names. Pick names that match the semantics and role of the underlying entities, within reason. Avoid abbreviations unless they are well known. After picking a good name, make sure to use consistent capitalization for the name, as inconsistency requires clients to either memorize the APIs or to look it up to find the exact spelling.

In general, names should be in camel case (e.g. TextFileReader and isLValue()). Different kinds of declarations have different rules:

Type names (including classes, structs, enums, typedefs, etc) should be nouns and start with an upper-case letter (e.g. TextFileReader).

Variable names should be nouns (as they represent state). The name should be camel case, and start with an upper case letter (e.g. Leader or Boats).

Function names should be verb phrases (as they represent actions), and command-like function should be imperative. The name should be camel case, and start with a lower case letter (e.g. openFile() or isFoo()).

Enum declarations (e.g. enum Foo {...}) are types, so they should follow the naming conventions for types. A common use for enums is as a discriminator for a union, or an indicator of a subclass. When an enum is used for something like this, it should have a Kind suffix (e.g. ValueKind).

Enumerators (e.g. enum { Foo, Bar }) and public member variables should start with an upper-case letter, just like types. Unless the enumerators are defined in their own small namespace or inside a class, enumerators should have a prefix corresponding to the enum declaration name. For example, enum ValueKind { ... }; may contain enumerators like VK_Argument, VK_BasicBlock, etc. Enumerators that are just convenience constants are exempt from the requirement for a prefix. For instance:

Code - C++: [Select]
  1. enum {
  2.   MaxSize = 42,
  3.   Density = 12
  4. };

As an exception, classes that mimic STL classes can have member names in STL's style of lower-case words separated by underscores (e.g. begin(), push_back(), and empty()).

Here are some examples of good and bad names:

Code - C++: [Select]
  1. class VehicleMaker {
  2.   ...
  3.   Factory<Tire> F;            // Bad -- abbreviation and non-descriptive.
  4.   Factory<Tire> Factory;      // Better.
  5.   Factory<Tire> TireFactory;  // Even better -- if VehicleMaker has more than one
  6.                               // kind of factories.
  7. };

Code - C++: [Select]
  1. Vehicle MakeVehicle(VehicleType Type) {
  2.   VehicleMaker M;                         // Might be OK if having a short life-span.
  3.   Tire tmp1 = M.makeTire();               // Bad -- 'tmp1' provides no information.
  4.   Light headlight = M.makeLight("head");  // Good -- descriptive.
  5.   ...
  6. }
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org