Nickvnlr Posted March 14 Posted March 14 I have this lisp that calculates friction loss in a pipe based on the length of line(s) selected and size/flow input by user. My issue: the trade size of pipe is not the actual ID. I would like to incorporate a lookup table somehow. I tried a hash table but ACAD didn't recognize "make-hash-table" ?? Here's the working LISP without table: (defun C:Hazen () (setq ss (ssget)) (if ss (progn (setq pipeDiameter (getreal "\nEnter pipe diameter (in inches): ")) (setq flowRateGPM (getreal "\nEnter flow rate (GPM): ")) (setq roughnessFactor 140) (setq pipeLength 0.0) (setq n (1- (sslength ss))) (while (>= n 0) (setq ent (entget (ssname ss n)) obj (cdr (assoc 0 ent))) (cond ((= obj "LINE") (setq pipeLength (+ pipeLength (distance (cdr (assoc 10 ent)) (cdr (assoc 11 ent)))))) ((= obj "ARC") (setq l (cdr (assoc 40 ent))) (if (minusp (setq l (- (cdr (assoc 51 ent)) (cdr (assoc 50 ent))))) (setq l (+ pi pi l))) (setq pipeLength (+ pipeLength l))) ((or (= obj "CIRCLE") (= obj "SPLINE") (= obj "POLYLINE") (= obj "LWPOLYLINE") (= obj "ELLIPSE")) (setq pipeLength (+ pipeLength (getvar "perimeter")))) (T nil)) (setq n (1- n))) ; Calculate pressure loss using Hazen-Williams equation (setq pressureLoss (/ (* (* 4.55 (expt (/ flowRateGPM 140) 1.852)) (/ pipeLength 12)) (expt pipeDiameter 4.87)) ) (alert (strcat "Pressure loss (psi): " (rtos pressureLoss 2 2))) ) (alert "No valid pipe selected.") ) (princ) ) I was hoping to add something like this and lookup the values to use for the calculation: (setq pipe-hash (make-hash-table :test 'equal)) (setf (gethash '1 pipe-hash) "1.189") (setf (gethash '1.5 pipe-hash) "1.72") (setf (gethash '2 pipe-hash) "2.22") (setf (gethash '3 pipe-hash) "3.23") (setf (gethash '4 pipe-hash) "4.267") (setf (gethash '5 pipe-hash) "5.27") (setf (gethash '6 pipe-hash) "6.282") (setf (gethash '8 pipe-hash) "7.82") (setf (gethash '10 pipe-hash) "9.78") (setf (gethash '12 pipe-hash) "11.73") (setf (gethash '15 pipe-hash) "14.66") (setf (gethash '18 pipe-hash) "17.92") (setf (gethash '21 pipe-hash) "21.13") (setf (gethash '24 pipe-hash) "23.77") (setf (gethash '27 pipe-hash) "26.79") Is there a better way or something that works? Thanks in advance! Quote
mhupp Posted March 14 Posted March 14 Don't know what your quite asking for. maybe a cond testing the value. (cond ((if (= test 1)) (setq pipe-hash 1.189) ;double ) ((if (= test 1.5)) (setq pipe-hash "1.720") ;string ) ) Quote
JerryFiedler Posted March 15 Posted March 15 You could use a list of dotted pairs. Make a list such as (setq pipelst '((1 . 1.189)(1.5 . 1.72)(2 . 2.22) .......) I am not on my computer so I can't properly write code. You then ask user for nominal size and using autolisp assoc command get the actual diameter with the cdr command. I know this is not very specific but look up dotted pairs , assoc and cdr commands. 1 Quote
Nickvnlr Posted March 15 Author Posted March 15 14 hours ago, JerryFiedler said: You could use a list of dotted pairs. Make a list such as (setq pipelst '((1 . 1.189)(1.5 . 1.72)(2 . 2.22) .......) I am not on my computer so I can't properly write code. You then ask user for nominal size and using autolisp assoc command get the actual diameter with the cdr command. I know this is not very specific but look up dotted pairs , assoc and cdr commands. I will look into that. Thank you. Quote
Nickvnlr Posted March 15 Author Posted March 15 14 hours ago, mhupp said: Don't know what your quite asking for. maybe a cond testing the value. (cond ((if (= test 1)) (setq pipe-hash 1.189) ;double ) ((if (= test 1.5)) (setq pipe-hash "1.720") ;string ) ) So you would do an IF statement for each condition? I am looking for a way to do this, except with a large data set. Something like an array or lookup table stored in the LISP. Quote
Steven P Posted March 15 Posted March 15 (edited) You could do 'if' or better 'cond'. I'd be like Jerry and go for dotted pairs: (setq pipe-hash (list (cons 1 "1.189") (cons 1.5 "1.72") (cons 2 "2.22") (cons 3 "3.23") (cons 4 "4.267") (cons 5 "5.27") (cons 6 "6.282") (cons 8 "7.82") (cons 10 "9.78") (cons 12 "11.73") (cons 15 "14.66") (cons 18 "17.92") (cons 21 "21.13") (cons 24 "23.77") (cons 27 "26.79") )) ; end setq, end list Note the use of cons allows for some calculation within each dotted pair, if these are static could use '(1 "1.189") for example, similarly the (lidt could be replaced with a '( if all the (cons .... ) are static and to interrogate this to get the value use (assoc ....) (setq Size (cdr (assoc 1.5 Pipe-Hash))) where 1.5 is the value you want, cdr above selects the 2nd item in the list, without it it returns the whole dotted pair Edited March 15 by Steven P Quote
Nickvnlr Posted March 15 Author Posted March 15 Dotted pairs worked great. Thank you! Here is the completed LISP. ;Created by Nick Van Laar for use @ STREAMLINE IRRIGATION ;Calculates the friction loss and velocity of water through common sizes of PVC for the distance of user selected lines/polylines/arcs/etc. (defun C:Hazen () (setq ss (ssget)) (if ss (progn (setq pipeDiameter (getreal "\nEnter pipe diameter (in inches): ")) (setq flowRateGPM (getreal "\nEnter flow rate (GPM): ")) (setq pipeLength 0.0) (setq pipelist '((1 . 1.189) (1.5 . 1.72) (2 . 2.22) (3 . 3.23) (4 . 4.267) (5 . 5.27) (6 . 6.282) (8 . 7.82) (10 . 9.78) (12 . 11.73) (15 . 14.66) (18 . 17.92) (21 . 21.13) (24 . 23.8) (27 . 26.8))) (setq n (1- (sslength ss))) ;Adapted TLEN.LSP - (C) Tee Square Graphics (while (>= n 0) (setq ent (entget (setq itm (ssname ss n))) obj (cdr (assoc 0 ent)) l (cond ((= obj "LINE") (distance (cdr (assoc 10 ent))(cdr (assoc 11 ent)))) ((= obj "ARC") (* (cdr (assoc 40 ent)) (if (minusp (setq l (- (cdr (assoc 51 ent)) (cdr (assoc 50 ent))))) (+ pi pi l) l))) ((or (= obj "CIRCLE")(= obj "SPLINE")(= obj "POLYLINE") (= obj "LWPOLYLINE")(= obj "ELLIPSE")) (command "_.area" "_o" itm) (getvar "perimeter")) (T 0)) pipeLength (+ pipeLength l) n (1- n))) ;Get pipe ID (defun get-value (key 1st) (cdr (assoc key 1st))) (setq pipeID (get-value pipeDiameter pipelist)) ;Get roughnessFactor (setq rCoef nil) (IF (>= pipeDiameter 8) (setq rCoef 150) (setq rCoef 140) ) ; Calculate pressure loss using Hazen-Williams equation (setq pressureLoss (/ (* (* 4.55 (expt (/ flowRateGPM rCoef) 1.852)) (/ pipeLength 12)) (expt pipeID 4.87)) ) ; Calculate Velocity (setq velocity (/ (* 0.408 flowRateGPM) (expt pipeID 2)) ) (alert (strcat "Pressure loss (psi): " (rtos pressureLoss 2 3) " Velocity (fps): " (rtos velocity 2 2))) ) (alert "No valid pipe selected.") ) 1 Quote
Nickvnlr Posted March 15 Author Posted March 15 Quick question, I know it's in the TLEN section, but is there a way to get rid of the perimeter/area/length display? Thank you. Quote
BIGAL Posted March 16 Posted March 16 (edited) Just me I dont use dotted pairs in list ((1.0 0.875)(1.25 1.034) the (car (nth x lst)) and (cadr (nth x lst)) are values from a list, as I say just my preference. Edited March 16 by BIGAL Quote
Recommended Posts
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.