Author Topic: Recursion.. not really right now but trying.  (Read 11539 times)

0 Members and 1 Guest are viewing this topic.

T.Willey

  • Needs a day job
  • Posts: 5251
Recursion.. not really right now but trying.
« on: March 20, 2006, 02:02:14 PM »
I'm sure this can be written to be recursive, but I can't figure it out right now.  I have looked at this for two days, and can't seem to grip what I should do.  I have it in a while loop, but I was trying to see if it can be done in a recursive way.  Here is my code.  It grabs all the sub directories from a staring directory.
Code: [Select]
(defun AllSubDirs (Main / DirList cnt Index tmpList FindSubDir)
; Returns a sorted list of all the directories found under the one supplied.

;--------------------------------------------------------------
(defun FindSubDir (Path / )

(mapcar
 '(lambda (x)
  (strcat Path x "\\")
 )
 (vl-remove-if
  '(lambda (y)
   (vl-position y '("." ".."))
  )
  (vl-directory-files Path "*" -1)
 )
)
)
;----------------------------------------------------------------------
(setq DirList (list Main))
(setq cnt 1)
(while (>= (setq Index (- (length DirList) cnt)) 0)
(setq tmpList (FindSubDir (nth Index DirList)))
 (foreach i tmpList
  (setq DirList (cons i DirList))
 )
 (setq cnt (1+ cnt))
)
(vl-sort DirList '(lambda (a b) (< (strcase a) (strcase b))))
)

Any help is appreciated.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

Jürg Menzi

  • Swamp Rat
  • Posts: 599
  • Oberegg, Switzerland
Re: Recursion.. not really right now but trying.
« Reply #1 on: March 20, 2006, 02:24:50 PM »
Hi Tim

That's what I use:
Code: [Select]
;
; == Function MeGetSubFolders
; Returns a recursive list of all folders behind a start folder.
; Arguments [Type]:
;   Fld = Start folder [STR]
; Return [Type]:
;   > List of all (sub)folders [LIST]
;   > Nil if nothing found [BOOLEAN]
; Notes:
;   - None
;
(defun MeGetSubFolders (Fld / CurFld)
 (mapcar
 '(lambda (l)
   (setq CurFld (strcat Fld "\\" l))
   (cons CurFld (apply 'append (MeGetSubFolders CurFld)))
  )
  (cddr (vl-directory-files Fld nil -1))
 )
)
A computer's human touch is its unscrupulousness!
MENZI ENGINEERING GmbH
Current A2k16... A2k24 - Start R2.18

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Recursion.. not really right now but trying.
« Reply #2 on: March 20, 2006, 02:38:52 PM »
Thanks Jurg.  I will have to study this one, and try and understand the logic of it, and see if I can do it.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Recursion.. not really right now but trying.
« Reply #4 on: March 20, 2006, 03:12:11 PM »
Thanks Alan.  I have a lot of reading to do.

I remember reading some when I first tried to figure out recursion, but not when I tried to write this one.  I like to write code blindly (not getting help from any source besides the help files), so that I can learn more, but I think I'm over my head here, and need the help.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Recursion.. not really right now but trying.
« Reply #5 on: March 20, 2006, 03:26:36 PM »
Here is some commented code:
http://www.theswamp.org/index.php?topic=3683.msg44477#msg44477

I typically avoid recursion if I can, makes my head hurt too.
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Recursion.. not really right now but trying.
« Reply #6 on: March 20, 2006, 03:39:04 PM »
Thanks again Alan.  I love learning, even more when it's hard to grasp at first.  This will take a lot of time for me.  I love having things to learn, that I want to learn.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

LE

  • Guest
Re: Recursion.. not really right now but trying.
« Reply #7 on: March 20, 2006, 04:00:03 PM »
It may not be what you are trying to do, but might be useful:

Two old functions. . .
Code: [Select]
;;; Usage: (search_sub_folders (getvar "DWGPREFIX") "*.dwg")
;;; Return: (list "subfolder" "files")
;;; (("." "2006generalindex.dwg" "T-1.dwg" "T-2.dwg" "TITLE SHEET.dwg")
;;; (".." "TITLEBLOCK.dwg")
;;; ("HARDSHIP SUBBMITTAL" "2006generalindex.dwg" "T-1.dwg" "T-2.dwg" "TITLE SHEET.dwg")
;;; ("New Folder"))

(defun search_sub_folders (pathfile ext)
  (mapcar '(lambda (sub)
     (cons sub
   (vl-directory-files
     (strcat pathfile sub)
     ext
     1
   )
     )
   )
  (vl-directory-files
    (vl-filename-directory
      pathfile
    )
    nil
    -1
  )
  )
)

