Calculation values in loop is not preserved

Calculation values in loop is not preserved

nam.lethai1995
Enthusiast Enthusiast
931 Views
13 Replies
Message 1 of 14

Calculation values in loop is not preserved

nam.lethai1995
Enthusiast
Enthusiast
(defun c:bka (/ ss len i sum blk blkref atts attval)
  (setq ss    (ssget)
        len   (sslength ss)
        i     0
        sumsv 0
        sumcd 0
        list1 ()
        list2 ()
  )
  (repeat len
    (progn
      (setq blk     (ssname ss i)
            blkref1 (entnext blk)
            dxf1    (entget blkref1)
            blkref2 (entnext blkref1)
            dxf2    (entget blkref2)
      )
      (cond
        ((eq
           (strcase (cdr (assoc 2 dxf1)) 1)
           "so_vach"
         )
         (progn
           (setq sv    (- (atof (cdr (assoc 1 dxf1))) 0.5)
                 sumsv (+ sumsv sv)
                 cd    (atof (cdr (assoc 1 dxf2)))
           )
           (if (assoc cd list1)
             (progn
               (setq temp (+ sv (cdr (assoc cd list1))))
               (subst (cons cd temp) (assoc cd list1) list1)
             )
               (setq list1 (cons (cons cd sv) list1))
           )
         )
        )
        ((eq
           (strcase (cdr (assoc 2 dxf1)) 1)
           "chieu_dai"
         )
         (progn
           (setq attval (atof (cdr (assoc 1 dxf1)))
                 sumcd  (+ sumcd attval)
           )
         )
        )
      )
      (setq i (1+ i))
    )
  )
  (princ (strcat "\n" "so vach 7.3: " (rtos sumsv)))
  (foreach ele list1
    (princ (strcat "\n" (rtos (cdr ele)) " vach " (rtos (car ele)) "(m)"))
  )
  (princ (strcat "\n" "tong cd vach 7.1: " (rtos sumcd 2 1)))
  (princ)
)
I am making lisp that count and display block's attributes. As showing in video, while the total number of road markings showing by lisp is just fine, the number of marks of each length is showing wrong. Calculated seem to stuck with the 1st encounterd value of each length type that it approaching
0 Likes
Accepted solutions (3)
932 Views
13 Replies
Replies (13)
Message 2 of 14

Sea-Haven
Mentor
Mentor

Ok another way around it we had a linetype that was the spacing for the road markings so the length can be used to work out markings. Made into a pline with a width much easier.

 

*STATCON1000,__  __  __  __  __  __
A,0.60,-0.60
Message 3 of 14

nam.lethai1995
Enthusiast
Enthusiast

Thanks for the helpful alternative solution but i still want to find out why my code wont work. Can you take a look at it?

0 Likes
Message 4 of 14

johnyDFFXO
Advocate
Advocate
Accepted solution

@nam.lethai1995 wrote:
(defun c:bka (/ ss len i sum blk blkref atts attval)
  (setq ss    (ssget)
        len   (sslength ss)
        i     0
        sumsv 0
        sumcd 0
        list1 ()
        list2 ()
  )
  (repeat len
    (progn
      (setq blk     (ssname ss i)
            blkref1 (entnext blk)
            dxf1    (entget blkref1)
            blkref2 (entnext blkref1)
            dxf2    (entget blkref2)
      )
      (cond
        ((eq
           (strcase (cdr (assoc 2 dxf1)) 1)
           "so_vach"
         )
         (progn
           (setq sv    (- (atof (cdr (assoc 1 dxf1))) 0.5)
                 sumsv (+ sumsv sv)
                 cd    (atof (cdr (assoc 1 dxf2)))
           )
           (if (assoc cd list1)
             (progn
               (setq temp (+ sv (cdr (assoc cd list1))))
               (setq list1 (subst (cons cd temp) (assoc cd list1) list1))
             )
               (setq list1 (cons (cons cd sv) list1))
           )
         )
        )
        ((eq
           (strcase (cdr (assoc 2 dxf1)) 1)
           "chieu_dai"
         )
         (progn
           (setq attval (atof (cdr (assoc 1 dxf1)))
                 sumcd  (+ sumcd attval)
           )
         )
        )
      )
      (setq i (1+ i))
    )
  )
  (princ (strcat "\n" "so vach 7.3: " (rtos sumsv)))
  (foreach ele list1
    (princ (strcat "\n" (rtos (cdr ele)) " vach " (rtos (car ele)) "(m)"))
  )
  (princ (strcat "\n" "tong cd vach 7.1: " (rtos sumcd 2 1)))
  (princ)
)
I am making lisp that count and display block's attributes. As showing in video, while the total number of road markings showing by lisp is just fine, the number of marks of each length is showing wrong. Calculated seem to stuck with the 1st encounterd value of each length type that it approaching

 

Message 5 of 14

nam.lethai1995
Enthusiast
Enthusiast

Omg! Dont know why i cant see that anoying bug =))) Thanks you so much Johny

0 Likes
Message 6 of 14

johnyDFFXO
Advocate
Advocate

Glad to help. But you should be able to find such an issue within a minute if you knew how to debug your code properly. THIS looks good...

Message 7 of 14

martti.halminen
Collaborator
Collaborator
Accepted solution

A few minor style suggestions:

 

- COND has an implicit PROGN for the consequent clauses, so adding an explicit PROGN there doesn't give you anything new. So it is just unnecessary clutter, and another place to add a typo or mismatched parenthesis.

 

- In the mainstream Lisp culture (Common Lisp etc.) the consensus is to write the closing parentheses at the end of the line instead of each on its own line. Saves vertical space, and is easier to read. Generally, the parentheses are for the compiler, programmers read the structure based on the indentation.

[In practice this requires an editor that shows paired parentheses and can indent Lisp according to structure. Most CL  programmers use Emacs for this.]

 

Your program modified to this style:

(defun c:bka (/ ss len i sum blk blkref atts attval)
  (setq ss    (ssget)
        len   (sslength ss)
        i     0
        sumsv 0
        sumcd 0
        list1 ()
        list2 ())
  (repeat len
          (progn
            (setq blk     (ssname ss i)
                  blkref1 (entnext blk)
                  dxf1    (entget blkref1)
                  blkref2 (entnext blkref1)
                  dxf2    (entget blkref2))
            (cond
              ((eq (strcase (cdr (assoc 2 dxf1)) 1)
                   "so_vach")
               (setq sv    (- (atof (cdr (assoc 1 dxf1))) 0.5)
                     sumsv (+ sumsv sv)
                     cd    (atof (cdr (assoc 1 dxf2))))
               (if (assoc cd list1)
                   (progn
                     (setq temp (+ sv (cdr (assoc cd list1))))
                     (setq list1 (subst (cons cd temp) (assoc cd list1) list1)))
                   (setq list1 (cons (cons cd sv) list1))))
              ((eq (strcase (cdr (assoc 2 dxf1)) 1)
                   "chieu_dai")
               (setq attval (atof (cdr (assoc 1 dxf1)))
                     sumcd  (+ sumcd attval))))
            (setq i (1+ i))))
  (princ (strcat "\n" "so vach 7.3: " (rtos sumsv)))
  (foreach ele list1
    (princ (strcat "\n" (rtos (cdr ele)) " vach " (rtos (car ele)) "(m)")))
  (princ (strcat "\n" "tong cd vach 7.1: " (rtos sumcd 2 1)))
  (princ))

 (assuming the web page doesn't clobber the indentation)

 

Message 8 of 14

Kent1Cooper
Consultant
Consultant

@martti.halminen wrote:

....

- COND has an implicit PROGN for the consequent clauses, so adding an explicit PROGN there doesn't give you anything new. So it is just unnecessary clutter, and another place to add a typo or mismatched parenthesis.

....


The same with (repeat) -- the (progn at line 10 of the modified code is also unnecessary [along with its concluding right parenthesis later].

Kent Cooper, AIA
0 Likes
Message 9 of 14

nam.lethai1995
Enthusiast
Enthusiast

Dont know why but if i remove the progn of cond function there will be "bad function error" appeare

0 Likes
Message 10 of 14

Kent1Cooper
Consultant
Consultant
Accepted solution

@nam.lethai1995 wrote:

.... if i remove the progn of cond function there will be "bad function error" appeare


Do you mean that @martti.halminen 's code in Message 7 causes that error?  [That's the one that removed (progn) from within a (cond) function.]  If not, post the code as you modified it.

 

[Don't use the "Reply to the topic..." slot at the bottom.  Things entered there are always shown as being in Reply to the author of Message 1, in this case to yourself.  Use the REPLY button near the bottom right of the Message you're Replying to.]

Kent Cooper, AIA
Message 11 of 14

martti.halminen
Collaborator
Collaborator

So show the changed code and the exact error report.

0 Likes
Message 12 of 14

john.kaulB9QW2
Advocate
Advocate

@martti.halminen wrote:

...>%

- In the mainstream Lisp culture (Common Lisp etc.) the consensus is to write the closing parentheses at the end of the line instead of each on its own line. Saves vertical space, and is easier to read. Generally, the parentheses are for the compiler, programmers read the structure based on the indentation.

[In practice this requires an editor that shows paired parentheses and can indent Lisp according to structure. Most CL  programmers use Emacs for this.]

...>%


"...but most good programmers use Vim."

You must have hit "post" too early so I thought, I'd leave that here.

 

another swamper
0 Likes
Message 13 of 14

nam.lethai1995
Enthusiast
Enthusiast

It turn out that i must not only remove progn but also the parenthesis that come along with it. I was thought that each condition's case must contains only 2 expressions inside it but it turn out that after logic expression we can out as many single expressions as we want

0 Likes
Message 14 of 14

nam.lethai1995
Enthusiast
Enthusiast

Yeah, am using vscode's Format Code so the code apperance may looking weird to you

0 Likes