Jump to content

Recommended Posts

Posted

Hi,

Could anyone please give me an idea on how to increment two numbers separated by a hyphen? Eg. C1-C5 to C2-C6 given the increment value of 1. Many thanks.

  • 2 weeks later...
Posted

Hi Artek!

 

 

As I needed something like that, this thread did not went unnoticed, not by me anyway. I worked on the subject part time, and here are my thoughts on your request. As I don't know your knowledge level of Autolisp, I'll put many details.

 

 

You always have better chances of getting answers if the question is very clear and complete. Many people wont bother asking questions, and many wont lose their valuable time if there are chances that the answer they could provide wont suit your needs. Is the format always the same? x#-x# to x(#+1)-x(#+1)? where is the information? On a text? mtext? attribute? What do you want to do with the answer? Put it in an attribute of an existing block? on a new instance of a block insert? into a created mtext? A simple variation on the format of the starting expression to process increases the complexity of the problem by a factor of 10, but worry not, that was exactly what I needed.

 

 

If the format is always the same, x#-x#, you could retrieve the using substr and constant digits (substr expression 1 1) to get the letter, (substr expression 2 1) to retrieve the digit. Since the digit is on a string format, you would need to transfer it to an integer (atoi), increment it, then turn it back to a string format (itoa) to concatenate (strcat) it with the letter(s) as follow

(strcat (substr expression 1 1) (itoa (+ 1 (atoi (substr expression 2 1 )))) (substr expression 3 2) (itoa (+ 1 (atoi (substr expression 5 1 )))))

But then, if the format of the starting expression changes, it would fail.

 

 

If the starting expression varies, then you have to take into consideration

the length of the string vary (obvious, right?) (cda1-x9)

there could be 1 or more numbers to increment (d97as) (F1G5-CS2)

number(s) to increment can be of 1 or more digits. (c12- c17)

it can start/end by a digit, a number or a text char/string. Yummyyyy!

 

 

The only choice left is to check char by char. For every character you must do as follow:

Retrieve the char, store it in a var
Check if the result is not a digit, go to next char.(and start over)
Check if the result is a digit, then you must...
         Retrieve the var & the following char, store it back in the var
         Check if the result is not a digit, go to next char, start over
         Check if the result is a digit, then you must...
                Retrieve the var & the following char, store it back in the var
                Check if the result is not a digit, go to next char, start over
                Check if the result is a digit, then you must...

If you don't know how many chars will be checked each time, and how many digits will there possibly be in a number, the checking function will have to call itself back if (and only if) required. Maybe you recognized the pattern, if you don't, that is what we call a recursive function. It is your lucky day, since I just learned few days ago one type of recursion (lambda embedded lambda, nifffffty!), and wanted to apply the concept. Maybe some other ways would have been easier (maybe not), and maybe I'm using a bazooka to kill a fly, but hey! killing a fly with a bazooka is sooooo cool! =)

 

 

Meanwhile

Every time you stumble onto the completion of a digit sequence, you must store it directly, or its position/length within the starting expression. I opted for the latter since if you know all the number positions within the string and their length, you can find and retrieve text parts by deduction.. The quantity of information being unknown, the best way to store it is (drum roll) a list! How convenient since we do that on LISt Processing =)

 

Next step.

Make the new expression, retrieving back text parts, and the digits (incrementing them).

 

 

The only things that I did not take into consideration:

a zero at the beginning of a number. (C05 would return C6). Could be done easily thought

text formatting

{\fArial|b1|i2|c1|p35;TEMPLATE

no way im going there =)

It don't work on mleader neither, dimensions, and can make dimensions within mtext look weird. 14/17" don't look natural to me. Oh, and don't try it on your dog, just in case =)

 

 

ps.: I left many alerts/princ and I commented them. supress the ";" in front, try to follow the flow. I left the building list princ. As for the way the returned list work, "c12-c217" would build that list; ((2 . 1) (2 . 2) (6 . 3))