;;; (MapSubfolders (search_sub_folders (getvar "DWGPREFIX") "*.dwg"))
;;; ("C:\\My Documents\\" "Piezas.dwg" "ARQCAD_15.dwg" "ARQCAD.dwg")
;;; ("C:\\My Documents\\toiltets\\" "t1000.dwg" "t200.dwg" "t300.dwg")
;;; ("C:\\My Documents\\toiltets\\" "t1000.dwg" "t200.dwg" "t300.dwg")

(defun MapSubfolders (sfolders)
  (setq tmp nil)
  (foreach s sfolders
    (if (= "." (car s))
      (setq
tmp
(append tmp
(list (cons (getvar "DWGPREFIX") (vl-remove "." s)))
)
      )
      (if (/= 1 (length s))
(setq
  tmp (append
tmp
(list (cons (strcat (getvar "DWGPREFIX") (car s) "\\")
    (vl-remove (car s) s)
      )
)
      )
)
      )
    )
  )
)

About recursion... I think I had used twice... if I recall...

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Recursion.. not really right now but trying.
« Reply #8 on: March 20, 2006, 04:48:51 PM »
Thanks Luis.  I will have fun studying these also.

I guess this brings up another questions then.  How many people actually use recursion in codes? and is it useful to know and understand?

Any and all comments welcomed.  If people think this should be a new topic, let me know and I will make a new one in the appropriate location.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

Jeff_M

  • King Gator
  • Posts: 4096
  • C3D user & customizer
Re: Recursion.. not really right now but trying.
« Reply #9 on: March 20, 2006, 05:32:07 PM »
Tim, I use recursion when I find it necessary to get an unknown number of objects/sub-objects. You've selected one good example. Another would be Blocks/Xrefs are another since they can be infinitely(nearly) nested.

IMO, search on the Adesk customization newsgroup for discussions that Doug Broad and Michael Puckett were involved with. The 2 of them (and Tony T.) have had some of the best discussions I've seen about the pros & cons of recursion.

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Recursion.. not really right now but trying.
« Reply #10 on: March 20, 2006, 05:42:37 PM »
Thanks Jeff; will do.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: Recursion.. not really right now but trying.
« Reply #11 on: March 20, 2006, 06:09:23 PM »
Hmmm. Briefly, recursion is typically less work work for the programmer (once you wrap your head around it) but conversley more work for the computer, especially the stack that must hold interim results. Also typically, a well written iterative function will run faster than a recursive one, but it will require more coding.

However, some problems lend themselves to recursion better than iterative solutions, like anything that can be nested -- directory structures, blocks, lists etc.

Here's a quick variant that attempts to optimize and illuminate the recursion process a bit by formally declaring local defuns where lambda calls would typically be invoked --

