Author Topic: Alternate for getkword  (Read 7973 times)

0 Members and 1 Guest are viewing this topic.

Rabbit

  • Guest
Alternate for getkword
« on: January 02, 2013, 02:04:40 PM »
Here's my situation;  I got a lot of code that will get the visibility parameters from a block and bring that up in the quick properties panel on the screen.  The user picks the visibility they want and the code sets that.  The code does more than just that, but that's just the jist of it.

My problem is using initget before the getkword.  The code gets the visibility parameters and processes it into a string with all of the visilibity parameters separated by spaces for the initget to use.  Since all of the blocks have visibility parameters that have an underscore in them, initget goes screwy.

I thought, "Hey, why not write code to replace the underscores with hyphens and then convert it back."  Nope.  That won't work because some of the visibility parameters have both underscores and hyphens.

So, does anybody have a work around for this?

Sample code:
Code - Auto/Visual Lisp: [Select]
  1.  
  2. (initget "Abc Def X_y X_y-z")
  3.   (setq ParameterType (getkword "\nType ["Abc/Def/X_y/X_y-z"]"))
  4.  

If it's hard to understand, just let me know and I'll try to explain better.

Rabbit

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Alternate for getkword
« Reply #1 on: January 02, 2013, 02:35:04 PM »
I thought, "Hey, why not write code to replace the underscores with hyphens and then convert it back."  Nope.  That won't work because some of the visibility parameters have both underscores and hyphens.

You can use a reference list.

Code: [Select]
(setq MyKeyWords (list "Abc" "Def" "X_y" "X_y-z"))
(setq ModList (RemoveUnderScore MyKeyWords)) ; returns ("Abc" "Def" "X-y" "X-y-z")
(initget (ADDSpaces ModList))
 (setq Answer (getkword (strcat "\nType ["(ADDSpaces ModList)"]")))
(setq  ParameterType (nth (vl-position Answer ModList) MyKeyWords))

Hope you get the gist.

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.

Rabbit

  • Guest
Re: Alternate for getkword
« Reply #2 on: January 02, 2013, 02:48:29 PM »
OH WOW!  :-o  That's brilliant.  I would've never come up with something like that.

Simple and easy to use.  Thanks CAB!

Rabbit
(note to self:  Always proofread a post before posting.  The grammar police might be watching :police: )   :lmao:

Lee Mac

  • Seagull
  • Posts: 12913
  • London, England
Re: Alternate for getkword
« Reply #3 on: January 02, 2013, 02:50:57 PM »
Or perhaps:

Code - Auto/Visual Lisp: [Select]
  1. (setq lst (mapcar 'strcase '("Abc" "Def" "X_y" "X_y-z")))
  2.     (not
  3.         (or (= "" (setq str (strcase (getstring "\nType: "))))
  4.             (member str lst)
  5.         )
  6.     )
  7.     (princ "\nInvalid Type.")
  8. )

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: Alternate for getkword
« Reply #4 on: January 03, 2013, 02:09:45 AM »
Just a query CAB: Where are those functions RemoveUnderScore & AddSpaces. I generally just use vl-string-translate and then just a mapcar construct
Code - Auto/Visual Lisp: [Select]
  1. (defun PrepareList->StrCat  (lst sep old new /)
  2.                  (mapcar '(lambda (s) (strcat sep (strcase (vl-string-translate old new s)))) lst))
  3.           (1+ (strlen sep))))
  4.  
  5. (setq lst '("Abc" "Def" "X_y" "X_y-z"))
  6. (initget (PrepareList->StrCat lst " " " _" "--")
  7. (setq Answer (getkword (strcat "\nType [" (PrepareList->StrCat lst "/" " _" "--") "]: ")))
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Alternate for getkword
« Reply #5 on: January 03, 2013, 09:08:28 AM »
I didn't include them.  Some fishing :-)
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.

Rabbit

  • Guest
Re: Alternate for getkword
« Reply #6 on: January 04, 2013, 09:56:43 AM »
irneb,  here's what I wrote for the underscore replacer.  Probably not as elegant as what CAB and LEE can do, but it works.

Code - Auto/Visual Lisp: [Select]
  1. ;;;the variable lst is a list of strings, i.e. (list "Abc" "Def" "X_y" "X_y-z")
  2. (defun RemoveUnderScore (lst / cnt item rlst)
  3.   (setq cnt (1- (length lst)))
  4.   (while (>= cnt 0)
  5.     (setq item (nth cnt lst))
  6.     (while (vl-string-search "_" item)
  7.       (setq item (strcat (substr item 1 (vl-string-search "_" item)) "-" (substr item (+ (vl-string-search "_" item) 2))))
  8.     );while
  9.     (setq rlst (cons item rlst))
  10.     (setq cnt (1- cnt))
  11.   );while
  12.   rlst
  13. );defun
  14.  

The way I wrote my code I didn't need to use the AddSpaces sub-routine.

Rabbit

Lee Mac

  • Seagull
  • Posts: 12913
  • London, England
Re: Alternate for getkword
« Reply #7 on: January 04, 2013, 10:26:22 AM »
Consider vl-string-translate as Irneb has noted:

Code - Auto/Visual Lisp: [Select]
  1. _$ (mapcar '(lambda ( x ) (vl-string-translate "_" "-" x)) '("Abc" "Def" "X_y" "X_y-z"))
  2. ("Abc" "Def" "X-y" "X-y-z")

Rabbit

  • Guest
Re: Alternate for getkword
« Reply #8 on: January 04, 2013, 01:23:36 PM »
See!  I knew there was a better and more elegant way of doing it.  Hopefully the whole lambda/mapcar thing will sink into my brain and I can truly understand the usage.  No matter what all I read about it, it still keeps me confused. :wink:

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: Alternate for getkword
« Reply #9 on: January 07, 2013, 12:45:32 AM »
Lambda is actually quite simple. It's not much different from making a normal defun and then calling it - it's just that the declaration (i.e. defining the defun) and the invocation (i.e. calling it) is in the same place and that there's no name declared for the function. E.g. the following 2 portions do much the same thing:
Code - Auto/Visual Lisp: [Select]
  1. ;; The normal defun way
  2. (defun add-mult (x y) (* (+ x y) y)) ;Creates a function called add-mult
  3. (add-mult 10 5) ;Invokes the add-mult function with arguments, returns the value 75
  4.  
  5. ;; Using lambda instead
  6. ((lambda (x y) (* (+ x y) y)) ;Defines an unnamed / temporary function
  7.   10 5) ;Send the arguments to the unnamed function and return 75

Now mapcar is a form of loop. It's meant to loop through one or more lists, calculating something for each item (or set of items) and returning a list with the new values for each iteration. The first argument to mapcar is the function (quoted so it can be applied with an arbitrary number of arguments) to invoke on each set of items, the next arguments are the source list(s). E.g. say you had the add-mult defun already. Then you can send 2 lists of numbers to it through mapcar:
Code - Auto/Visual Lisp: [Select]
  1. (defun add-mult (x y) (* (+ x y) y)) ;Declare the function first
  2.  
  3. (mapcar 'add-mult '(2 3 4 5) '(7 6 5 4 3 2)) ;Returns a new list: (63 54 45 36)
Note the source lists need not be the same length, but the returned list is the same length as the shortest source.

Usually you'd use lambda inside the mapcar instead of making a new defun just so you can send it to mapcar as above. So instead of making the function first and then sending it into mapcar, use lambda so it's done in one step and does not use up some symbol name:
Code - Auto/Visual Lisp: [Select]
  1. (mapcar '(lambda (x y) (* (+ x y) y)) '(2 3 4 5) '(7 6 5 4 3 2)) ;Also returns (63 54 45 36)
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Alternate for getkword
« Reply #10 on: January 07, 2013, 07:20:58 AM »
It does take some practice but you will learn if you do some for your self.

----------  Mapcar  Lambda  Apply   ------------
http://www.theswamp.org/index.php?topic=2953.0   (MP)
http://www.theswamp.org/index.php?topic=340.0   (CAB)
http://www.cadtutor.net/forum/showthread.php?52127-Mapcar-lambda-Description
http://lee-mac.com/mapcarlambda.html
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.

Rabbit

  • Guest
Re: Alternate for getkword
« Reply #11 on: January 08, 2013, 10:35:26 AM »
Nice explanations guys.  I think I understand it now.  I may have to go back and update my routines.  By using mapcar and lambda the code will be a lot smaller.

Rabbit

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: Alternate for getkword
« Reply #12 on: January 08, 2013, 02:26:03 PM »
By using mapcar and lambda the code will be a lot smaller.
That's usually the major reason for using them. Smaller code means less possibility for errors thus makes it easier to get something working properly.
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

Lee Mac

  • Seagull
  • Posts: 12913
  • London, England
Re: Alternate for getkword
« Reply #13 on: January 08, 2013, 05:49:23 PM »
By using mapcar and lambda the code will be a lot smaller.
That's usually the major reason for using them. Smaller code means less possibility for errors thus makes it easier to get something working properly.

Not to mention concision *usually* results in greater efficiency...

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: Alternate for getkword
« Reply #14 on: January 09, 2013, 01:22:02 AM »
Not to mention concision *usually* results in greater efficiency...
Well it's definitely more efficient to write the code! Less to type :)
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.