the first dotted pair is ((nb of numbers found . needed constant)

every following dotted pair is (position of first digit of a number . length of number)

 

 

;;with this routine (made by Jef!, 2014-03-28) you will be able to
;;select any text, mtext or attribute containing any combinations of
;;digits and number, and it will return an expression with all the digit sequences
;;from the original selected expression will be incremented by 1, if any.
;ie: "c2-c4" will become "c3-c5", "99b22" will become "100b23"..
(defun c:increment ()
      (Jef!:IncrementDigitSequence)
  )
(defun Jef!:IncrementDigitSequence ( / *error* StartingPos EndingPos digitnumb wcmComp SEntity startingexp digitlist buildinginprogressflag ReturnExp tmp)
  (defun *error* (msg)
     (if (not (member msg '("Function cancelled" "quit / exit abort")))
         (princ (strcat "\nError: " msg))
     )
  )
  (setq StartingPos 1)
  (setq EndingPos 1)
  (setq digitnumb 0)
  (setq wcmComp (list " " "#" "##"))
  (while (equal nil SEntity)
         (setq SEntity (nentsel "Pick object to extract value (Text/Mtext/Block Attribute): \n"))
  )
(setq startingexp (cdr(assoc 1 (entget (car SEntity)))))
;(princ)
  ((lambda ( check )
     (check StartingPos EndingPos nil)
     )
     (lambda ( StartingPos EndingPos buildinginprogressflag / )
        (if (equal nil (nth EndingPos wcmComp))
            (setq wcmComp (append wcmComp (list (strcat (nth 1 wcmComp) (nth (- EndingPos 1) wcmComp)))  ))
        )
        ;(alert (strcat "Values at beginning \nStarting position: " (itoa Startingpos) "\nEnding position : "(itoa EndingPos)"\n résultat: "(substr startingexp StartingPos EndingPos) ))
        (if (wcmatch (substr startingexp StartingPos EndingPos) (nth EndingPos wcmComp))
            (progn
               ;(princ (substr startingexp StartingPos EndingPos));
               ;(princ "\n")
               ;(alert "1 - Match! RELOOP")
               (if (> (+ StartingPos EndingPos) (strlen startingexp))
                   (progn ; finito
                       ;(alert "finito1")
                       (setq digitnumb (+ 1 digitnumb))
                       (if (equal nil digitlist)
                           (setq digitlist (list (cons StartingPos EndingPos)))
                           (progn
                              (setq digitlist (append digitlist (list (cons StartingPos EndingPos))))
                           )
                       )
                      (setq digitlist (reverse (append (reverse digitlist)(list(cons digitnumb 1)))));cherry
                   );end prong finito
                   (progn
                       ;(alert "not finito")
                       (setq EndingPos (+ EndingPos 1))
                       (check StartingPos EndingPos t)
                   )
               )
               ;(princ "flag is :")
               ;(princ buildinginprogressflag)
               ;(princ "\n")
               ;(alert (strcat "recursive ending\nSPOS: "(itoa Startingpos)" , Ending position: "(itoa EndingPos)" , et wcmcomp: " (nth EndingPos wcmComp)))
            )
            (progn ; no match
               ;(princ "\nflag non valeur StartingPos : ");
               ;(princ StartingPos);
               ;(princ "\nflag non valeur EndingPos : ");
               ;(princ EndingPos);
               ;(princ "\n");
               ;(princ (substr startingexp StartingPos EndingPos));
               ;(princ "\n")
               (if (equal nil buildinginprogressflag)
                   (progn; no match & no flag
                      (if (> (+ StartingPos EndingPos) (strlen startingexp));
                          (progn ; finito 2
                             ;(alert "finito 2 - no match")
                             (if (equal nil digitlist)
                                 (progn;
                                    (alert "No digits were detected!\nPress ok to exit routine")
                                    (exit)
                                 )
                                 (progn
                                    (setq digitlist (reverse (append (reverse digitlist)(list(cons digitnumb 1)))));cherry
                                 )
                             )
                          );end prong finito
                          (progn
                              ;(alert "not finito")
                              (setq StartingPos (+ StartingPos 1))
                              (check StartingPos EndingPos nil)
                          )
                      )
                   )
                   (progn; no match flag ON
                      (setq buildinginprogressflag nil)
                      (if (equal nil digitlist)
                          (setq digitlist (list (cons StartingPos (- EndingPos 1))))
                          (setq digitlist (append digitlist (list (cons StartingPos (- EndingPos 1))) ));;;;;;;;;;;;;
                      )
                      ;(princ digitlist)
                      ;(princ "\n")
                      ;(alert "digitlist has been modified")
                      (setq digitnumb (+ 1 digitnumb))
                      (if (> (+ StartingPos EndingPos) (strlen startingexp))
                          (progn ; finito
                             ;(alert "finito3")
                             (setq digitlist (reverse (append (reverse digitlist)(list(cons digitnumb 1)))));cherry
                      ;(princ digitlist)
                   );end prong finito
                   (progn
                       ;(alert "not finito")
                       (setq StartingPos (+ StartingPos EndingPos))
                       (setq EndingPos 1)
                       (check StartingPos EndingPos nil)
                   )
               )
                      
                      
                      
                   )
               )
           )
       )
     )
     
  );lambdas
  (princ digitlist)(princ "\n")
  ;;;;;;----Finished retrieving, the fun begins here!----;;;;
  (if (equal digitlist nil)
      (princ "nothing to return!")
      (progn
         (if (= 1 (car (nth 1 digitlist))); start by digit
             (setq ReturnExp "");dont do *****
             (setq ReturnExp (substr startingexp (cdr(car digitlist))(- (car (car (cdr digitlist))) 1)));grab 1rst txt part
         )
         ;(alert ReturnExp)
         (setq tmp digitlist)
         (while (nth 2 tmp)
                (setq tmp (cdr tmp))
                (setq ReturnExp (strcat ReturnExp (itoa (+ 1 (atoi (substr startingexp (car(car tmp)) (cdr (car tmp)) ))))   ));digit(s)
                (setq ReturnExp (strcat ReturnExp (substr startingexp (+ (car(car tmp)) (cdr(car tmp)) )(-(car (car (cdr tmp))) (+ (car(car tmp)) (cdr(car tmp)) ) ))));lettre(s)
                ;(alert ReturnExp)
         )
         (setq tmp (cdr tmp)) ;lets handle last digit(s)
         (setq ReturnExp (strcat ReturnExp (itoa (+ 1(atoi (substr startingexp (car(car tmp)) (cdr (car tmp)) ))))   ))
            (if (/= (+ (car(last digitlist)) (- (cdr(last digitlist)) 1) ) (strlen startingexp));y = letter(s) at the end
                (setq ReturnExp (strcat ReturnExp (substr startingexp (+ (car(last digitlist)) (cdr(last digitlist))) (+ (- (strlen startingexp) (+ (car(last digitlist)) (cdr(last digitlist)))) 1) )))
            )
      )
  )
  (alert (strcat "The Starting Expression was: " StartingExp"\nSo the incremented expression is: " ReturnExp))
  (princ)
)
(princ "\nFly killing Bazooka incrementer loaded. Type \"increment\" to launch the command")
(princ)

Seems to work nice, ive tested and debugged with examples as these, Try it on texts/mtexts containing anything like 555, 5, c, c42-, c99-8, d17bd, c17bd43. c2-c5, 99b99999999, a4v6s9f6s0v99... and please keep the header =)

 

 

Special thank to cwake. Clint? Clint? Cliiiiiiiiiiiiint? =D

 

 

Have a great week-end!

Jef!

Posted

wow, great stuff but the routine is not finished or?

it only shows me the incremented number and doesn't offer me to place that text somewhere...also i have a challenge for you...what if i want to increment only part of the text from like a1-b1-c1 to a2-b1-c2 or to increment with different value different part like a1-b1-c1 to a2-b1-c5...i guess that could be done with a form of entering command modifiers 'starting place of 1.number to increment-value of increment,starting place of 2.number to increment-value of increment...' so in my example that would be

'increment,2-1,8-4'

Posted
wow, great stuff but the routine is not finished or?

it only shows me the incremented number and doesn't offer me to place that text somewhere...

Thanks! No it is not finished. For a starter, the 2nd part works as intended, but I did not optimize its readability at all. In your original post, you asked for an idea on how to increment two numbers separated by a hyphen which is actually more than what I did. As for "offering you to place that text somewhere..." I did ask you (amongst others) What do you want to do with the answer? Put it in an attribute of an existing block? on a new instance of a block insert? into a created mtext? You wont spend few seconds to answer my questions, and yet you want me to spend a lot more to mold my lisp to suits your needs, without even stating them clearly? Well well well..

 

also i have a challenge for you...what if i want to increment only part of the text from like a1-b1-c1 to a2-b1-c2 or to increment with different value different part like a1-b1-c1 to a2-b1-c5...i guess that could be done with a form of entering command modifiers 'starting place of 1.number to increment-value of increment,starting place of 2.number to increment-value of increment...' so in my example that would be

'increment,2-1,8-4'

Disregard some digits, and modify the increment of others? With lisp everything is possible, but different goal also quite often mean different path. Not to mention that I dont really see the advantage of launching a command that will extract all digits from an expression, and ask what increment I want to apply to every single one of them. At that point, why dont you simply change the digits yourself?

 

If you want to learn lisp, this place is one of the best I've seen. Beside giving you one part of my work, I took quite some time writing down my previous post to help you learn, but I have the feeling that learning might not the goal here. Am I wrong?

 

Feel free to post your work in progress, we'll be glad to help you dubug. If you don't mind, I have to go now, it is saturday o-clock! =)

Cheers,

Jef!

Posted

I didn't ask for this lisp, it was Artek so I don't know what he wants with the answer...I simply saw this post on forum and got few ideas about how it could be improved...as for learning , I learned some things but the problem is connecting it all in my head :)

Posted

Artek/Timislav, sorry for the mix up!

 

While killing flies with bazookas if fun, when doing complex routines its better to keep it as simple as possible. My next milestone will be to try to achieve my goals with different paths, then using a benchmark routine on them to see which one is the fastest. Sometimes doing so we get nice surprises.

 

About improving it, or should I say use it, depending on what is required, you could, instead of making an (alert) at the end feed the value to a (entmake) to create a text, mtext, or use mod to modify the assoc 1 of any existing text, mtext or block attribute. My goal on that one was to create the incrementation process, but I'm still not decided yet if I'm going to use it on block insertions or a table. Most probably I'll use it to fill attributes of a new block inserts.

 

I have tool ideas of more than 10 years as a draftsman to put into lisp, and as you say, the problem is connecting them all in my head :P

Posted

When we talk about speed I think Lee has that covered with his 'short' lisp he mentioned here, but the learning process is precious...and you said it right when it comes to ideas :thumbsup:

  • 1 month later...
Posted

Hi Jef!

 

 

Sorry I missed to see your reply. This website used to notify me by email whenever there's any response to my query and unfortunately that didn't happen this time. I really thought that no one ever noticed my post to be honest :(. Anyways, thank you very much for your effort. Really appreciate it. I may need sometime to digest your code as it's too complex for my level in programming. :)

Posted

Hi Jef!

 

 

Are you an instructor? If you're not then you should consider that because you have this ability to explain things clearly to people.

 

 

I tried running your code and it worked like a charm. I do apologise if I missed to mention a lot of important details on my query. My initial objective is just to get an idea on how to do it or a sample code perhaps and then use that as a sub-code to an existing one. It's only now that I realized that it's not going to be that simple. :(

 

 

What I actually need is to increment some selected texts and overwrite/replace the selected texts with the newly incremented ones. The Text_Inc by Lee Mac is so close to how I really want it. Thanks ever so much, Lee for that by the way. If only there's a way to limit the selection within a specified group of numbers, say for example, starting with C45 and ending with C98, instead of selecting all if not each number one by one. With a given increment value of say 1, the code will increment and replace the values of the texts starting from C45 up to C98 including the numbers in between that are hyphenated like C50-C57. The code should work on plain numbers as well to be more flexible. If that is possible to include in your program then that would be a double yummy! :) Thanks again.

Posted
Here is an alternative program: Increment Numbers in Text

 

 

Hi Lee Mac,

 

 

Thanks for that. Your code is really close to what I need. I'm trying to understand every line of it hoping I'd be able to tweak it a little to suit my requirements. My problem is I'm not very familiar with vlisp so I'm wondering if you'd be able to give me hand on this part where I'm now struggling with:

 

I want to replace this selection set:

(if (ssget "_X" '((0 . "MTEXT,TEXT")(1 . "*#*")))

 

to select a range of numbers. Say, select only the numbers starting from 23 up to 45 instead of the "all" or by manual selection. Please let me know if you need more info on this.

 

 

Many thanks.

Posted
I want to replace this selection set:

 

(if (ssget "_X" '((0 . "MTEXT,TEXT")(1 . "*#*")))

 

to select a range of numbers. Say, select only the numbers starting from 23 up to 45

 

Change:

(1 . "*#*")

To:

(1 . "2[3-9],3[0-9],4[0-5]")

Posted
Change:
(1 . "*#*")

To:

(1 . "2[3-9],3[0-9],4[0-5]")

 

 

Hi Lee Mac,

 

 

Thanks for your reply. I just realised that I forgot to mention the most important words in my query and that is "by prompt". Apologies for that Lee. I actually meant as two prompts like: "From number:" and "To number:". Your code is selecting either all the numbers or by manual selection -- can I have them only as prompts because there are just too many texts/numbers to be selected manually and not all of them need to be replaced?

Posted
Hi Jef!

Sorry I missed to see your reply. This website used to notify me by email whenever there's any response to my query and unfortunately that didn't happen this time.

No problem Artek. I'm not 100% sure but I think that I don't get all notifications either. I just saw your reply as well.

Hi Jef!

Are you an instructor? If you're not then you should consider that because you have this ability to explain things clearly to people.

I tried running your code and it worked like a charm. I do apologise if I missed to mention a lot of important details on my query. My initial objective is just to get an idea on how to do it or a sample code perhaps and then use that as a sub-code to an existing one. It's only now that I realized that it's not going to be that simple. :(

I'm not an instructor, I'm just a 2nd-year-padawan-guy who got carried away a little, but thanks! :)

I had a very basic knowledge but decided to dive seriously into it maybe 6 months back. For someone who wants to learn on his own (like me) this community is a great resource. Plenty of examples, explanations, and people with different backgrounds (AutoLisp, VLisp, ActiveX..) I've read few very detailed explanations here and there about a bunch of functions and most of the times I've learned much more from them then the basic help from autodesk. I try to give some help back when I can, not to mention that the best way to learn is to practice. In my case, few days prior to your first post one member helped me understand lamda function and explained me recursive lambda embedded lamba concept, so helping you helped me as well

can I have them only as prompts because there are just too many texts/numbers to be selected manually and not all of them need to be replaced?
With lisp everything is possible, just dive and give it a try! If you still have issues to work out, post your work in progress.
Posted

Hi Jef,

 

To be honest with you it would take me ages to produce a code like you did. I tried to study each line but I just ended up scratching my head in confusion. Also tried to modify it but I'm not sure what I'm supposed to do or even where to start. :)

 

Going back to our topic. Lee Mac suggested his code earlier on this post. I've attached again the link for your reference below:

 

Here is an alternative program: Increment Numbers in Text

 

It's a brilliant code same as your one only a bit shorter and easy :unsure: to follow for my level! It would have been perfect for my need if only there are prompts for starting and ending numbers to process. I'm still hoping that either you or Lee Mac can help me with this request. Cheers!

Posted

Hi Artek.

 

I had the same kind of thoughts few months back. I rolled up my sleeves and dug in because I really wanted to learn lisp. At the beginning, Lee drop into one of my threads and gave me equivalences of some things I made in AutoLisp and commands. He made the same things in VLisp and ActiveX. "Here's some food for thoughts" he said. At first I freaked out a little and discarded most of it saying that I wasn't at this level yet, and wanted to do it only by lisp because at that time I had no knowledge of VLisp and ActiveX. Later on, I started to try to get a hand onto VLisp and ActiveX, and wasn't able to achieve what I wanted. I googled what I needed and.. the first result was in that "food for thoughts" that I discarded on my very own thread. I don't know how someone can laugh and feel bad at the same time, but I manage to do it. :P

 

I must say that Lee is one of the best and most active member that I had the chance to stumble upon not only here, but in many other forums (autodesks, augi...) and I'm pretty sure he has over 50 000 posts all added together (over 16 000 here). And beside "you are welcome" at the end of threads, most of them are simply gold mines. He has a way to simplify code and achieve things without unnecessay detours. That comes with experience. To be perfectly honest with you, I would not be comfortable modifying one of Lee Mac's code (to mold it to suit your needs). It would be the same as asking any painter to do touch ups to The Mona Lisa because even if its not the way da Vinci made it, you'd like to see it with a red background to fit with your couch. I hope you'll understand. :)

 

It would take you ages to produce such code? Maybe it would take you some time, but it is not impossible. Few things that I can tell you: put only 100 hours in Lisp, you'll be amazed of what you will be able to achieve. When I make Lisps, I always add princ/prompts to monitor variables, and alerts to "freeze" the execution. As long as I don't hit the "ok" button, the lisp is paused. Depending on the popup alert displayed, I know exactly where the execution paused (searching for the popup ed alert into my code), and looking at the lines printed on my cad session, I monitor my variables. When I understand whats going on, I hit "ok" to resume to the next alert. I could have erased them, the lisp would be much shorter, but I didn't; I commented them (by adding ";" in front of them). My code might look longer for that, but it has a higher educative purpose; suppress all the ";" and you'll be able to follow the execution of the code line by line. I'm not as fluent as Lee to make lisp routines, that one took me in between 12 to 14 hours to make. I'm glad I did it though.

 

I know that my code isn't as efficient as Lee's, but I "dare" you to uncomment every one of my princ/alerts, and spend only half the time that I took to make the lisp to really try to understand it. If you don't know a function, google and study it as needed then go back to the execution. You WILL get most of it. Give yourself a chance! You might have to spend some hours but every time you'll make new connections and learn new things, you will potentially save a lot more making lisp to automatically do redundant tasks. See that as an investment.

 

You went from Please give me an idea on how to to I want to replace this to the code Lee generously gave you to I actually meant as two prompts like: "From number:" and "To number:"... sometimes the modification is simple, but sometimes different goal also quite often mean different path. On the last request my feeling (as a few months old lisper) is that it would take quite some tweeking to achieve your goal.

 

Sorry for the length of my post, I write too much, and add too much details (I know), but I'd be curious to have your estimation on these:

-How much time do you think I took to write the code, the detailed explanation and that message?

-How much time do you think Lee took to write his original routine, read this thread and tweak it at your request?

-How much time did you spend to try to study our routines to learn new stuff?

Give it a try! :)

 

The way I see things; If you want to get some advices on how to proceed, you need help to understand some functions, or want feedback on your routines, this place is the best around. If you want the best lispers to give you custom tools for free, you misinterpreted the goal of this forum...

 

That being said, I wish you good luck on achieving your goals.

Cheers,

Jef!

The views and opinions expressed in this post are mine alone and are not necessarily representative of the views and opinions of any other members nor cadtutor.net... just saying =)

Posted

Thanks very much for the thoughts Jef! I'll take those into consideration. I got mixed reactions after reading your post - I don't know if I should feel encouraged by it or feel guilty about the whole thing. I do appreciate your time and effort and I'll try to heed your advice and hopefully be in the position to give advice to others in the future. Glad that there are people like you around.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...