Code: [Select]
(defun GetFolders ( path / _GetFolders _Collector _Main )

    (defun _GetFolders ( path / folders )
        (defun _GetFolders ( path )
            (cddr
                (vl-directory-files path nil -1)
            )
        )
        (if (vl-position "."
                (setq folders
                    (vl-directory-files path nil -1)
                )
            )    
            (cddr folders)
            folders
        )    
    )

    (defun _Collector ( folder / temp )
        (cons
            (setq temp (strcat path "\\" folder))
            (apply 'append (_Main temp))
        )
    )

    (defun _Main ( path )
        (mapcar '_Collector
            (_GetFolders path)
        )
    )

    (apply 'append (_Main path))

)

While it looks verbose it should perform decent enough and is safer than some of the variants already posted (not dissing, just an observation). See the "An aside ..." comment at the end of this post.

If run on a folder structure like this --

Code: [Select]
C:\Folder1
    |
    +-- Folder1
    |   |
    |   +-- Folder1
    |   |
    |   +-- Folder2
    |   |
    |   +-- Folder3
    |
    +-- Folder2
    |   |
    |   +-- Folder1
    |   |
    |   +-- Folder2
    |   |
    |   +-- Folder3
    |
    +-- Folder3
        |
        +-- Folder1
        |
        +-- Folder2
        |
        +-- Folder3

it will return a list of 12 items.

Code: [Select]
(GetFolders "C:\\Folder1")
Code: [Select]
(  "c:\\folder1\\folder1"
    "c:\\folder1\\folder1\\folder1"
    "c:\\folder1\\folder1\\folder2"
    "c:\\folder1\\folder1\\folder3"
    "c:\\folder1\\folder2"
    "c:\\folder1\\folder2\\folder1"
    "c:\\folder1\\folder2\\folder2"
    "c:\\folder1\\folder2\\folder3"
    "c:\\folder1\\folder3"
    "c:\\folder1\\folder3\\folder1"
    "c:\\folder1\\folder3\\folder2"
    "c:\\folder1\\folder3\\folder3"
)

An aside ... using cddr to strip out "." and ".." unconditionally is a little dangerous, as the vl-directory-files function will not include them if you run said function on a root directory like (vl-directory-files "c:\\" nil -1). That's why I redefine the _GetFolders function after the first call. On the first call it checks to see if "." is a member of the result list and if so strips it (and ".." ) out. Thereafter the program uses the redefined version which uses cddr unconditionally, as there is no need to pay the penaly of testing each subsequent iteration.

Hope (that makes sense and) that helps some.
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Recursion.. not really right now but trying.
« Reply #12 on: March 20, 2006, 06:31:48 PM »
Thanks for the example, and explanation.  Hopefully I will get a handle one this style, so that I know when it would be useful to use it.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: Recursion.. not really right now but trying.
« Reply #13 on: March 20, 2006, 06:33:52 PM »
Tim, I use recursion when I find it necessary to get an unknown number of objects/sub-objects. You've selected one good example. Another would be Blocks/Xrefs are another since they can be infinitely(nearly) nested.

IMO, search on the Adesk customization newsgroup for discussions that Doug Broad and Michael Puckett were involved with. The 2 of them (and Tony T.) have had some of the best discussions I've seen about the pros & cons of recursion.

Whoa, I'm honored to be included in the same sentence as those 2. There were times way back when there used to be challenging and fun contests / discussions on the autodesk news servers. Folks like Vladimir Nesterovsky (hope I spelled that correctly) and Reini Urban would sometimes participate in addition to the afore mentioned (sadly this is before google indexed those groups). Those discussion always resulted in me pounded out dozens and dozens of different solution variants, trying to do this, optimize that. Understatement: Very educational. Speaking of Vladimir, it was Vladimir who had recommended a book (Structure And Interpretation of Computer Programs that was instrumental in pushing my lispin' knowledge to the next level. It really changed the landscape for me and "took the reigns and blinders completely off" so to speak (tho I've still lots to learn). I don't know what ever happened to Vladimir, he stopped posting to the ngs long ago (as did Mr. Urban) but I'm sure he excelled at whatever he set his mind to and I'm grateful to this day that he mentioned said book. Thank you Vladimir.

/tangent, but it's your fault for making me think of it.

Anyway, thanks for the props Jeff, appreciate it.
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: Recursion.. not really right now but trying.
« Reply #14 on: March 20, 2006, 06:36:13 PM »
My pleasure Tim, thanks for posing the question.
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst